// 9-phase lifecycle
Learn
/ttm-learn
Learn phase: extract lessons from campaign measurement data, propose reference file edits with human approval gates, log root-cause taxonomy entries to LEARNINGS.md, and extract cross-campaign patterns.
Overview
ttm-learn runs the Learn phase of the takeToMarket lifecycle. It reads finished campaigns — briefs, gate results, ship records, measurement output — and extracts compound learnings: which positioning angles converted, which channels under- or over-delivered, and which playbook variants worked. Those lessons are logged to .taketomarket/LEARNINGS.md with a structured root-cause taxonomy, and the skill proposes reference file edits behind per-edit human approval gates.
Invoke it with ttm-learn [campaign-slug]. A campaign must already be measured (run ttm-measure first). Future briefs auto-load LEARNINGS.md as Tier 1 context, so each campaign's data biases the next brief toward what actually worked — the marketing equivalent of a postmortem doc plus a regression suite of tactics.
Why it matters: marketing learnings without a structured store dissolve into folklore inside three months. Learn turns each campaign's data into a versioned doc that compounds reference-file improvements and a cross-campaign pattern library.
How it works
The workflow at ${CLAUDE_PLUGIN_ROOT}/workflows/lifecycle/learn.md closes the learning loop: lessons from each campaign compound into reference file improvements and pattern libraries that make future campaigns better. LEARNINGS.md is already loaded as Tier 1 context in the brief workflow (LRNG-04), so future campaigns automatically benefit from past learnings. It proposes reference file edits as narratives with per-edit approval gates (D-07, D-08), logs root-cause taxonomy entries (D-10, LIFE-17), and runs pattern extraction across campaigns once 3+ campaigns have lessons (LRNG-03).
Required reading
${CLAUDE_PLUGIN_ROOT}/references/context-loading.md${CLAUDE_PLUGIN_ROOT}/references/learnings-extraction.md
Constraints
Reference file edit targets
Only the following files may be edited via this workflow (per D-09):
.taketomarket/BRAND.md.taketomarket/ICP.md.taketomarket/CHANNELS.md.taketomarket/POSITIONING.md(via /ttm-positioning-shift only — never directly).taketomarket/METRICS.md.taketomarket/COMPETITORS.md
Append-only LEARNINGS.md
Lessons are appended after the <!-- LESSONS BELOW THIS LINE --> marker. Existing lesson rows must never be deleted or modified. Summary counters are updated atomically with the append.
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.
if echo "$ARGUMENTS" | grep -q -- '--text'; then TEXT_MODE=true; fiIf the 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 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-learn 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-learnUse this exact check (bash) to decide whether to print: node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" first-run check ttm-learn --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 and campaign state reads/writes.
Explainer for /ttm-learn
/ttm-learn reads finished campaigns — briefs, gate results, ship records, measurement output — and extracts compound learnings into .taketomarket/LEARNINGS.md: what positioning angles converted, which channels under- or over-delivered, which playbook variants worked. Future briefs auto-load this file.
Why it matters: marketing learnings without a structured store dissolve into folklore inside three months. Learn turns each campaign's data into a versioned doc that biases the next brief toward what actually worked — the marketing equivalent of a postmortem doc plus a regression suite of tactics.
(Canonical source: references/inline-education-blurbs.md. Embedded verbatim because workflows do not @-resolve files at runtime.)
Step 1: Load context
takeToMarket > LOADING CAMPAIGN CONTEXT FOR LEARNINGExtract SLUG from $ARGUMENTS (strip the --text flag if present):
SLUG=$(echo "$ARGUMENTS" | sed 's/--text//g' | xargs)If SLUG is empty, error: "Usage: /ttm-learn [campaign-slug]. Provide a campaign slug." Exit.
Load 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
Load Tier 2 (full content) for learning analysis:
.taketomarket/LEARNINGS.md(existing lessons and patterns).taketomarket/METRICS.md(metric definitions for delta interpretation).taketomarket/BRAND.md(brand guidelines for edit proposals).taketomarket/ICP.md(ICP data for edit proposals).taketomarket/CHANNELS.md(channel data for edit proposals).taketomarket/COMPETITORS.md(competitor data for edit proposals).taketomarket/POSITIONING.md(read-only — for positioning drift detection)
Load campaign artifacts per the scan order from learnings-extraction.md:
.taketomarket/CAMPAIGNS/${SLUG}/STATE.md(frontmatter for gate results, run counts).taketomarket/CAMPAIGNS/${SLUG}/MEASUREMENT.md(measurement report with outcome data).taketomarket/CAMPAIGNS/${SLUG}/BRIEF.md(original strategy and targets).taketomarket/CAMPAIGNS/${SLUG}/VERIFICATION.md(gate details if it exists).taketomarket/CAMPAIGNS/${SLUG}/FIX-BRIEF-*.md(fix details if they exist).taketomarket/CAMPAIGNS/${SLUG}/REVIEW-FEEDBACK-*.md(reviewer comments if they exist)
If .taketomarket/CAMPAIGNS/${SLUG}/ does not exist, error: "Campaign '${SLUG}' not found. Check the slug and try again." Exit.
If .taketomarket/CAMPAIGNS/${SLUG}/MEASUREMENT.md does not exist, error: "No measurement data found for '${SLUG}'. Run /ttm-measure first." Exit.
Step 2: Validate campaign state
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign state ${SLUG} --raw- Verify campaign is in
measuredorlearnedphase (re-learning is allowed) - If not measured, display an error and exit:
takeToMarket > ERROR
Campaign must be measured before learning. Current phase: ${PHASE}.
Run /ttm-measure first.Step 3: Extract outcome deltas (per LRNG-02)
Compare measurement results from MEASUREMENT.md against brief targets from BRIEF.md:
- For each metric in MEASUREMENT.md, find the corresponding target from BRIEF.md
- Calculate delta:
((actual - target) / target) * 100 - Classify each delta:
- overperformed: more than 10% above target
- met: within +/-10% of target
- underperformed: more than 10% below target
Display:
takeToMarket > OUTCOME DELTAS
| Metric | Target | Actual | Delta | Classification |
|--------|--------|--------|-------|----------------|
| [outcome metric] | [target] | [actual] | [+/-X%] | [over/met/under] |
| [output metric 1] | ... | ... | ... | ... |Step 4: Classify lessons per root-cause taxonomy (per LRNG-01, LIFE-17)
For each underperforming or failing element, classify using the 7-category root-cause taxonomy from learnings-extraction.md:
positioning-drift— asset deviated from POSITIONING.md (used competitor language, wrong value prop, or off-brand messaging)weak-hook— opening failed to capture attention (generic intro, no specific pain addressed, buried lede)wrong-channel— content published on ineffective channel for target ICP or content typebad-timing— published at wrong time, wrong cadence, or conflicted with external eventsunverifiable-claim— claim lacked proof point, source, or measurable evidencebroken-funnel— CTA or conversion path was broken, misaligned, or missingcreative-fatigue— repeated format or angle with diminishing returns (audience saturation)
For each overperforming element, classify as success with a description of what pattern drove the win.
Artifact scan order (per learnings-extraction.md):
- STATE.md gate fields for pass/fail patterns
- VERIFICATION.md for specific gate failure details
- FIX-BRIEF files for root-cause analysis already performed
- REVIEW-FEEDBACK files for human reviewer signals
- BRIEF.md for strategic context
Generate 1 lesson per notable delta (both successes and failures). Each lesson is one specific, actionable sentence — not a generic observation.
Display each lesson:
takeToMarket > LESSONS EXTRACTED
${N} lessons identified:
1. [${CATEGORY}] ${LESSON_TEXT}
2. [${CATEGORY}] ${LESSON_TEXT}
...Step 5: Propose reference file edits (per D-07, D-08, D-09, LIFE-16)
For each lesson that implies a systemic change to a reference file, propose an edit using the narrative + apply approach (per D-07).
If no lessons imply systemic changes, display:
takeToMarket > REFERENCE FILE EDITS
No systemic reference file edits identified. All lessons logged as observations.5a. Present the narrative
Display the reasoning in plain language:
takeToMarket > PROPOSED EDIT ${N} of ${TOTAL}
Based on campaign "${SLUG}" results, [specific observation from measurement data].
[Reasoning derived from the data and campaign artifacts].
Therefore, [specific edit proposal describing the change].
File: .taketomarket/${TARGET_FILE}.md
Section: [section name where the edit applies]
Change: [specific addition, modification, or removal]5b. Ask for approval (per D-08)
Each edit gets its own approval gate. No batch-apply.
If AskUserQuestion is available (TEXT_MODE=false): Use AskUserQuestion with options:
- Apply — Update ${TARGET_FILE}.md with this change
- Skip — Keep ${TARGET_FILE}.md unchanged, log lesson only
- Modify — Edit the proposed change before applying
If TEXT_MODE=true:
Apply this edit to .taketomarket/${TARGET_FILE}.md?
1. Apply -- Update ${TARGET_FILE}.md with this change
2. Skip -- Keep ${TARGET_FILE}.md unchanged, log lesson only
3. Modify -- Edit the proposed change before applying
Type the number of your choice:5c. POSITIONING.md special handling (per D-09)
If the proposed edit targets POSITIONING.md, do NOT offer direct apply. Instead:
If AskUserQuestion is available (TEXT_MODE=false): Use AskUserQuestion with header "POSITIONING.md Edit Detected":
- Launch positioning shift — Start /ttm-positioning-shift with this proposal
- Skip — Log the lesson but do not change POSITIONING.md
If TEXT_MODE=true:
This edit targets POSITIONING.md, which is locked during campaigns.
This change requires /ttm-positioning-shift.
1. Launch positioning shift -- Start /ttm-positioning-shift with this proposal
2. Skip -- Log the lesson but do not change POSITIONING.md
Type the number of your choice:5d. Apply the user's choice
- If user selects "Apply": Read the target file, find the specified section, apply the edit, write the updated file. Track as edits_applied.
- If user selects "Modify": Ask user for the modified version (via AskUserQuestion or text prompt), then apply the modified edit. Track as edits_applied.
- If user selects "Skip": Set Action Taken for this lesson to "none — skipped by user."
- If user selects "Launch positioning shift": Note in the lesson log Action Taken: "Deferred to /ttm-positioning-shift." Do NOT apply the edit.
Track counts: edits_proposed (total proposed), edits_applied (Apply + Modify selections).
Step 6: Append lessons to LEARNINGS.md (per LRNG-01, LIFE-17)
- Read
.taketomarket/LEARNINGS.md - Find the marker line:
<!-- LESSONS BELOW THIS LINE --> - Insert new lesson rows immediately after the marker, one row per lesson from Step 4:
| ${DATE} | ${SLUG} | ${CATEGORY} | ${LESSON_TEXT} | ${ACTION_TAKEN} |Where:
${DATE}is today's ISO date (e.g., 2024-03-15)${SLUG}is the campaign slug${CATEGORY}is the root-cause taxonomy category (orsuccess)${LESSON_TEXT}is the one-sentence lesson${ACTION_TAKEN}is what was done (e.g., "Updated BRAND.md hook guidelines", "none — skipped by user", "Deferred to /ttm-positioning-shift")
Update the Summary section counters at the top of the file:
- Total lessons: increment by number of new lessons
- Last lesson date: set to today's date
- Top pattern: recalculate the most frequent category across all lesson rows
Write updated LEARNINGS.md.
Step 7: Pattern extraction (per LRNG-03)
Count the number of distinct campaign slugs in the LEARNINGS.md Lessons Log table (the Campaign column).
If fewer than 3 campaigns have entries:
takeToMarket > PATTERN EXTRACTION
Pattern extraction requires 3+ campaigns with lessons. Current: ${N}.
Skipping pattern extraction -- will run automatically after ${3 - N} more campaigns.If 3 or more campaigns have entries: scan all lesson rows in the Lessons Log for frequency patterns across campaigns:
- Winning Hooks: Identify hooks or openings that appeared in
successlessons across 2+ campaigns. Extract the common pattern or approach. - Winning Angles: Identify positioning angles or themes that showed consistent overperformance across campaigns.
- Winning Formats: Identify content formats that produced the best outcome metric results across campaigns.
- Anti-Patterns: Identify approaches that appeared in failure lessons (any root-cause category except
success) across 2+ campaigns.
Update the Pattern Extraction sections in LEARNINGS.md:
- Replace the
[Populated after 3+ campaigns...]placeholder text with actual patterns - Each pattern entry should include: the pattern description, which campaigns exhibited it, and the measured impact
Write updated LEARNINGS.md.
Step 8: Update campaign state
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update ${SLUG} phase learned
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update ${SLUG} phase.learned "${ISO_DATE}"
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update ${SLUG} learn.run_count ${RUN_COUNT}
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update ${SLUG} learn.last_run ${ISO_DATE}
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update ${SLUG} learn.lessons_extracted ${LESSON_COUNT}
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update ${SLUG} learn.edits_proposed ${PROPOSED_COUNT}
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update ${SLUG} learn.edits_applied ${APPLIED_COUNT}Where:
${RUN_COUNT}is the previous learn.run_count + 1 (or 1 if first run)${ISO_DATE}is today's ISO date${LESSON_COUNT}is the number of lessons extracted in Step 4${PROPOSED_COUNT}is the number of reference file edits proposed in Step 5${APPLIED_COUNT}is the number of edits the user approved (Apply + Modify)
Step 9: Display summary and next steps
takeToMarket > LEARN PHASE COMPLETE
Campaign: ${SLUG}
Lessons extracted: ${LESSON_COUNT} (${SUCCESS_COUNT} successes, ${FAILURE_COUNT} failures)
Reference edits proposed: ${PROPOSED_COUNT}
Reference edits applied: ${APPLIED_COUNT}
Pattern extraction: ${PATTERN_STATUS}
Lessons appended to: .taketomarket/LEARNINGS.md
Next: Run /ttm-archive ${SLUG} to finalize the campaign, or start a new campaign.
Future campaigns will load these lessons via /ttm-brief to prevent repeating mistakes.Where ${PATTERN_STATUS} is one of:
- "Completed — ${PATTERN_COUNT} patterns identified" (if 3+ campaigns)
- "Skipped — ${N} of 3 campaigns needed" (if fewer than 3)
Checklist
- Campaign is in measured or learned phase
- Campaign artifacts scanned in correct order (STATE > VERIFICATION > FIX-BRIEF > REVIEW-FEEDBACK > BRIEF)
- Outcome deltas calculated for all metrics
- Each lesson classified with root-cause taxonomy category
- Reference file edits proposed as narratives with per-edit human approval
- POSITIONING.md edits routed through /ttm-positioning-shift (not direct edit)
- Lessons appended to LEARNINGS.md after marker line
- Summary counters updated in LEARNINGS.md
- Pattern extraction runs only if 3+ campaign slugs in lessons log
- Campaign state updated with learn.* fields