Claude Skill

content-engine

Use when a content operation needs a SYSTEM: a dated editorial calendar built top-down from pillars, plus the stage gates, briefs, WIP limits and 1:10 atomization plan that move each slot to publish-ready. NOT writing the pieces (that is `article-writing`), NOT publishing them (t

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download ericrisco-rsc-harness-skills_content-engine-953fef5.zip · 14 KB
Part of ericrisco/rsc-harness — 46 skills

Install

skills CLI npx skills add https://github.com/ericrisco/rsc-harness/tree/main/skills/content-engine
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install ericrisco-rsc-harness@llmmart
Git git clone https://github.com/ericrisco/rsc-harness.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole ericrisco/rsc-harness collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Content Engine — The Calendar and the Pipeline That Feeds It

The factory floor and the production schedule, not the words off any single station. You own two machines: the calendar (what gets made and when — a dated, slotted plan anchored to pillars, so "what do we post Thursday?" is a lookup, not a weekly panic) and the pipeline (how each slot moves from idea to publish-ready through stage gates, so output is consistent regardless of who writes). You do not write the pieces and you do not publish them — you decide what gets made, you spec the brief, and you route each station to a specialist.

Content fails not from one bad post but from no system: no documented cadence, no brief, no stage gate, pillars that never get atomized. ~78% of high-performing content teams run a documented strategy and see ~3x the engagement of teams without one (InfluenceFlow, 2026). This skill is that system.

Ground first (STOP gate)

You plan content for a real brand; you do not invent its strategy. Before building anything, read what already exists.

  1. Read the brand study and pillars from 02-DOCS/ (the project wiki). If the project uses the harness convention, that is 02-DOCS/wiki/ — see ../harness/SKILL.md.
  2. If voice/tone is missing → STOP. Route the user to brand-voice to codify do/don't words and voice samples. Do not invent a voice; a calendar built on a guessed voice produces off-brand drafts at every station.
  3. If pillars/clusters/keywords are missing → STOP for the research half. Route topic-cluster and keyword work to seo-geo. You consume pillars and clusters; you do not derive them from search data — that is its job.
  4. Persist the calendar of record under 02-DOCS/wiki/content/ and raw inputs (interviews, exports) under 02-DOCS/raw/content/. Why: the calendar must be a durable artifact of record, not a chat message that scrolls away.
  5. Cite what you grounded in (e.g. "pillars from 02-DOCS/wiki/brand-study.md"). If you grounded in nothing, say so and stop.

Build the calendar

Build top-down, slot last. Personas → Pillars → Clusters → Assets, in that order. The calendar is derived from this architecture; it is never a bottom-up pile of "post ideas." Bottom-up calendars are the #1 failure mode — they have no theme, no leverage, and no reason any given post exists. Why this one is absolute: structure makes topic choice a lookup, not a creative emergency every Monday.

Four-layer architecture (counts are defaults, state them):

Layer Count What it is
Personas 2–4 who you are writing for
Pillars 4–6 durable themes you own; fewer is too narrow, more dilutes effort
Clusters 3–5 per pillar sub-topics under each pillar
Assets concrete the actual dated formats (the slots)

Why 4–6 pillars: calendars anchor to pillars so topic choice is structural. Below 4 you are too narrow to sustain a cadence; above 6 effort scatters and no theme compounds (Entasher 2025-11-29; InfluenceFlow 2026).

Cadence baseline (sustainable, the default you propose):

  • ~1 flagship piece / month — a guide, report, or webinar; the thing you atomize.
  • 4–8 supporting posts / week.
  • ~1 proof piece / month — case study or result.

Consistency for 6–12 months beats a one-month sprint. The real constraint is creating, not posting — brands already averaged ~9.5 social posts/day across networks in 2024 (Kontent.ai). The pipeline exists to relieve creation, not posting.

Slot-mix rule (encode these as allocation defaults):

  • 70 / 20 / 10: ~70% evergreen, ~20% timely/seasonal, ~10% experimental.
  • Leave 20–30% of slots OPEN for reactive content — do not fully pre-fill the calendar.
  • Budget 15–25% of weekly capacity for UPDATING existing winners, not only net-new.

Why: a 100%-planned calendar with zero slack cannot react and rots into a graveyard; never refreshing winners throws away your highest-ROI slots (InfluenceFlow 2026).

Decision table — cadence by team size (a real branch, so the table earns its place):

Team Flagship Supporting Atomize per flagship WIP cap
Solo 1 / 6–8 wks 3–4 / wk 5–7 derivatives 1–2 in flight
Small (2–5) 1 / mo 4–6 / wk ≥10 derivatives 3–4 in flight
Multi-stakeholder 1–2 / mo 6–8 / wk ≥10 + paid cutdowns 5–6, gated by owner

Slot schema — emit the calendar as CSV (one row per slot) so scripts/verify.sh can lint it:

date,pillar,cluster,format,owner,stage,brief_link,atomization,mix
2026-07-07,Onboarding,activation-checklist,flagship-guide,ana,brief,02-DOCS/wiki/content/briefs/onboarding-guide.md,planned,evergreen
2026-07-09,Onboarding,activation-checklist,linkedin-post,ana,idea,,,evergreen
2026-07-15,Trends,q3-benchmarks,reactive-open,,idea,,,timely

mix is one of evergreen|timely|experimental (plus leave reactive-open slots with empty owner). Full column docs + a filled example live in references/brief-and-pipeline.md.

The brief

A slot cannot leave the idea stage without a brief. One canonical brief format means consistent output regardless of who writes it. The brief is a .md page in the 02-DOCS/wiki/ OKF v0.1 bundle: its YAML frontmatter carries a non-empty type: content-brief (plus the OKF-recommended title/description/tags/timestamp) alongside the domain fields below, and any body cross-references use standard markdown links, never wikilinks. Required fields (inline minimum):

  • objective — the one outcome this piece drives.
  • persona — which of the 2–4 you target.
  • pillar / cluster — where it sits in the architecture.
  • angle — the specific take (not the topic).
  • format — flagship-guide / linkedin-post / video-short / newsletter-issue / …
  • owner — the human accountable for the slot.
  • target keyword — handed off from seo-geo, not invented here.
  • success metric — how you will know it worked.
  • atomization intent — for flagships, the derivative count and target channels.

Full template with a filled example → references/brief-and-pipeline.md. Why one brief: the brief is where "AI is a station, not the author" gets enforced — a human sets objective, angle, and what "good" is before a draft exists.

The pipeline: stages + gate

idea → brief → draft → edit → atomize → publish-ready. Each stage has an entry gate (what must be true to enter) and an exit gate (what must be true to leave). Run the gates as a checklist — this is a real branch, so the checklist earns its place:

  • idea → brief: slot exists in the calendar with a pillar/cluster assigned. Exit: brief written and owner set.
  • brief → draft: brief complete, target keyword present, voice reference linked. Exit: a draft exists.
  • draft → edit: draft hits the brief's format and angle. Exit: edited against the brief and the voice guide.
  • edit → atomize: flagship has a passing edit. Exit: atomization plan filled (≥ derivative count). Non-flagships skip to publish-ready.
  • atomize → publish-ready: derivatives are planned and routed. Exit: every asset has an owner and a destination.

WIP limits matter more than throughput. Cap in-flight slots per the team-size table; pulling a new idea before finishing the last one is how the calendar becomes a graveyard.

AI is a station, not the author. Use AI for research, outlines, drafts, repurposing, and angle-testing. Humans decide which pillars matter, which stories to tell, and what "good" is. Voice is grounded via brand-voice, never invented (Entasher 2025-11-29).

Atomization (1:10)

Every flagship carries an atomization plan, not just a publish date. Aim for ≥10 distinct derivatives per flagship — repurposing yields ~3–5x reach, ~60% less creation time, and 94% of B2B marketers say it extends content ROI (DigitalApplied 2026-01-16).

Three phases:

  1. Audit — pick the high-value source by traffic / intent / conversion.
  2. Atomize — extract the reusable atoms: stats, quotes, frameworks, how-to steps, case studies.
  3. Reformat — reassemble atoms into platform-native formats, each adapted to its destination's length and language. Channel-native, never copy-paste: LinkedIn = numbered insights + an engagement question; an X thread = a bold hook in tweet 1, links back in the final tweet.

The derivative menu, a worked 1→10 example, and per-channel Bad→Good rewrites live in references/atomization.md.

Route the derivatives, do not write or ship them: each derivative goes to its specialist (../article-writing/SKILL.md, newsletter, video-shorts); the act of shipping goes to social-publisher; wiring publish/atomize into a cron or webhook flow goes to automation-flows.

Handoffs — who owns what

Ask Owner
Write the long-form article body ../article-writing/SKILL.md
Write the newsletter issue copy newsletter
Write/schedule/queue posts to platforms (the act of publishing) social-publisher
Script/storyboard a short-form video video-shorts
Keyword research, topic clustering, schema seo-geo
Codify tone, do/don't words, voice samples brand-voice
Landing/launch/web-page conversion copy ../marketing/SKILL.md
One-off reminders / scheduling meetings calendar-scheduling
Automate publish/atomize as a cron/webhook flow automation-flows

The tell: if the ask is the system that decides what gets made, when, and how it moves, it is here. If the ask is producing one artifact or the act of distributing, it is a sibling.

Anti-patterns

Anti-pattern Why it fails Do instead
Bottom-up calendar (pile of post ideas) no theme, no leverage, no reason a post exists derive slots from Personas→Pillars→Clusters
Slot with no brief output drifts per author; can't enforce voice block exit from idea until brief is complete
Flagship with no atomization plan 1:10 leverage left on the floor require an atomization plan to leave edit
Inventing brand voice off-brand at every station STOP, route to brand-voice
AI as author nobody owns angle, story, or "good" AI is a station; humans set objective and bar
Calendar-as-graveyard slots planned but never pulled enforce WIP limits; pull, don't pile
100%-planned, zero slack can't react to anything timely leave 20–30% of slots open
Net-new only, never updating discards highest-ROI winners budget 15–25% capacity for updates
Copy-paste cross-posting each channel punishes non-native content reformat per channel (references/atomization.md)
>7 pillars effort scatters, no theme compounds hold to 4–6

Verify

scripts/verify.sh path/to/calendar.csv lints an emitted calendar: required columns present, every stage is a valid pipeline state, every flagship row has a brief_link and an atomization plan, and it warns on mix sanity (>80% evergreen, or 0% reactive/open). It is read-only and exits 0 on a clean or empty target — it gates structure, not whether the plan is good.

Files (rsc-harness)
  • evals
    • cases.yaml 4.1 KB
      skill: content-engine
      
      # Prompts that MUST load `content-engine`. The skill owns the editorial CALENDAR
      # (built top-down from pillars) and the production PIPELINE that moves slots through
      # stages, plus the atomization PLAN. It does NOT write the pieces (article-writing,
      # newsletter, video-shorts), publish them (social-publisher), do keyword/cluster
      # research (seo-geo), or codify voice (brand-voice).
      should_trigger:
        - prompt: "Build me a content calendar for next quarter."
          why: "Core calendar ask — a dated, slotted editorial plan is exactly what this skill produces."
      
        - prompt: "Set up our content production pipeline with a brief template and stages."
          why: "Core pipeline ask — stage gates, the canonical brief, and WIP limits are the skill's second machine."
      
        - prompt: "Turn this pillar blog post into everything — plan all the derivatives and where each goes."
          why: "Non-obvious: looks like a writing ask but it's the atomization PLAN and routing (1:10), not the writing — owned here, then routed out."
      
        - prompt: "móntame un calendario de contenidos y un pipeline para el equipo."
          why: "Spanish phrasing for 'build me a content calendar and a pipeline for the team' — the core calendar+pipeline request."
      
        - prompt: "Our content is chaos, nobody knows what to post when — give us a system."
          why: "Non-obvious symptom phrasing with no calendar/pipeline word; the cure (documented cadence + stage gate + calendar of record) is exactly this skill."
      
        - prompt: "What should we post and when? Define our pillars and cadence for the next quarter."
          why: "Pillar definition + cadence + the dated plan is the top-down calendar build this skill owns."
      
      should_not_trigger:
        - prompt: "Write the actual 1,500-word blog post about user activation."
          route_to: article-writing
          why: "Producing one long-form artifact is article-writing; content-engine writes the brief and owns the slot, not the prose."
      
        - prompt: "Schedule and publish these posts to LinkedIn and X this week."
          route_to: social-publisher
          why: "The act of distributing/queuing to platforms is social-publisher; content-engine plans the slot, it does not ship it."
      
        - prompt: "Do keyword research and build the topic clusters for our SEO."
          route_to: seo-geo
          why: "Keyword/cluster research and ranking strategy decide inputs the calendar consumes; that research is seo-geo, not the calendar."
      
        - prompt: "Define our brand tone of voice and a do/don't word list."
          route_to: brand-voice
          why: "Codifying voice/tone and sample words is brand-voice; content-engine grounds in that artifact, it does not create it."
      
        - prompt: "Remind me to post every Tuesday at 9am."
          route_to: calendar-scheduling
          why: "A one-off recurring reminder is calendar-scheduling, not an editorial calendar built from pillars."
      
      capability:
        - scenario: >
            We're a 4-person B2B SaaS team. We have a brand study and content pillars in
            02-DOCS but no calendar and no pipeline. Build a Q3 editorial calendar and a
            production pipeline.
          must_include:
            - "Grounds in the 02-DOCS brand study and pillars (or STOPs and routes to brand-voice / seo-geo if missing) before building"
            - "Uses 4–6 pillars mapped to 3–5 clusters each, top-down (no bottom-up pile of post ideas)"
            - "Applies the cadence baseline: ~1 flagship/month + 4–8 supporting/week + ~1 proof/month"
            - "Honors the slot-mix rule: ~70/20/10, 20–30% slots left open/reactive, 15–25% capacity for updates"
            - "Emits a CSV calendar artifact with the required columns (date,pillar,cluster,format,owner,stage,brief_link,atomization,mix)"
            - "Provides a canonical brief per flagship slot (objective, persona, pillar/cluster, angle, format, owner, target keyword, success metric, atomization intent)"
            - "Defines the pipeline stages with entry/exit gates and WIP limits matched to a small (2–5) team"
            - "Includes an atomization plan of ≥10 derivatives per flagship, each routed to the correct sibling"
            - "Routes writing to article-writing/newsletter/video-shorts and shipping to social-publisher — nothing is written or published in-skill"
      
    • README.md 1.3 KB
      # Evals — content-engine
      
      `cases.yaml` is read by the repo's standard eval harness. The `should_trigger` and
      `should_not_trigger` cases check routing discrimination: each `should_trigger` prompt
      must select this skill (including the non-obvious "turn this pillar post into everything"
      atomization-plan case, the symptom-only "our content is chaos" case, and the Spanish
      phrasing), while each `should_not_trigger` prompt must route to the named sibling
      (`article-writing`, `social-publisher`, `seo-geo`, `brand-voice`, `calendar-scheduling`)
      rather than here — they guard the description's boundary between *the system* and
      *producing/distributing one artifact*. The single `capability` case is rubric-graded,
      not auto-scored: have the skill build the 4-person B2B SaaS Q3 calendar+pipeline and
      check the output against the `must_include` list (grounded in 02-DOCS, 4–6 pillars,
      cadence baseline, slot-mix, a CSV artifact, briefs, stage gates, a ≥10 atomization plan,
      and everything routed out). Run it through whatever runner the skills repo uses. For the
      CSV-artifact subset you can sanity-check a real calendar with
      `../scripts/verify.sh path/to/calendar.csv` — it lints columns, stages, flagship
      brief/atomization, and mix sanity, but does not judge whether the plan is good.
      
  • references
    • atomization.md 4.1 KB
      # Reference — Atomization (1 flagship → 10 derivatives)
      
      Offloaded detail for `content-engine`. The body states the 3 phases and the rule; this
      is the derivative menu, a worked 1→10 example, and per-channel Bad→Good rewrites.
      
      **Leverage:** aim for ≥10 distinct derivatives per flagship. Repurposing yields ~3–5x
      reach, ~60% less creation time, and 94% of B2B marketers say it extends content ROI
      (DigitalApplied, "Content Repurposing: One Piece, Ten Formats", 2026-01-16).
      
      ## The three phases
      
      1. **Audit** — pick the source by traffic / search intent / conversion, not by recency.
         Atomize your proven winners, not your latest post.
      2. **Atomize** — extract reusable atoms: **stats**, **quotes**, **frameworks**,
         **how-to steps**, **case studies**. Each atom can seed several derivatives.
      3. **Reformat** — reassemble atoms into platform-**native** formats. Adapt length and
         language to the destination; never paste the same text everywhere.
      
      ## Derivative menu (with length specs)
      
      | # | Derivative | Source atoms | Length / spec | Routed to |
      |---|---|---|---|---|
      | 1 | LinkedIn insight post | one framework + one stat | 1,200–1,800 chars, ends in a question | `social-publisher` (copy: `marketing`) |
      | 2 | LinkedIn carousel | how-to steps | 6–10 slides, one idea/slide | `social-publisher` |
      | 3 | X / thread | hook + 4–6 steps | tweet 1 = bold hook, last tweet links back | `social-publisher` |
      | 4 | Short-form video | one how-to step | 20–45s vertical, hook in 2s | `video-shorts` |
      | 5 | Short-form video #2 | a surprising stat | 20–45s vertical | `video-shorts` |
      | 6 | Newsletter section | the full framework | 200–400 words + CTA | `newsletter` |
      | 7 | Quote graphic | one quote | single image, attributed | `social-publisher` |
      | 8 | Infographic | stats + steps | one tall image | `social-publisher` |
      | 9 | Email nurture beat | one objection handled | 80–150 words | `newsletter` |
      | 10 | Internal-link / FAQ update | a how-to step | added to a related article | `article-writing` |
      
      (Beyond 10: paid cutdowns, a webinar segment, a SlideShare — for multi-stakeholder teams.)
      
      ## Worked 1 → 10 example
      
      **Flagship:** "The SaaS User-Activation Checklist" (guide, ~2,000 words, pillar Onboarding).
      
      1. LinkedIn post: "We watched 50 trials. The 3 setup steps teams skip — and the
         activation hit each one costs. Which do you skip?" (framework + stat)
      2. LinkedIn carousel: the 8-step checklist, one step per slide.
      3. X thread: hook "Most trials die in week one. Here's the autopsy 🧵", steps 2–7,
         final tweet → the guide.
      4. Short #1: "The one setup step 60% of teams skip" (single step, 30s).
      5. Short #2: "Activated users retain 4x longer" (the stat, 25s).
      6. Newsletter section: the full 8-step framework + "get the checklist" CTA.
      7. Quote graphic: "Activation is a week-one problem, not a month-three one."
      8. Infographic: the 8 steps + the retention stat as one tall image.
      9. Email nurture beat: handle "we don't have time to onboard" objection.
      10. FAQ/internal-link update: add "What is user activation?" answer to the pricing page,
          linking the guide.
      
      ## Per-channel native adaptation — Bad → Good
      
      **LinkedIn**
      
      - Bad: paste the guide's intro paragraph verbatim with a link.
      - Good: "3 setup steps most teams skip in week one:" → numbered insights → "Which one
        is your team guilty of?" Native = scannable + an engagement question.
      
      **X / thread**
      
      - Bad: one tweet with the headline and a link.
      - Good: tweet 1 is a bold standalone hook; the thread delivers the steps; the final
        tweet links back. Native = the hook earns the click before the link appears.
      
      **Short-form video**
      
      - Bad: a 3-minute screen recording reading the guide.
      - Good: 25–45s, hook in the first 2 seconds, ONE step, captions on. Native = one idea,
        vertical, no warm-up.
      
      **Newsletter**
      
      - Bad: dump the whole 2,000-word guide into the email.
      - Good: one framework + your take + a single CTA to the full guide. Native = a curated
        beat, not a re-host.
      
      The rule across all four: **reformat to the channel's language and length, never
      copy-paste.** Copy-paste cross-posting is an anti-pattern (see `../SKILL.md`).
      
    • brief-and-pipeline.md 5.2 KB
      # Reference — Brief, pipeline stages, and calendar slot schema
      
      Offloaded detail for `content-engine`. The body states the rules; this is the full
      template, the stage gates, and the CSV column docs you fill in.
      
      ## The canonical brief
      
      Every slot carries one brief in the same shape. A slot cannot leave the `idea` stage
      without it. Store briefs under `02-DOCS/wiki/content/briefs/<slug>.md`.
      
      These briefs live in the `02-DOCS/wiki/` OKF v0.1 bundle, so each brief `.md` carries YAML
      frontmatter with a non-empty `type: content-brief` (the OKF-recommended `title`/`description`/
      `tags`/`timestamp` are added where meaningful). The domain brief fields below are kept as-is —
      OKF allows any extra key. Cross-references in the body use **standard markdown links**, never
      wikilinks (e.g. `[brand voice](../brand-voice.md)`). See
      `../../harness/references/wiki-protocol.md` "## Conventions".
      
      | Field | Required | What goes here |
      |---|---|---|
      | `objective` | yes | the one outcome (e.g. "drive activation-checklist signups") |
      | `persona` | yes | which of the 2–4 personas |
      | `pillar` / `cluster` | yes | position in the architecture |
      | `angle` | yes | the specific take, not the topic ("the 3 setup steps most teams skip") |
      | `format` | yes | flagship-guide / linkedin-post / video-short / newsletter-issue / x-thread / … |
      | `owner` | yes | the human accountable |
      | `target_keyword` | flagship/article | handed off from `seo-geo`, never invented here |
      | `success_metric` | yes | how you'll know it worked (e.g. "100 checklist downloads in 30d") |
      | `atomization_intent` | flagship | derivative count + target channels |
      | `voice_ref` | yes | link to the `brand-voice` artifact the writer must follow |
      
      ### Filled example
      
      ```markdown
      ---
      # OKF v0.1 standard surface — `type` is the only REQUIRED field (non-empty).
      type: content-brief
      title: "Onboarding activation guide — brief"
      description: "Brief of record for the flagship activation-checklist guide."
      tags: [content-brief, onboarding, flagship]
      timestamp: 2026-07-01T00:00:00Z
      # Domain brief fields (OKF allows any extra key; the pipeline + verify read these).
      slug: onboarding-activation-guide
      objective: drive activation-checklist signups from new-trial users
      persona: hands-on-ops-lead
      pillar: Onboarding
      cluster: activation-checklist
      angle: the 3 setup steps most teams skip in week one
      format: flagship-guide
      owner: ana
      target_keyword: "saas user activation checklist"
      success_metric: 100 checklist downloads in 30 days
      atomization_intent: 10 derivatives — 3 LinkedIn, 1 X thread, 2 shorts, 1 newsletter, 3 carousels
      voice_ref: ../brand-voice.md
      ---
      ```
      
      ## Pipeline stages — entry/exit gates and WIP
      
      `idea → brief → draft → edit → atomize → publish-ready`
      
      | Stage | Entry gate | Exit gate | Typical WIP |
      |---|---|---|---|
      | `idea` | slot exists in calendar, pillar+cluster assigned | brief complete, owner set | unbounded (backlog) |
      | `brief` | brief written | target keyword present, voice_ref linked | small |
      | `draft` | brief complete | a draft exists, hits format+angle | cap per team-size table |
      | `edit` | draft exists | edited against brief + voice guide | cap per team-size table |
      | `atomize` | flagship passed edit (non-flagships skip) | atomization plan filled (≥ count) | 1–2 |
      | `publish-ready` | derivatives planned + routed | every asset has owner + destination | — |
      
      **WIP rule:** finish before you pull. Caps come from the cadence-by-team-size table in
      `../SKILL.md`. Exceeding the cap is how a calendar becomes a graveyard of half-done slots.
      
      **Station ownership:** `content-engine` owns the slot and its stage. Drafting/editing
      the words is routed out — long-form to `article-writing`, newsletter to `newsletter`,
      video to `video-shorts`, landing copy to `marketing`. The act of publishing is
      `social-publisher`. Automating the flow is `automation-flows`.
      
      ## Calendar slot schema (CSV)
      
      One row per slot. This is the artifact `scripts/verify.sh` lints.
      
      | Column | Meaning | Notes |
      |---|---|---|
      | `date` | publish/target date | `YYYY-MM-DD` |
      | `pillar` | one of the 4–6 pillars | required |
      | `cluster` | sub-topic under the pillar | required |
      | `format` | the asset format | `flagship-*` rows trigger the brief+atomization checks |
      | `owner` | accountable human | empty allowed only on `reactive-open` slots |
      | `stage` | pipeline state | `idea\|brief\|draft\|edit\|atomize\|publish-ready` |
      | `brief_link` | path to the brief | required non-empty for flagship rows |
      | `atomization` | plan ref or `planned` | required non-empty for flagship rows |
      | `mix` | allocation bucket | `evergreen\|timely\|experimental\|reactive-open` |
      
      ### Filled example
      
      ```csv
      date,pillar,cluster,format,owner,stage,brief_link,atomization,mix
      2026-07-07,Onboarding,activation-checklist,flagship-guide,ana,brief,02-DOCS/wiki/content/briefs/onboarding-activation-guide.md,planned,evergreen
      2026-07-09,Onboarding,activation-checklist,linkedin-post,ana,idea,,,evergreen
      2026-07-11,Onboarding,activation-checklist,x-thread,leo,idea,,,evergreen
      2026-07-15,Trends,q3-benchmarks,reactive-open,,idea,,,reactive-open
      2026-07-21,Proof,customer-results,case-study,leo,brief,02-DOCS/wiki/content/briefs/acme-results.md,planned,evergreen
      2026-07-28,Seasonal,back-to-work,linkedin-post,ana,idea,,,timely
      ```
      
  • scripts
    • verify.sh 5 KB
      #!/usr/bin/env bash
      #
      # verify.sh — structural lint for a `content-engine` editorial calendar CSV.
      #
      # WHAT IT DOES (read-only; never edits a file)
      #   Static, network-free checks on one calendar CSV emitted by the skill.
      #     1. A calendar artifact exists at the given path and has a header row.
      #     2. Required columns present:
      #        date,pillar,cluster,format,owner,stage,brief_link,atomization,mix
      #     3. Every row's `stage` is an allowed pipeline state
      #        (idea|brief|draft|edit|atomize|publish-ready).
      #     4. Every flagship-format row (format starts with "flagship") has a non-empty
      #        `brief_link` AND a non-empty `atomization` — the two hard rules (no flagship
      #        slot without a brief or an atomization plan).
      #     5. Mix sanity (warn only): warns if >80% of slots are evergreen, or if 0 slots
      #        are left open/reactive (catches the over-planned / no-slack anti-pattern).
      #
      #   Hard failures (missing artifact, missing column, bad stage, flagship missing
      #   brief/atomization) exit 1. Mix issues are warnings, not failures. A missing or
      #   empty target is reported and exits 0 (no false failure on a clean/empty target).
      #   Pure bash + awk, no dependencies. It is a lint, not a strategy oracle.
      #
      # HOW TO RUN
      #   ./verify.sh path/to/calendar.csv     # lint one calendar
      #   ./verify.sh                          # no target -> nothing to check, exit 0
      #
      # EXIT CODES
      #   0  clean, or nothing to check
      #   1  a hard structural failure
      #   2  bad usage
      #
      # Runs on stock macOS bash 3.2.
      
      set -euo pipefail
      
      if [ -t 1 ]; then
        RED=$'\033[31m'; GREEN=$'\033[32m'; YELLOW=$'\033[33m'; NC=$'\033[0m'
      else
        RED=''; GREEN=''; YELLOW=''; NC=''
      fi
      
      ok_count=0; warn_count=0; fail_count=0
      ok()   { printf '%s[ ok ]%s %s\n' "$GREEN"  "$NC" "$*"; ok_count=$((ok_count + 1)); }
      warn() { printf '%s[warn]%s %s\n' "$YELLOW" "$NC" "$*"; warn_count=$((warn_count + 1)); }
      fail() { printf '%s[fail]%s %s\n' "$RED"    "$NC" "$*"; fail_count=$((fail_count + 1)); }
      
      usage() { sed -n '2,33p' "$0" | sed 's/^# \{0,1\}//'; }
      
      summary_exit() {
        printf '\nok=%d warn=%d fail=%d\n' "$ok_count" "$warn_count" "$fail_count"
        [ "$fail_count" -gt 0 ] && exit 1
        exit 0
      }
      
      # --- arg parse --------------------------------------------------------------
      TARGET=""
      while [ $# -gt 0 ]; do
        case "$1" in
          -h|--help) usage; exit 0 ;;
          -*) printf 'unknown flag: %s\n' "$1" >&2; usage >&2; exit 2 ;;
          *) TARGET="$1"; shift ;;
        esac
      done
      
      # No target, or empty/missing file -> nothing to check, clean exit (no false fail).
      if [ -z "$TARGET" ]; then
        ok "no calendar path given — nothing to lint"
        summary_exit
      fi
      if [ ! -f "$TARGET" ]; then
        warn "file not found: $TARGET — nothing to lint"
        summary_exit
      fi
      if [ ! -s "$TARGET" ]; then
        warn "file is empty: $TARGET — nothing to lint"
        summary_exit
      fi
      
      # --- header / required columns ---------------------------------------------
      REQUIRED="date pillar cluster format owner stage brief_link atomization mix"
      
      # Map column name -> 1-based index from the header.
      get_idx() {
        awk -v want="$1" -F',' 'NR==1{for(i=1;i<=NF;i++){g=$i; gsub(/^[ \t]+|[ \t]+$/,"",g); if(g==want){print i; exit}}}' "$TARGET"
      }
      
      missing_cols=""
      for col in $REQUIRED; do
        idx="$(get_idx "$col")"
        if [ -z "$idx" ]; then
          missing_cols="$missing_cols $col"
        fi
      done
      
      if [ -n "$missing_cols" ]; then
        fail "missing required column(s):$missing_cols"
        summary_exit
      fi
      ok "all required columns present"
      
      STAGE_IDX="$(get_idx stage)"
      FORMAT_IDX="$(get_idx format)"
      BRIEF_IDX="$(get_idx brief_link)"
      ATOM_IDX="$(get_idx atomization)"
      MIX_IDX="$(get_idx mix)"
      
      # --- per-row checks (awk emits FAIL:/WARN:/STAT: lines we count below) ------
      RESULT="$(awk -F',' \
        -v si="$STAGE_IDX" -v fi="$FORMAT_IDX" -v bi="$BRIEF_IDX" -v ai="$ATOM_IDX" -v mi="$MIX_IDX" '
        function trim(s){ gsub(/^[ \t\r]+|[ \t\r]+$/,"",s); return s }
        NR==1 { next }
        trim($0)=="" { next }
        {
          total++
          stage=trim($si); fmt=trim($fi); brief=trim($bi); atom=trim($ai); mix=trim($mi)
          if (stage !~ /^(idea|brief|draft|edit|atomize|publish-ready)$/)
            print "FAIL:row " NR ": stage \"" stage "\" not an allowed pipeline state"
          if (fmt ~ /^flagship/) {
            flagship++
            if (brief == "") print "FAIL:row " NR ": flagship \"" fmt "\" has empty brief_link"
            if (atom  == "") print "FAIL:row " NR ": flagship \"" fmt "\" has empty atomization plan"
          }
          if (mix == "evergreen") evergreen++
          if (mix == "reactive-open" || fmt ~ /reactive/) reactive++
        }
        END {
          if (total > 0) {
            ev_pct = (evergreen*100)/total
            if (ev_pct > 80) printf "WARN:%d%% of slots are evergreen (>80%%) — thin on timely/experimental mix\n", ev_pct
            if (reactive == 0) print "WARN:0 slots left open/reactive — calendar has no slack to react"
          }
          printf "STAT:total=%d flagship=%d evergreen=%d reactive=%d\n", total, flagship+0, evergreen+0, reactive+0
        }
      ' "$TARGET")"
      
      while IFS= read -r line; do
        case "$line" in
          FAIL:*) fail "${line#FAIL:}" ;;
          WARN:*) warn "${line#WARN:}" ;;
          STAT:*) ok  "rows checked — ${line#STAT:}" ;;
        esac
      done <<EOF
      $RESULT
      EOF
      
      summary_exit
      
  • SKILL.md 11.6 KB
    ---
    name: content-engine
    description: "Use when a content operation needs a SYSTEM: a dated editorial calendar built top-down from pillars, plus the stage gates, briefs, WIP limits and 1:10 atomization plan that move each slot to publish-ready. NOT writing the pieces (that is `article-writing`), NOT publishing them (that is `social-publisher`), NOT keyword research (that is `seo-geo`)."
    tags: [content, editorial-calendar, content-pipeline, repurposing, marketing-ops]
    recommends: [brand-voice, seo-geo, social-publisher, article-writing, video-shorts, newsletter, automation-flows]
    origin: risco
    ---
    
    # Content Engine — The Calendar and the Pipeline That Feeds It
    
    *The factory floor and the production schedule, not the words off any single station.* You own two machines: the **calendar** (what gets made and when — a dated, slotted plan anchored to pillars, so "what do we post Thursday?" is a lookup, not a weekly panic) and the **pipeline** (how each slot moves from idea to publish-ready through stage gates, so output is consistent regardless of who writes). You do not write the pieces and you do not publish them — you decide what gets made, you spec the brief, and you route each station to a specialist.
    
    Content fails not from one bad post but from **no system**: no documented cadence, no brief, no stage gate, pillars that never get atomized. ~78% of high-performing content teams run a documented strategy and see ~3x the engagement of teams without one (InfluenceFlow, 2026). This skill is that system.
    
    ## Ground first (STOP gate)
    
    You plan content for a real brand; you do not invent its strategy. Before building anything, read what already exists.
    
    1. Read the brand study and pillars from `02-DOCS/` (the project wiki). If the project uses the harness convention, that is `02-DOCS/wiki/` — see `../harness/SKILL.md`.
    2. **If voice/tone is missing → STOP.** Route the user to `brand-voice` to codify do/don't words and voice samples. Do not invent a voice; a calendar built on a guessed voice produces off-brand drafts at every station.
    3. **If pillars/clusters/keywords are missing → STOP for the research half.** Route topic-cluster and keyword work to `seo-geo`. You consume pillars and clusters; you do not derive them from search data — that is its job.
    4. Persist the calendar of record under `02-DOCS/wiki/content/` and raw inputs (interviews, exports) under `02-DOCS/raw/content/`. *Why: the calendar must be a durable artifact of record, not a chat message that scrolls away.*
    5. Cite what you grounded in (e.g. "pillars from `02-DOCS/wiki/brand-study.md`"). If you grounded in nothing, say so and stop.
    
    ## Build the calendar
    
    **Build top-down, slot last.** Personas → Pillars → Clusters → Assets, in that order. The calendar is derived from this architecture; it is never a bottom-up pile of "post ideas." Bottom-up calendars are the #1 failure mode — they have no theme, no leverage, and no reason any given post exists. *Why this one is absolute: structure makes topic choice a lookup, not a creative emergency every Monday.*
    
    **Four-layer architecture (counts are defaults, state them):**
    
    | Layer | Count | What it is |
    |---|---|---|
    | Personas | 2–4 | who you are writing for |
    | Pillars | 4–6 | durable themes you own; fewer is too narrow, more dilutes effort |
    | Clusters | 3–5 per pillar | sub-topics under each pillar |
    | Assets | concrete | the actual dated formats (the slots) |
    
    *Why 4–6 pillars: calendars anchor to pillars so topic choice is structural. Below 4 you are too narrow to sustain a cadence; above 6 effort scatters and no theme compounds (Entasher 2025-11-29; InfluenceFlow 2026).*
    
    **Cadence baseline (sustainable, the default you propose):**
    
    - ~1 **flagship** piece / month — a guide, report, or webinar; the thing you atomize.
    - 4–8 **supporting** posts / week.
    - ~1 **proof** piece / month — case study or result.
    
    Consistency for 6–12 months beats a one-month sprint. The real constraint is *creating*, not posting — brands already averaged ~9.5 social posts/day across networks in 2024 (Kontent.ai). The pipeline exists to relieve creation, not posting.
    
    **Slot-mix rule (encode these as allocation defaults):**
    
    - **70 / 20 / 10**: ~70% evergreen, ~20% timely/seasonal, ~10% experimental.
    - Leave **20–30% of slots OPEN** for reactive content — do not fully pre-fill the calendar.
    - Budget **15–25% of weekly capacity for UPDATING** existing winners, not only net-new.
    
    *Why: a 100%-planned calendar with zero slack cannot react and rots into a graveyard; never refreshing winners throws away your highest-ROI slots (InfluenceFlow 2026).*
    
    **Decision table — cadence by team size** (a real branch, so the table earns its place):
    
    | Team | Flagship | Supporting | Atomize per flagship | WIP cap |
    |---|---|---|---|---|
    | Solo | 1 / 6–8 wks | 3–4 / wk | 5–7 derivatives | 1–2 in flight |
    | Small (2–5) | 1 / mo | 4–6 / wk | ≥10 derivatives | 3–4 in flight |
    | Multi-stakeholder | 1–2 / mo | 6–8 / wk | ≥10 + paid cutdowns | 5–6, gated by owner |
    
    Slot schema — emit the calendar as CSV (one row per slot) so `scripts/verify.sh` can lint it:
    
    ```csv
    date,pillar,cluster,format,owner,stage,brief_link,atomization,mix
    2026-07-07,Onboarding,activation-checklist,flagship-guide,ana,brief,02-DOCS/wiki/content/briefs/onboarding-guide.md,planned,evergreen
    2026-07-09,Onboarding,activation-checklist,linkedin-post,ana,idea,,,evergreen
    2026-07-15,Trends,q3-benchmarks,reactive-open,,idea,,,timely
    ```
    
    `mix` is one of `evergreen|timely|experimental` (plus leave `reactive-open` slots with empty owner). Full column docs + a filled example live in `references/brief-and-pipeline.md`.
    
    ## The brief
    
    A slot **cannot leave the `idea` stage without a brief.** One canonical brief format means consistent output regardless of who writes it. The brief is a `.md` page in the `02-DOCS/wiki/` OKF v0.1 bundle: its YAML frontmatter carries a non-empty `type: content-brief` (plus the OKF-recommended `title`/`description`/`tags`/`timestamp`) alongside the domain fields below, and any body cross-references use standard markdown links, never wikilinks. Required fields (inline minimum):
    
    - **objective** — the one outcome this piece drives.
    - **persona** — which of the 2–4 you target.
    - **pillar / cluster** — where it sits in the architecture.
    - **angle** — the specific take (not the topic).
    - **format** — flagship-guide / linkedin-post / video-short / newsletter-issue / …
    - **owner** — the human accountable for the slot.
    - **target keyword** — handed off from `seo-geo`, not invented here.
    - **success metric** — how you will know it worked.
    - **atomization intent** — for flagships, the derivative count and target channels.
    
    Full template with a filled example → `references/brief-and-pipeline.md`. *Why one brief: the brief is where "AI is a station, not the author" gets enforced — a human sets objective, angle, and what "good" is before a draft exists.*
    
    ## The pipeline: stages + gate
    
    `idea → brief → draft → edit → atomize → publish-ready`. Each stage has an entry gate (what must be true to enter) and an exit gate (what must be true to leave). Run the gates as a checklist — this is a real branch, so the checklist earns its place:
    
    - **idea → brief:** slot exists in the calendar with a pillar/cluster assigned. Exit: brief written and owner set.
    - **brief → draft:** brief complete, target keyword present, voice reference linked. Exit: a draft exists.
    - **draft → edit:** draft hits the brief's format and angle. Exit: edited against the brief and the voice guide.
    - **edit → atomize:** flagship has a passing edit. Exit: atomization plan filled (≥ derivative count). Non-flagships skip to publish-ready.
    - **atomize → publish-ready:** derivatives are planned and routed. Exit: every asset has an owner and a destination.
    
    **WIP limits matter more than throughput.** Cap in-flight slots per the team-size table; pulling a new idea before finishing the last one is how the calendar becomes a graveyard.
    
    **AI is a station, not the author.** Use AI for research, outlines, drafts, repurposing, and angle-testing. Humans decide which pillars matter, which stories to tell, and what "good" is. Voice is grounded via `brand-voice`, never invented (Entasher 2025-11-29).
    
    ## Atomization (1:10)
    
    Every flagship carries an atomization plan, not just a publish date. Aim for **≥10 distinct derivatives** per flagship — repurposing yields ~3–5x reach, ~60% less creation time, and 94% of B2B marketers say it extends content ROI (DigitalApplied 2026-01-16).
    
    Three phases:
    
    1. **Audit** — pick the high-value source by traffic / intent / conversion.
    2. **Atomize** — extract the reusable atoms: stats, quotes, frameworks, how-to steps, case studies.
    3. **Reformat** — reassemble atoms into platform-**native** formats, each adapted to its destination's length and language. Channel-native, never copy-paste: LinkedIn = numbered insights + an engagement question; an X thread = a bold hook in tweet 1, links back in the final tweet.
    
    The derivative menu, a worked 1→10 example, and per-channel Bad→Good rewrites live in `references/atomization.md`.
    
    **Route the derivatives, do not write or ship them:** each derivative goes to its specialist (`../article-writing/SKILL.md`, `newsletter`, `video-shorts`); the **act of shipping** goes to `social-publisher`; wiring publish/atomize into a cron or webhook flow goes to `automation-flows`.
    
    ## Handoffs — who owns what
    
    | Ask | Owner |
    |---|---|
    | Write the long-form article body | `../article-writing/SKILL.md` |
    | Write the newsletter issue copy | `newsletter` |
    | Write/schedule/queue posts to platforms (the act of publishing) | `social-publisher` |
    | Script/storyboard a short-form video | `video-shorts` |
    | Keyword research, topic clustering, schema | `seo-geo` |
    | Codify tone, do/don't words, voice samples | `brand-voice` |
    | Landing/launch/web-page conversion copy | `../marketing/SKILL.md` |
    | One-off reminders / scheduling meetings | `calendar-scheduling` |
    | Automate publish/atomize as a cron/webhook flow | `automation-flows` |
    
    The tell: if the ask is **the system that decides what gets made, when, and how it moves**, it is here. If the ask is **producing one artifact** or **the act of distributing**, it is a sibling.
    
    ## Anti-patterns
    
    | Anti-pattern | Why it fails | Do instead |
    |---|---|---|
    | Bottom-up calendar (pile of post ideas) | no theme, no leverage, no reason a post exists | derive slots from Personas→Pillars→Clusters |
    | Slot with no brief | output drifts per author; can't enforce voice | block exit from `idea` until brief is complete |
    | Flagship with no atomization plan | 1:10 leverage left on the floor | require an atomization plan to leave `edit` |
    | Inventing brand voice | off-brand at every station | STOP, route to `brand-voice` |
    | AI as author | nobody owns angle, story, or "good" | AI is a station; humans set objective and bar |
    | Calendar-as-graveyard | slots planned but never pulled | enforce WIP limits; pull, don't pile |
    | 100%-planned, zero slack | can't react to anything timely | leave 20–30% of slots open |
    | Net-new only, never updating | discards highest-ROI winners | budget 15–25% capacity for updates |
    | Copy-paste cross-posting | each channel punishes non-native content | reformat per channel (`references/atomization.md`) |
    | >7 pillars | effort scatters, no theme compounds | hold to 4–6 |
    
    ## Verify
    
    `scripts/verify.sh path/to/calendar.csv` lints an emitted calendar: required columns present, every `stage` is a valid pipeline state, every flagship row has a `brief_link` and an `atomization` plan, and it warns on mix sanity (>80% evergreen, or 0% reactive/open). It is read-only and exits 0 on a clean or empty target — it gates structure, not whether the plan is good.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related