// 9-phase lifecycle
Produce
/ttm-produce
Produce phase: generate content assets in fresh contexts loaded with brief, positioning, brand, ICP, and playbook. Use after a brief is approved.
Overview
Produce is the production wave of the lifecycle. It generates content assets in fresh Task() subagent contexts loaded with the brief, positioning, brand, ICP, and the relevant discipline playbook. Run ttm-produce after a brief is approved.
The hero asset is produced first (blocking), then derivatives are spawned in parallel. Each producer runs in isolation and writes to MANIFEST.json for the verify step to consume. Producing in a fresh context (rather than the main conversation) keeps generic chat history from polluting the output, which is why takeToMarket assets pass verification at a higher rate than free-form prompts.
This is also the only place where multiple assets are built in parallel; sequential production is two-to-five times slower at the same quality. Invoke it as ttm-produce with an optional [campaign-slug] argument.
How it works
The skill reads and follows the workflow at ${CLAUDE_PLUGIN_ROOT}/workflows/lifecycle/produce.md. Its required reading is ${CLAUDE_PLUGIN_ROOT}/references/context-loading.md and ${CLAUDE_PLUGIN_ROOT}/agents/ttm-producer.md.
Purpose: Production orchestration for /ttm-produce. Generates content assets in fresh Task() subagent contexts loaded with brief + positioning (full) + brand (full) + ICP (full) + playbook (per D-03). The hero asset is produced first (blocking), then derivatives are spawned in parallel (per D-01). Writes MANIFEST.json for verify consumption (per D-11).
Step 0: First-run inline education
Read .taketomarket/CONFIG.md. Parse first_run_seen (object) and inline_education (boolean, default true).
If inline_education is false: skip this step. Else if first_run_seen.ttm-produce is not true, print the explainer below verbatim, then mark this skill as seen:
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" first-run mark ttm-produceUse this exact check (bash) to decide whether to print: node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" first-run check ttm-produce --raw -- the JSON seen field is true once the explainer has run before.
This skill is backed by the bundled script ${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs, which handles first-run tracking, campaign state reads/updates, and timestamp generation. Its source is not inlined here.
Explainer for /ttm-produce
/ttm-produce is the production wave. It loads the brief, positioning, brand, ICP, and playbook into a fresh 200K-token Task() subagent context, generates the hero asset, then fans out parallel subagents for derivatives. Each producer runs in isolation and writes to MANIFEST.json for the verify step to consume.
Why it matters: producing in the main conversation context means your generic chat history pollutes the output. Fresh contexts + structured inputs are why takeToMarket assets pass verification at a higher rate than free-form prompts. This is also the only place where multiple assets are built in parallel -- sequential production is two-to-five times slower at the same quality.
(Canonical source: references/inline-education-blurbs.md. Embedded verbatim because workflows do not @-resolve files at runtime.)
Text-Mode Detection
Text mode (--text flag): Set TEXT_MODE=true if --text is present in $ARGUMENTS or if the runtime is not Claude Code. When TEXT_MODE is active, replace every AskUserQuestion call with a plain-text numbered list.
Detection:
if echo "$ARGUMENTS" | grep -q -- '--text'; then TEXT_MODE=true; fiIf AskUserQuestion tool is not available in the current runtime, set TEXT_MODE=true.
When TEXT_MODE is active, replace each AskUserQuestion with a plain-text numbered list:
[HEADER]
[QUESTION]
1. [OPTION_1_LABEL] -- [OPTION_1_DESCRIPTION]
2. [OPTION_2_LABEL] -- [OPTION_2_DESCRIPTION]
...
Type the number of your choice:Step 1: Load Context
takeToMarket > LOADING CONTEXTExtract SLUG from $ARGUMENTS (strip --text flag if present):
SLUG=$(echo "$ARGUMENTS" | sed 's/--text//g' | xargs)Read Tier 1 summaries from all 9 reference files (lines 1 to <!-- END_SUMMARY -->):
.taketomarket/POSITIONING.md.taketomarket/BRAND.md.taketomarket/ICP.md.taketomarket/CHANNELS.md.taketomarket/STATE.md(frontmatter only).taketomarket/CALENDAR.md.taketomarket/COMPETITORS.md.taketomarket/METRICS.md.taketomarket/LEARNINGS.md
Read Tier 2 (full content) for production context (per D-03):
.taketomarket/POSITIONING.md.taketomarket/BRAND.md.taketomarket/ICP.md
Read campaign-specific files (always full-load per context-loading.md rule 4):
.taketomarket/CAMPAIGNS/${SLUG}/STATE.md.taketomarket/CAMPAIGNS/${SLUG}/BRIEF.md
Step 2: Validate Campaign State
Check campaign exists:
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign state "${SLUG}" --rawIf result shows exists: false: Tell the user the campaign does not exist and suggest running /ttm-new-campaign first. Exit.
Read campaign state. Check the phase field:
- If phase is
"briefed": This is the expected state. Proceed normally. - If phase is
"created"or"researched": Warn the user -- "Campaign has not been briefed yet. Run/ttm-brief ${SLUG}first to generate a brief before producing content." Exit. - If phase is
"produced"or later (verified, reviewed, fixed, shipped, measured, learned): Warn the user -- "Campaign is already in phase '${PHASE}'. Re-producing will overwrite existing assets in CAMPAIGNS/${SLUG}/ASSETS/. Proceed?" Wait for user confirmation. If user declines, exit.
Step 3: Parse Assets List from Brief
takeToMarket > PARSING BRIEFRead .taketomarket/CAMPAIGNS/${SLUG}/BRIEF.md.
Extract the assets list from the brief. The brief contains an "Assets List" section (created by /ttm-brief) structured as a Markdown table with columns: asset type, channel, and role.
Parse each row into an asset entry:
type: The asset type (e.g., blog-post, linkedin-post, email, landing-page)channel: The target channel (e.g., organic-search, linkedin, email)is_hero:truefor the FIRST asset in the list,falsefor all others (per D-01)
The FIRST asset in the list is the hero asset. All others are derivatives.
If no assets list is found in the brief, or if the table is empty: Error -- "Brief has no assets list -- run /ttm-brief ${SLUG} first to generate a complete brief." Exit.
Store the parsed list as ASSETS_LIST with the total count as TOTAL_ASSETS.
Step 4: Resolve Playbooks
For each asset in ASSETS_LIST:
1. Map the asset type to a discipline playbook using the PLAYBOOK_MAP lookup table (asset type slug -> playbook filename):
| Asset Type | Playbook File | Discipline |
|---------------------|---------------|------------|
| blog-post | seo.md | SEO |
| landing-page | seo.md | SEO |
| pillar-page | seo.md | SEO |
| programmatic-seo | seo.md | SEO |
| faq-page | aeo.md | AEO |
| knowledge-base | aeo.md | AEO |
| how-to-guide | aeo.md | AEO |
| email | email.md | Email |
| email-sequence | email.md | Email |
| newsletter | email.md | Email |
| linkedin-post | linkedin.md | LinkedIn |
| linkedin-article | linkedin.md | LinkedIn |
| linkedin-carousel | linkedin.md | LinkedIn |
| social-post | social.md | Social |
| twitter-thread | social.md | Social |
| instagram-carousel | social.md | Social |
| youtube-video | youtube.md | YouTube |
| youtube-short | youtube.md | YouTube |
| paid-ad | paid-ads.md | Paid Ads |
| google-ad | paid-ads.md | Paid Ads |
| meta-ad | paid-ads.md | Paid Ads |
| affiliate-kit | affiliate.md | Affiliate |
| affiliate-creative | affiliate.md | Affiliate |
| press-release | pr-media.md | PR/Media |
| media-pitch | pr-media.md | PR/Media |
| event-landing | events.md | Events |
| webinar-funnel | events.md | Events |
| event-recap | events.md | Events |For the given asset type:
- Look up the asset type in PLAYBOOK_MAP
- If found: set
PLAYBOOK_FILEto the mapped filename - If NOT found: set
PLAYBOOK_FILEto the asset type slug with.mdextension (fallback:${TYPE}.md)
2. Resolve the playbook file path: ${CLAUDE_PLUGIN_ROOT}/playbooks/${PLAYBOOK_FILE}
3. Check if the playbook file exists:
test -f "${CLAUDE_PLUGIN_ROOT}/playbooks/${PLAYBOOK_FILE}"4. If playbook exists: Record the full path as the asset's playbook_path.
5. If playbook does NOT exist: Log a warning:
takeToMarket > WARNING: No playbook found for "${TYPE}" (tried ${PLAYBOOK_FILE}) -- producing with base context onlySet the asset's playbook_path to "none".
This is the loading MECHANISM only -- playbook content files are created in Phase 8.
Step 5: Produce Hero Asset
takeToMarket > PRODUCING HERO ASSETIdentify the hero asset (first entry in ASSETS_LIST).
Read the agent prompt template from ${CLAUDE_PLUGIN_ROOT}/agents/ttm-producer.md.
Fill all placeholders with actual paths:
[BRIEF_PATH]-->.taketomarket/CAMPAIGNS/${SLUG}/BRIEF.md[POSITIONING_PATH]-->.taketomarket/POSITIONING.md[BRAND_PATH]-->.taketomarket/BRAND.md[ICP_PATH]-->.taketomarket/ICP.md[PLAYBOOK_PATH]--> resolved playbook path from Step 4, or"none"[OUTPUT_PATH]-->.taketomarket/CAMPAIGNS/${SLUG}/ASSETS/01-${HERO_TYPE}-${HERO_CHANNEL}.md[ASSET_TYPE]--> hero asset type from brief (e.g., "blog-post")[CHANNEL]--> hero asset channel from brief (e.g., "organic-search")[HERO_PATH]-->none(this IS the hero asset)
Call Task() with the populated prompt.
WAIT for Task() to complete. The hero MUST finish before any derivatives are spawned.
After Task() returns, verify the hero file exists and has content:
test -s ".taketomarket/CAMPAIGNS/${SLUG}/ASSETS/01-${HERO_TYPE}-${HERO_CHANNEL}.md"If the file is empty or missing: Error -- "Hero asset production failed -- file not written by subagent. Check the brief for completeness and try again." Exit.
Store the hero filename as HERO_FILE for derivative reference.
Step 6: Produce Derivative Assets
If TOTAL_ASSETS is 1 (hero only), skip this step.
takeToMarket > PRODUCING DERIVATIVES (${N} assets)Where N = TOTAL_ASSETS - 1.
For each derivative asset in ASSETS_LIST (all entries after the hero):
1. Read the agent prompt template from ${CLAUDE_PLUGIN_ROOT}/agents/ttm-producer.md.
2. Assign a sequential filename:
- Asset 2:
02-${TYPE}-${CHANNEL}.md - Asset 3:
03-${TYPE}-${CHANNEL}.md - etc.
3. Fill all placeholders:
[BRIEF_PATH]-->.taketomarket/CAMPAIGNS/${SLUG}/BRIEF.md[POSITIONING_PATH]-->.taketomarket/POSITIONING.md[BRAND_PATH]-->.taketomarket/BRAND.md[ICP_PATH]-->.taketomarket/ICP.md[PLAYBOOK_PATH]--> resolved playbook path from Step 4, or"none"[OUTPUT_PATH]-->.taketomarket/CAMPAIGNS/${SLUG}/ASSETS/${NN}-${TYPE}-${CHANNEL}.md[ASSET_TYPE]--> derivative asset type[CHANNEL]--> derivative asset channel[HERO_PATH]-->.taketomarket/CAMPAIGNS/${SLUG}/ASSETS/${HERO_FILE}
4. Call Task() with the populated prompt.
All derivative Task() calls can run in parallel (per D-01 wave-parallel pattern).
After ALL derivative Task() calls complete, verify each derivative file exists and has content:
test -s ".taketomarket/CAMPAIGNS/${SLUG}/ASSETS/${NN}-${TYPE}-${CHANNEL}.md"For any derivative that failed (file empty or missing):
- Log a warning:
takeToMarket > WARNING: Derivative ${NN}-${TYPE}-${CHANNEL}.md failed -- file not written - Continue with the remaining assets. Do NOT abort the entire production run.
Track successful and failed derivatives for the manifest.
Step 7: Write Production Manifest
takeToMarket > WRITING MANIFESTRead the manifest template from ${CLAUDE_PLUGIN_ROOT}/templates/production-manifest.json.
Fill with actual values:
{
"campaign": "${SLUG}",
"produced_at": "${ISO_TIMESTAMP}",
"context_loaded": {
"brief": ".taketomarket/CAMPAIGNS/${SLUG}/BRIEF.md",
"positioning": ".taketomarket/POSITIONING.md",
"brand": ".taketomarket/BRAND.md",
"icp": ".taketomarket/ICP.md"
},
"hero": {
"asset_id": 1,
"name": "01-${HERO_TYPE}-${HERO_CHANNEL}",
"type": "${HERO_TYPE}",
"channel": "${HERO_CHANNEL}",
"playbook": "${HERO_PLAYBOOK_PATH_OR_NONE}",
"file": "ASSETS/01-${HERO_TYPE}-${HERO_CHANNEL}.md"
},
"derivatives": [
{
"asset_id": 2,
"name": "02-${TYPE}-${CHANNEL}",
"type": "${TYPE}",
"channel": "${CHANNEL}",
"playbook": "${PLAYBOOK_PATH_OR_NONE}",
"file": "ASSETS/02-${TYPE}-${CHANNEL}.md",
"derived_from": 1
}
],
"total_assets": ${TOTAL_SUCCESSFUL_ASSETS}
}Generate the timestamp:
TIMESTAMP=$(node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" timestamp --raw)Only include successfully produced assets (those that passed the test -s check) in the manifest. If any derivatives failed, total_assets reflects only the successful count.
Write the completed manifest to .taketomarket/CAMPAIGNS/${SLUG}/MANIFEST.json.
The manifest is the ONLY bridge between produce and verify contexts (per D-11). Verify reads this file to discover which assets exist and what context was loaded during production.
Step 8: Update Campaign State and Summary
Update campaign phase:
TIMESTAMP=$(node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" timestamp --raw)
if [ -z "$TIMESTAMP" ]; then
echo "Error: could not get timestamp"; exit 1
fi
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update "${SLUG}" phase produced
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update "${SLUG}" phase.produced "$TIMESTAMP"Display completion banner:
takeToMarket > PRODUCTION COMPLETE
Assets produced: ${TOTAL_SUCCESSFUL_ASSETS}
Hero: 01-${HERO_TYPE}-${HERO_CHANNEL}.md
Derivatives: [list of derivative filenames]
Manifest: .taketomarket/CAMPAIGNS/${SLUG}/MANIFEST.json
[If any derivatives failed:]
WARNING: ${FAILED_COUNT} derivative(s) failed production. Check the manifest for details.
Next: Run /ttm-verify ${SLUG} to validate assets against quality gatesStep 9: Final humanization (MANDATORY)
Every audience-facing asset MUST pass through /ttm-humanize before write.
For each draft asset produced in this phase:
- Invoke
/ttm-humanize <draft-path>via the Skill tool. - Wait for the rewritten version.
- Write the humanized output to the final asset destination.
- Do not write the un-humanized draft.
Internal state files (campaign briefs, manifests, STATE.md) are exempt.
Success criteria
- All assets from brief's assets list written to CAMPAIGNS/<slug>/ASSETS/
- Hero asset produced before derivatives (sequential then parallel)
- Each subagent loaded with brief + positioning (full) + brand (full) + ICP (full) + playbook
MANIFEST.jsonwritten with all successful asset entries- Campaign STATE.md updated to phase=produced with timestamp
- No playbook errors (graceful fallback for missing playbooks with warning)
- Failed derivatives logged but do not abort the run
- Each audience-facing asset passed through
/ttm-humanizebefore final write.
Output
.taketomarket/CAMPAIGNS/${SLUG}/ASSETS/*.md(produced content files).taketomarket/CAMPAIGNS/${SLUG}/MANIFEST.json(production manifest for /ttm-verify)
What if this doesn't fit?
Looks like /ttm-produce can't do that yet.
- Want a new skill?
/ttm-request-skill - Existing skill needs work?
/ttm-improve-skill