A voice pack is the unit sitekit makes pluggable for how the site sounds — tone, cadence, vocabulary, CTA discipline, and the phrases that are forbidden. It is one of the four dimensions of a playbook; the others are the style pack (how it looks), the shape (what it builds), and the valence (the industry overlay). The dimensions are independent. Any voice pairs with any style pack and any shape.

What a voice pack ships

voices/<name>/
  voice.json      # the machine contract — verify reads this
  voice.md        # the prose guide — the agent reads this
  palettes.css    # optional, only when the pack claims palette ownership
  README.md       # one paragraph: what makes this voice
voice.json declares constraints in machine form (bannedPhrases, imagery rules, version). voice.md is written guidance for the agent — sentence shapes, register, how to handle a CTA. There is deliberately no cross-validation between the two. The prose is interpretive; the JSON is literal. That split is the point.
A voice pack ships no CSS. A style pack ships a canonical style.css that gets inlined verbatim into every page. A voice pack is rules and prose only, because applying voice depends on the specific copy being written. The brand’s visual atoms live in the style pack; its verbal atoms live here.

The core writing guide sits underneath

Every voice pack is an overlay on a universal prose foundation at writing/core.md. The core guide holds the rules that are true for every brand — directness, specificity, no invented numbers, no marketing filler. The voice pack adds what makes this brand distinct: its audience, cadence, vocabulary, and CTA register.
A voice pack may tighten the core guide. It may never relax it. If a voice calls for a warmer or more technical register, apply that register while keeping the core guide’s directness and anti-pattern rules. Facts outrank style — neither layer authorizes an invented number, claim, or customer.
Resolution is two-level and site-local first:
LocationWins when
<site>/writing/core.mdpresent — copied into every new workspace
the bundled writing/core.mdno site-local file — used for new scaffolds and ephemeral work
The site-local file is ordinary, reviewable source your site owns, so git records its history. Replace it to change the foundation for one site. Because existing sites keep their own copy, upgrading sitekit never silently rewrites a live brand’s prose standard. Composition order is explicit:
core writing guide  →  voice pack  →  shape / valence  →  content store
That order is applied everywhere prose is authored or judged — run inlines the core guide into each emitted scaffold ahead of the voice block, serve and section re-authoring prepend it before voice.md, and verify --fragment and align return it as a judgment input so the reviewing agent grades against the same base the author wrote from.

The bundled voices

Two voice packs ship in the binary:

editorial

Considered, specific, unhurried. Full sentences, concrete nouns, no exclamation. The default pairing for most style packs.

brutalist

Blunt and declarative. Short sentences, plain words, no hedging. Pairs with the harder-edged visual packs.
Most brands want neither verbatim — they want their own. That’s what capture and authoring are for.

Two enforcement modes

The split between voice.json and voice.md produces two genuinely different kinds of enforcement, and it is worth understanding which is which.
bannedPhrases in voice.json is a deterministic string check. If a banned phrase appears in emitted copy, sitekit verify fails the page. No model judgment, no ambiguity, no negotiation. This is how you make “we never say unlock the power of” a structural property of the site rather than a hope.Banned phrases also come from content/messaging.yaml, so a brand can add its own without forking the pack.
voice.md cannot be reduced to a string scan, and sitekit does not pretend otherwise. Register, cadence, and CTA discipline are applied by the agent at authoring time and judged by an agent at review time via verify --fragment or align.This is a prompt-level contract, not a linter. It is enforced by being placed in front of the model every single time copy is written — never by hoping the model remembers.

Capture a voice from a site you already have

If the brand already exists in writing somewhere, infer the pack instead of authoring it:
sitekit voice capture <name> --url https://example.com
sitekit scaffolds the pack, records the evidence, and installs the capturing-a-voice-pack skill into your harness. Your agent then reads the source copy and extracts the register, the recurring sentence shapes, the vocabulary, and — importantly — the phrases this brand demonstrably never uses, which become bannedPhrases. You can capture from a local copy file instead of a URL when the writing lives in a document rather than on a site.

Author one from scratch

sitekit voice author <name>
Scaffolds a blank workshop pack and installs the authoring-a-voice-pack skill, which drives a clarify-intent → draft → preview → iterate → verify loop with your agent.

Working with voices

sitekit voice list                 # bundled + workshop + site-local, active marked
sitekit voice show <name>          # print voice.json
sitekit voice docs [section]       # print sections of the active voice.md
sitekit voice inspect <name>       # resolved details + the three-tier resolution chain
sitekit voice check <name>         # validate schema + banned-phrase sanity
sitekit voice verify <name>        # validate the manifest at any tier
sitekit voice init <name>          # scaffold a site-local pack from a bundled base
sitekit voice activate <name>      # swap <site>/voice/ and update the manifest
inspect is the one to reach for when a voice isn’t resolving the way you expect — it prints the full three-tier chain (site-local → workshop → bundled) and shows which tier won.

Where voices live

Same three tiers as every other pack:
TierPathScope
Site-local<site>/voices/<name>/this site only, committed with it
Workshop~/.sitekit/voices/<name>/every site on your machine, private
Bundlednext to the binaryships with sitekit
A bare-named workshop pack may not shadow a bundled one — sitekit reports E_WORKSHOP_NAME_COLLISION. Fork a bundled pack under a scoped name (@me/editorial) instead; scoped names are exempt by design.

What’s next

Capture a brand

Rip a voice or a full visual identity from a site, screenshot, or screen recording.

Style packs

The visual half of the brand.