Imported from lukesw55/ai-pm-toolkit (
.agents/skills/humanize-deliverables/SKILL.md). Install upstream withnpx skills add lukesw55/ai-pm-toolkit --skill humanize-deliverables. Copyright stays with the author.
Humanize-deliverables: voice gate before delivery
This skill is a gate, not a writer. It sits between drafting and delivery and ensures every external-facing prose artefact has been stripped of AI tells before another human reads it.
Why this exists
Your deliverables — exec memos, PRDs, Confluence pages, Slack updates, customer comms — get read by leadership, customers, and cross-functional partners. Text that smells like ChatGPT erodes credibility silently. The humanizer skill (../humanizer/SKILL.md) carries the AI-writing pattern catalogue from Wikipedia's "Signs of AI writing". This gate enforces a pass through it before the artefact ships.
When to trigger
Always trigger before:
- calling the Atlassian MCP
createConfluencePage/updateConfluencePage/createConfluenceFooterComment/createConfluenceInlineComment(tool names shown as theirmcp__<server>__<tool>suffix — the server prefix varies by environment) - calling the Slack MCP
slack_send_message/slack_send_message_draft/slack_create_canvas/slack_update_canvas - calling Jira comment tools (
addCommentToJiraIssue) - pasting "here is the final X" into chat for the user to copy-paste elsewhere
- producing release notes, launch comms, FAQs, public-docs copy
- producing exec memos, status reports, QBR slide text, DACI rationale narrative
- producing customer-facing copy (B2B emails, KB articles, in-app strings, marketing-adjacent text)
- producing PRDs that will be circulated outside the immediate team
Skip when:
- replying conversationally to the user in this session ("yes, here's what I found")
- emitting raw machine output: JSON, logs, CSVs, terminal commands
- writing/editing code, config, schemas
- structured ticket fields (Jira labels, components, fixVersion) — only the prose body of a ticket is in scope
- internal notes / scratchpads /
.ai/memory/updates that nobody outside the user will read
When unsure → run the gate. The cost of an unnecessary pass is seconds; the cost of shipping AI-tinted prose to a customer or to leadership is real reputational drag.
How to run the gate
-
Draft normally. Don't pre-censor while drafting — easier to clean up than to write under constraint.
-
Pull the catalogue. Read
../humanizer/SKILL.md(or the relevant section if you've already loaded it this session). Itsreferences/hold the full pattern list with before/after examples;../humanizer/references/progressive-loading.mdsays which file fits the text. -
Sweep for the patterns that bite hardest in PM/Eng prose (this is the high-yield subset of humanizer's catalogue):
- Em and en dashes — the final text carries none unless the author's own writing sample uses them (humanizer §14); replace each with a period, comma, colon, or parentheses, and check spaced dashes and double hyphens too
- Rule of three — "fast, reliable, and scalable" reads like AI; cut to two or expand to a real list
- Link-words as throat-clearing — "Furthermore", "Moreover", "Additionally", "It is important to note that", "In the context of"
- Inflated verbs / vocabulary — "delve into", "leverage", "underscore", "navigate", "robust", "seamless", "comprehensive", "holistic", "tapestry", "foster", "facilitate"
- Vague attributions — "studies show", "experts agree", "research indicates" without citation
- Superficial -ing analyses — "...highlighting the importance of...", "...showcasing the synergy of...", "...underscoring the need for..."
- Promotional / marketing register — "we are excited to announce", "best-in-class", "cutting-edge", "game-changer"
- Negative parallelisms — "not just X, but Y", "it's not about X — it's about Y" (rarely earns its weight)
- Passive voice when active is shorter — "the decision was made" → "we decided"
- Hedging stacks — "may potentially be able to" → "can"
-
Final anti-AI pass (humanizer Rewrite process, step 3; mandatory). Ask: "What still makes this obviously AI-generated?" — name the remaining tells in one short sentence. Then revise.
-
Substance check. AI-tell removal can quietly strip the load-bearing content; this pass restores it. For every list of suggestions / findings / actions in the draft, audit each item against three checks:
- Does it carry action + example/anchor + why-it-matters? A bullet that says "cross-team dependency as a first-class concept (#1)" without saying what to do or what fixes fails. Roughly 2–4 sentences per item is the right density.
- Would this bullet read identically if the initiative were a different feature on the same team? If yes, it's padding. Drop it or rewrite to carry initiative-specific signal.
- If the recipient could ignore the message and still understand what was meant just by reading the headlines, is the message too thin? The recipient should be able to act on at least one item without pinging back for context.
If any bullet fails, expand or cut — never leave category labels masquerading as content. A 290-word substantive deliverable beats a 70-word polished placeholder.
-
Preserve voice, strip polish. Write lean, direct, evidence-first, with explicit decisions and named asks. The gate removes AI texture; it does not remove the author's cadence, jargon, or evidence density. Concretely: keep shorthand the reader shares and drop internal jargon they do not; attribute load-bearing quotes to a named source; drop framework labels lifted into prose; prefer a humble peer voice over a presenter voice.
-
Mark the final bytes (REQUIRED for hard-gated tools). A
PreToolUsehook in.claude/settings.json(Claude Code) and.codex/hooks.json(Codex) blocks the publish/send MCP tools (createConfluencePage,updateConfluencePage,createConfluenceFooterComment,createConfluenceInlineComment,createJiraIssue,editJiraIssue,addCommentToJiraIssue,slack_send_message,slack_send_message_draft,slack_schedule_message,slack_create_canvas,slack_update_canvas) until a sha256 sentinel matches the prose body. Run:printf '%s' "<final body, exact bytes>" | hooks/humanize-mark.sh -Or pass the body as an argument:
hooks/humanize-mark.sh "<final body>"The helper writes
.ai/gates/humanized/<hash>.flag(gitignored). The hook recomputes the hash fromtool_input(longest string wins) and only allows the call if the flag exists. Any byte change after marking — one extra newline, one swapped emoji — invalidates the flag; mark again with the EXACT bytes that will go to the tool. -
Deliver. Call the publish/send tool, or hand the cleaned text to the user.
Voice anchors per destination
Different destinations want different shapes; the gate respects that.
- Exec memos / leadership briefs — short sentences. Headed claims. Evidence inline (not in footnotes). No throat-clearing. First sentence states the decision or ask.
- Confluence pages — headed sections, tables for comparisons, decisions explicit, evidence linked. Status line at top ("Published — informative / factual" / "Draft — pending review").
- Slack — first sentence carries the ask or update. No "Hi team, hope you're well". No emoji unless your prior messages in the channel use them.
- Release notes — user-language, not internal-language. "X works now" beats "the X experience has been enhanced". Skip the "we are thrilled" opening.
- Customer comms (B2B) — warm but not effusive. Concrete benefit before brand voice. No "we are excited to announce".
- PRDs / specs — problem before solution. Non-goals named. Success criteria measurable. Cut adjectives.
What the gate does NOT do
- Does not humanize the user's own writing — only prose Claude is producing for the user to forward, paste, or publish. If the user pastes text and asks to "review" or "polish", invoke
humanizerdirectly; this gate is for outbound deliverables. - Does not strip technical precision. If a phrase looks AI-flavoured but carries load-bearing meaning (a regulated term, an SLA wording, a contractual data-retention clause), keep it.
- Does not expand the text. Humanizing makes prose shorter or the same length, never longer.
- Does not re-format structure. Headings, tables, bullet hierarchy stay; only the prose voice changes.
Enforcement (hard, since 2026-04-27)
The publish/send MCP tools listed in step 7 are hard-gated by hooks/humanize-gate.sh via a PreToolUse hook in .claude/settings.json (Claude Code) and .codex/hooks.json (Codex) — same script, same matcher, wired to both harnesses. The hook computes sha256 over the longest string in tool_input (the prose body, in practice) and blocks the call unless .ai/gates/humanized/<hash>.flag exists.
This means: forgetting to humanize → tool call fails with stderr instructions to mark and retry. The skill body still teaches the what and why; the hook enforces the that.
Out-of-scope tools (e.g. reading Confluence, listing Slack channels, structured Jira field updates without prose) are not matched and run normally. To extend the gate, add tool names to the matcher regex in both .claude/settings.json and .codex/hooks.json — they must stay in sync.
If the gate ever needs to be bypassed for a legitimate non-prose call (e.g. Confluence page with only a table and no prose), narrow the matcher rather than disabling the script.