// utility
Archive
/ttm-archive
Archive a completed campaign, finalize state, and update LEARNINGS.md. Use when a campaign lifecycle is fully complete.
Overview
Archives a completed campaign: it finalizes the campaign state, extracts structured learnings from the campaign artifacts, moves the campaign into the archive directory, and records the lessons in LEARNINGS.md. Use it when a campaign lifecycle is fully complete.
Invoke it with ttm-archive followed by a campaign slug (for example ttm-archive [campaign-slug]). Archiving is the marketing equivalent of merging and deleting a branch: the work is preserved, but the campaign is removed from the active workspace and the ttm-next queue. Archived campaigns still feed ttm-learn.
How it works
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-archive 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-archiveUse this exact check (bash) to decide whether to print: node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" first-run check ttm-archive --raw — the JSON seen field is true once the explainer has run before.
Explainer for /ttm-archive
/ttm-archive moves a finished campaign out of the active set into .taketomarket/archive/. It freezes STATE.md, preserves the gate results and ship records, and removes the campaign from the /ttm-next queue. Archived campaigns still feed /ttm-learn.
Why it matters: campaigns that should be done but stay marked active pollute scheduling and waste cognitive budget every time you run /ttm-state. Archive is the marketing equivalent of merging and deleting a branch — the work is preserved, but it's out of your active workspace.
(Canonical source: references/inline-education-blurbs.md. Embedded verbatim because workflows do not @-resolve files at runtime.)
Purpose
Archive workflow for /ttm-archive. Validates campaign is shipped or learned (only shipped or learned campaigns can be archived per D-08), extracts structured learnings from campaign artifacts (D-09), moves campaign to ARCHIVE/ directory (D-07), and updates LEARNINGS.md with extracted lessons.
Archive is irreversible (D-10). Once archived, a campaign cannot be un-archived via this command. Cancelled campaigns cannot be archived — they stay in CAMPAIGNS/ as cautionary records (D-08).
Required reading
${CLAUDE_PLUGIN_ROOT}/references/context-loading.md${CLAUDE_PLUGIN_ROOT}/references/learnings-extraction.md
Constraints
POSITIONING.md is READ-ONLY
Do NOT modify .taketomarket/POSITIONING.md during this workflow.
POSITIONING.md is an architectural invariant. If you detect positioning drift:
- In verify: use the Escalate option to launch /ttm-positioning-shift
- In other workflows: flag the issue and recommend running /ttm-positioning-check
Only /ttm-positioning-shift and /ttm-init may modify POSITIONING.md.
Archive is Irreversible
Once archived, a campaign cannot be un-archived via this command. The user must be informed and must confirm before the archive operation executes. This is a destructive operation that moves files to ARCHIVE/ permanently.
Shipped or Learned Validation
Only campaigns with phase = "shipped" or phase = "learned" can be archived. Campaigns in any other phase (including "cancelled") must be rejected with a clear explanation of why and what to do instead.
Process
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)If SLUG is empty, error: "Usage: /ttm-archive [campaign-slug]. Provide a campaign slug." Exit.
Step 2: Validate Campaign
takeToMarket > VALIDATING CAMPAIGNRun:
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign state "${SLUG}" --rawParse output and validate:
- If
exists: false: tell user campaign not found. Exit. - If
phaseequals'archived': tell user campaign is already archived. Exit. - If
phaseequals'cancelled': tell user cancelled campaigns cannot be archived per policy. They stay in CAMPAIGNS/ as cautionary records for future reference. Exit. - If
phaseis NOT one of'shipped'or'learned': tell user only shipped or learned campaigns can be archived. Display current phase and suggest completing remaining phases: "Campaign '${SLUG}' is in phase '${phase}'. Only shipped or learned campaigns can be archived. Complete the remaining phases first." Exit.
Step 3: Extract Learnings
Skip check: If campaign phase is "learned" (meaning /ttm-learn already ran), skip this step entirely:
takeToMarket > Learnings already extracted via /ttm-learn. Skipping re-extraction.Proceed directly to Step 4.
takeToMarket > EXTRACTING LEARNINGSFollowing the learnings-extraction.md reference guide, scan campaign artifacts.
Read these files from the campaign directory:
.taketomarket/CAMPAIGNS/${SLUG}/STATE.md(full file — frontmatter and body).taketomarket/CAMPAIGNS/${SLUG}/MANIFEST.json(if exists — per-asset gate results).taketomarket/CAMPAIGNS/${SLUG}/BRIEF.md(if exists — original strategy)VERIFICATION.mdin the campaign directory (gate details)- Any
FIX-BRIEF-*.mdfiles (fix attempts and outcomes) - Any
REVIEW-FEEDBACK-*.mdfiles (human review feedback)
Extract structured learnings in three categories:
1. What worked
Identify successes from the campaign:
- First-attempt gate passes (verify.run_count = 1 AND verify.overall_result = pass)
- High review scores (review.overall_result = approved without fix loops)
- Assets shipped without fix loops (fix.run_count = 0 or null)
- Any asset with review_status = "approved" on first submission in MANIFEST.json
For each success, identify the specific pattern or approach that drove it.
2. What didn't work
Identify failures or friction:
- Gate failures (verify.overall_result = fail on any run)
- Fix loops (fix.run_count > 0) — check FIX-BRIEF-*.md for root cause
- Review rejections in REVIEW-FEEDBACK-*.md
- Multiple verification runs (verify.run_count > 1)
Categorize each using the root-cause taxonomy from learnings-extraction.md:
- positioning-drift
- weak-hook
- wrong-channel
- bad-timing
- unverifiable-claim
- broken-funnel
- creative-fatigue
3. Campaign-level decisions
Extract key strategic decisions:
- Positioning anchor chosen (from BRIEF.md)
- Channel mix rationale
- Hook strategy used
- ICP targeting decisions
- Any deviations accepted during verify
Format each learning as a LEARNINGS.md table row:
| ${today} | ${SLUG} | ${category} | ${lesson} | ${action_taken} |Where:
today= current ISO date (YYYY-MM-DD)category= one of: success, positioning-drift, weak-hook, wrong-channel, bad-timing, unverifiable-claim, broken-funnel, creative-fatiguelesson= one-sentence specific summary of what happened and whyaction_taken= recommended reference file update, or "none" if no systemic fix
Step 4: Confirm Archive
takeToMarket > CONFIRM ARCHIVEDisplay the extracted learnings to the user in a readable format:
## Learnings Extracted from ${SLUG}
### What Worked
${for each success lesson: bullet point with category and lesson text}
### What Didn't Work
${for each failure lesson: bullet point with category and lesson text}
### Campaign-Level Decisions
${for each decision lesson: bullet point with description}
**Total lessons to record:** ${N}Ask for confirmation using AskUserQuestion (or text-mode numbered list):
Archive campaign '${SLUG}'? This will:
1. Move campaign to CAMPAIGNS/ARCHIVE/${SLUG}/
2. Add ${N} lessons to LEARNINGS.md
3. Set campaign state to 'archived'
This action is irreversible.
Options:
1. Confirm archive -- proceed with archive and learnings extraction
2. Cancel -- keep campaign in current stateIf user selects Cancel, exit without making any changes.
Step 5: Execute Archive
takeToMarket > ARCHIVING CAMPAIGNRun the archive CLI command:
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign archive "${SLUG}" --rawParse output and verify archived: true.
If the command returns an error:
- Display the error message to the user
- Do NOT attempt to manually move files (the CLI handles all filesystem operations)
- Do NOT update LEARNINGS.md — the archive did not succeed
- Exit with the error context
The CLI command handles:
- Moving the campaign directory to
.taketomarket/CAMPAIGNS/ARCHIVE/${SLUG}/ - Updating the campaign state to "archived"
- Validating the campaign is in "shipped" or "learned" phase before allowing archive
Step 6: Update LEARNINGS.md
takeToMarket > UPDATING LEARNINGSImportant: This step runs only after the archive CLI command succeeds in Step 5. The campaign is now in ARCHIVE/ with phase set to "archived". Writing learnings after archive confirmation prevents data-loss on retry (duplicate rows) if archive were to fail.
Read .taketomarket/LEARNINGS.md.
Duplicate guard: Before inserting rows, scan existing LEARNINGS.md content for any row containing | ${SLUG} | with today's date. If matching rows already exist for this campaign slug and today's date, skip insertion and log: "Learnings for ${SLUG} already present in LEARNINGS.md — skipping duplicate write." This prevents duplicate lesson rows if the workflow is retried after a partial failure.
Find the marker line: <!-- LESSONS BELOW THIS LINE -->
Marker validation (T-07-10 mitigation):
- Count occurrences of the marker in the file
- If exactly 1 marker found: insert all extracted lesson rows immediately AFTER the marker line (one row per line, each on its own line)
- If 0 markers found: fall back to appending rows after the last table row in the Lessons Log table section (look for the last line starting with
|) - If >1 markers found: fall back to appending rows after the FIRST marker only. Log a warning about duplicate markers.
Write the updated LEARNINGS.md back to disk.
Also update the Summary section at the top of LEARNINGS.md:
- Increment "Total lessons" count by the number of new rows added
- Update "Last lesson date" to today's date
Step 7: Confirm Completion
takeToMarket > ARCHIVE COMPLETEDisplay completion summary:
## Archive Complete: ${SLUG}
**Campaign:** ${name}
**Archived at:** ${timestamp}
**Lessons extracted:** ${N}
### Lessons Added to LEARNINGS.md
| Date | Campaign | Category | Lesson | Action Taken |
|------|----------|----------|--------|-------------|
${extracted_rows}
Campaign directory moved to `.taketomarket/CAMPAIGNS/ARCHIVE/${SLUG}/`
### Next Steps
- Lessons are now available in LEARNINGS.md for future campaigns
- Run /ttm-health to verify system consistency
- Start a new campaign with /ttm-new-campaign when readySuccess criteria
- Campaign validated as shipped or learned before archive (D-08)
- Cancelled campaigns rejected with explanation (D-08)
- Learnings extracted from campaign artifacts using extraction guide (D-09)
- Root-cause taxonomy applied to failure categorization (D-09)
- User confirmed before destructive archive action (D-10)
- LEARNINGS.md marker validated (exactly 1 occurrence) before append (T-07-10)
- LEARNINGS.md updated with new lesson rows via marker-based append
- Campaign directory moved to ARCHIVE/ via CLI command (D-07)
- Campaign state set to archived
- Completion summary displayed with all extracted lessons
Output
.taketomarket/LEARNINGS.md(updated with extracted lessons).taketomarket/CAMPAIGNS/ARCHIVE/${SLUG}/STATE.md(phase set to archived, via CLI)
What if this doesn't fit?
Looks like /ttm-archive can't do that yet.
- Want a new skill? /ttm-request-skill
- Existing skill needs work? /ttm-improve-skill