taketomarket 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +10 -0
- package/LICENSE +21 -0
- package/README.md +419 -0
- package/agents/ttm-producer.md +53 -0
- package/bin/lib/campaign.cjs +553 -0
- package/bin/lib/commit.cjs +105 -0
- package/bin/lib/core.cjs +172 -0
- package/bin/lib/deviation.cjs +149 -0
- package/bin/lib/drift-log.cjs +219 -0
- package/bin/lib/health.cjs +438 -0
- package/bin/lib/slug.cjs +59 -0
- package/bin/lib/state.cjs +96 -0
- package/bin/ttm-tools.cjs +157 -0
- package/gates/base-gates.md +266 -0
- package/gates/discipline/.gitkeep +0 -0
- package/gates/gate-evaluation.md +341 -0
- package/gates/meta-gates.md +19 -0
- package/install.js +307 -0
- package/package.json +53 -0
- package/playbooks/.gitkeep +0 -0
- package/playbooks/aeo.md +223 -0
- package/playbooks/affiliate.md +272 -0
- package/playbooks/base.md +110 -0
- package/playbooks/email.md +306 -0
- package/playbooks/events.md +320 -0
- package/playbooks/linkedin.md +263 -0
- package/playbooks/paid-ads.md +318 -0
- package/playbooks/pr-media.md +296 -0
- package/playbooks/seo.md +284 -0
- package/playbooks/social.md +305 -0
- package/playbooks/youtube.md +325 -0
- package/references/context-loading.md +107 -0
- package/references/learnings-extraction.md +94 -0
- package/references/measurement-template.md +48 -0
- package/references/meta-gate-evaluation.md +169 -0
- package/references/positioning-check-report.md +197 -0
- package/references/review-checklist.md +78 -0
- package/references/ship-checklist-items.md +94 -0
- package/settings.json +4 -0
- package/skills/ttm-aeo-check/SKILL.md +20 -0
- package/skills/ttm-affiliate-kit/SKILL.md +19 -0
- package/skills/ttm-archive/SKILL.md +13 -0
- package/skills/ttm-brand-refresh/SKILL.md +19 -0
- package/skills/ttm-brief/SKILL.md +14 -0
- package/skills/ttm-competitor-scan/SKILL.md +19 -0
- package/skills/ttm-email-preflight/SKILL.md +19 -0
- package/skills/ttm-fix/SKILL.md +13 -0
- package/skills/ttm-health/SKILL.md +12 -0
- package/skills/ttm-icp-refresh/SKILL.md +19 -0
- package/skills/ttm-init/SKILL.md +12 -0
- package/skills/ttm-keyword-map/SKILL.md +19 -0
- package/skills/ttm-learn/SKILL.md +14 -0
- package/skills/ttm-measure/SKILL.md +14 -0
- package/skills/ttm-new-campaign/SKILL.md +13 -0
- package/skills/ttm-next/SKILL.md +12 -0
- package/skills/ttm-positioning-check/SKILL.md +19 -0
- package/skills/ttm-positioning-shift/SKILL.md +19 -0
- package/skills/ttm-produce/SKILL.md +14 -0
- package/skills/ttm-repurpose/SKILL.md +20 -0
- package/skills/ttm-research/SKILL.md +13 -0
- package/skills/ttm-resume/SKILL.md +13 -0
- package/skills/ttm-review/SKILL.md +13 -0
- package/skills/ttm-seo-audit/SKILL.md +20 -0
- package/skills/ttm-ship/SKILL.md +13 -0
- package/skills/ttm-state/SKILL.md +13 -0
- package/skills/ttm-verify/SKILL.md +14 -0
- package/templates/agents-md.md +65 -0
- package/templates/campaign-brief.md +74 -0
- package/templates/campaign-research.md +39 -0
- package/templates/campaign-state.md +40 -0
- package/templates/claude-md.md +65 -0
- package/templates/deviation-log.md +12 -0
- package/templates/drift-log.md +17 -0
- package/templates/fix-brief.md +59 -0
- package/templates/fix-log.md +22 -0
- package/templates/measurement-report.md +75 -0
- package/templates/migration-plan.md +24 -0
- package/templates/production-manifest.json +20 -0
- package/templates/reference-files/brand.md +45 -0
- package/templates/reference-files/calendar.md +30 -0
- package/templates/reference-files/channels.md +40 -0
- package/templates/reference-files/competitors.md +40 -0
- package/templates/reference-files/icp.md +50 -0
- package/templates/reference-files/learnings.md +40 -0
- package/templates/reference-files/metrics.md +42 -0
- package/templates/reference-files/positioning.md +38 -0
- package/templates/reference-files/state.md +27 -0
- package/templates/verification-report.md +59 -0
- package/workflows/discipline/.gitkeep +0 -0
- package/workflows/discipline/aeo-check.md +180 -0
- package/workflows/discipline/affiliate-kit.md +147 -0
- package/workflows/discipline/email-preflight.md +150 -0
- package/workflows/discipline/keyword-map.md +125 -0
- package/workflows/discipline/repurpose.md +329 -0
- package/workflows/discipline/seo-audit.md +169 -0
- package/workflows/lifecycle/.gitkeep +0 -0
- package/workflows/lifecycle/brief-positioning-check.md +90 -0
- package/workflows/lifecycle/brief.md +355 -0
- package/workflows/lifecycle/fix.md +495 -0
- package/workflows/lifecycle/learn.md +405 -0
- package/workflows/lifecycle/measure.md +379 -0
- package/workflows/lifecycle/produce.md +383 -0
- package/workflows/lifecycle/research.md +264 -0
- package/workflows/lifecycle/review.md +432 -0
- package/workflows/lifecycle/ship.md +521 -0
- package/workflows/lifecycle/verify.md +507 -0
- package/workflows/reference-mgmt/.gitkeep +0 -0
- package/workflows/reference-mgmt/brand-refresh.md +193 -0
- package/workflows/reference-mgmt/competitor-scan.md +228 -0
- package/workflows/reference-mgmt/icp-refresh.md +200 -0
- package/workflows/reference-mgmt/positioning-check.md +339 -0
- package/workflows/reference-mgmt/positioning-shift.md +368 -0
- package/workflows/setup/.gitkeep +0 -0
- package/workflows/setup/init-questions.md +225 -0
- package/workflows/setup/init-validation.md +155 -0
- package/workflows/setup/init.md +449 -0
- package/workflows/setup/new-campaign.md +134 -0
- package/workflows/utility/.gitkeep +0 -0
- package/workflows/utility/archive.md +334 -0
- package/workflows/utility/health.md +166 -0
- package/workflows/utility/next.md +187 -0
- package/workflows/utility/resume.md +249 -0
- package/workflows/utility/state.md +207 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
<purpose>
|
|
2
|
+
Technical and content SEO audit of a URL or content. Evaluates against SEO playbook
|
|
3
|
+
gate definitions and generates a structured PASS/WARN/FAIL report per check.
|
|
4
|
+
Single-pass analysis workflow per D-07.
|
|
5
|
+
</purpose>
|
|
6
|
+
|
|
7
|
+
<required_reading>
|
|
8
|
+
@${CLAUDE_PLUGIN_ROOT}/references/context-loading.md
|
|
9
|
+
@${CLAUDE_PLUGIN_ROOT}/playbooks/seo.md
|
|
10
|
+
</required_reading>
|
|
11
|
+
|
|
12
|
+
<constraints>
|
|
13
|
+
## POSITIONING.md is READ-ONLY
|
|
14
|
+
|
|
15
|
+
**Do NOT modify `.marketing/POSITIONING.md` during this workflow.**
|
|
16
|
+
|
|
17
|
+
POSITIONING.md is an architectural invariant. If you detect positioning drift:
|
|
18
|
+
- Flag the issue and recommend running /ttm-positioning-check
|
|
19
|
+
|
|
20
|
+
Only /ttm-positioning-shift and /ttm-init may modify POSITIONING.md.
|
|
21
|
+
</constraints>
|
|
22
|
+
|
|
23
|
+
<process>
|
|
24
|
+
|
|
25
|
+
## Text-Mode Detection
|
|
26
|
+
|
|
27
|
+
**Text mode (`--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS`
|
|
28
|
+
or if the runtime is not Claude Code. When TEXT_MODE is active, replace every
|
|
29
|
+
`AskUserQuestion` call with a plain-text numbered list.
|
|
30
|
+
|
|
31
|
+
Detection:
|
|
32
|
+
```bash
|
|
33
|
+
if echo "$ARGUMENTS" | grep -q -- '--text'; then TEXT_MODE=true; fi
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
If `AskUserQuestion` tool is not available in the current runtime, set `TEXT_MODE=true`.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Step 1: Load Context
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
takeToMarket > LOADING CONTEXT FOR SEO AUDIT
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Tier 1 summaries** (lines 1 to `<!-- END_SUMMARY -->`) from all 9 `.marketing/` reference files.
|
|
47
|
+
**Tier 2 (full):** `.marketing/CHANNELS.md` (channel-specific SEO config).
|
|
48
|
+
**Playbook gates:** @${CLAUDE_PLUGIN_ROOT}/playbooks/seo.md
|
|
49
|
+
|
|
50
|
+
If `.marketing/POSITIONING.md` does not exist: Error and exit.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Step 2: Get Audit Target
|
|
55
|
+
|
|
56
|
+
Ask: "What would you like to audit? Provide a URL, file path, or paste content directly."
|
|
57
|
+
|
|
58
|
+
Parse input:
|
|
59
|
+
- **URL** (starts with `http://` or `https://`): Attempt WebFetch for page content.
|
|
60
|
+
- **WebFetch available (SEARCH_MODE=web):** Fetch and analyze.
|
|
61
|
+
- **WebFetch NOT available (SEARCH_MODE=manual):** Ask user to paste page content.
|
|
62
|
+
- **File path:** Read the file directly.
|
|
63
|
+
- **Pasted content:** Use directly.
|
|
64
|
+
|
|
65
|
+
Store as `AUDIT_CONTENT` and `AUDIT_TARGET`.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Step 3: Run SEO Gate Checks
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
takeToMarket > RUNNING SEO GATE CHECKS
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Evaluate `AUDIT_CONTENT` against 8 SEO discipline gates:
|
|
76
|
+
|
|
77
|
+
**1. Search Intent Match (DISC-SEO-02)**
|
|
78
|
+
- PASS: Content format and opening directly match the search intent
|
|
79
|
+
- WARN: Content addresses query but format is mixed or answer is buried
|
|
80
|
+
- FAIL: Content format contradicts the search intent
|
|
81
|
+
|
|
82
|
+
**2. Keyword Placement (DISC-SEO-01)**
|
|
83
|
+
Target keyword in: title tag, H1, first 100 words, meta description, H2.
|
|
84
|
+
- PASS: Keyword in title, H1, first 100 words; title 50-60 chars
|
|
85
|
+
- WARN: Missing from 1-2 placements; title 45-49 or 61-70 chars
|
|
86
|
+
- FAIL: Missing from title or H1; title under 30 or over 70 chars
|
|
87
|
+
|
|
88
|
+
**3. Content Structure**
|
|
89
|
+
Heading hierarchy (H1 > H2 > H3), no skipped levels, H2 sections 150-400 words.
|
|
90
|
+
- PASS: Single H1, logical hierarchy, no skipped levels
|
|
91
|
+
- WARN: Minor hierarchy issues or uneven section lengths
|
|
92
|
+
- FAIL: No H1, multiple H1s, or broken hierarchy
|
|
93
|
+
|
|
94
|
+
**4. Internal Linking Density (DISC-SEO-04)**
|
|
95
|
+
- PASS: 3-6 internal links per 1000 words with descriptive anchors
|
|
96
|
+
- WARN: 1-2 internal links per 1000 words
|
|
97
|
+
- FAIL: 0 internal links
|
|
98
|
+
|
|
99
|
+
**5. Schema Markup (DISC-SEO-03)**
|
|
100
|
+
Article, FAQ, HowTo, or Product schema with required fields.
|
|
101
|
+
- PASS: Appropriate schema type with all required fields
|
|
102
|
+
- WARN: Schema present but incomplete
|
|
103
|
+
- FAIL: No schema for content that qualifies
|
|
104
|
+
|
|
105
|
+
**6. Entity Coverage**
|
|
106
|
+
Key entities search engines associate with the topic.
|
|
107
|
+
- PASS: References relevant entities (people, orgs, concepts)
|
|
108
|
+
- WARN: Some coverage but missing key entities
|
|
109
|
+
- FAIL: No recognizable entity references
|
|
110
|
+
|
|
111
|
+
**7. Thin Content Detection (DISC-SEO-05)**
|
|
112
|
+
- PASS: 800+ words standard (300+ programmatic); original analysis present
|
|
113
|
+
- WARN: 500-799 words; mostly summarized
|
|
114
|
+
- FAIL: Under 500 words; boilerplate content
|
|
115
|
+
|
|
116
|
+
**8. Core Web Vitals Budget (DISC-SEO-07)**
|
|
117
|
+
- PASS: Optimized images with dimensions, lazy-load, no render blockers
|
|
118
|
+
- WARN: Images missing dimensions or unoptimized formats
|
|
119
|
+
- FAIL: Heavy unoptimized media or render-blocking embeds
|
|
120
|
+
|
|
121
|
+
Per check: assign PASS / WARN / FAIL with specific evidence.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Step 4: Generate Report
|
|
126
|
+
|
|
127
|
+
Display structured report:
|
|
128
|
+
```
|
|
129
|
+
========================================
|
|
130
|
+
takeToMarket > SEO AUDIT REPORT
|
|
131
|
+
========================================
|
|
132
|
+
Target: [URL or filename]
|
|
133
|
+
Date: [current date]
|
|
134
|
+
Overall: [X/8 PASS] [Y/8 WARN] [Z/8 FAIL]
|
|
135
|
+
|
|
136
|
+
| # | Gate | Result | Evidence |
|
|
137
|
+
|---|------------------------|--------|-----------------------|
|
|
138
|
+
| 1 | Search Intent Match | [P/W/F] | [brief evidence] |
|
|
139
|
+
| 2 | Keyword Placement | [P/W/F] | [brief evidence] |
|
|
140
|
+
| 3 | Content Structure | [P/W/F] | [brief evidence] |
|
|
141
|
+
| 4 | Internal Linking | [P/W/F] | [brief evidence] |
|
|
142
|
+
| 5 | Schema Markup | [P/W/F] | [brief evidence] |
|
|
143
|
+
| 6 | Entity Coverage | [P/W/F] | [brief evidence] |
|
|
144
|
+
| 7 | Thin Content Detection | [P/W/F] | [brief evidence] |
|
|
145
|
+
| 8 | Core Web Vitals Budget | [P/W/F] | [brief evidence] |
|
|
146
|
+
|
|
147
|
+
FINDINGS (WARN/FAIL details):
|
|
148
|
+
- [Gate]: [Issue and recommendation]
|
|
149
|
+
|
|
150
|
+
RECOMMENDATIONS (priority-ordered):
|
|
151
|
+
1. [Highest-impact fix]
|
|
152
|
+
2. [Next priority]
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Step 5: Completion
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
========================================
|
|
161
|
+
takeToMarket > SEO AUDIT COMPLETE
|
|
162
|
+
========================================
|
|
163
|
+
Target: ${AUDIT_TARGET} | Result: [X/8 PASS] [Y/8 WARN] [Z/8 FAIL]
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Offer: "Save this report to .marketing/AUDITS/seo-audit-[date].md? (yes/no)"
|
|
167
|
+
If yes: create `.marketing/AUDITS/` directory if needed and write the report.
|
|
168
|
+
|
|
169
|
+
</process>
|
|
File without changes
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Positioning Check Rules
|
|
2
|
+
|
|
3
|
+
## Usage
|
|
4
|
+
|
|
5
|
+
Referenced by `workflows/lifecycle/brief.md` via @-syntax.
|
|
6
|
+
Applied after brief content is fully generated to detect positioning drift.
|
|
7
|
+
This is a soft gate per D-05 -- the brief is ALWAYS generated regardless of gate result.
|
|
8
|
+
Drift produces a warning, not a block.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Check 1: Positioning Anchor Alignment
|
|
13
|
+
|
|
14
|
+
**Field:** Brief's "Positioning Anchor > Key message"
|
|
15
|
+
**Checks against:** POSITIONING.md primary differentiator phrase
|
|
16
|
+
|
|
17
|
+
- PASS: Brief's positioning anchor restates or naturally extends the primary differentiator
|
|
18
|
+
- WARN: Brief's anchor partially overlaps but introduces claims not present in POSITIONING.md
|
|
19
|
+
- FAIL: Brief's anchor uses a different differentiation claim entirely
|
|
20
|
+
|
|
21
|
+
**Drift detail format:** "Positioning anchor '[brief anchor]' does not align with primary differentiator '[positioning differentiator]'"
|
|
22
|
+
|
|
23
|
+
## Check 2: ICP Segment Match
|
|
24
|
+
|
|
25
|
+
**Field:** Brief's "ICP Segment > Primary segment"
|
|
26
|
+
**Checks against:** POSITIONING.md target audience
|
|
27
|
+
|
|
28
|
+
- PASS: Brief's ICP segment matches or is a sub-segment of the POSITIONING.md target audience
|
|
29
|
+
- WARN: Brief targets an adjacent audience not explicitly in POSITIONING.md
|
|
30
|
+
- FAIL: Brief targets a completely different audience
|
|
31
|
+
|
|
32
|
+
**Drift detail format:** "ICP segment '[brief segment]' does not match target audience '[positioning audience]'"
|
|
33
|
+
|
|
34
|
+
## Check 3: Proof Point Sourcing
|
|
35
|
+
|
|
36
|
+
**Field:** Brief's "Proof Points" table
|
|
37
|
+
**Checks against:** POSITIONING.md must-include proof points
|
|
38
|
+
|
|
39
|
+
- PASS: All proof points in the brief are sourced from POSITIONING.md proof point library
|
|
40
|
+
- WARN: Brief includes proof points not in the library (may be valid new evidence)
|
|
41
|
+
- FAIL: Brief makes claims with no proof point sourcing at all
|
|
42
|
+
|
|
43
|
+
**Drift detail format:** "Proof point '[claim]' not found in POSITIONING.md proof point library"
|
|
44
|
+
|
|
45
|
+
## Check 4: Must-Not-Say Terms
|
|
46
|
+
|
|
47
|
+
**Field:** Entire brief content
|
|
48
|
+
**Checks against:** POSITIONING.md must-not-say terms list
|
|
49
|
+
|
|
50
|
+
- PASS: No must-not-say terms found in brief
|
|
51
|
+
- FAIL: One or more must-not-say terms detected
|
|
52
|
+
|
|
53
|
+
**Drift detail format:** "Must-not-say term '[term]' found in brief [section]"
|
|
54
|
+
|
|
55
|
+
## Check 5: Hook-Positioning Coherence
|
|
56
|
+
|
|
57
|
+
**Field:** Brief's "Hook" section
|
|
58
|
+
**Checks against:** POSITIONING.md primary differentiator and category
|
|
59
|
+
|
|
60
|
+
- PASS: Hook reinforces the positioning -- uses aligned language and framing
|
|
61
|
+
- WARN: Hook is neutral -- does not reinforce but does not contradict
|
|
62
|
+
- FAIL: Hook contradicts the positioning or uses competitor framing
|
|
63
|
+
|
|
64
|
+
**Drift detail format:** "Hook framing '[hook summary]' contradicts positioning category '[category]'"
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Gate Result Logic
|
|
69
|
+
|
|
70
|
+
- If ALL checks PASS: gate result = "pass"
|
|
71
|
+
- If ANY check is WARN or FAIL: gate result = "warn"
|
|
72
|
+
- The brief is ALWAYS generated regardless of gate result (per D-05)
|
|
73
|
+
|
|
74
|
+
## Drift Warning Template
|
|
75
|
+
|
|
76
|
+
When gate result is "warn", insert at the TOP of BRIEF.md after the title line:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
<!--
|
|
80
|
+
!! POSITIONING DRIFT WARNING !!
|
|
81
|
+
The following items may not align with your positioning:
|
|
82
|
+
- [drift detail from each failing check]
|
|
83
|
+
Review .marketing/POSITIONING.md and adjust the brief if needed.
|
|
84
|
+
Run /ttm-positioning-check for a full audit.
|
|
85
|
+
-->
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
This is an HTML comment so it is visible in source but not rendered.
|
|
89
|
+
The warning uses specific drift detail format strings from each failing check
|
|
90
|
+
so the user can pinpoint exactly what drifted and from what reference value.
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
<purpose>
|
|
2
|
+
Campaign brief generation workflow with outcome metric enforcement (LIFE-04) and
|
|
3
|
+
positioning check gate (LIFE-05). Collects all mandatory brief fields (D-07),
|
|
4
|
+
validates outcome metrics with guided re-prompting (D-06), runs 5-check positioning
|
|
5
|
+
gate that warns on drift without blocking (D-05), and writes the completed brief
|
|
6
|
+
to CAMPAIGNS/<slug>/BRIEF.md. This is the gate between campaign planning and
|
|
7
|
+
content production.
|
|
8
|
+
</purpose>
|
|
9
|
+
|
|
10
|
+
<required_reading>
|
|
11
|
+
@${CLAUDE_PLUGIN_ROOT}/references/context-loading.md
|
|
12
|
+
@${CLAUDE_PLUGIN_ROOT}/workflows/lifecycle/brief-positioning-check.md
|
|
13
|
+
@${CLAUDE_PLUGIN_ROOT}/templates/campaign-brief.md
|
|
14
|
+
</required_reading>
|
|
15
|
+
|
|
16
|
+
<constraints>
|
|
17
|
+
## POSITIONING.md is READ-ONLY
|
|
18
|
+
|
|
19
|
+
**Do NOT modify `.marketing/POSITIONING.md` during this workflow.**
|
|
20
|
+
|
|
21
|
+
POSITIONING.md is an architectural invariant. If you detect positioning drift:
|
|
22
|
+
- In verify: use the Escalate option to launch /ttm-positioning-shift
|
|
23
|
+
- In other workflows: flag the issue and recommend running /ttm-positioning-check
|
|
24
|
+
|
|
25
|
+
Only /ttm-positioning-shift and /ttm-init may modify POSITIONING.md.
|
|
26
|
+
</constraints>
|
|
27
|
+
|
|
28
|
+
<process>
|
|
29
|
+
|
|
30
|
+
## Text-Mode Detection
|
|
31
|
+
|
|
32
|
+
**Text mode (`--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS`
|
|
33
|
+
or if the runtime is not Claude Code. When TEXT_MODE is active, replace every
|
|
34
|
+
`AskUserQuestion` call with a plain-text numbered list.
|
|
35
|
+
|
|
36
|
+
Detection:
|
|
37
|
+
```bash
|
|
38
|
+
if echo "$ARGUMENTS" | grep -q -- '--text'; then TEXT_MODE=true; fi
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
If `AskUserQuestion` tool is not available in the current runtime, set `TEXT_MODE=true`.
|
|
42
|
+
|
|
43
|
+
When TEXT_MODE is active, replace each AskUserQuestion with a plain-text numbered list:
|
|
44
|
+
```
|
|
45
|
+
[HEADER]
|
|
46
|
+
[QUESTION]
|
|
47
|
+
1. [OPTION_1_LABEL] -- [OPTION_1_DESCRIPTION]
|
|
48
|
+
2. [OPTION_2_LABEL] -- [OPTION_2_DESCRIPTION]
|
|
49
|
+
...
|
|
50
|
+
Type the number of your choice:
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
For multiSelect questions, instruct the user: "Type the numbers of your choices separated by commas (e.g., 1,3,5):"
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Step 1: Load Context
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
takeToMarket > LOADING CONTEXT
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Extract SLUG from $ARGUMENTS (strip `--text` flag if present):
|
|
64
|
+
```bash
|
|
65
|
+
SLUG=$(echo "$ARGUMENTS" | sed 's/--text//g' | xargs)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Read Tier 1 summaries from all 9 reference files (lines 1 to `<!-- END_SUMMARY -->`):
|
|
69
|
+
- `.marketing/POSITIONING.md`
|
|
70
|
+
- `.marketing/BRAND.md`
|
|
71
|
+
- `.marketing/ICP.md`
|
|
72
|
+
- `.marketing/CHANNELS.md`
|
|
73
|
+
- `.marketing/STATE.md` (frontmatter only)
|
|
74
|
+
- `.marketing/CALENDAR.md`
|
|
75
|
+
- `.marketing/COMPETITORS.md`
|
|
76
|
+
- `.marketing/METRICS.md`
|
|
77
|
+
- `.marketing/LEARNINGS.md`
|
|
78
|
+
|
|
79
|
+
Read Tier 2 (full content) for:
|
|
80
|
+
- `.marketing/ICP.md`
|
|
81
|
+
- `.marketing/CHANNELS.md`
|
|
82
|
+
- `.marketing/METRICS.md`
|
|
83
|
+
- `.marketing/CALENDAR.md`
|
|
84
|
+
|
|
85
|
+
Read full `.marketing/POSITIONING.md` (needed for positioning check gate in Step 6).
|
|
86
|
+
|
|
87
|
+
Read campaign-specific files (always full-load per context-loading.md rule 4):
|
|
88
|
+
- `.marketing/CAMPAIGNS/${SLUG}/STATE.md`
|
|
89
|
+
- `.marketing/CAMPAIGNS/${SLUG}/RESEARCH.md`
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Step 2: Validate Campaign and Phase Order (per D-08)
|
|
94
|
+
|
|
95
|
+
Check campaign exists:
|
|
96
|
+
```bash
|
|
97
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign state "${SLUG}" --raw
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
If result shows `exists: false`: Tell the user the campaign does not exist and suggest running `/ttm-new-campaign` first. Exit.
|
|
101
|
+
|
|
102
|
+
Read campaign state. Check the `phase` field:
|
|
103
|
+
|
|
104
|
+
- If phase is `"created"`:
|
|
105
|
+
Warn the user:
|
|
106
|
+
"Research not yet completed for this campaign. Brief quality will be limited without research data. Run `/ttm-research ${SLUG}` first for better results. Proceed without research?"
|
|
107
|
+
Wait for user confirmation. If user declines, exit.
|
|
108
|
+
|
|
109
|
+
- If phase is NOT `"created"` and NOT `"researched"`:
|
|
110
|
+
Warn the user:
|
|
111
|
+
"Campaign is in phase `${PHASE}`. Expected 'researched' before briefing. Running /ttm-brief now will overwrite the existing BRIEF.md. Proceed?"
|
|
112
|
+
Wait for user confirmation. If user declines, exit.
|
|
113
|
+
|
|
114
|
+
Check if RESEARCH.md has actual content (not just template placeholders):
|
|
115
|
+
- Read `.marketing/CAMPAIGNS/${SLUG}/RESEARCH.md`
|
|
116
|
+
- If file contains only `[GENERATED BY /ttm-research]` placeholders: set `RESEARCH_AVAILABLE=false`
|
|
117
|
+
- If file has real content beyond placeholders: set `RESEARCH_AVAILABLE=true`
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Step 3: Outcome Metric Enforcement (per D-06, LIFE-04)
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
takeToMarket > GENERATING BRIEF
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Collect campaign goal:**
|
|
128
|
+
|
|
129
|
+
Ask (freeform, NOT AskUserQuestion):
|
|
130
|
+
"What is the goal of this campaign? (One sentence describing the campaign's purpose)"
|
|
131
|
+
|
|
132
|
+
Store the response as `CAMPAIGN_GOAL`.
|
|
133
|
+
|
|
134
|
+
**Collect outcome metric:**
|
|
135
|
+
|
|
136
|
+
Ask (freeform):
|
|
137
|
+
"What is the outcome metric for this campaign? An outcome metric measures a business result, not an output action.
|
|
138
|
+
|
|
139
|
+
Examples:
|
|
140
|
+
- VALID: 'Increase trial signups by 20% within 30 days'
|
|
141
|
+
- VALID: 'Generate 50 qualified leads from organic search in Q2'
|
|
142
|
+
- NOT VALID: 'Publish 4 blog posts' (this is an output, not an outcome)
|
|
143
|
+
|
|
144
|
+
What business outcome will this campaign drive?"
|
|
145
|
+
|
|
146
|
+
**Validate the response:**
|
|
147
|
+
|
|
148
|
+
- FAIL if metric starts with output verbs: publish, write, send, create, post, design, build, launch (without a measurable outcome attached)
|
|
149
|
+
- FAIL if no target value (number, percentage, or specific benchmark) is present
|
|
150
|
+
- FAIL if no measurement window (timeframe) is present
|
|
151
|
+
|
|
152
|
+
**On FAIL (retry 1):** Re-prompt with explanation:
|
|
153
|
+
"That looks like an output metric, not an outcome. An output is what you produce (blog posts, emails). An outcome is the business result (signups, revenue, leads). Please provide: [specific business outcome] + [target value] + [measurement window]"
|
|
154
|
+
|
|
155
|
+
**On FAIL (retry 2):** Re-prompt once more with different framing:
|
|
156
|
+
"I still need a measurable business outcome. Think about what changes in your business AFTER the content is published. Example: 'Increase demo requests by 15% within 60 days of launch.' What business result are you targeting?"
|
|
157
|
+
|
|
158
|
+
**After 2 failed retries:** Block brief generation entirely. Tell user:
|
|
159
|
+
"Cannot generate a brief without a valid outcome metric. A brief without a measurable business outcome would produce untestable content. Run `/ttm-brief ${SLUG}` again when ready."
|
|
160
|
+
Exit.
|
|
161
|
+
|
|
162
|
+
**On PASS:** Store as `OUTCOME_METRIC`. Extract `target_value` and `measurement_window` from the response.
|
|
163
|
+
|
|
164
|
+
**Collect output metric:**
|
|
165
|
+
|
|
166
|
+
Ask (freeform):
|
|
167
|
+
"What are the output metrics? (Assets and volume to produce, e.g., '4 blog posts, 2 emails, 1 landing page')"
|
|
168
|
+
|
|
169
|
+
If the user provides an empty response or declines: set `OUTPUT_METRIC_MISSING=true`. Continue. This is allowed per D-06.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Step 4: Collect Remaining Brief Fields (per D-07)
|
|
174
|
+
|
|
175
|
+
**ICP Segment:**
|
|
176
|
+
Read the primary segment from `.marketing/ICP.md` Tier 1 summary. Present it to the user:
|
|
177
|
+
"Your primary ICP segment is: [segment from ICP.md]. Is this correct for this campaign, or are you targeting a specific sub-segment?"
|
|
178
|
+
Store the confirmed or adjusted segment as `ICP_SEGMENT`.
|
|
179
|
+
|
|
180
|
+
**Channel Mix:**
|
|
181
|
+
Read active channels from `.marketing/CHANNELS.md`.
|
|
182
|
+
|
|
183
|
+
Use AskUserQuestion (or text-mode numbered list) with `multiSelect=true`:
|
|
184
|
+
- header: "Channel Selection"
|
|
185
|
+
- question: "Which channels will this campaign use?"
|
|
186
|
+
- options: One option per active channel from CHANNELS.md
|
|
187
|
+
|
|
188
|
+
After selection, for each selected channel ask:
|
|
189
|
+
"What is the role of [channel] in this campaign? (primary / support / amplification)"
|
|
190
|
+
Store channel selections with roles as `CHANNEL_MIX`.
|
|
191
|
+
|
|
192
|
+
**Hook:**
|
|
193
|
+
If `RESEARCH_AVAILABLE=true`: Present key findings from RESEARCH.md (ambient narrative, content gaps) and suggest hook angles based on them.
|
|
194
|
+
Ask: "What is the opening angle or attention-capture strategy for this campaign?"
|
|
195
|
+
Store as `HOOK`.
|
|
196
|
+
|
|
197
|
+
**Proof Points:**
|
|
198
|
+
Read proof points from `.marketing/POSITIONING.md` Proof Point Library table.
|
|
199
|
+
Display the available proof points. Ask:
|
|
200
|
+
"These are your approved proof points. Do you want to add any campaign-specific claims or evidence?"
|
|
201
|
+
Store base proof points plus any additions as `PROOF_POINTS`.
|
|
202
|
+
|
|
203
|
+
**Timeline:**
|
|
204
|
+
Ask: "What is the target ship date for this campaign?"
|
|
205
|
+
Derive remaining timeline dates backward from the ship date:
|
|
206
|
+
- Brief complete: today
|
|
207
|
+
- Production start: ship date minus appropriate buffer
|
|
208
|
+
- Review complete: ship date minus review buffer
|
|
209
|
+
- Measurement start: ship date
|
|
210
|
+
- Learn review: ship date + measurement window
|
|
211
|
+
Store as `TIMELINE`.
|
|
212
|
+
|
|
213
|
+
**Success Criteria:**
|
|
214
|
+
Ask: "What specific, measurable outcomes define success for this campaign beyond the outcome metric?"
|
|
215
|
+
Store as `SUCCESS_CRITERIA`.
|
|
216
|
+
|
|
217
|
+
**Failure Criteria:**
|
|
218
|
+
Ask: "What conditions should trigger a campaign pause or kill?"
|
|
219
|
+
Store as `FAILURE_CRITERIA`.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Step 5: Generate BRIEF.md
|
|
224
|
+
|
|
225
|
+
Read the brief template:
|
|
226
|
+
```
|
|
227
|
+
${CLAUDE_PLUGIN_ROOT}/templates/campaign-brief.md
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Fill ALL `[GENERATED BY /ttm-brief]` placeholders with collected data:
|
|
231
|
+
|
|
232
|
+
- **Campaign Name:** From campaign STATE.md `name` field
|
|
233
|
+
- **Goal:** From `CAMPAIGN_GOAL`
|
|
234
|
+
- **Outcome Metric section:**
|
|
235
|
+
- Metric: `OUTCOME_METRIC`
|
|
236
|
+
- Target value: extracted `target_value`
|
|
237
|
+
- Measurement window: extracted `measurement_window`
|
|
238
|
+
- Data source: inferred from metric type or ask user
|
|
239
|
+
- **Output Metric section:** From output metrics collected in Step 3
|
|
240
|
+
- If `OUTPUT_METRIC_MISSING=true`, insert after the Output Metric section:
|
|
241
|
+
`<!-- OUTPUT_METRIC_MISSING: Add output metrics before /ttm-produce -->`
|
|
242
|
+
- **ICP Segment:** From `ICP_SEGMENT` (Step 4)
|
|
243
|
+
- **Positioning Anchor:**
|
|
244
|
+
- Key message: derived from POSITIONING.md primary differentiator, adapted for campaign
|
|
245
|
+
- Primary differentiator: quoted directly from POSITIONING.md
|
|
246
|
+
- **Hook:** From `HOOK` (Step 4)
|
|
247
|
+
- **Proof Points table:** From `PROOF_POINTS` -- POSITIONING.md proof library + campaign additions
|
|
248
|
+
- **Channel Mix table:** From `CHANNEL_MIX` with roles (Step 4)
|
|
249
|
+
- **Assets List table:** Derived from output metrics + channel mix
|
|
250
|
+
- **Success Criteria:** From `SUCCESS_CRITERIA` (Step 4)
|
|
251
|
+
- **Failure Criteria:** From `FAILURE_CRITERIA` (Step 4)
|
|
252
|
+
- **Dependencies:** Inferred from campaign context (reference files, tools, approvals needed)
|
|
253
|
+
- **Timeline table:** From `TIMELINE` (Step 4)
|
|
254
|
+
|
|
255
|
+
Store the generated content as `BRIEF_CONTENT`.
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Step 6: Positioning Check Gate (per D-05, LIFE-05)
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
takeToMarket > POSITIONING CHECK
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Read the positioning check rules from `@${CLAUDE_PLUGIN_ROOT}/workflows/lifecycle/brief-positioning-check.md`.
|
|
266
|
+
|
|
267
|
+
Apply all 5 checks against `BRIEF_CONTENT`:
|
|
268
|
+
|
|
269
|
+
1. **Positioning Anchor Alignment:** Compare brief's "Positioning Anchor > Key message" against POSITIONING.md primary differentiator phrase. Determine PASS/WARN/FAIL.
|
|
270
|
+
|
|
271
|
+
2. **ICP Segment Match:** Compare brief's "ICP Segment > Primary segment" against POSITIONING.md target audience. Determine PASS/WARN/FAIL.
|
|
272
|
+
|
|
273
|
+
3. **Proof Point Sourcing:** Check each proof point in the brief against POSITIONING.md proof point library. Determine PASS/WARN/FAIL.
|
|
274
|
+
|
|
275
|
+
4. **Must-Not-Say Terms:** Scan entire brief content for any terms from POSITIONING.md must-not-say list. Determine PASS/FAIL.
|
|
276
|
+
|
|
277
|
+
5. **Hook-Positioning Coherence:** Compare brief's hook against POSITIONING.md primary differentiator and category. Determine PASS/WARN/FAIL.
|
|
278
|
+
|
|
279
|
+
**Determine gate result:**
|
|
280
|
+
- If ALL checks PASS: gate result = `"pass"`
|
|
281
|
+
- If ANY check is WARN or FAIL: gate result = `"warn"`
|
|
282
|
+
|
|
283
|
+
**If gate result is "warn":** Insert the drift warning HTML comment block at the top of BRIEF_CONTENT, after the title line. List each specific drift item using the drift detail format string from the check rules:
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
<!--
|
|
287
|
+
!! POSITIONING DRIFT WARNING !!
|
|
288
|
+
The following items may not align with your positioning:
|
|
289
|
+
- [drift detail from each failing check, using format strings from brief-positioning-check.md]
|
|
290
|
+
Review .marketing/POSITIONING.md and adjust the brief if needed.
|
|
291
|
+
Run /ttm-positioning-check for a full audit.
|
|
292
|
+
-->
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
The brief is written unconditionally. NEVER block brief generation on positioning drift (per D-05).
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Step 7: Write BRIEF.md and Update State
|
|
300
|
+
|
|
301
|
+
Write `BRIEF_CONTENT` to `.marketing/CAMPAIGNS/${SLUG}/BRIEF.md`.
|
|
302
|
+
|
|
303
|
+
Update campaign state:
|
|
304
|
+
```bash
|
|
305
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update "${SLUG}" phase briefed
|
|
306
|
+
TIMESTAMP=$(node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" timestamp --raw)
|
|
307
|
+
if [ -z "$TIMESTAMP" ]; then
|
|
308
|
+
echo "Error: could not get timestamp"; exit 1
|
|
309
|
+
fi
|
|
310
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update "${SLUG}" phase.briefed "$TIMESTAMP"
|
|
311
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update "${SLUG}" gate.outcome_metric pass
|
|
312
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" campaign update "${SLUG}" gate.positioning_check [pass|warn]
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Replace `[pass|warn]` with the actual gate result from Step 6.
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Step 8: Display Summary
|
|
320
|
+
|
|
321
|
+
```
|
|
322
|
+
takeToMarket > BRIEF COMPLETE
|
|
323
|
+
|
|
324
|
+
Brief saved to .marketing/CAMPAIGNS/${SLUG}/BRIEF.md
|
|
325
|
+
|
|
326
|
+
Outcome metric: [OUTCOME_METRIC]
|
|
327
|
+
Positioning check: [pass|warn]
|
|
328
|
+
Output metric: [defined|MISSING -- add before /ttm-produce]
|
|
329
|
+
Channels: [list of selected channels]
|
|
330
|
+
Assets: [count] planned
|
|
331
|
+
|
|
332
|
+
[If positioning_check=warn:]
|
|
333
|
+
!! Positioning drift detected -- see warning in BRIEF.md
|
|
334
|
+
Review .marketing/POSITIONING.md and adjust if needed.
|
|
335
|
+
|
|
336
|
+
Next: Run /ttm-produce ${SLUG}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
</process>
|
|
340
|
+
|
|
341
|
+
<success_criteria>
|
|
342
|
+
- [ ] Context loaded (Tier 1 all files, Tier 2 ICP/CHANNELS/METRICS/CALENDAR, full POSITIONING.md)
|
|
343
|
+
- [ ] Campaign validated and phase order checked (D-08)
|
|
344
|
+
- [ ] Outcome metric enforced -- valid business outcome with target value and measurement window (D-06, LIFE-04)
|
|
345
|
+
- [ ] Output metric collected or flagged as missing (D-06)
|
|
346
|
+
- [ ] All mandatory brief fields present in generated BRIEF.md (D-07)
|
|
347
|
+
- [ ] Positioning check gate executed with all 5 checks from brief-positioning-check.md (D-05, LIFE-05)
|
|
348
|
+
- [ ] BRIEF.md written unconditionally -- never blocked by positioning drift (D-05)
|
|
349
|
+
- [ ] Campaign state updated: phase=briefed, gate.outcome_metric, gate.positioning_check
|
|
350
|
+
- [ ] OUTPUT_METRIC_MISSING flag visible in BRIEF.md when applicable
|
|
351
|
+
</success_criteria>
|
|
352
|
+
|
|
353
|
+
<output>
|
|
354
|
+
- `.marketing/CAMPAIGNS/<slug>/BRIEF.md` (populated with all mandatory fields)
|
|
355
|
+
</output>
|