Blog Brand: Durable Editorial Context
Establish durable brand and voice context for cross-skill consumption.
How to use it
- Hit Copy SKILL.md — or use the Claude Code line below to get every file.
- Claude: ⋯ → Download .md, then Customize → Skills → Add → Upload skill.
ChatGPT: make a Project and paste it into Instructions.
Neither? Paste it at the top of a new chat — it works for that chat. - Describe your job in plain words. The AI follows the skill from there.
npx degit AgriciDaniel/claude-blog/skills/blog-brand#main ~/.claude/skills/blog-brand-2For one project only, change the path to .claude/skills/blog-brand-2. This skill also uses BRAND.md, VOICE.md, PRODUCT.md, DESIGN.md — copying SKILL.md alone won't be enough. See the folder on GitHub.
Not working?
- Check which app you pasted it into — the steps above name the right one.
- Some skills need the paid tier of Claude or ChatGPT.
Paste into Claude, ChatGPT or Cursor.
Show the full text241 lines
Blog Brand: Durable Editorial Context
Generates two project-root files that the blog orchestrator auto-loads for supported writing and planning commands when present:
BRAND.md: who the audience is, what the brand stands for, what to never sayVOICE.md: how the brand sounds, structurally and lexically
These are the editorial equivalent of impeccable's PRODUCT.md / DESIGN.md pattern: persistent context that survives across sessions and propagates to every command.
Why this exists
Today, persona JSON (from blog-persona) is loaded by some skills and not others. Topic-cluster context lives inside cluster vaults. Competitor positioning lives nowhere. Each blog command re-derives "what is the brand" from whatever context it has.
BRAND.md and VOICE.md fix this: one canonical source, loaded by the blog orchestrator at the start of every command.
When neither file exists, behavior is unchanged from v1.7.1. Backward compatible.
Commands
| Command | Purpose |
|---|---|
/blog brand init |
Interactive interview, writes BRAND.md and VOICE.md to project root |
/blog brand show |
Display current contents (or report missing) |
/blog brand update |
Re-run the interview with current values as defaults |
Init Workflow
Run the 5-step interactive interview. Ask each step, wait for response, then proceed. If blog-persona JSON already exists, pre-fill voice answers from it.
Step 1: Audience
Ask:
- Primary audience role (e.g. "head of marketing at a 50-500 person B2B SaaS")
- Secondary audience (optional)
- Reader expertise level: beginner / intermediate / advanced / mixed
- Problems the reader is actively trying to solve (3 to 5 bullets)
- Common misconceptions the audience holds (used to anchor information gain)
Step 2: Positioning and Canonical Entity
Ask:
- Official entity name (legal or public brand name)
- Homepage URL (canonical brand front door)
- Logo URL or file path (preferred square or SVG asset)
- sameAs profiles (LinkedIn, X, YouTube, Crunchbase, GitHub, or other official profiles)
- Wikidata Q-ID if one exists; leave blank if not notable
- One-sentence brand mission (what the brand helps people do)
- Distinctive point of view (the contrarian or non-obvious belief that shapes content)
- What this brand is NOT (anti-positioning, what to never be confused with)
- Top 3 direct competitors with the one-line differentiator vs each
Step 3: Editorial rules
Ask:
- Do list (3 to 7 things the blog will always do; e.g. "cite primary sources only," "name the practitioner not the product")
- Don't list (3 to 7 things the blog will never do; e.g. "no clickbait titles," "no listicle filler")
- Taboo phrases (specific words or phrases this brand never uses; separate from the repository's optional project style list)
- Required disclosures (e.g. affiliate disclosure, AI-content disclosure, conflict-of-interest patterns)
Step 4: Topic boundaries
Ask:
- Topics fully in scope (core content pillars)
- Topics partially in scope (adjacent; covered only with original angle)
- Topics out of scope (will not cover; redirect to partner content)
- Recurring formats / column names if any (e.g. "Monthly Field Notes," "Reader Q&A")
Step 5: Voice (auto-fill from blog-persona if present)
Ask:
- Pronoun stance: first-person (we / I), second-person (you), third-person (the team), or mixed
- Acceptable contractions: full / partial / none
- Sentence ceiling: max words per sentence as a hard cap
- Paragraph ceiling: max words per paragraph (default 150)
- Headline patterns to favor: numbered / question / promise / statement
- Headline patterns to avoid: any patterns banned for this brand
- Summary box label: from blog-persona, or pick one
Output Files
BRAND.md template
Write to project root as:
# Brand Context
> This file is auto-loaded by all blog sub-skills. Last updated: YYYY-MM-DD.
## Audience
- **Primary**: [role + context]
- **Secondary**: [if any]
- **Expertise**: [level]
- **Active problems**:
- [problem 1]
- [problem 2]
- [problem 3]
- **Common misconceptions**:
- [misconception 1]
- [misconception 2]
## Positioning
- **Official entity name**: [brand/entity]
- **Homepage**: [canonical URL]
- **Logo**: [URL or file path]
- **sameAs profiles**:
- [profile URL 1]
- [profile URL 2]
- **Wikidata Q-ID**: [QID or none]
- **Mission**: [one sentence]
- **Distinctive POV**: [contrarian or non-obvious belief]
- **What we are NOT**: [anti-positioning]
- **Competitors**:
- [Competitor A]: [our one-line differentiator]
- [Competitor B]: [our one-line differentiator]
- [Competitor C]: [our one-line differentiator]
## Editorial Rules
### Always do
- [rule 1]
- [rule 2]
- [rule 3]
### Never do
- [rule 1]
- [rule 2]
- [rule 3]
### Taboo phrases
- [phrase 1]
- [phrase 2]
### Required disclosures
- [disclosure rule]
## Topic Scope
- **In scope**: [pillars]
- **Partial scope**: [adjacent topics]
- **Out of scope**: [topics to refuse]
- **Recurring formats**: [if any]
VOICE.md template
Write to project root as:
# Voice Context
> This file is auto-loaded by all blog sub-skills. Last updated: YYYY-MM-DD.
## Pronoun stance
[first-person / second-person / third-person / mixed]
## Lexical rules
- **Contractions**: [full / partial / none]
- **Sentence ceiling**: [N words max]
- **Paragraph ceiling**: [N words max, default 150]
- **Summary label**: [Key Takeaways / TL;DR / etc.]
## Headline patterns
- **Favor**: [list]
- **Avoid**: [list]
## Voice fingerprint (from blog-persona)
- Funny vs serious: [0.0 to 1.0]
- Formal vs casual: [0.0 to 1.0]
- Respectful vs irreverent: [0.0 to 1.0]
- Enthusiastic vs matter-of-fact: [0.0 to 1.0]
## Readability target
- Audience tier: [consumer / professional / technical]
- Flesch Grade: [range]
- Flesch Ease: [range]
## Reference samples
- [URL 1] (extracted patterns: [summary])
- [URL 2] (extracted patterns: [summary])
Show Workflow
- Check for
BRAND.mdandVOICE.mdat project root. - If both exist, print a summary table (key sections only) and the file paths.
- If one or both are missing, print which are missing and suggest
/blog brand init.
Update Workflow
Same as Init, but pre-fills every answer with the current value. The user can press enter to accept or type a new value. After collecting all answers, overwrite both files with the new contents and update the Last updated: line.
Integration with the blog orchestrator
When /blog write, /blog rewrite, /blog brief, /blog outline, /blog calendar, or /blog strategy runs, the orchestrator (skills/blog/SKILL.md) checks for BRAND.md and VOICE.md at the project root. If present, the contents are injected into the system prompt for downstream agents (blog-researcher, blog-writer, blog-seo, blog-reviewer).
If absent, behavior is unchanged. The orchestrator does not prompt the user to create them; they are opt-in context.
Relationship to blog-persona
| Concern | blog-persona | blog-brand |
|---|---|---|
| Structured persona JSON for programmatic use | Yes | No |
| Readable brand context for cross-skill prompts | No | Yes |
| Audience and positioning | No | Yes |
| Taboo phrases and editorial don'ts | Partial (don't list) | Full (taboo + disclosures + scope) |
| Competitor differentiation | No | Yes |
| Topic boundaries | No | Yes |
| Voice fingerprint (tone sliders) | Yes (canonical) | Mirror (read-only) |
blog-brand does not replace blog-persona; it consumes it. The persona JSON remains the source of truth for tone dimensions, sentence-length distribution, and contraction frequency. VOICE.md mirrors the readable parts so prompts are self-contained.
If no persona exists when /blog brand init runs, the voice questions still produce a VOICE.md. Users who want programmatic enforcement can run /blog persona create after.
Error Handling
- Project root unclear: ask the user where to write the files. Default is the current working directory.
- Files already exist on init: ask whether to overwrite or run update instead.
- Persona referenced but missing: ask whether to leave the persona reference blank or create one.
- Reader provides minimal answers: prompt for at least 2 audience bullets and 3 editorial rules; refuse to write skeletons.
| 1 | |
| 2 | name blog-brand |
| 3 | description > |
| 4 | Establish durable brand and voice context for cross-skill consumption. |
| 5 | Generates BRAND.md (audience, positioning, do/don't editorial rules, taboo |
| 6 | phrases, competitor differentiation) and VOICE.md (existing persona JSON |
| 7 | re-expressed as readable prose), both written to the project root. When |
| 8 | present, the blog orchestrator auto-loads these files for write, rewrite, |
| 9 | brief, outline, calendar, and strategy workflows. Pairs with blog-persona, which manages the structured persona |
| 10 | JSON. Use when user says "blog brand", "create brand context", "brand |
| 11 | voice doc", "BRAND.md", "VOICE.md", "establish editorial brand", |
| 12 | "brand guidelines for blog". |
| 13 | user-invokable true |
| 14 | argument-hint "[init|show|update]" |
| 15 | license MIT |
| 16 | |
| 17 | |
| 18 | # Blog Brand: Durable Editorial Context |
| 19 | |
| 20 | Generates two project-root files that the blog orchestrator auto-loads for supported writing and planning commands when present: |
| 21 | |
| 22 | `BRAND.md`: who the audience is, what the brand stands for, what to never say |
| 23 | `VOICE.md`: how the brand sounds, structurally and lexically |
| 24 | |
| 25 | These are the editorial equivalent of impeccable's PRODUCT.md / DESIGN.md pattern: persistent context that survives across sessions and propagates to every command. |
| 26 | |
| 27 | ## Why this exists |
| 28 | |
| 29 | Today, persona JSON (from `blog-persona`) is loaded by some skills and not others. Topic-cluster context lives inside cluster vaults. Competitor positioning lives nowhere. Each blog command re-derives "what is the brand" from whatever context it has. |
| 30 | |
| 31 | `BRAND.md` and `VOICE.md` fix this: one canonical source, loaded by the `blog` orchestrator at the start of every command. |
| 32 | |
| 33 | When neither file exists, behavior is unchanged from v1.7.1. Backward compatible. |
| 34 | |
| 35 | ## Commands |
| 36 | |
| 37 | | Command | Purpose | |
| 38 | |---|---| |
| 39 | | `/blog brand init` | Interactive interview, writes BRAND.md and VOICE.md to project root | |
| 40 | | `/blog brand show` | Display current contents (or report missing) | |
| 41 | | `/blog brand update` | Re-run the interview with current values as defaults | |
| 42 | |
| 43 | ## Init Workflow |
| 44 | |
| 45 | Run the 5-step interactive interview. Ask each step, wait for response, then proceed. If `blog-persona` JSON already exists, pre-fill voice answers from it. |
| 46 | |
| 47 | ### Step 1: Audience |
| 48 | |
| 49 | Ask: |
| 50 | **Primary audience role** (e.g. "head of marketing at a 50-500 person B2B SaaS") |
| 51 | **Secondary audience** (optional) |
| 52 | **Reader expertise level**: beginner / intermediate / advanced / mixed |
| 53 | **Problems the reader is actively trying to solve** (3 to 5 bullets) |
| 54 | **Common misconceptions the audience holds** (used to anchor information gain) |
| 55 | |
| 56 | ### Step 2: Positioning and Canonical Entity |
| 57 | |
| 58 | Ask: |
| 59 | **Official entity name** (legal or public brand name) |
| 60 | **Homepage URL** (canonical brand front door) |
| 61 | **Logo URL or file path** (preferred square or SVG asset) |
| 62 | **sameAs profiles** (LinkedIn, X, YouTube, Crunchbase, GitHub, or other official profiles) |
| 63 | **Wikidata Q-ID** if one exists; leave blank if not notable |
| 64 | **One-sentence brand mission** (what the brand helps people do) |
| 65 | **Distinctive point of view** (the contrarian or non-obvious belief that shapes content) |
| 66 | **What this brand is NOT** (anti-positioning, what to never be confused with) |
| 67 | **Top 3 direct competitors** with the one-line differentiator vs each |
| 68 | |
| 69 | ### Step 3: Editorial rules |
| 70 | |
| 71 | Ask: |
| 72 | **Do list** (3 to 7 things the blog will always do; e.g. "cite primary sources only," "name the practitioner not the product") |
| 73 | **Don't list** (3 to 7 things the blog will never do; e.g. "no clickbait titles," "no listicle filler") |
| 74 | **Taboo phrases** (specific words or phrases this brand never uses; separate |
| 75 | from the repository's optional project style list) |
| 76 | **Required disclosures** (e.g. affiliate disclosure, AI-content disclosure, conflict-of-interest patterns) |
| 77 | |
| 78 | ### Step 4: Topic boundaries |
| 79 | |
| 80 | Ask: |
| 81 | **Topics fully in scope** (core content pillars) |
| 82 | **Topics partially in scope** (adjacent; covered only with original angle) |
| 83 | **Topics out of scope** (will not cover; redirect to partner content) |
| 84 | **Recurring formats / column names** if any (e.g. "Monthly Field Notes," "Reader Q&A") |
| 85 | |
| 86 | ### Step 5: Voice (auto-fill from blog-persona if present) |
| 87 | |
| 88 | Ask: |
| 89 | **Pronoun stance**: first-person (we / I), second-person (you), third-person (the team), or mixed |
| 90 | **Acceptable contractions**: full / partial / none |
| 91 | **Sentence ceiling**: max words per sentence as a hard cap |
| 92 | **Paragraph ceiling**: max words per paragraph (default 150) |
| 93 | **Headline patterns to favor**: numbered / question / promise / statement |
| 94 | **Headline patterns to avoid**: any patterns banned for this brand |
| 95 | **Summary box label**: from blog-persona, or pick one |
| 96 | |
| 97 | ## Output Files |
| 98 | |
| 99 | ### BRAND.md template |
| 100 | |
| 101 | Write to project root as: |
| 102 | |
| 103 | |
| 104 | # Brand Context |
| 105 | |
| 106 | > This file is auto-loaded by all blog sub-skills. Last updated: YYYY-MM-DD. |
| 107 | |
| 108 | ## Audience |
| 109 | |
| 110 | - **Primary**: [role + context] |
| 111 | - **Secondary**: [if any] |
| 112 | - **Expertise**: [level] |
| 113 | - **Active problems**: |
| 114 | - [problem 1] |
| 115 | - [problem 2] |
| 116 | - [problem 3] |
| 117 | - **Common misconceptions**: |
| 118 | - [misconception 1] |
| 119 | - [misconception 2] |
| 120 | |
| 121 | ## Positioning |
| 122 | |
| 123 | - **Official entity name**: [brand/entity] |
| 124 | - **Homepage**: [canonical URL] |
| 125 | - **Logo**: [URL or file path] |
| 126 | - **sameAs profiles**: |
| 127 | - [profile URL 1] |
| 128 | - [profile URL 2] |
| 129 | - **Wikidata Q-ID**: [QID or none] |
| 130 | - **Mission**: [one sentence] |
| 131 | - **Distinctive POV**: [contrarian or non-obvious belief] |
| 132 | - **What we are NOT**: [anti-positioning] |
| 133 | - **Competitors**: |
| 134 | - [Competitor A]: [our one-line differentiator] |
| 135 | - [Competitor B]: [our one-line differentiator] |
| 136 | - [Competitor C]: [our one-line differentiator] |
| 137 | |
| 138 | ## Editorial Rules |
| 139 | |
| 140 | ### Always do |
| 141 | - [rule 1] |
| 142 | - [rule 2] |
| 143 | - [rule 3] |
| 144 | |
| 145 | ### Never do |
| 146 | - [rule 1] |
| 147 | - [rule 2] |
| 148 | - [rule 3] |
| 149 | |
| 150 | ### Taboo phrases |
| 151 | - [phrase 1] |
| 152 | - [phrase 2] |
| 153 | |
| 154 | ### Required disclosures |
| 155 | - [disclosure rule] |
| 156 | |
| 157 | ## Topic Scope |
| 158 | |
| 159 | - **In scope**: [pillars] |
| 160 | - **Partial scope**: [adjacent topics] |
| 161 | - **Out of scope**: [topics to refuse] |
| 162 | - **Recurring formats**: [if any] |
| 163 | |
| 164 | |
| 165 | ### VOICE.md template |
| 166 | |
| 167 | Write to project root as: |
| 168 | |
| 169 | |
| 170 | # Voice Context |
| 171 | |
| 172 | > This file is auto-loaded by all blog sub-skills. Last updated: YYYY-MM-DD. |
| 173 | |
| 174 | ## Pronoun stance |
| 175 | [first-person / second-person / third-person / mixed] |
| 176 | |
| 177 | ## Lexical rules |
| 178 | - **Contractions**: [full / partial / none] |
| 179 | - **Sentence ceiling**: [N words max] |
| 180 | - **Paragraph ceiling**: [N words max, default 150] |
| 181 | - **Summary label**: [Key Takeaways / TL;DR / etc.] |
| 182 | |
| 183 | ## Headline patterns |
| 184 | - **Favor**: [list] |
| 185 | - **Avoid**: [list] |
| 186 | |
| 187 | ## Voice fingerprint (from blog-persona) |
| 188 | - Funny vs serious: [0.0 to 1.0] |
| 189 | - Formal vs casual: [0.0 to 1.0] |
| 190 | - Respectful vs irreverent: [0.0 to 1.0] |
| 191 | - Enthusiastic vs matter-of-fact: [0.0 to 1.0] |
| 192 | |
| 193 | ## Readability target |
| 194 | - Audience tier: [consumer / professional / technical] |
| 195 | - Flesch Grade: [range] |
| 196 | - Flesch Ease: [range] |
| 197 | |
| 198 | ## Reference samples |
| 199 | - [URL 1] (extracted patterns: [summary]) |
| 200 | - [URL 2] (extracted patterns: [summary]) |
| 201 | |
| 202 | |
| 203 | ## Show Workflow |
| 204 | |
| 205 | Check for `BRAND.md` and `VOICE.md` at project root. |
| 206 | If both exist, print a summary table (key sections only) and the file paths. |
| 207 | If one or both are missing, print which are missing and suggest `/blog brand init`. |
| 208 | |
| 209 | ## Update Workflow |
| 210 | |
| 211 | Same as Init, but pre-fills every answer with the current value. The user can press enter to accept or type a new value. After collecting all answers, overwrite both files with the new contents and update the `Last updated:` line. |
| 212 | |
| 213 | ## Integration with the blog orchestrator |
| 214 | |
| 215 | When `/blog write`, `/blog rewrite`, `/blog brief`, `/blog outline`, `/blog calendar`, or `/blog strategy` runs, the orchestrator (`skills/blog/SKILL.md`) checks for `BRAND.md` and `VOICE.md` at the project root. If present, the contents are injected into the system prompt for downstream agents (`blog-researcher`, `blog-writer`, `blog-seo`, `blog-reviewer`). |
| 216 | |
| 217 | If absent, behavior is unchanged. The orchestrator does not prompt the user to create them; they are opt-in context. |
| 218 | |
| 219 | ## Relationship to blog-persona |
| 220 | |
| 221 | | Concern | blog-persona | blog-brand | |
| 222 | |---|---|---| |
| 223 | | Structured persona JSON for programmatic use | Yes | No | |
| 224 | | Readable brand context for cross-skill prompts | No | Yes | |
| 225 | | Audience and positioning | No | Yes | |
| 226 | | Taboo phrases and editorial don'ts | Partial (don't list) | Full (taboo + disclosures + scope) | |
| 227 | | Competitor differentiation | No | Yes | |
| 228 | | Topic boundaries | No | Yes | |
| 229 | | Voice fingerprint (tone sliders) | Yes (canonical) | Mirror (read-only) | |
| 230 | |
| 231 | `blog-brand` does not replace `blog-persona`; it consumes it. The persona JSON remains the source of truth for tone dimensions, sentence-length distribution, and contraction frequency. `VOICE.md` mirrors the readable parts so prompts are self-contained. |
| 232 | |
| 233 | If no persona exists when `/blog brand init` runs, the voice questions still produce a `VOICE.md`. Users who want programmatic enforcement can run `/blog persona create` after. |
| 234 | |
| 235 | ## Error Handling |
| 236 | |
| 237 | **Project root unclear**: ask the user where to write the files. Default is the current working directory. |
| 238 | **Files already exist on init**: ask whether to overwrite or run update instead. |
| 239 | **Persona referenced but missing**: ask whether to leave the persona reference blank or create one. |
| 240 | **Reader provides minimal answers**: prompt for at least 2 audience bullets and 3 editorial rules; refuse to write skeletons. |
| 241 |