An unsourced trusted by N teams line doesn’t reach your draft
The claim-scan hook stops quotes with a name attached and as seen on lines before they reach a copy file, unless your evidence table names them or the line carries a [NEEDS PROOF] or [SLOT: …] mark.
This box runs a JavaScript copy of the hook’s social-proof check in your browser, against an empty Evidence table. The hook itself is claim_scan.py.
Add [NEEDS PROOF: reason] to the line and it goes through.
The problem
You’ve shipped your product, and now you have to write its launch post or landing page yourself. You ask Claude Code for a post, then strip the hype and delete the made-up numbers by hand.
How it works
1. Install. On an empty git repo, it adds CLAUDE.md, MARKETING_MAP.md, .claude/, agent_docs/, CLAUDE.project.md and linear.md. An existing CLAUDE.md is kept, and the kit’s rules won’t load. To fix that, move your rules into CLAUDE.project.md and rerun with --force.
2. Fill the map. /brief fills Product, Audience, Positioning and Voice in MARKETING_MAP.md, from your repo and then short questions. Each claim you want to use gets a row in its Evidence table: the claim, the source, the date you checked it.
3. Draft. claim-scan runs on each write to a copy file. Here is claim-scan stopping a one-line file on this page’s own first write:
BLOCKED by claim-scan: social proof with no source. "Trusted by 400 teams.": "Trusted by 400 teams" with no Evidence row Never invent a testimonial, name, logo or "used by" line (agent_docs/claims-and-evidence.md → Never invent). Add an Evidence row that names the person or the phrase, or leave a labelled slot: [SLOT: customer quote, needs a real one].
The write goes through if Evidence names the phrase, or if the line carries [NEEDS PROOF] or [SLOT: …].
Numbers aren’t blocked: you get a warning after the write, and the write stays.
4. Publish calls go through a gate. A second hook, publish-gate.sh, denies publish calls to a channel with publish: off. It turns the rest into a permission prompt showing channel, time and text.
The same post, two maps.
With publish: off, which is how all six channels are set on this site’s own map:
BLOCKED by publish-gate: LinkedIn has publish: off in MARKETING_MAP.md → Channels. Save it as a draft instead. Turning a channel on needs the user's approval.
With LinkedIn set to publish: on in a test copy of that map:
publish-gate: mcp__buffer__create_post will publish.
- Channel:
- Time:
- not given (queue default)
- Text:
- I put the evidence check in a hook.
Approving this prompt approves this one post only.
The call was piped straight into publish_gate.py. Nothing was sent to Buffer.
Proof
The 8 hook test files pass, 162 checks in all, on one run at commit 3eca77a. These test the hooks, not marketing results. Read the tests.
The kit ships 16 skills, 3 agents and 8 hooks. Count them in .claude/.
I have no user feedback yet, so there is no quote on this page.
Limits
The hook matches patterns. It blocks a quote only when a name follows it, so an unattributed quote gets through. Invented numbers get a warning after the write, and the write stays. It checks that Evidence names the phrase, not that the row is true.
The publish gate has a gap. It can’t read the conversation, and bypassPermissions mode may skip the prompt.
Install. The clone is the one path that works today. There is no npx package and no /plugin install yet.
Not tried yet. Publishing through a real Buffer account, and /video-produce end to end.
Not for you if you want a content calendar, analytics or ad management, or you want posts to go out without a human approving each one.
Start here
From your product’s repo. MIT licence.
git clone https://github.com/tansuasici/claude-marketing-kit ~/claude-marketing-kit
bash ~/claude-marketing-kit/install.sh "$PWD"
Your next command is /brief.