copywriting — write it in the product's own voice
Part of super-ux — see system-map.md.
After changes, run python3 docs/brand/lint.py.
First action, every time: read the brand pack. docs/brand/voice.md,
terminology.md, and the channels.md record for the surface being written.
No pack? Stop and hand off to brand-voice. Do not improvise a voice.
Guessing it and being wrong costs more than the pause, and a product whose
copy was invented surface by surface is exactly the drift this layer exists
to remove.
The opt-out is spoken, never assumed: "no brand" / «без бренда» —
or "draft it" / «черновиком» — is the operator declining this route:
write directly and say the pack was skipped on request, never skip it silently.
Ownership is by FILE, not by directory. brand-voice owns the pack's
sources of truth — voice.md, the terminology dictionary, facts.md, the
channel playbooks and the locale policy — and this skill never writes those:
a term missing from the dictionary, or a number with no row in facts.md, is
reported, never invented to finish the sentence — adding it is
brand-voice's decision. This skill DOES own strings.md (the interface-
string registry, written with Status: proposed) and the product text itself.
Both live under docs/brand/, but the directory is not the owner — the file
is. Writing a strings.md row is this skill's job and needs no extra approval
for its LOCATION; a coordinated run claims the file before editing, and voice
and facts stay untouched in the same pass.
References
| Read |
When |
| ui-copy.md |
any string inside the product |
| marketing-copy.md |
pages, long form, the seven sweeps, grounding |
| landing-pages.md |
assembling a landing page: the offer, awareness, proof, the action |
| channel-playbooks.md |
a social, blog, changelog, ads or email surface |
| store-copy.md |
App Store or Google Play |
| seo-aeo-safety.md |
anything a crawler or answer engine reads |
| ai-tells.md |
every mode that produces text: the pass runs by default |
| localization.md |
any locale that is not primary |
| surface-registers.md |
the register for a surface |
Modes
The humanization pass runs by default, in every mode that produces text.
It is not a mode you enter, it is the last step of Write, Edit and Adapt, under
the guards in ai-tells.md which are not optional. The
reason it is a default rather than an option: a draft nobody swept carries the
markers that file grades, and a reader registers them before they can name why.
voice.md records the state in two fields that answer different questions.
Humanization: on | off is whether the pass runs, and it defaults to on
when the field is absent. Humanization pass: names which implementation
runs, and absent it is own, the only one that reads this pack's registers and
canonical facts. Turning it off is a legitimate decision that outlives whoever
made it, so off carries a Humanization declined: line with the reason and
the date. B064 checks all three states.
Every delivery of copy states what happened, in one line, before the copy
or immediately after it:
Humanization: on — own pass, 7 markers at 2 densities, 4 addressed, 11% changed
Humanization: off — declined 2026-08-30, wording fixed by counsel
The line is not decoration. A pass that runs invisibly is indistinguishable
from one that did not run, and the reader of the copy is usually not the person
who chose the setting.
Write
- Name the surface. It must exist in
channels.md; if it does not, that is
a brand-voice decision, not an improvisation here.
- Apply the register: the axes from
voice.md, plus that surface's deltas.
Deltas move axes; they never cross the invariants.
- Write. Every claim traces to
facts.md. Every product term comes from
terminology.md.
- Deliver the copy first, then the reasoning. For headlines and CTAs give
two or three options with what each trades away.
- For interface strings, add or update the
strings.md row — key,
file:line, scenario, Status: proposed.
- Run the humanization pass under the Humanize guards below, then print
the status line. On new text the change rate is measured against the draft
you just wrote, so the 50% ceiling does not apply the way it does to an
edit; report the rate regardless.
Edit
The seven sweeps from marketing-copy.md, in order, looping back after each:
clarity, voice and tone, so-what, prove-it, specificity, emotion, zero risk.
Deliver sweep by sweep, prioritised by impact, not by reading order.
The humanization pass runs last, after the seven, and then the status line.
Last because the sweeps rewrite whole sentences and a humanization pass run
before them is measured against text that no longer exists; and because the
semantic-preservation checklist is cheapest to apply to a version nobody is
about to rewrite again.
Adapt
One piece across several surfaces. Re-write per surface — never paste one
register into another. What survives adaptation is the claim and the proof;
what changes is length, structure, CTA policy and register.
State plainly what each version drops. A thread is not a page with line
breaks.
The pass runs per surface, not once on the source. Each version is
different text in a different register, and a marker density that is fine in a
blog post is not fine in a landing hero. One status line per surface.
Humanize
The standalone mode, for auditing text that already exists without writing any:
an inherited page, a competitor's copy, a draft somebody else wrote. The same
guards govern the pass wherever it runs, and they are not optional:
- Above ~10 markers per 500 words, say so and rewrite from the argument — a
patch produces the same patterns with better words.
- Above a 50% change rate, do not ship. Report the rate and ask. That is
no longer an edit.
- Run the semantic-preservation checklist before output: numbers, dates and
proper nouns intact; causal direction unchanged; no negation inverted;
quotations untouched; the core claim the same.
- Text that already reads naturally is left alone. Editing what is fine to
prove the pass ran is this mode's failure.
- A marker count is not a verdict and never gates anything. Say which markers
are present at what density; never say a text was AI-written. A number of
markers does not prove authorship — the false positives fall hardest on people
writing in a second language, and a writer is not a defect to be edited into
fluency they did not ask for. The humanization pass is ADVISORY throughout:
B060 warns, it does not error. ai-tells.md carries the measurement and
what it binds.
- A quote, a registered term, and an explicit
off never force a rewrite. A
marker inside a quotation is the source's word; a term in terminology.md is
meant to recur; and Humanization: off (with its reason) preserves the text
exactly. Brand bans are a separate user policy — a forbidden word is the
brand's own choice in terminology.md, not a machine-drafting tell, and it is
that check's business, not this pass's.
- Read
voice.md's two fields first. Humanization: is whether the pass
runs and defaults to on; Humanization pass: names which implementation,
and absent it is own. Neither absence stops work: run the default, print the
status line saying it was a default, and offer to record it once. A value naming
a tool that is not installed falls back to own and says so — a missing optional
tool must not stop copy being written.
- Other implementations exist and two are worth knowing —
npx sshlg-skills humanizers lists what this machine has. Reach for one for an
audit with no rewrite, for long-form prose, or when the writer has a sample of
their own writing to match. Stay here for product copy: the brand pack's
registers and canonical facts are the constraint, and a general-purpose
humanizer does not read them.
Non-negotiables
- No fabricated facts, statistics, quotes or experts. Not for a deadline,
not for a benchmark, not because a placeholder would look better. Refuse,
say why, offer to find a real one.
- No humor on
error, destructive confirm, billing and receipts or
paywall and upgrade — in any pack. The user is losing something there.
- One action, one name. Before naming an action, search
strings.md for
it. A second name for an existing action is a defect, not a synonym.
- Never quote a number that is not in
facts.md.
Definition of done
- Every string or section traces to a surface record and a voice.
- The humanization status line is printed, whichever state it reports.
- New interface strings are in
strings.md with location and scenario.
python3 docs/brand/lint.py exits 0 for the touched surfaces.
- Anything reported as missing — a term, a fact, a surface — is named
explicitly, not worked around.
1---2name: copywriting3description: Use when writing, rewriting or editing any text a user will read — interface strings, buttons, errors, empty states, landing and pricing pages, blog posts, changelogs, social posts, app store listings, ads, lifecycle email. Triggers - "write copy" / "напиши текст", "rewrite this" / "перепиши", "headline" / "заголовок", "CTA" / "кнопка", "post for X" / "пост в твиттер", "store listing" / "описание в сторе", "this sounds like AI" / "звучит как нейросеть", "microcopy" / "микрокопия", "error text" / "текст ошибки", "build a landing page" / "сделай лендинг" (the copy for it; the visual layer is sheleg-design's). For defining the voice itself, see brand-voice.4license: MIT5---67# copywriting — write it in the product's own voice89> Part of **super-ux** — see [system-map.md](references/system-map.md).10> After changes, run `python3 docs/brand/lint.py`.1112**First action, every time: read the brand pack.** `docs/brand/voice.md`,13`terminology.md`, and the `channels.md` record for the surface being written.1415**No pack? Stop and hand off to `brand-voice`.** Do not improvise a voice.16Guessing it and being wrong costs more than the pause, and a product whose17copy was invented surface by surface is exactly the drift this layer exists18to remove.1920**The opt-out is spoken, never assumed:** **"no brand"** / **«без бренда»** —21or **"draft it"** / **«черновиком»** — is the operator declining this route:22write directly and say the pack was skipped on request, never skip it silently.2324**Ownership is by FILE, not by directory.** `brand-voice` owns the pack's25sources of truth — `voice.md`, the terminology dictionary, `facts.md`, the26channel playbooks and the locale policy — and this skill **never writes those**:27a term missing from the dictionary, or a number with no row in `facts.md`, is28**reported**, never invented to finish the sentence — adding it is29`brand-voice`'s decision. This skill DOES own **`strings.md`** (the interface-30string registry, written with `Status: proposed`) and the product text itself.31Both live under `docs/brand/`, but the directory is not the owner — the file32is. Writing a `strings.md` row is this skill's job and needs no extra approval33for its LOCATION; a coordinated run claims the file before editing, and voice34and facts stay untouched in the same pass.3536## References3738| Read | When |39|---|---|40| [ui-copy.md](references/ui-copy.md) | any string inside the product |41| [marketing-copy.md](references/marketing-copy.md) | pages, long form, the seven sweeps, grounding |42| [landing-pages.md](references/landing-pages.md) | assembling a landing page: the offer, awareness, proof, the action |43| [channel-playbooks.md](references/channel-playbooks.md) | a social, blog, changelog, ads or email surface |44| [store-copy.md](references/store-copy.md) | App Store or Google Play |45| [seo-aeo-safety.md](references/seo-aeo-safety.md) | anything a crawler or answer engine reads |46| [ai-tells.md](references/ai-tells.md) | every mode that produces text: the pass runs by default |47| [localization.md](references/localization.md) | any locale that is not primary |48| [surface-registers.md](references/surface-registers.md) | the register for a surface |4950## Modes5152**The humanization pass runs by default, in every mode that produces text.**53It is not a mode you enter, it is the last step of Write, Edit and Adapt, under54the guards in [ai-tells.md](references/ai-tells.md) which are not optional. The55reason it is a default rather than an option: a draft nobody swept carries the56markers that file grades, and a reader registers them before they can name why.5758`voice.md` records the state in two fields that answer different questions.59**`Humanization: on | off`** is whether the pass runs, and it defaults to `on`60when the field is absent. **`Humanization pass:`** names which implementation61runs, and absent it is `own`, the only one that reads this pack's registers and62canonical facts. Turning it off is a legitimate decision that outlives whoever63made it, so `off` carries a `Humanization declined:` line with the reason and64the date. `B064` checks all three states.6566**Every delivery of copy states what happened**, in one line, before the copy67or immediately after it:6869```70Humanization: on — own pass, 7 markers at 2 densities, 4 addressed, 11% changed71Humanization: off — declined 2026-08-30, wording fixed by counsel72```7374The line is not decoration. A pass that runs invisibly is indistinguishable75from one that did not run, and the reader of the copy is usually not the person76who chose the setting.7778### Write79801. Name the surface. It must exist in `channels.md`; if it does not, that is81 a `brand-voice` decision, not an improvisation here.822. Apply the register: the axes from `voice.md`, plus that surface's deltas.83 **Deltas move axes; they never cross the invariants.**843. Write. Every claim traces to `facts.md`. Every product term comes from85 `terminology.md`.864. Deliver the copy first, then the reasoning. For headlines and CTAs give87 two or three options with what each trades away.885. For interface strings, add or update the `strings.md` row — key,89 `file:line`, scenario, `Status: proposed`.906. **Run the humanization pass** under the Humanize guards below, then print91 the status line. On new text the change rate is measured against the draft92 you just wrote, so the 50% ceiling does not apply the way it does to an93 edit; report the rate regardless.9495### Edit9697The seven sweeps from `marketing-copy.md`, in order, looping back after each:98clarity, voice and tone, so-what, prove-it, specificity, emotion, zero risk.99Deliver sweep by sweep, prioritised by impact, not by reading order.100101**The humanization pass runs last**, after the seven, and then the status line.102Last because the sweeps rewrite whole sentences and a humanization pass run103before them is measured against text that no longer exists; and because the104semantic-preservation checklist is cheapest to apply to a version nobody is105about to rewrite again.106107### Adapt108109One piece across several surfaces. Re-write per surface — never paste one110register into another. What survives adaptation is the claim and the proof;111what changes is length, structure, CTA policy and register.112113State plainly what each version drops. A thread is not a page with line114breaks.115116**The pass runs per surface, not once on the source.** Each version is117different text in a different register, and a marker density that is fine in a118blog post is not fine in a landing hero. One status line per surface.119120### Humanize121122The standalone mode, for auditing text that already exists without writing any:123an inherited page, a competitor's copy, a draft somebody else wrote. The same124guards govern the pass wherever it runs, and they are not optional:125126- Above ~10 markers per 500 words, say so and rewrite from the argument — a127 patch produces the same patterns with better words.128- **Above a 50% change rate, do not ship.** Report the rate and ask. That is129 no longer an edit.130- Run the semantic-preservation checklist before output: numbers, dates and131 proper nouns intact; causal direction unchanged; no negation inverted;132 quotations untouched; the core claim the same.133- Text that already reads naturally is left alone. Editing what is fine to134 prove the pass ran is this mode's failure.135- **A marker count is not a verdict and never gates anything.** Say which markers136 are present at what density; never say a text was AI-written. A number of137 markers does not prove authorship — the false positives fall hardest on people138 writing in a second language, and a writer is not a defect to be edited into139 fluency they did not ask for. The humanization pass is ADVISORY throughout:140 `B060` warns, it does not error. `ai-tells.md` carries the measurement and141 what it binds.142- **A quote, a registered term, and an explicit `off` never force a rewrite.** A143 marker inside a quotation is the source's word; a term in `terminology.md` is144 meant to recur; and `Humanization: off` (with its reason) preserves the text145 exactly. **Brand bans are a separate user policy** — a forbidden word is the146 brand's own choice in `terminology.md`, not a machine-drafting tell, and it is147 that check's business, not this pass's.148- **Read `voice.md`'s two fields first.** `Humanization:` is whether the pass149 runs and defaults to `on`; `Humanization pass:` names which implementation,150 and absent it is `own`. Neither absence stops work: run the default, print the151 status line saying it was a default, and offer to record it once. A value naming152 a tool that is not installed falls back to `own` and says so — a missing optional153 tool must not stop copy being written.154- Other implementations exist and two are worth knowing —155 `npx sshlg-skills humanizers` lists what this machine has. Reach for one for an156 audit with no rewrite, for long-form prose, or when the writer has a sample of157 their own writing to match. Stay here for product copy: the brand pack's158 registers and canonical facts are the constraint, and a general-purpose159 humanizer does not read them.160161## Non-negotiables162163- **No fabricated facts, statistics, quotes or experts.** Not for a deadline,164 not for a benchmark, not because a placeholder would look better. Refuse,165 say why, offer to find a real one.166- **No humor on `error`, `destructive confirm`, `billing and receipts` or167 `paywall and upgrade`** — in any pack. The user is losing something there.168- **One action, one name.** Before naming an action, search `strings.md` for169 it. A second name for an existing action is a defect, not a synonym.170- **Never quote a number that is not in `facts.md`.**171172## Definition of done173174- Every string or section traces to a surface record and a voice.175- The humanization status line is printed, whichever state it reports.176- New interface strings are in `strings.md` with location and scenario.177- `python3 docs/brand/lint.py` exits 0 for the touched surfaces.178- Anything reported as missing — a term, a fact, a surface — is named179 explicitly, not worked around.