name: ideate-topics description: "This skill should be used when the user asks to "ideate content topics", "brainstorm content angles", or "what should we write about this month". Reads client-profile, style guide, first-party KB, publish log, and stack-cadence fields, then proposes 8-12 ranked angles filtered to lanes the client actually publishes (cadence >= 1). Each angle carries working title, pillar, audience, evidence pointer, and lane. Writes 02_inputs/content-topics_YYYY-MM.md for the user to pick from."
ideate-topics
Propose a month's batch of content angles grounded in the client's actual profile, voice, and first-party material — not generic prompts. The user picks which angles to draft from the list this skill produces. First step of the monthly planning pass.
Template convention. Fenced code blocks below show
# ---where YAML front-matter delimiters belong, to keep Cowork's SKILL.md parser from misreading them. When writing the actual output file, emit real---, not# ---.
When to run
- First business day of the month — monthly ideation pass.
- User asks for topic ideas across any of the four content lanes.
- Publish log is getting thin and the pipeline needs refilling.
- User has supplied new first-party KB material and wants to turn it into content angles.
Preconditions
/rockstarr-ai/00_intake/client-profile.mdexists./rockstarr-ai/00_intake/style-guide.mdexists and is approved (front-matter should not flag LOW CONFIDENCE on positioning)./rockstarr-ai/00_intake/stack.mdexists with the v0.2 content-cadence fields populated:blogs_per_month,thought_leadership_per_month,email_newsletters_per_month,linkedin_newsletters_per_month,records_videos,case_studies_per_quarter./rockstarr-ai/01_knowledge_base/index.mdexists with at least one first-party processed file.
If the style guide is missing or unapproved, stop and tell the user
to run rockstarr-infra:generate-style-guide first. Topic ideation
without a locked voice produces generic drift.
If the cadence block is missing from stack.md, stop and tell the
user to run rockstarr-infra:capture-stack to fill the content-
cadence fields first. Without them this skill has no way to know
which lanes are even live.
Inputs
Read in this order:
/rockstarr-ai/00_intake/client-profile.md— positioning, audience, offers./rockstarr-ai/00_intake/style-guide.md— voice, tone, pillars, banned language./rockstarr-ai/00_intake/stack.md— content-cadence fields. This is the gate: only propose lanes whose cadence is >= 1./rockstarr-ai/02_inputs/seo/backlog.mdif it exists. The SEO content backlog is the strategic plan that scoped which topics matter for this client across 6-12 months. When present, the backlog is the preferred source for blog lane topics — see "Backlog-aware ideation" below./rockstarr-ai/01_knowledge_base/index.md— summary of every KB file withkb_scopetags.- Every first-party processed KB file (
kb_scope: owned) — pull concrete claims, frameworks, numbers, customer stories, and phrases the client has already used. These become evidence pointers for topics. - Third-party processed KB files (
kb_scope: third_party) — reference only. They can inform what competitors or the category are saying, but never act as voice signal and never get paraphrased into a topic angle. /rockstarr-ai/05_published/_publish.log— the last 90 days of shipped pieces. Use this to avoid repeating recent topics within 90 days, and to filter backlog items that have already shipped./rockstarr-ai/04_approved/content/and/rockstarr-ai/03_drafts/content/— list the slugs currently in flight. Filter these out of any backlog-driven proposals soideate-topicsdoesn't re-propose work already moving through the workflow.
Stack-cadence filter — the non-negotiable rule
Every topic this skill emits must belong to a lane the client actually publishes. For each lane:
blogs_per_month== 0 → no researched-blog topics proposed.thought_leadership_per_month== 0 → no thought-leadership topics proposed.email_newsletters_per_month== 0 → no email-newsletter topics proposed.linkedin_newsletters_per_month== 0 → no LinkedIn-newsletter topics proposed (note: LinkedIn newsletters reuse an approved thought-leadership piece viapublish-linkedin-newsletter, so TL cadence must also be >= 1).
Quota guidance: aim to propose roughly twice the month's cadence
per lane (e.g., blogs_per_month: 2 → propose 4 researched blog
angles so the client has choice). Cap the total at 12 across all
lanes.
Case studies are NOT generated here. They run on a quarterly
reminder via draft-case-study, outside the monthly calendar.
Backlog-aware ideation (v0.5)
If /rockstarr-ai/02_inputs/seo/backlog.md exists, the
strategic plan has already decided which blog topics matter
for this client. Monthly ideation in that case is sequencing,
not free generation.
How the backlog changes the blog lane
For the researched-blog lane, when the backlog exists:
- Read the backlog and parse every item's slug, cluster, cluster role (pillar / supporting), parent pillar (for supports), target keyword, search intent, difficulty, and quick-win flag.
- Filter out items whose slug appears in:
05_published/_publish.log(already published).04_approved/content/(approved, awaiting publish).03_drafts/content/(currently drafting).- The previous month's
content-topics_[YYYY-MM].mdwithPick: yes(already in flight from last month).
- From the remaining backlog items, propose this month's
blog picks at roughly 2× monthly cadence (so the user has
choice). Ranking heuristic, in order:
- Quick-win items first (⭐ in the backlog).
- Pillar pages BEFORE their supporting posts within a
cluster (supports link to pillar; pillar should ship
first —
content-calendarenforces this hard, but ideate-topics should propose in the right order). - Items in clusters that are not yet represented in any month's ideation.
- Each proposed angle carries
from_backlog: true,cluster: <cluster name>,cluster_role: pillar | supporting,parent_pillar_slug: <slug or null>,target_keyword,search_intent, anddifficultyin its line-item block — sooutline-blogdownstream can use the cluster info for internal linking defaults.
Fix-existing items (work_type)
As of the seo-site-audit integration, backlog items also carry
a work_type of new, refresh, consolidate, or expand.
Most are new (net-new topics). The others are audit-sourced
items acting on an existing post and carry an existing_url.
Treat them like any other backlog item for sequencing — they
already have their OWN unique slug (the strategist suffixes
fix-existing slugs, e.g. -refresh-2026, precisely so they are
NOT filtered out by the publish-log dedup in step 2). When you
propose one, carry its work_type and existing_url through to
the topic line so outline-blog knows it's refreshing or
consolidating an existing URL rather than starting from scratch.
No special-casing beyond that: a refresh item is a blog topic
for the month like any other.
For the other lanes (thought leadership, email newsletter, LinkedIn newsletter), the backlog is informational only. TL angles still come from the rubric-driven free ideation flow (the TL rubric is upstream of the SEO strategy — TL is opinion, not keyword-targeted). Newsletters anchor to the month's approved long-form pieces, same as before.
Low-backlog warning
After filtering, count the remaining un-covered blog items in
the backlog. If the count is fewer than 2× monthly blog
cadence (e.g., for blogs_per_month: 2, fewer than 4 items
remain), surface a warning to the user in the chat summary:
⚠ SEO backlog is running thin. [N] blog items remain against a monthly cadence of [N]. Consider re-running
seo-strategyto refresh the backlog before the next ideation pass.
This does NOT block ideation — propose what's there, plus fall back to free ideation for the remainder if needed. The warning just creates visibility so the strategist can refill before the backlog fully empties.
When the backlog does NOT exist
Skip this section entirely. Run the original
free-ideation flow for the blog lane (read profile, style
guide, KB, publish log, propose topics that fit the client's
pillars and the month's cadence). The backlog is additive —
its absence is a fully supported state, especially for
clients pre-onboarding or for clients on
blogs_per_month: 0.
Pillar selection
Derive 3 to 5 content pillars from the profile and style guide before listing topics. Pillars are the buckets topics fit into — for a B2B founder-led coach, pillars might be "Positioning", "Pipeline systems", "Founder-led selling", "The Growth Amplifier in practice". Every topic you propose must sit under one pillar. If you can only justify 2 pillars from the inputs, say so — do not invent pillars to hit a number.
Output
Write to
/rockstarr-ai/02_inputs/content-topics_YYYY-MM.md (ISO
year-month in the filename; if a file for the month already exists,
append -2, -3).
File structure:
# ---
client_id: [from client.toml]
generated_at: [ISO timestamp]
generate_skill_version: "rockstarr-content/ideate-topics@0.2.0"
month: "YYYY-MM"
pillars: ["Pillar A", "Pillar B", ...]
lanes_enabled:
blog: true # based on blogs_per_month >= 1
thought_leadership: true
email_newsletter: true
linkedin_newsletter: false
cadence_snapshot:
blogs_per_month: 2
thought_leadership_per_month: 2
email_newsletters_per_month: 4
linkedin_newsletters_per_month: 0
topic_count: [int]
recent_publish_window_days: 90
kb_sources_scanned: [int]
# ---
# Content topics — [Client name] — [Month Year]
## Pillars
- **Pillar A** — one-line description
- **Pillar B** — one-line description
- ...
## Cadence snapshot
This month's targets from stack.md:
- Researched blogs: N per month
- Thought-leadership pieces: N per month
- Email newsletters: N per month
- LinkedIn newsletters: N per month (gated on thought leadership)
Lanes with cadence 0 are suppressed — no topics proposed.
## Topic list
### 1. [Working title]
- **Pillar:** Pillar A
- **Lane:** blog | thought-leadership | email-newsletter | linkedin-newsletter
- **Audience:** [specific audience from the profile]
- **Angle:** [one sentence — the contrarian / specific POV, not a summary]
- **Enemy** (thought-leadership only): [one-sentence headline of what this angle argues AGAINST. See "Enemy field — thought leadership only" below.]
- **Evidence (first-party):** [KB file or client-profile.md section]
- **References (third-party, optional):** [KB file + link]
- **Why now:** [one line — topical, seasonal, gap in publish log, customer question]
- **Rough length:** [800-word TL | 1500-word researched blog | 700-word newsletter | etc.]
- **Handoff:** outline-blog | outline-thought-leadership | draft-newsletter | publish-linkedin-newsletter
- **LinkedIn newsletter:** true | false (thought-leadership lane only; true when this angle is flagged for LinkedIn-newsletter republish. Carries downstream to the TL draft's `linkedin_newsletter_eligible` front-matter and tells `content-calendar` to add a LinkedIn-newsletter slot sourced from this piece. Default false. Only set true when `linkedin_newsletters_per_month >= 1`.)
- **From backlog:** true | false (default false; true when the angle was sourced from `02_inputs/seo/backlog.md`)
- **Slug:** kebab-cased-slug (required when from_backlog is true; carried verbatim from the backlog so downstream slug matching works)
- **Work type:** new | refresh | consolidate | expand (blog lane, when from_backlog; default new)
- **Existing URL:** [url] | null (required when work_type is refresh/consolidate/expand; carried from the backlog item)
- **Cluster:** [cluster name from backlog] (blog lane, when from_backlog)
- **Cluster role:** pillar | supporting (blog lane, when from_backlog)
- **Parent pillar slug:** [slug] | null (when cluster_role=supporting)
- **Target keyword:** [primary keyword from backlog] (blog lane, when from_backlog)
- **Search intent:** Informational | Commercial | Transactional (blog lane, when from_backlog)
- **Difficulty:** Low | Medium | High (blog lane, when from_backlog)
- **Quick win:** true | false (blog lane, when from_backlog)
### 2. ...
Aim for 8 to 12 topics total across enabled lanes. Rank them by strength of first-party evidence, not by how viral they feel. Angles grounded in a real claim the client has made are more useful than clever frames with no evidence.
Lane — how to decide
Researched blog (1200–2500 words, outline-first): Single-focus informational angle, SEO-friendly, answers a question or teaches a system. Cites first-party evidence heavily; may cite third-party research in a References section. Routed through
outline-blog(gate) →draft-blog.Thought leadership (600–1200 words, outline-first as of v0.3): Stance-led opinion piece. Pushes back on a view, names a pattern, reframes a problem. Weight from POV, not research. Each TL angle MUST carry an
enemyfield — see the next section. Routed throughoutline-thought-leadership(gate) →draft-thought-leadership. This is also the source for LinkedIn newsletter republishes when that lane is active.Email newsletter (600–900 words): Personal, conversational, stitches 2–3 short thoughts, CTA links to the month's blog and thought-leadership pieces on the website. Routed through
draft-newsletter.LinkedIn newsletter (reuse of TL): Not a new angle — a thought-leadership piece already in the pipeline that will be republished as a LinkedIn article. When a TL angle is especially well-suited for republishing AND
linkedin_newsletters_per_month >= 1, setLinkedIn newsletter: trueon that angle's line item. The handoff ispublish-linkedin-newsletter, running against the approved TL piece;content-calendaradds the LinkedIn-newsletter slot.
Enemy field — thought leadership only
Per the canonical TL rubric at
rockstarr-infra/skills/_shared/references/tl-rubric.md §
"Multi-article series — enemy diversity":
If the newsletter publishes multiple articles in a series, each piece must make a different argument with a different enemy. Four pieces that all defend the same product around the same villain read as one ad repeated four times.
For every thought-leadership angle proposed, capture an enemy
field — a one-sentence headline of what the piece argues
AGAINST. Examples:
- "Vague positioning that blocks referrals."
- "Owner-dependent AI use that scales the bottleneck."
- "Buying execution instead of building a system."
- "Confusing pipeline that runs on memory with pipeline that runs on infrastructure."
Each enemy must be specific enough to write a counter-piece against. "Bad marketing" or "doing it wrong" are not enemies — they're labels. If the writer can't name the specific villain the piece argues against, the angle isn't ready and should be re-worked or dropped.
Enemy diversity check
After proposing the month's TL angles, run a diversity check on their enemies. The test: can you imagine reading two of these pieces back-to-back and feeling like the second one repeated the first one's argument under a different title?
Concretely, for each pair of TL enemies in the month's slate, compare:
- Same target? (Same villain, just rephrased.)
- Same systemic root cause? ("Founders not delegating" and "Owner-dependent ops" are the same root cause stated two ways — that's a rhyme.)
- Same fix? (If the implied solution is the same product or same methodology in both pieces, the enemies rhyme even if they sound different.)
If two TL angles' enemies fail any of those three sub-tests,
flag them as rhyming. Surface to the user via
AskUserQuestion:
Two thought-leadership angles for [Month] have rhyming enemies. They'll read as the same argument restated:
- "[Title 1]" — enemy: [enemy 1]
- "[Title 2]" — enemy: [enemy 2]
Which would you like to do?
- Drop one of these and re-propose
- Keep both, accept the redundancy
- Sharpen the enemy on one to differentiate
- Skip this check (override)
Do NOT silently swap or modify the angle. The user decides.
If only one TL angle is proposed for the month, skip the check. The diversity test only applies when multiple TL pieces ship in the same monthly cadence.
Run modes (foreground / background)
- Foreground (default): an operator is in chat — run the
Interview step below (surface rhyming enemies, summarize, ask for
picks via
AskUserQuestion). - Background (invoked by
plan-monthon the scheduled monthly run): there is no operator to ask. Write the ranked topics file exactly as in foreground, run the enemy-diversity check and FLAG any rhyming pairs inline in the file (add a clear note under each flagged TL angle) rather than asking, and do NOT run the picksAskUserQuestion—plan-monthauto-selects the provisional pick set and a human approves the calendar downstream. Return the file path and stop. Never pick on the user's behalf in this skill; the selection isplan-month's job, the approval is the human's.
Interview step (foreground only)
After writing the file:
- Run the enemy diversity check on the TL angles (see "Enemy field" above). Surface any rhyming pairs to the user before asking for picks. Resolve those before proceeding.
- Summarize the top picks per lane in chat: count per lane, top 1–2 topic titles per lane.
- Ask the user, via
AskUserQuestion, which topics they want to commit to for the month to hit each lane's cadence. Use at most 4 options per question; if there are more than 4 topics worth presenting, ask across multiple rounds. - Do not proceed to outlining or drafting inside this skill.
Hand off to
content-calendar(to slot the picks across the month) as the next step.
What NOT to do
- Do not propose a topic for a lane whose cadence is 0. Honor the stack as the single source of truth.
- Do not use third-party KB content as a topic angle or an evidence pointer. Third-party material may only appear in the optional references line and must remain clearly attributed.
- Do not propose topics that contradict the style guide's Do Not list or the banned-language list.
- Do not propose topics that repeat a headline from
_publish.login the last 90 days, unless the user explicitly asks for a follow-up or refresh. - Do not invent customer stories, numbers, or case studies. If a proposed topic needs a stat or story the client has not already made public, flag it as a blocker in the evidence line.
- Do not emit case-study angles here — those are quarterly via
draft-case-study. - Do not draft the actual content here. Ideation is the whole job.
- Do not run calendar assignment here — that's
content-calendar.