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,157 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ttm-tools.cjs -- CLI utility for takeToMarket deterministic operations
|
|
5
|
+
*
|
|
6
|
+
* Single entry point with subcommand router. All command implementations
|
|
7
|
+
* live in bin/lib/*.cjs modules. Zero npm dependencies.
|
|
8
|
+
*
|
|
9
|
+
* Usage: node ttm-tools.cjs <command> [args] [--raw]
|
|
10
|
+
*
|
|
11
|
+
* Commands:
|
|
12
|
+
* slug <text> Generate URL-safe slug from text
|
|
13
|
+
* timestamp [format] Get timestamp (full|date|filename)
|
|
14
|
+
* init Check .marketing/ initialization status
|
|
15
|
+
* state <read|update> Read or update .marketing/STATE.md
|
|
16
|
+
* campaign <sub> [args] Campaign operations (init, state, update, list)
|
|
17
|
+
* drift-log <sub> [args] Drift log operations (append, deprecation)
|
|
18
|
+
* health Validate .marketing/ directory structure
|
|
19
|
+
* commit <msg> [--files] Stage files and git commit
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
'use strict';
|
|
23
|
+
|
|
24
|
+
const { error, parseNamedArgs } = require('./lib/core.cjs');
|
|
25
|
+
|
|
26
|
+
const args = process.argv.slice(2);
|
|
27
|
+
const raw = args.includes('--raw');
|
|
28
|
+
const command = args[0];
|
|
29
|
+
|
|
30
|
+
switch (command) {
|
|
31
|
+
case 'slug': {
|
|
32
|
+
const { cmdSlug } = require('./lib/slug.cjs');
|
|
33
|
+
cmdSlug(args.slice(1).filter(a => a !== '--raw').join(' '), raw);
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
case 'timestamp': {
|
|
37
|
+
const { cmdTimestamp } = require('./lib/slug.cjs');
|
|
38
|
+
const format = args.slice(1).filter(a => a !== '--raw')[0] || 'full';
|
|
39
|
+
cmdTimestamp(format, raw);
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
case 'init': {
|
|
43
|
+
const { cmdInit } = require('./lib/health.cjs');
|
|
44
|
+
cmdInit(raw);
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
case 'state': {
|
|
48
|
+
const stateArgs = args.slice(1).filter(a => a !== '--raw');
|
|
49
|
+
const subCmd = stateArgs[0];
|
|
50
|
+
const { cmdStateRead, cmdStateUpdate } = require('./lib/state.cjs');
|
|
51
|
+
if (subCmd === 'read') cmdStateRead(raw);
|
|
52
|
+
else if (subCmd === 'update') cmdStateUpdate(stateArgs[1], stateArgs[2], raw);
|
|
53
|
+
else error('state subcommand required: read, update');
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case 'commit': {
|
|
57
|
+
const { cmdCommit } = require('./lib/commit.cjs');
|
|
58
|
+
const parsed = parseNamedArgs(args.slice(1));
|
|
59
|
+
const files = parsed.named.files
|
|
60
|
+
? parsed.named.files.split(',')
|
|
61
|
+
: parsed.positional.slice(1);
|
|
62
|
+
cmdCommit(parsed.positional[0], files, raw);
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
case 'campaign': {
|
|
66
|
+
const { cmdCampaignInit, cmdCampaignState, cmdCampaignUpdate, cmdCampaignList, cmdCampaignArchive, cmdRepurposeManifest } = require('./lib/campaign.cjs');
|
|
67
|
+
const campaignArgs = args.slice(1).filter(a => a !== '--raw');
|
|
68
|
+
const subCmd = campaignArgs[0];
|
|
69
|
+
const slug = campaignArgs[1];
|
|
70
|
+
if (subCmd !== 'list' && slug && /\s/.test(slug)) {
|
|
71
|
+
error('campaign slug must not contain whitespace -- use hyphens');
|
|
72
|
+
}
|
|
73
|
+
if (subCmd === 'init') cmdCampaignInit(slug, campaignArgs.slice(2).join(' '), raw);
|
|
74
|
+
else if (subCmd === 'state') cmdCampaignState(slug, raw);
|
|
75
|
+
else if (subCmd === 'update') cmdCampaignUpdate(slug, campaignArgs[2], campaignArgs[3], raw);
|
|
76
|
+
else if (subCmd === 'list') {
|
|
77
|
+
const listParsed = parseNamedArgs(campaignArgs.slice(1));
|
|
78
|
+
// Support --since as a named flag (e.g., --since 30d)
|
|
79
|
+
const since = listParsed.named.since || listParsed.positional.find(a => a.match(/^\d+d$/)) || '';
|
|
80
|
+
// Filter is the first positional that starts with '--' (e.g., --active, --shipped-since-last-audit)
|
|
81
|
+
const filter = listParsed.positional.find(a => a.startsWith('--')) || '';
|
|
82
|
+
cmdCampaignList(filter, since, raw);
|
|
83
|
+
}
|
|
84
|
+
else if (subCmd === 'archive') cmdCampaignArchive(slug, raw);
|
|
85
|
+
else if (subCmd === 'repurpose-manifest') {
|
|
86
|
+
const sourceAssetId = campaignArgs[2];
|
|
87
|
+
const derivativesJson = campaignArgs[3];
|
|
88
|
+
let derivatives;
|
|
89
|
+
try {
|
|
90
|
+
derivatives = JSON.parse(derivativesJson);
|
|
91
|
+
} catch (e) {
|
|
92
|
+
error('Failed to parse derivatives JSON: ' + e.message);
|
|
93
|
+
}
|
|
94
|
+
cmdRepurposeManifest(slug, sourceAssetId, derivatives, raw);
|
|
95
|
+
}
|
|
96
|
+
else error('campaign subcommand required: init, state, update, list, archive, repurpose-manifest');
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
case 'deviation': {
|
|
100
|
+
const devArgs = args.slice(1).filter(a => a !== '--raw');
|
|
101
|
+
const devCmd = devArgs[0];
|
|
102
|
+
if (devCmd === 'append') {
|
|
103
|
+
const { cmdDeviationAppend } = require('./lib/deviation.cjs');
|
|
104
|
+
const parsed = parseNamedArgs(args.slice(2));
|
|
105
|
+
const extra = {
|
|
106
|
+
gate_id: parsed.named['gate-id'],
|
|
107
|
+
tier: parsed.named.tier,
|
|
108
|
+
finding: parsed.named.finding,
|
|
109
|
+
action: parsed.named.action,
|
|
110
|
+
run: parsed.named.run,
|
|
111
|
+
};
|
|
112
|
+
cmdDeviationAppend(parsed.named.slug, parsed.named.gate, parsed.named.result, parsed.named.justification, parsed.named.asset, raw, extra);
|
|
113
|
+
} else {
|
|
114
|
+
error('deviation subcommand required: append');
|
|
115
|
+
}
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
case 'drift-log': {
|
|
119
|
+
const dlArgs = args.slice(1).filter(a => a !== '--raw');
|
|
120
|
+
const dlCmd = dlArgs[0];
|
|
121
|
+
if (dlCmd === 'append') {
|
|
122
|
+
const { cmdDriftLogAppend } = require('./lib/drift-log.cjs');
|
|
123
|
+
const parsed = parseNamedArgs(args.slice(2));
|
|
124
|
+
cmdDriftLogAppend(
|
|
125
|
+
parsed.named['event-type'],
|
|
126
|
+
parsed.named.source,
|
|
127
|
+
parsed.named.details,
|
|
128
|
+
parsed.named.affected,
|
|
129
|
+
raw
|
|
130
|
+
);
|
|
131
|
+
} else if (dlCmd === 'deprecation') {
|
|
132
|
+
const { cmdDriftLogDeprecation } = require('./lib/drift-log.cjs');
|
|
133
|
+
const parsed = parseNamedArgs(args.slice(2));
|
|
134
|
+
cmdDriftLogDeprecation(
|
|
135
|
+
parsed.named.asset,
|
|
136
|
+
parsed.named.campaign,
|
|
137
|
+
parsed.named['old-element'],
|
|
138
|
+
parsed.named['required-update'],
|
|
139
|
+
parsed.named.deadline,
|
|
140
|
+
raw
|
|
141
|
+
);
|
|
142
|
+
} else {
|
|
143
|
+
error('drift-log subcommand required: append, deprecation');
|
|
144
|
+
}
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
case 'health': {
|
|
148
|
+
const { cmdHealth } = require('./lib/health.cjs');
|
|
149
|
+
const full = args.includes('--full');
|
|
150
|
+
cmdHealth(raw, full);
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
default:
|
|
154
|
+
error(
|
|
155
|
+
`Unknown command: ${command || '(none)'}. Available: slug, timestamp, init, state, campaign, commit, deviation, drift-log, health`
|
|
156
|
+
);
|
|
157
|
+
}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# Base Quality Gates
|
|
2
|
+
|
|
3
|
+
10 quality gates evaluated during `/ttm-verify`. Tier 1 gates are blocking (require user action on failure). Tier 2 gates are advisory (reported but no action required).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Gate 1: Positioning Drift (GATE-01) -- Tier 1
|
|
8
|
+
|
|
9
|
+
**Checks:** Asset content alignment with approved positioning
|
|
10
|
+
**Against:** `.marketing/POSITIONING.md`
|
|
11
|
+
|
|
12
|
+
### Evaluation Criteria
|
|
13
|
+
|
|
14
|
+
1. **Primary differentiator alignment**
|
|
15
|
+
- PASS: Asset restates or naturally extends the primary differentiator from POSITIONING.md
|
|
16
|
+
- WARN: Asset partially overlaps but introduces claims not present in POSITIONING.md
|
|
17
|
+
- FAIL: Asset uses a different differentiation claim entirely or contradicts the differentiator
|
|
18
|
+
|
|
19
|
+
2. **Proof point sourcing**
|
|
20
|
+
- PASS: All claims in the asset are backed by proof points in POSITIONING.md proof point library
|
|
21
|
+
- WARN: Asset includes claims that could be inferred from proof points but are not explicitly listed
|
|
22
|
+
- FAIL: Asset makes claims with no matching proof point in POSITIONING.md
|
|
23
|
+
|
|
24
|
+
3. **Must-not-say compliance**
|
|
25
|
+
- PASS: No must-not-say terms from POSITIONING.md found in asset
|
|
26
|
+
- WARN: N/A (must-not-say is binary)
|
|
27
|
+
- FAIL: One or more must-not-say terms detected in asset content
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Gate 2: Claim Accuracy (GATE-02) -- Tier 1
|
|
32
|
+
|
|
33
|
+
**Checks:** Factual and numeric claims against approved proof points
|
|
34
|
+
**Against:** `.marketing/BRAND.md` proof points section
|
|
35
|
+
|
|
36
|
+
### Evaluation Criteria
|
|
37
|
+
|
|
38
|
+
1. **Proof point coverage**
|
|
39
|
+
- PASS: Every factual or numeric claim in the asset has a matching proof point in BRAND.md
|
|
40
|
+
- WARN: Claim exists that is directionally supported but uses different numbers or phrasing
|
|
41
|
+
- FAIL: Asset contains a factual or numeric claim with no corresponding proof point
|
|
42
|
+
|
|
43
|
+
2. **Source citation**
|
|
44
|
+
- PASS: Proof points referenced in the asset cite their source (study, benchmark, customer data)
|
|
45
|
+
- WARN: Proof points are used but source is implied rather than stated
|
|
46
|
+
- FAIL: Claims are asserted without any source attribution where BRAND.md requires it
|
|
47
|
+
|
|
48
|
+
3. **Proof point currency**
|
|
49
|
+
- PASS: All proof points used are current (not marked deprecated or expired in BRAND.md)
|
|
50
|
+
- WARN: A proof point is approaching its review date
|
|
51
|
+
- FAIL: Asset uses a proof point marked as deprecated or expired in BRAND.md
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Gate 3: Voice Drift (GATE-03) -- Tier 2
|
|
56
|
+
|
|
57
|
+
**Checks:** Tone, vocabulary, and register against brand voice definition
|
|
58
|
+
**Against:** `.marketing/BRAND.md` voice archetype and banned words list
|
|
59
|
+
|
|
60
|
+
### Evaluation Criteria
|
|
61
|
+
|
|
62
|
+
1. **Voice archetype match**
|
|
63
|
+
- PASS: Asset tone matches the voice archetype defined in BRAND.md (e.g., "authoritative but approachable")
|
|
64
|
+
- WARN: Tone is inconsistent -- some sections match the archetype while others diverge
|
|
65
|
+
- FAIL: Asset tone fundamentally contradicts the voice archetype
|
|
66
|
+
|
|
67
|
+
2. **Banned words check**
|
|
68
|
+
- PASS: No banned words from BRAND.md banned words list found in asset
|
|
69
|
+
- WARN: N/A (banned words are binary)
|
|
70
|
+
- FAIL: One or more banned words from BRAND.md detected in asset content
|
|
71
|
+
|
|
72
|
+
3. **Register consistency**
|
|
73
|
+
- PASS: Language register is consistent throughout the asset (no sudden shifts from formal to casual)
|
|
74
|
+
- WARN: Minor register shift detected (e.g., one informal phrase in otherwise formal content)
|
|
75
|
+
- FAIL: Major register inconsistency -- asset reads as if written by two different voices
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Gate 4: Outcome Alignment (GATE-04) -- Tier 1
|
|
80
|
+
|
|
81
|
+
**Checks:** Whether the asset is designed to drive the campaign's stated outcome metric
|
|
82
|
+
**Against:** `.marketing/CAMPAIGNS/<slug>/BRIEF.md` outcome metric
|
|
83
|
+
|
|
84
|
+
### Evaluation Criteria
|
|
85
|
+
|
|
86
|
+
1. **Outcome connection**
|
|
87
|
+
- PASS: Asset is clearly designed to drive the outcome metric defined in the brief
|
|
88
|
+
- WARN: Asset may indirectly contribute to the outcome metric but the connection is not explicit
|
|
89
|
+
- FAIL: Asset has no discernible connection to the outcome metric
|
|
90
|
+
|
|
91
|
+
2. **CTA-outcome alignment**
|
|
92
|
+
- PASS: The asset's CTA or desired reader action directly serves the outcome metric
|
|
93
|
+
- WARN: CTA is present but serves a tangential goal rather than the primary outcome
|
|
94
|
+
- FAIL: CTA contradicts or is disconnected from the outcome metric entirely
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Gate 5: Funnel Integrity (GATE-05) -- Tier 2
|
|
99
|
+
|
|
100
|
+
**Checks:** CTA presence, destination, and conversion path logic
|
|
101
|
+
**Against:** `.marketing/CAMPAIGNS/<slug>/BRIEF.md` funnel/CTA section
|
|
102
|
+
|
|
103
|
+
### Evaluation Criteria
|
|
104
|
+
|
|
105
|
+
1. **CTA presence and specificity**
|
|
106
|
+
- PASS: Asset has a clear, specific CTA (not vague "learn more" or "click here")
|
|
107
|
+
- WARN: CTA is present but generic or weak
|
|
108
|
+
- FAIL: No CTA found in an asset that requires one per the brief
|
|
109
|
+
- N/A: Asset type does not require a CTA (purely informational content)
|
|
110
|
+
|
|
111
|
+
2. **CTA destination**
|
|
112
|
+
- PASS: CTA destination URL or next step is defined and logical
|
|
113
|
+
- WARN: CTA destination is defined but may not be live or accessible
|
|
114
|
+
- FAIL: CTA has no defined destination -- dead end
|
|
115
|
+
- N/A: Asset type does not require a CTA
|
|
116
|
+
|
|
117
|
+
3. **Conversion path logic**
|
|
118
|
+
- PASS: Path from CTA to outcome is logical and unbroken (CTA -> landing page -> conversion)
|
|
119
|
+
- WARN: Path exists but includes unnecessary friction or extra steps
|
|
120
|
+
- FAIL: Conversion path has a dead end or logical gap
|
|
121
|
+
- N/A: Asset type does not require a CTA
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Gate 6: UTM Hygiene (GATE-06) -- Tier 2
|
|
126
|
+
|
|
127
|
+
**Checks:** UTM parameter presence and naming convention compliance
|
|
128
|
+
**Against:** `.marketing/CHANNELS.md` UTM schema
|
|
129
|
+
|
|
130
|
+
### Evaluation Criteria
|
|
131
|
+
|
|
132
|
+
1. **UTM parameter presence**
|
|
133
|
+
- PASS: All trackable links in the asset have UTM parameters (source, medium, campaign at minimum)
|
|
134
|
+
- WARN: Some links have UTM parameters but others are missing them
|
|
135
|
+
- FAIL: No UTM parameters on any trackable link
|
|
136
|
+
- N/A: Asset contains no trackable links
|
|
137
|
+
|
|
138
|
+
2. **Naming convention compliance**
|
|
139
|
+
- PASS: UTM source and medium values match the naming conventions defined in CHANNELS.md
|
|
140
|
+
- WARN: UTM values are present but use non-standard naming (e.g., "LinkedIn" vs "linkedin")
|
|
141
|
+
- FAIL: UTM values contradict CHANNELS.md conventions entirely
|
|
142
|
+
- N/A: Asset contains no trackable links
|
|
143
|
+
|
|
144
|
+
3. **Campaign tag consistency**
|
|
145
|
+
- PASS: UTM campaign tag matches the campaign slug
|
|
146
|
+
- WARN: Campaign tag is present but uses a variant of the slug
|
|
147
|
+
- FAIL: Campaign tag is missing or uses an unrelated identifier
|
|
148
|
+
- N/A: Asset contains no trackable links
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Gate 7: Compliance (GATE-07) -- Tier 2
|
|
153
|
+
|
|
154
|
+
**Checks:** Regulatory requirements, disclaimers, and PII exposure
|
|
155
|
+
**Against:** Industry-standard requirements and channel regulations
|
|
156
|
+
|
|
157
|
+
### Evaluation Criteria
|
|
158
|
+
|
|
159
|
+
1. **Required disclaimers**
|
|
160
|
+
- PASS: All required disclaimers are present (financial, health, affiliate, sponsorship)
|
|
161
|
+
- WARN: Disclaimers are present but incomplete or improperly formatted
|
|
162
|
+
- FAIL: Required disclaimers are missing entirely
|
|
163
|
+
- N/A: Asset content does not trigger disclaimer requirements
|
|
164
|
+
|
|
165
|
+
2. **PII exposure**
|
|
166
|
+
- PASS: No PII exposed in asset body copy (email addresses, phone numbers, personal names)
|
|
167
|
+
- WARN: PII-like patterns detected but may be intentional (e.g., example email in tutorial)
|
|
168
|
+
- FAIL: Actual PII exposed in asset content
|
|
169
|
+
|
|
170
|
+
3. **Opt-out mechanism**
|
|
171
|
+
- PASS: Unsubscribe or opt-out mechanism referenced where applicable (email, SMS)
|
|
172
|
+
- WARN: Opt-out reference is present but unclear or hard to find
|
|
173
|
+
- FAIL: No opt-out mechanism in a channel that legally requires one
|
|
174
|
+
- N/A: Channel does not require opt-out (blog post, social media)
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Gate 8: Competitor Collision (GATE-08) -- Tier 2
|
|
179
|
+
|
|
180
|
+
**Checks:** Unintended competitor promotion or positioning echo
|
|
181
|
+
**Against:** `.marketing/COMPETITORS.md`
|
|
182
|
+
|
|
183
|
+
### Evaluation Criteria
|
|
184
|
+
|
|
185
|
+
1. **Competitor brand name usage**
|
|
186
|
+
- PASS: No competitor brand names used, or used only with substantiated comparative claims
|
|
187
|
+
- WARN: Competitor mentioned without a direct comparison or substantiation
|
|
188
|
+
- FAIL: Competitor brand name used in a way that promotes or elevates the competitor
|
|
189
|
+
|
|
190
|
+
2. **Positioning echo**
|
|
191
|
+
- PASS: Asset framing and language are distinct from competitor positioning in COMPETITORS.md
|
|
192
|
+
- WARN: Some phrasing overlaps with a competitor's known messaging
|
|
193
|
+
- FAIL: Asset accidentally echoes a competitor's tagline, slogan, or core positioning claim
|
|
194
|
+
|
|
195
|
+
3. **Differentiation clarity**
|
|
196
|
+
- PASS: Asset clearly differentiates from competitors rather than validating their approach
|
|
197
|
+
- WARN: Asset is neutral -- does not differentiate but does not validate competitors either
|
|
198
|
+
- FAIL: Asset inadvertently validates a competitor's approach or frames the market in their terms
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Gate 9: ICP Fit (GATE-09) -- Tier 2
|
|
203
|
+
|
|
204
|
+
**Checks:** Whether content speaks to the target ICP in their language
|
|
205
|
+
**Against:** `.marketing/ICP.md`
|
|
206
|
+
|
|
207
|
+
### Evaluation Criteria
|
|
208
|
+
|
|
209
|
+
1. **Pain point relevance**
|
|
210
|
+
- PASS: Hook and core message address a pain point from ICP.md pains list
|
|
211
|
+
- WARN: Content addresses a related pain but not one explicitly listed in ICP.md
|
|
212
|
+
- FAIL: Content does not address any ICP pain point -- generic or unrelated audience
|
|
213
|
+
|
|
214
|
+
2. **Customer vocabulary**
|
|
215
|
+
- PASS: Asset uses customer vocabulary from ICP.md language library, not internal jargon
|
|
216
|
+
- WARN: Mix of customer vocabulary and internal jargon
|
|
217
|
+
- FAIL: Asset is written in internal jargon that the ICP would not recognize or relate to
|
|
218
|
+
|
|
219
|
+
3. **Anti-ICP avoidance**
|
|
220
|
+
- PASS: Content clearly addresses the target ICP segment, not the anti-ICP defined in ICP.md
|
|
221
|
+
- WARN: Content is broad enough that it could attract the anti-ICP alongside the target
|
|
222
|
+
- FAIL: Content is more likely to attract the anti-ICP than the target segment
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Gate 10: Format Correctness (GATE-10) -- Tier 2
|
|
227
|
+
|
|
228
|
+
**Checks:** Platform-specific format requirements and structural conventions
|
|
229
|
+
**Against:** Channel-specific rules (from playbook if loaded, otherwise general platform guidelines)
|
|
230
|
+
|
|
231
|
+
### Evaluation Criteria
|
|
232
|
+
|
|
233
|
+
1. **Character and word count**
|
|
234
|
+
- PASS: Asset meets platform character/word limits (tweet < 280 chars, LinkedIn < 3000, email subject < 60)
|
|
235
|
+
- WARN: Asset is within 10% of the limit
|
|
236
|
+
- FAIL: Asset exceeds platform limits
|
|
237
|
+
|
|
238
|
+
2. **Required elements**
|
|
239
|
+
- PASS: All required structural elements present (subject line for email, H1 for blog, hook for social)
|
|
240
|
+
- WARN: Most required elements present but one is missing or weak
|
|
241
|
+
- FAIL: Multiple required structural elements are missing
|
|
242
|
+
|
|
243
|
+
3. **Channel conventions**
|
|
244
|
+
- PASS: Structure follows channel conventions (email has preview text, blog has meta description)
|
|
245
|
+
- WARN: Structure mostly follows conventions with minor gaps
|
|
246
|
+
- FAIL: Structure ignores channel conventions entirely
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Tier Classification (GATE-11)
|
|
251
|
+
|
|
252
|
+
| Gate | ID | Tier | Effect on Verification |
|
|
253
|
+
|------|----|------|----------------------|
|
|
254
|
+
| Positioning Drift | GATE-01 | Tier 1 (blocking) | User prompted for deviation action |
|
|
255
|
+
| Claim Accuracy | GATE-02 | Tier 1 (blocking) | User prompted for deviation action |
|
|
256
|
+
| Outcome Alignment | GATE-04 | Tier 1 (blocking) | User prompted for deviation action |
|
|
257
|
+
| Voice Drift | GATE-03 | Tier 2 (advisory) | Reported but no action required |
|
|
258
|
+
| Funnel Integrity | GATE-05 | Tier 2 (advisory) | Reported but no action required |
|
|
259
|
+
| UTM Hygiene | GATE-06 | Tier 2 (advisory) | Reported but no action required |
|
|
260
|
+
| Compliance | GATE-07 | Tier 2 (advisory) | Reported but no action required |
|
|
261
|
+
| Competitor Collision | GATE-08 | Tier 2 (advisory) | Reported but no action required |
|
|
262
|
+
| ICP Fit | GATE-09 | Tier 2 (advisory) | Reported but no action required |
|
|
263
|
+
| Format Correctness | GATE-10 | Tier 2 (advisory) | Reported but no action required |
|
|
264
|
+
|
|
265
|
+
**Tier 1:** Gate failure requires explicit user action (Correct, Accept+log, or Escalate per GATE-12).
|
|
266
|
+
**Tier 2:** Gate findings are reported as advisory. User may optionally act on them.
|
|
File without changes
|