brand-voice
Brand Voice
Govern BRAND-VOICE.md — the canonical writing voice document for a brand. Two layers: YAML frontmatter (machine-readable normative rules consumed by writing skills) plus eleven prose sections (human-readable rationale). Same split as DESIGN.md and the same design-system skill pattern: a canonical file at the project root, CLI-style subcommands for the lifecycle.
Additional context from the user: $ARGUMENTS
Subcommand routing
Parse the first positional token of $ARGUMENTS. If it matches a verb below, load the referenced file and follow its workflow. Otherwise fall through to the default workflow at the end of this document.
| First token | Mode | Reference |
|---|---|---|
extract |
Ingest sources, synthesise canonical voice doc, write to ./BRAND-VOICE.md |
steps/extract.md |
update |
Refresh an existing voice doc from new sources, preserve manual sections | steps/update.md |
diff |
Show what changed between two versions of the voice doc (git-aware) | steps/diff.md |
validate (aliases: lint, check) |
Lint a voice doc against canonical-format.md — verdict + errors + warnings + fix suggestions, CI-friendly exit codes |
steps/validate.md |
show |
Print the flat list of testable rules from the voice doc | steps/show.md |
| (none) | See Default workflow below | (this file) |
There is no apply subcommand. Application of the voice — rewriting prose to match it — is the consumer skill's job. The current consumer is humanize-en -f BRAND-VOICE.md, which calls scripts/extract_rules.py --full for chain-resolved flat rules. Any other skill that needs the voice contract follows the same path; alternative consumers can read the YAML frontmatter directly when their allowed-tools excludes Bash.
Canonical file location
The voice doc lives at ./BRAND-VOICE.md by default — at the project root, versioned in git, alongside DESIGN.md, README.md, LICENSE.md. Override the path with -o <path> when the voice is multi-project.
extract refuses to overwrite an existing file. To refresh, use update. To replace, delete first.
When -s is passed alongside extract, the skill also writes a copy to .claude/output/brand-voice/{slug}/voice.md for pipeline-history consumers. The slug is derived from voice.name (kebab-case, max 5 words). The canonical file at ./BRAND-VOICE.md remains the single source of truth.
Cross-repo distribution
When a brand spans multiple repositories (a www repo, an iOS repo, a docs repo, a marketing site), the same BRAND-VOICE.md should govern all of them. Pick one pattern and document it in each project's CLAUDE.md:
- Brand workspace canonical — keep
BRAND-VOICE.mdat the brand workspace root (e.g.~/<brand>/BRAND-VOICE.md). Each subproject references it via absolute path:/humanize-en -f ~/<brand>/BRAND-VOICE.md draft.md. Simplest. Best when subprojects share a local workspace. - Monorepo —
packages/brand/BRAND-VOICE.mdconsumed by every app in the monorepo. Single PR for cross-cutting voice changes. - Git submodule — canonical brand repo included as a submodule. Atomic updates via submodule bump. Best when the brand is owned by a separate team.
- Published package —
@<org>/brand-voiceon npm withBRAND-VOICE.mdplus the bundled scripts (extract_rules.py,voice_lint.py). Versioned, works cross-repo without a shared filesystem. - Copy + periodic
/brand-voice diff— a copy in each repo; periodicdiff <canonical> <local>catches drift. Simplest tooling, highest drift risk. Pair with a CI check.
Notion-as-source-of-truth is its own pattern: keep the spec in Notion, refresh local BRAND-VOICE.md periodically via /brand-voice update -n <page-id>. Notion stays the editorial surface; the local file is the executable artifact.
Multi-target: one file or many?
The default and recommended pattern is one BRAND-VOICE.md per brand. Within that file, contexts: handles register variation across document types (RFC vs landing page vs press release), audience segments (B2B vs consumer, technical vs lay), or channels (long-form vs social vs email):
contexts:
rfc: { density: max, numbered_sections: true }
landing: { sentence_count: 1 }
social: { shorter_form: true, formality_preserved: true }
Different contexts share the same lexicon, the same forbidden patterns, the same pronouns — what changes is the register, the sentence rhythm, the example openers.
Multiple voice files are warranted only when the brand has genuinely separate sub-brands with separate voices: a luxury group that owns Maison X Couture (institutional, French-rooted) and Maison X Beauty (more accessible, broader audience). Each sub-brand gets its own BRAND-VOICE.md. The skills consume each independently — humanize-en -f maison-x-couture.md for one, humanize-en -f maison-x-beauty.md for the other.
Inheritance via voice.extends — when sub-voices share a common substrate (founder voice on top of corporate, persona on top of institutional, multi-host media brand), declare voice.extends: ./BRAND-VOICE.md on the child file. The child inherits the parent's rules and overrides only what differs. Per-field merge policy, _replace / _remove overrides, cycle detection, and validation order live in references/canonical-format.md § Inheritance; a worked example sits in references/example-multi-voice.md.
When in doubt, start with one file. Adding contexts.foo later is cheaper than splitting two files later. Adding voice.extends later, when a real second voice emerges, is cheaper than over-engineering inheritance up front.
Source resolution
Sources are combinable — pass any number of -u, -n, -d, -f. The skill aggregates all sources into a working draft, then synthesises the canonical format once.
| Flag | Source | Mechanism |
|---|---|---|
-u <url> |
URL | WebFetch direct → fallback /markitdown -s <url> if binary/error |
-n <id|url> |
Notion page | mcp__claude_ai_Notion__notion-fetch (page + linked sub-pages, depth 1) |
-d <dir> |
Folder of MD/MDX | Glob <dir>/**/*.md → aggregate |
-f <file> |
Single MD/MDX/TXT | Read direct |
(none, with extract) |
Interview | 8 canonical questions via AskUserQuestion |
Full resolution rules — including failure handling, conflicts, MCP unavailability, large-folder fan-out, and contribution summary — live in references/source-resolution.md.
The Notion MCP is authorised through Claude Code's permission layer, not via this skill's allowed-tools. If the MCP is not installed, -n errors with a clear install pointer and the workaround (export Notion → MD, then -d).
Canonical format
BRAND-VOICE.md has two parts:
- YAML frontmatter — machine-readable normative rules. Required fields:
voice.name,forbidden_lexicon,rewrite_rules,sentence_norms. Optional:core_attributes,required_lexicon,forbidden_patterns,contexts,pronouns,voice.source_urls,voice.last_updated,voice.source. - Eleven prose sections in this exact order:
- Core voice attributes
- Rewrite rules — do/don't
- Forbidden lexicon and patterns
- Sentence-level norms
- Tone by context
- Pronouns and self-reference
- Format conventions
- Visual pairing
- Quick diagnostic
- Counter-examples
- Reference texts
Full schema, field constraints, manual-section markers, and section-heading normalisation rules: references/canonical-format.md. A complete reference example: references/example-chanel.md.
The split is deliberate. Tooling reads YAML; humans read prose. Consumers like humanize-en -f BRAND-VOICE.md load only the rule block (50–150 lines via extract_rules.py --full), not the full doc, so the voice doc can be richly explained without bloating downstream contexts.
Pipeline integration
Brand voice is consumed by writing skills via -f. The current consumer is humanize-en:
/brand-voice extract -u https://example.com/about
→ ./BRAND-VOICE.md
/humanize-en -f ./BRAND-VOICE.md draft.md
→ draft humanized against universal AI tells + brand-specific rules
Two ways for a consumer to read the rules:
-
Invoke
extract_rules.py --full— preferred. The script flattens the YAML to plain text, automatically resolves anyvoice.extendschain, applies_replaceand_removeoverrides, and emits a 50–150 line block ready for inclusion in an LLM prompt. This is whathumanize-en -fdoes as of the inheritance release.python3 ${CLAUDE_SKILL_DIR}/scripts/extract_rules.py --full ./BRAND-VOICE.md -
Readthe YAML frontmatter directly — fallback when the consumer'sallowed-toolsdoes not includeBash, or when the consumer wants raw structure. The consumer parses the YAML and usesforbidden_lexicon,rewrite_rules,sentence_norms,forbidden_patterns,pronouns,core_attributes,contextsdirectly. This path does not resolvevoice.extends— child files appear as-written.
Both shapes are documented in references/schemas.md § extract_rules.py. The --legacy flag emits the v1 minimal output (byte-identical to the pre-inheritance shape) for any external consumer pinned to it.
When a brand voice rule conflicts with a universal AI-tell pattern (e.g., the voice requires em-dashes vs pattern #14), the brand rule wins — it is the user's contract. Conflicts are logged in the consumer's report.
Validation — voice_lint.py
Every doc the skill writes (or the user authors) is validated by scripts/voice_lint.py:
python3 ${CLAUDE_SKILL_DIR}/scripts/voice_lint.py ./BRAND-VOICE.md
Verdicts: GREEN (zero errors, zero warnings), YELLOW (warnings only — acceptable but flagged), RED (errors — block). Output is JSON per references/schemas.md § voice_lint.py.
extract and update lint before writing. RED → fix and re-lint without prompting the user. YELLOW → present warnings to the user and proceed on confirmation.
Default workflow (no subcommand)
When the first token of $ARGUMENTS does not match extract|update|diff|validate|lint|check|show, the skill behaves as follows:
- No
BRAND-VOICE.mdat the target → suggest/brand-voice extractwith the sources the user mentions inline. Do not silently extract. BRAND-VOICE.mdexists → runshow --rulesand print the testable rules. Useful when the user types/brand-voiceto glance at the current contract.- The argument looks like a URL → suggest
/brand-voice extract -u <url>(or/brand-voice update -u <url>if a doc exists). - The argument looks like a file path → suggest the corresponding
-finvocation.
The default workflow exists to avoid silent state-modifying actions. Every write goes through an explicit subcommand.
Rules
- Canonical file is git-versioned. Treat
./BRAND-VOICE.mdas a code asset. Diff before merge. The git history is the audit trail. - Lint before write. Every
extractandupdaterunsvoice_lint.pyon the synthesised content before the user is asked to approve. RED never reaches disk. - Never overwrite.
extractrefuses to overwrite an existing file.updatealways shows a diff and asks for explicityes.diffis read-only by definition. - Manual sections are sacred. A section marked
<!-- manual: true -->is preserved verbatim byupdate. Do not re-synthesise. - Conflicts surface, never override. When two sources disagree, surface via
AskUserQuestion. When a source contradicts the existing doc duringupdate, surface. No silent picks. - Output paths follow the repo contract. Default canonical at
./BRAND-VOICE.md. Pipeline copies under.claude/output/brand-voice/{slug}/voice.mdonly when-sis passed.
When to defer to another skill
- Apply the voice on a prose draft →
/humanize-en -f BRAND-VOICE.md <draft>. This skill never humanises. - Convert a non-Markdown source to MD first →
/markitdown -s <source>, then/brand-voice extract -f <markitdown-output>. - Extract design tokens, not voice →
/award-designand/design-system. Brand voice is prose; brand visuals are tokens. Different docs, different lifecycles. - Pure grammar fix on the voice doc →
/fix-grammar BRAND-VOICE.md. This skill governs structure and content, not typos.
Reference
steps/extract.md,steps/update.md,steps/diff.md,steps/validate.md,steps/show.md— per-subcommand workflows, flags, edge cases.references/canonical-format.md— full schema, required vs recommended sections, section ordering, manual-section markers, inheritance viavoice.extends. The contract.references/example-chanel.md— complete reference voice doc, anchored on chanel.com primary sources (Métiers d'art savoir-faire page, House of Chanel history, founder page) plus Met Museum and Wikipedia as cross-references. Use as a structural template.references/example-multi-voice.md— worked example ofvoice.extends: a fictional founder-led startup with parent + child + merged result side-by-side, plus when to use_replacevs_removevs default merge.references/source-resolution.md— how each-u/-n/-d/-fflag resolves, failure modes, conflict handling.references/interview-questions.md— eight canonical questions forextractwith no source flag.references/schemas.md— JSON shape forvoice_lint.py, plain-text shape forextract_rules.py. Stable contract for downstream consumers.scripts/voice_lint.py— validates aBRAND-VOICE.md, walksvoice.extendschain, emitschainandmerged_statswhen inheritance applies. Python 3.7+, no third-party deps.scripts/extract_rules.py— emits flat testable rules. Resolvesvoice.extendschain by default.--full(default) includescore_attributes/contexts/source_urls;--legacyemits the v1 minimal output. Consumed byhumanize-en -f.scripts/lint_all.py— globs everyBRAND-VOICE*.mdunder a root and lints each. Single-command audit for the parent-change blast-radius problem: a parent edit that breaks N children surfaces as N RED verdicts. CI-friendly; recommended in pre-merge hooks.scripts/utils.py— shared I/O helpers, chain resolution (resolve_extends_chain), merge engine (merge_voice_dicts,apply_replace_overrides,apply_remove_overrides). Not invoked directly.
More from coroboros/agent-skills
markitdown
Convert any document to Markdown with Microsoft's `markitdown` CLI — PDF, Word, Excel, PowerPoint, HTML, CSV, JSON, XML, ZIP, EPub, images (OCR/EXIF), audio (transcription), and YouTube URLs. Use whenever the user wants to extract text from a binary document, transcribe audio, OCR an image, scrape a YouTube transcript, or pre-process a file for an LLM context window — even when they just say "convert this pdf", "what's in this docx", "transcribe this mp3", or "get the text out of this".
11design-system
Govern the DESIGN.md — Google's open standard for design tokens (YAML frontmatter + eight prose sections). Auto-activates during UI edits to enforce token-only sourcing for colors, typography, spacing, and corner radius. Also exposes six CLI-backed subcommands — audit (lint + fix proposals), diff (regression check), export (Tailwind / DTCG), spec (canonical spec emission), migrate (port from legacy Stitch format), init (minimal scaffold). When a UI/UX change is requested, DESIGN.md is updated first, audited, then code propagates.
3award-design
Build award-winning websites (Awwwards SOTD 7.5+, FWA, CSSDA). Recommends the best design archetype for the brief, calibrates atmosphere, and produces a complete DESIGN.md. Applies anti-AI-slop rules and targets real judging criteria. Use when building landing pages, portfolios, product sites, or any web interface that needs to look exceptional — not for dashboards or internal tools.
3apex
Systematic implementation using APEX methodology (Analyze-Plan-Execute-eXamine) with parallel subagents and self-validation. Use when implementing features, fixing bugs, or making code changes that benefit from structured workflow.
1spec
Transform ideas into structured execution specs with prioritized workstreams, complexity ratings, dependencies, and acceptance criteria. Use this whenever the user needs to decompose work before building — even when they don't explicitly say "spec" (e.g. "break this down", "plan this out", "create issues for", "what are the steps"). The bridge between thinking and building.
1oneshot
Single-pass feature implementation using Explore → Code → Test. Ships focused changes at maximum speed, with a built-in circuit breaker that stops and recommends `/apex` or `/spec` when the task turns out more complex than it looked. Use this whenever the user wants a quick win on a single, focused task — even when they don't say "oneshot" (e.g. "just", "quickly", "small change", "#42", or a GitHub issue URL for a small fix).
1