@agentproto/corpus-presets 0.1.0-alpha.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 agentproto contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # @agentproto/corpus-presets
2
+
3
+ Catalog of starter workspaces for the AIP-10 corpus runtime. Subpath exports per vertical — pure TS data, no filesystem dependency. Host iterates `files` and writes via FsPort.
4
+
5
+ ## Discovery
6
+
7
+ The `corpus` CLI discovers presets via the `agentproto/corpus-preset/v1` manifest declared in this package's `package.json#agentproto-corpus-preset`. Third-party packages following the same convention can be added to the discovery set via `corpusPresetPackages[]` in `~/.agentproto/config.json`.
8
+
9
+ ## Direct usage
10
+
11
+ ```ts
12
+ import { MarketingCorpusPreset } from "@agentproto/corpus-presets/marketing"
13
+
14
+ for (const [rel, content] of Object.entries(MarketingCorpusPreset.files)) {
15
+ await fs.writeFile(path.join(workspaceRoot, rel), content)
16
+ }
17
+ ```
18
+
19
+ Or via the CLI, which uses the manifest to resolve the slug:
20
+
21
+ ```bash
22
+ corpus init marketing ./my-corpus
23
+ corpus init --list # show every discoverable preset
24
+ ```
25
+
26
+ ## Source of truth
27
+
28
+ The fixture dir at `@agentproto/corpus/test/fixtures/<slug>/` is the single source of truth. The TS file `src/<slug>/files.ts` is a build artifact — gitignored, regenerated by this package's `prebuild` / `precheck-types` / `pretest` / `predev` hooks. The conformance test enforces those `.md` files validate against the actual AgentProto JSON Schemas, so what ships here is always AIP-conformant by construction.
29
+
30
+ To edit a preset:
31
+
32
+ 1. Edit `packages/corpus/test/fixtures/<vertical>/...`
33
+ 2. Run `pnpm --filter @agentproto/corpus test` to confirm conformance still holds
34
+ 3. Build (or check-types, or test) the preset — the regen runs automatically: `pnpm --filter @agentproto/corpus-presets build`
35
+
36
+ The standalone `pnpm gen:marketing` script still exists for explicit regen but isn't needed in the normal flow.
37
+
38
+ ## Adding a new vertical to this package
39
+
40
+ 1. Add fixtures: `packages/corpus/test/fixtures/<slug>/`
41
+ 2. Extend `packages/corpus/src/__tests__/conformance.test.ts` to cover them
42
+ 3. Copy `scripts/gen-marketing.mjs` → `scripts/gen-<slug>.mjs`
43
+ 4. Add `gen-<slug>` to each pre-hook in `package.json` (or fold it into a single bootstrap script that runs all generators)
44
+ 5. Add `src/<slug>/index.ts` exporting `<Slug>CorpusPreset: CorpusPreset`
45
+ 6. Add `./<slug>` subpath to `package.json#exports`
46
+ 7. Add `"<slug>/index"` entry to `tsup.config.ts`
47
+ 8. Append an entry to `package.json#agentproto-corpus-preset.presets[]` with the slug + entry + export
48
+ 9. Add the generated file to the root `.gitignore`
49
+
50
+ ## Shipping a preset from a third-party package
51
+
52
+ Create your own npm package (`@vendor/corpus-presets`, `<name>-corpus-presets`, …) and add the same manifest block to its `package.json`:
53
+
54
+ ```jsonc
55
+ {
56
+ "agentproto-corpus-preset": {
57
+ "schema": "agentproto/corpus-preset/v1",
58
+ "presets": [
59
+ { "slug": "<your-slug>", "entry": "./dist/index.mjs", "export": "<YourPreset>" }
60
+ ]
61
+ }
62
+ }
63
+ ```
64
+
65
+ Then point the CLI at it:
66
+
67
+ ```jsonc
68
+ // ~/.agentproto/config.json
69
+ {
70
+ "corpusPresetPackages": [
71
+ "@agentproto/corpus-presets",
72
+ "@vendor/corpus-presets"
73
+ ]
74
+ }
75
+ ```
76
+
77
+ `corpus init --list` will show every discovered preset.
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/index.mjs ADDED
@@ -0,0 +1,3 @@
1
+
2
+ //# sourceMappingURL=index.mjs.map
3
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.mjs"}
@@ -0,0 +1,31 @@
1
+ import { CorpusPreset } from '@agentproto/corpus';
2
+
3
+ /**
4
+ * AUTO-GENERATED build artifact — DO NOT COMMIT, DO NOT EDIT.
5
+ *
6
+ * Regenerated from @agentproto/corpus/test/fixtures/marketing/
7
+ * by the prebuild / precheck-types / pretest / predev hooks on
8
+ * this package. To change the preset content, edit the fixtures.
9
+ */
10
+ declare const MARKETING_PRESET_FILES: Readonly<Record<string, string>>;
11
+
12
+ /**
13
+ * Marketing corpus preset.
14
+ *
15
+ * Pure TS data — `files` is inlined from the M0 fixture workspace at
16
+ * build time via `scripts/gen-marketing.mjs`. The M0 conformance test
17
+ * proves every file validates against the actual AgentProto JSON
18
+ * Schemas, so a host that writes these to disk gets a known-good
19
+ * starter workspace.
20
+ *
21
+ * Usage:
22
+ *
23
+ * import { MarketingCorpusPreset } from "@agentproto/corpus-presets/marketing"
24
+ * for (const [rel, content] of Object.entries(MarketingCorpusPreset.files)) {
25
+ * await fs.writeFile(path.join(workspaceRoot, rel), content)
26
+ * }
27
+ */
28
+
29
+ declare const MarketingCorpusPreset: CorpusPreset;
30
+
31
+ export { MARKETING_PRESET_FILES, MarketingCorpusPreset };
@@ -0,0 +1,684 @@
1
+ /**
2
+ * @agentproto/corpus-presets v0.1.0-alpha
3
+ * Pure-TS starter workspaces for the AIP-10 corpus runtime.
4
+ */
5
+
6
+ // src/marketing/files.ts
7
+ var MARKETING_PRESET_FILES = Object.freeze({
8
+ "collections/corpus-candidate/COLLECTION.md": '---\nschema: collection.schema/v1\nname: corpus-candidate\ntitle: Corpus Candidate\ndescription: |\n Candidate corpus item awaiting analysis and promotion to an AIP-10 entry.\n Discovered candidates live in `_candidates.yaml` sidecar; materialized\n ITEM.md files appear only after transition out of `discovered`.\nversion: 1.0.0\ninitialStatus: discovered\nstatuses:\n - { id: discovered, label: Discovered, transitionsTo: [analyzed, rejected] }\n - { id: analyzed, label: Analyzed, transitionsTo: [approved, rejected, needs-work] }\n - { id: needs-work, label: Needs Work, transitionsTo: [analyzed, rejected] }\n - { id: approved, label: Approved, terminal: true }\n - { id: rejected, label: Rejected, terminal: true }\nidentity:\n slugSource: id\n filingPath: "collections/corpus-candidate/{slug}/ITEM.md"\nfields:\n - { name: sourcePath, type: string, required: true }\n - { name: sourceUrl, type: url }\n - { name: targetEntryPath, type: string }\n - { name: corpusKind, type: enum, enum: [principle, example, pattern, critique, summary, timeline, playbook], required: true }\n - { name: qualityScore, type: number }\n - { name: riskScore, type: number }\n - { name: promotionMode, type: enum, enum: [auto, human] }\n - { name: contentHash, type: string }\n - { name: reviewerNotes, type: text }\nlints:\n - { id: required-field-source-path, kind: required-field, appliesTo: "*", severity: error, params: { fields: [sourcePath] } }\n - { id: required-field-corpus-kind, kind: required-field, appliesTo: "*", severity: error, params: { fields: [corpusKind] } }\nmetadata:\n corpus:\n description: Used by source-scout (writes), marketing-analyst (writes), quality-reviewer (scores), corpus-curator (promotes).\n---\n\n# Corpus Candidate collection\n\nHolds candidates discovered by the scout, analyzed by the analyst, scored by the reviewer, and promoted by the curator. State machine enforced by `statuses[].transitionsTo`.\n',
9
+ "collections/corpus-candidate/tiktok-hook-2026-05/ITEM.md": '---\nschema: collection.item/v1\ncollection: corpus-candidate\nid: tiktok-hook-2026-05\ntitle: TikTok contrarian hook pattern\nstatus: analyzed\nsourcePath: sources/fresh/tiktok-hook-2026-05.md\nsourceUrl: https://example.com/tiktok/123\ntargetEntryPath: entries/patterns/2026/contrarian-short-form-hooks.md\ncorpusKind: pattern\ncontentHash: sha256:abc1234567890def1234567890abcdef1234567890abcdef1234567890abcdef\ntags: [short-form, hooks]\ncreatedAt: "2026-05-22T14:30:00Z"\nupdatedAt: "2026-05-22T15:00:00Z"\nmetadata:\n corpus:\n qualityScore: 4.3\n riskScore: 1.1\n promotionMode: auto\n---\n\n# Candidate: TikTok contrarian hook\n\nCandidate extracted from fresh social examples. The pattern (contrarian belief-flip in <5s hooks) generalizes across short-form channels. Analyst recommends auto-promotion.\n\n## Analysis\n- Pattern present in 6 of 10 top-performing TikToks reviewed\n- Transferable to Reels, Shorts, cold-email subject lines\n- No risk of legal / brand misuse identified\n\n## Decision\n- promotionMode: auto\n- gates pass: qualityScore 4.3 \u2265 4.2, riskScore 1.1 \u2264 1.5, archive hash present, all required fields populated\n',
10
+ "entries/critiques/2026/weak-positioning-saas.md": `---
11
+ schema: knowledge.entry/v1
12
+ slug: weak-positioning-saas
13
+ kind: critique
14
+ title: Weak positioning \u2014 "powerful platform for X"
15
+ updated_at: "2026-05-22T14:30:00Z"
16
+ sources:
17
+ - tiktok-hook-2026-05
18
+ confidence: 0.85
19
+ tags: [positioning, anti-pattern, saas]
20
+ metadata:
21
+ corpus:
22
+ status: active
23
+ qualityScore: 4.1
24
+ riskScore: 1.2
25
+ domain: marketing
26
+ funnelStage: consideration
27
+ temporal:
28
+ firstSeen: "2024-08-01T00:00:00Z"
29
+ lastSeen: "2026-05-22T14:30:00Z"
30
+ mentions:
31
+ - { at: "2024-08-01T00:00:00Z", sourceId: tiktok-hook-2026-05, weight: 0.7 }
32
+ - { at: "2026-05-22T14:30:00Z", sourceId: tiktok-hook-2026-05, weight: 1.0 }
33
+ promotionMode: human
34
+ promotedAt: "2026-05-22T14:30:00Z"
35
+ promotedBy: corpus-curator
36
+ ---
37
+
38
+ ## What's wrong
39
+ "Powerful platform for [audience]" makes zero claims. It's substitutable for any competitor's homepage.
40
+
41
+ ## Why it fails
42
+ - No specific outcome promised
43
+ - No specific cost / friction acknowledged
44
+ - No specific audience excluded
45
+ - Reader can't tell if it's for them
46
+
47
+ ## How to fix
48
+ Replace with: "[outcome] for [specific audience] without [specific pain]". E.g. "Ship marketing copy in 10 minutes, not 10 days \u2014 without hiring a copywriter".
49
+
50
+ ## Use this critique when
51
+ - Reviewing landing-page hero copy
52
+ - Reviewing PRD positioning sections
53
+ - Onboarding a new marketing-analyst operator
54
+ `,
55
+ "entries/examples/2026/apple-2007-iphone-keynote.md": `---
56
+ schema: knowledge.entry/v1
57
+ slug: apple-2007-iphone-keynote
58
+ kind: example
59
+ title: Apple 2007 iPhone keynote \u2014 three-products framing
60
+ updated_at: "2026-05-22T14:30:00Z"
61
+ sources:
62
+ - tiktok-hook-2026-05
63
+ confidence: 0.92
64
+ tags: [keynote, framing, apple, launch]
65
+ metadata:
66
+ corpus:
67
+ status: active
68
+ qualityScore: 4.7
69
+ riskScore: 0.3
70
+ domain: marketing
71
+ channel: keynote
72
+ funnelStage: awareness
73
+ temporal:
74
+ firstSeen: "2024-01-09T00:00:00Z"
75
+ lastSeen: "2026-05-22T14:30:00Z"
76
+ mentions:
77
+ - { at: "2024-01-09T00:00:00Z", sourceId: tiktok-hook-2026-05, weight: 1.0 }
78
+ - { at: "2026-05-22T14:30:00Z", sourceId: tiktok-hook-2026-05, weight: 1.0 }
79
+ promotionMode: human
80
+ promotedAt: "2026-05-22T14:30:00Z"
81
+ promotedBy: corpus-curator
82
+ ---
83
+
84
+ ## Summary
85
+ Jobs opened the 2007 keynote by saying Apple was launching three products: a widescreen iPod with touch controls, a revolutionary mobile phone, and a breakthrough internet communicator. After repeating the trio twice, he revealed: "These are not three separate devices. This is one device. And we are calling it iPhone." The pattern earned a standing ovation before any feature was shown.
86
+
87
+ ## What's specific
88
+ - Three concrete categories the audience already understood (iPod, phone, internet).
89
+ - Deliberate repetition built rhythm; the reveal collapsed all three into one.
90
+ - The reveal happened on word 47 of the keynote \u2014 pre-product, pre-spec.
91
+
92
+ ## Transferable lesson
93
+ For a category-creating product, don't announce the new category. Announce three known things, then collapse them.
94
+
95
+ ## Use this example when
96
+ - Pitching anything that's "X + Y + Z combined".
97
+ - Launching to an audience that doesn't have a mental slot for the new thing yet.
98
+
99
+ ## Avoid this pattern when
100
+ - The product genuinely is one thing \u2014 manufacturing a trio is fake.
101
+ - The audience already knows the category (then specs, not framing, win).
102
+ `,
103
+ "entries/patterns/2026/contrarian-short-form-hooks.md": `---
104
+ schema: knowledge.entry/v1
105
+ slug: contrarian-short-form-hooks
106
+ kind: pattern
107
+ title: Contrarian short-form hooks
108
+ updated_at: "2026-05-22T14:30:00Z"
109
+ sources:
110
+ - tiktok-hook-2026-05
111
+ confidence: 0.88
112
+ links:
113
+ - specificity-beats-superlatives
114
+ tags: [hooks, short-form, tiktok, contrarian]
115
+ metadata:
116
+ corpus:
117
+ status: active
118
+ qualityScore: 4.5
119
+ riskScore: 1.0
120
+ domain: marketing
121
+ channel: tiktok
122
+ funnelStage: awareness
123
+ temporal:
124
+ firstSeen: "2023-04-12T00:00:00Z"
125
+ lastSeen: "2026-05-22T14:30:00Z"
126
+ halfLifeDays: 180
127
+ mentions:
128
+ - { at: "2023-04-12T00:00:00Z", sourceId: tiktok-hook-2026-05, weight: 1.0 }
129
+ - { at: "2026-05-22T14:30:00Z", sourceId: tiktok-hook-2026-05, weight: 1.0 }
130
+ promotionMode: auto
131
+ promotedAt: "2026-05-22T14:30:00Z"
132
+ promotedBy: corpus-curator
133
+ ---
134
+
135
+ ## Summary
136
+ Open with a popularly-held belief, then contradict it with a specific counter-claim. Forces a "wait, what?" pattern interrupt that buys 3-5 more seconds of attention.
137
+
138
+ ## Why it works
139
+ Pattern-interrupt + curiosity gap. The viewer's brain treats the contradiction as a problem to resolve.
140
+
141
+ ## Transferable pattern
142
+ 1. State a widely-held belief in 5 words
143
+ 2. Counter with one specific contradiction
144
+ 3. Promise the why in the next 30 seconds
145
+
146
+ ## Use when
147
+ - Short-form video (TikTok, Reels, Shorts)
148
+ - Cold-outbound email subject lines
149
+ - Ad creative for low-awareness audiences
150
+
151
+ ## Avoid when
152
+ - Branded content (feels manipulative)
153
+ - Audience already aligned with your stance
154
+ - Long-form (the hook doesn't sustain)
155
+
156
+ ## Examples
157
+ - "Most marketers write listicles. Here's why every viral piece I've made started with a contradiction."
158
+ - "Cold email is dead \u2014 for the 99% who do it wrong. Here's the 1%."
159
+ `,
160
+ "entries/patterns/2026/story-then-payoff.md": `---
161
+ schema: knowledge.entry/v1
162
+ slug: story-then-payoff
163
+ kind: pattern
164
+ title: Story-then-payoff structure
165
+ updated_at: "2026-05-22T14:30:00Z"
166
+ sources:
167
+ - tiktok-hook-2026-05
168
+ confidence: 0.85
169
+ links:
170
+ - contrarian-short-form-hooks
171
+ - clarity-beats-cleverness
172
+ tags: [storytelling, structure, copy]
173
+ metadata:
174
+ corpus:
175
+ status: active
176
+ qualityScore: 4.3
177
+ riskScore: 0.8
178
+ domain: marketing
179
+ funnelStage: awareness
180
+ temporal:
181
+ firstSeen: "2023-09-15T00:00:00Z"
182
+ lastSeen: "2026-05-22T14:30:00Z"
183
+ mentions:
184
+ - { at: "2023-09-15T00:00:00Z", sourceId: tiktok-hook-2026-05, weight: 1.0 }
185
+ - { at: "2026-05-22T14:30:00Z", sourceId: tiktok-hook-2026-05, weight: 1.0 }
186
+ promotionMode: auto
187
+ promotedAt: "2026-05-22T14:30:00Z"
188
+ promotedBy: corpus-curator
189
+ ---
190
+
191
+ ## Summary
192
+ Open with a 1-2 sentence story (specific, sensory), then deliver the payoff (principle, product, CTA). The story buys attention; the payoff cashes it in.
193
+
194
+ ## Why it works
195
+ Brains are pattern-completion engines. A half-told story creates open loop tension. Closing the loop with the payoff delivers a small dopamine hit + transfers credibility from the story to the claim.
196
+
197
+ ## Transferable pattern
198
+ - Story: \u22642 sentences, one concrete moment.
199
+ - Payoff: \u22641 sentence, names the principle / product / CTA.
200
+ - Optional: 1 sentence connecting the two.
201
+
202
+ ## Use when
203
+ - Cold email openers, ad creative, landing-page heros.
204
+ - Audiences that don't know the product yet.
205
+
206
+ ## Avoid when
207
+ - Internal comms (waste of words).
208
+ - Audiences past consideration stage \u2014 they want specs, not stories.
209
+ `,
210
+ "entries/principles/2026/clarity-beats-cleverness.md": `---
211
+ schema: knowledge.entry/v1
212
+ slug: clarity-beats-cleverness
213
+ kind: principle
214
+ title: Clarity beats cleverness
215
+ updated_at: "2026-05-22T14:30:00Z"
216
+ sources:
217
+ - tiktok-hook-2026-05
218
+ confidence: 0.95
219
+ tags: [copy, clarity, conversion]
220
+ metadata:
221
+ corpus:
222
+ status: active
223
+ qualityScore: 4.8
224
+ riskScore: 0.5
225
+ domain: marketing
226
+ funnelStage: awareness
227
+ temporal:
228
+ firstSeen: "2022-01-01T00:00:00Z"
229
+ lastSeen: "2026-05-22T14:30:00Z"
230
+ mentions:
231
+ - { at: "2022-01-01T00:00:00Z", sourceId: tiktok-hook-2026-05, weight: 1.0 }
232
+ - { at: "2026-05-22T14:30:00Z", sourceId: tiktok-hook-2026-05, weight: 1.0 }
233
+ promotionMode: human
234
+ promotedAt: "2026-05-22T14:30:00Z"
235
+ promotedBy: corpus-curator
236
+ ---
237
+
238
+ ## Summary
239
+ If the reader has to re-read a sentence, the joke is on the writer. Wordplay that's clever-but-confusing loses 100% of distracted readers.
240
+
241
+ ## Why it works
242
+ Reading is involuntary effort. Clever copy taxes that effort; clear copy doesn't. The cheapest conversion is the one where the reader didn't have to work.
243
+
244
+ ## Transferable pattern
245
+ - Write at a 6th-grade reading level (Hemingway score).
246
+ - Replace every metaphor that doesn't add new information.
247
+ - One idea per sentence.
248
+
249
+ ## Use when
250
+ - Landing-page headlines, CTAs, ad creative.
251
+ - Any audience that hasn't already paid attention.
252
+
253
+ ## Avoid when
254
+ - Brand-content where the voice IS the product (Liquid Death, Cards Against Humanity).
255
+ - Inside-baseball content for an already-converted audience.
256
+ `,
257
+ "entries/principles/2026/specificity-beats-superlatives.md": `---
258
+ schema: knowledge.entry/v1
259
+ slug: specificity-beats-superlatives
260
+ kind: principle
261
+ title: Specificity beats superlatives
262
+ updated_at: "2026-05-22T14:30:00Z"
263
+ sources:
264
+ - tiktok-hook-2026-05
265
+ confidence: 0.92
266
+ tags: [copy, specificity, conversion]
267
+ metadata:
268
+ corpus:
269
+ status: active
270
+ qualityScore: 4.7
271
+ riskScore: 0.8
272
+ domain: marketing
273
+ funnelStage: consideration
274
+ temporal:
275
+ firstSeen: "2023-04-12T00:00:00Z"
276
+ lastSeen: "2026-05-22T14:30:00Z"
277
+ mentions:
278
+ - { at: "2023-04-12T00:00:00Z", sourceId: tiktok-hook-2026-05, weight: 1.0 }
279
+ - { at: "2026-05-22T14:30:00Z", sourceId: tiktok-hook-2026-05, weight: 1.0 }
280
+ promotionMode: human
281
+ promotedAt: "2026-05-22T14:30:00Z"
282
+ promotedBy: corpus-curator
283
+ ---
284
+
285
+ ## Summary
286
+ Concrete claims with numbers outperform superlative adjectives. "3x conversion" beats "amazing results"; "287 customers in 90 days" beats "many happy customers".
287
+
288
+ ## Why it works
289
+ Readers parse numbers as evidence; adjectives as marketing noise. Specificity transfers credibility because it implies the author can be checked.
290
+
291
+ ## Transferable pattern
292
+ - Replace every superlative with a specific number, date, or named entity
293
+ - If you can't substitute, the claim is probably untrue
294
+
295
+ ## Use when
296
+ - Writing landing-page copy
297
+ - Drafting ad creative
298
+ - Replying to objections
299
+
300
+ ## Avoid when
301
+ - Numbers are unverifiable (then say nothing)
302
+ - Aspirational brand voice required
303
+ `,
304
+ "entries/summaries/2026/short-form-hook-meta.md": `---
305
+ schema: knowledge.entry/v1
306
+ slug: short-form-hook-meta
307
+ kind: summary
308
+ title: Short-form hook meta \u2014 what's working in 2026
309
+ updated_at: "2026-05-22T14:30:00Z"
310
+ sources:
311
+ - tiktok-hook-2026-05
312
+ confidence: 0.7
313
+ links:
314
+ - contrarian-short-form-hooks
315
+ - story-then-payoff
316
+ - clarity-beats-cleverness
317
+ tags: [meta, short-form, hooks, trends]
318
+ metadata:
319
+ corpus:
320
+ status: active
321
+ qualityScore: 4.0
322
+ riskScore: 1.0
323
+ domain: marketing
324
+ channel: tiktok
325
+ funnelStage: awareness
326
+ temporal:
327
+ firstSeen: "2026-04-01T00:00:00Z"
328
+ lastSeen: "2026-05-22T14:30:00Z"
329
+ halfLifeDays: 60
330
+ mentions:
331
+ - { at: "2026-04-01T00:00:00Z", sourceId: tiktok-hook-2026-05, weight: 1.0 }
332
+ - { at: "2026-05-22T14:30:00Z", sourceId: tiktok-hook-2026-05, weight: 1.0 }
333
+ promotionMode: human
334
+ promotedAt: "2026-05-22T14:30:00Z"
335
+ promotedBy: corpus-curator
336
+ ---
337
+
338
+ ## Summary
339
+ As of mid-2026, the dominant short-form hook patterns on TikTok / Reels / Shorts share three traits: (1) contradiction in the first 2 seconds, (2) specific number or named entity by the 5-second mark, (3) the payoff arrives before 30 seconds.
340
+
341
+ ## What's NOT working anymore
342
+ - Generic "POV:" openers \u2014 algo deprioritized them after the Q1 update.
343
+ - Long establishing shots \u2014 90% drop-off before the 3-second mark.
344
+ - "Watch till the end" framing \u2014 overuse killed effectiveness.
345
+
346
+ ## Patterns that scale across channels
347
+ - [[contrarian-short-form-hooks]] \u2014 universal, lowest production cost.
348
+ - [[story-then-payoff]] \u2014 needs a sharp specific story; expensive to source.
349
+
350
+ ## Half-life
351
+ 60 days. Re-mention via scout when a new platform algorithm update lands.
352
+ `,
353
+ "entries/timelines/2026/saas-positioning-shifts-2020-2026.md": `---
354
+ schema: knowledge.entry/v1
355
+ slug: saas-positioning-shifts-2020-2026
356
+ kind: timeline
357
+ title: SaaS positioning shifts \u2014 2020 to 2026
358
+ updated_at: "2026-05-22T14:30:00Z"
359
+ sources:
360
+ - tiktok-hook-2026-05
361
+ confidence: 0.78
362
+ links:
363
+ - weak-positioning-saas
364
+ tags: [positioning, saas, timeline, trend]
365
+ metadata:
366
+ corpus:
367
+ status: active
368
+ qualityScore: 4.1
369
+ riskScore: 1.2
370
+ domain: marketing
371
+ funnelStage: consideration
372
+ temporal:
373
+ firstSeen: "2024-06-01T00:00:00Z"
374
+ lastSeen: "2026-05-22T14:30:00Z"
375
+ halfLifeDays: 180
376
+ mentions:
377
+ - { at: "2024-06-01T00:00:00Z", sourceId: tiktok-hook-2026-05, weight: 1.0 }
378
+ - { at: "2026-05-22T14:30:00Z", sourceId: tiktok-hook-2026-05, weight: 1.0 }
379
+ promotionMode: human
380
+ promotedAt: "2026-05-22T14:30:00Z"
381
+ promotedBy: corpus-curator
382
+ ---
383
+
384
+ ## Summary
385
+ B2B SaaS positioning evolved through five distinct phases between 2020 and 2026, each driven by a buyer environment shift.
386
+
387
+ ## 2020 \u2014 "All-in-one platform"
388
+ Buyers consolidating tools post-COVID; positioning prized breadth.
389
+ Result: feature-list arms race, undifferentiated category copy.
390
+
391
+ ## 2022 \u2014 "Best-in-class for X"
392
+ Stack-fatigue reversed; buyers wanted focused tools.
393
+ Result: "the [adjective] [category] for [vertical]" replaced "all-in-one".
394
+
395
+ ## 2023 \u2014 "AI-native"
396
+ GPT-3.5 wave; everything claimed AI even when it was a wrapper.
397
+ Result: skepticism by mid-2024; AI claims now require demonstrated trade-offs.
398
+
399
+ ## 2024 \u2014 "Replace your [old tool]"
400
+ Direct displacement framing. Worked for late-comers in mature categories.
401
+
402
+ ## 2026 \u2014 "We don't ship a [thing]"
403
+ Reactive positioning \u2014 define yourself by what you refused to build.
404
+ Most credible when accompanied by a concrete reason (compliance, philosophy).
405
+
406
+ ## Pattern
407
+ Positioning rotates roughly every 18-24 months. The current peak narrative is the most-imitated; the next winner is usually the inverse of the saturated one.
408
+ `,
409
+ "KNOWLEDGE.md": '---\nschema: knowledge.workspace/v1\nname: marketing-corpus\ntitle: Marketing Expert Corpus\ndescription: |\n Expert marketing knowledge for autonomous agents. Composes AIP-10 (knowledge),\n AIP-12 (playbooks), AIP-18 (curation collections), AIP-9 (operators),\n AIP-15 (workflows), and AIP-41 (routines) into an autonomous improvement loop.\nversion: 1.0.0\nentityTypes:\n - { name: Principle, description: "Durable expert rule" }\n - { name: Example, description: "Concrete source-derived example" }\n - { name: Pattern, description: "Reusable transferable mechanic" }\n - { name: Critique, description: "Negative example or failure mode" }\n - { name: Summary, description: "Compressed source synthesis" }\n - { name: Timeline, description: "Time-sensitive trend evolution" }\n - { name: PlaybookCase, description: "Documented case study of a great playbook" }\nsources:\n retention: forever\n signing: optional\n hashAlgo: sha256\n authorityDefault: secondary\nlints:\n - { id: require-source-on-examples, kind: require-source, appliesTo: Example, severity: error }\n - { id: min-confidence-principles, kind: min-confidence, appliesTo: Principle, severity: warn, params: { min: 0.6 } }\n - { id: max-age-timelines, kind: max-age, appliesTo: Timeline, severity: warn, params: { days: 730 } }\n - { id: max-age-summaries, kind: max-age, appliesTo: Summary, severity: warn, params: { days: 180 } }\n - { id: broken-ref-all, kind: broken-ref, appliesTo: "*", severity: error }\n - { id: orphan-all, kind: orphan, appliesTo: "*", severity: info }\ncuration:\n tone: "neutral, expert, source-backed"\n depth: medium\n autoLink: byName\n conflictResolution: authority\nqueryHints:\n preferRecent: true\n preferAuthoritative: true\nmetadata:\n corpus:\n version: 1\n domain: marketing\n autoPromote:\n enabled: true\n requires:\n qualityScore: { min: 4.2 }\n riskScore: { max: 1.5 }\n hasArchiveHash: true\n requiredFields: [why_it_works, transferable_pattern, use_when, avoid_when]\n notRestricted: true\n temporal:\n defaultHalfLifeDays: 180\n scoreFormula: max-mention-decay\n retrievalBoosts:\n qualityScore: { weight: 0.30 }\n temporalScore: { weight: 0.20 }\n mentionCount: { weight: 0.10 }\n confidence: { weight: 0.15 }\n retrievalDefaults:\n status: active\n minQualityScore: 3.5\n minTemporalScore: 0.1\n accessModes:\n read: { allowedRoles: ["*"] }\n cite: { allowedRoles: ["*"] }\n flag-learning: { allowedRoles: ["*"], rateLimit: { perOperator: 20, window: "24h" } }\n curate: { allowedRoles: [corpus-curator, admin] }\n promote: { allowedRoles: [corpus-curator, admin] }\n activate-playbook: { allowedRoles: [corpus-curator, admin], requireApproval: true }\n admin-reindex: { allowedRoles: [admin] }\n bypass-default-filters: { allowedRoles: [corpus-curator, admin], audit: true }\n---\n\n# Marketing Corpus\n\nSource-of-truth for autonomous marketing agents. Composes AgentProto AIPs into a closed-loop knowledge-improvement system.\n\n## Three loops\n- **Knowledge curation** \u2014 gap-finder \u2192 curator \u2192 entries\n- **Playbook evolution** \u2014 gap \u2192 AIP-12 shadow playbook \u2192 evaluator \u2192 active|archived\n- **Retrieval-quality feedback** \u2014 every query logged; `utility` + `lift` written back to entries\n\nAll corpus-specific policy lives under `metadata.corpus.*`. AIP amendments (A1-A8) may hoist specific fields to first-class later \u2014 strictly additive, no rip-and-replace.\n',
410
+ "operators/corpus-curator/OPERATOR.md": '---\nname: Corpus Curator\nid: corpus-curator\npersona_summary: Promotes approved candidates to AIP-10 entries, maintains _index.md, handles deprecation + supersession. The corpus\'s editor-in-chief.\nversion: "1.0.0"\nprofile:\n role: |\n Promote candidates that pass the auto-promote gate. Review the\n human-review queue, decide approve/reject/needs-work. Keep the\n corpus tidy: dedupe, deprecate stale entries, resolve\n contradictions.\n voice: |\n Direct, decisive, opinionated about quality bar. First-person\n plural for company voice. Cites specific entry slugs when\n discussing deprecation or supersession.\n boundaries:\n - Never promote an entry that fails the auto-promote gate without explicit bypass.\n - Never deprecate without a written reason in metadata.corpus.archiveReason.\n - Always preserve the audit chain \u2014 _log.md events are append-only.\ngovernance:\n audit_log: "audit:corpus/marketing/_log.md"\n autonomy: autonomous\n policies:\n - "policy:corpus/marketing/curation"\nskills:\n - source-analysis\n - taxonomy\n - editorial-judgment\ntools:\n - corpus-promote-candidate\n - corpus-activate-playbook\n - corpus-archive-playbook\n - corpus-log-event\n - knowledge-query\nparticipation:\n mode: proactive\nmemory:\n kind: operator-context\nruntime:\n kind: in-process\ntags: [marketing, curator, corpus]\nmetadata:\n corpus:\n domain: marketing\n overlays:\n policy: open\n maxActiveCount: 10\n---\n\n# Corpus Curator\n\nRuns after the reviewer scores a candidate. Promotes auto-approved entries; queues human-review-required candidates for the team. Also drives playbook lifecycle (`activate` / `archive`).\n',
411
+ "operators/gap-finder/OPERATOR.md": '---\nname: Gap Finder\nid: gap-finder\npersona_summary: Mines low-scoring eval-cases for systematic weaknesses in the corpus. Opens corpus-gap items so the scout knows what to look for next.\nversion: "1.0.0"\nprofile:\n role: |\n Read recent eval-case results, identify recurring failure modes,\n classify them (generic-output, weak-strategy, stale-reference,\n poor-style, missing-domain-context), and open corpus-gap items\n with priority based on frequency.\n voice: |\n Diagnostic, pattern-oriented, prescriptive. Says "we have N\n failures of kind X" not "the agent sometimes struggles".\n Recommends a concrete next scouting target.\n boundaries:\n - Never open a gap on a single low-score case \u2014 require \u22653 occurrences.\n - Never blame the operator \u2014 gaps describe missing knowledge, not bad reasoning.\n - Always link the eval-case refs that motivated the gap.\ngovernance:\n audit_log: "audit:corpus/marketing/_log.md"\n autonomy: autonomous\nskills:\n - source-analysis\n - pattern-recognition\ntools:\n - corpus-log-event\n - knowledge-query\nparticipation:\n mode: proactive\nmemory:\n kind: operator-context\nruntime:\n kind: in-process\ntags: [marketing, gap-finder, corpus]\nmetadata:\n corpus:\n domain: marketing\n---\n\n# Gap Finder\n\nRuns monthly (via `monthly-eval-gap-finder` routine). Scans the last 30 days of `eval-case` results, finds clusters of failure, opens `corpus-gap/*/ITEM.md` items with `weaknessType` + `priority`. The scout reads these to prioritize the next harvest.\n',
412
+ "operators/marketing-analyst/OPERATOR.md": '---\nname: Marketing Analyst\nid: marketing-analyst\npersona_summary: Senior marketing analyst who converts raw social/web sources into expert principles, patterns, and critiques for the marketing corpus.\nversion: "1.0.0"\nprofile:\n role: |\n Convert candidate sources discovered by the scout into corpus-grade\n expert analysis: principles, patterns, critiques. Score quality and\n risk to inform promotion gates.\n voice: |\n Concrete, source-backed, never superlative. Cite specific numbers and\n named entities. First-person plural ("we") for company voice.\n boundaries:\n - Never invent quantitative claims; cite a source or mark as opinion.\n - Never promote without quality-reviewer signoff (unless auto-promote gates pass).\n - Never edit raw sources \u2014 only entries.\ngovernance:\n audit_log: "audit:corpus/marketing/_log.md"\n autonomy: supervised\n policies:\n - "policy:corpus/marketing/curation"\nskills:\n - source-analysis\n - copywriting\ntools:\n - corpus-flag-learning\n - knowledge-query\nparticipation:\n mode: proactive\nmemory:\n kind: operator-context\nruntime:\n kind: in-process\ntags: [marketing, analyst, corpus]\nmetadata:\n corpus:\n domain: marketing\n knowledgeViews:\n - corpus: marketing\n filter:\n domain: [marketing]\n minQualityScore: 3.5\n defaultBoosts:\n qualityScore: { weight: 0.40 }\n temporalScore: { weight: 0.30 }\n overlays:\n policy: gated\n maxActiveCount: 5\n requireApprovalFrom: corpus-curator\n allowedKinds: [overlay, block-replacement]\n---\n\n# Marketing Analyst\n\nReads candidate sources from the scout, writes expert analysis as AIP-10 entries. Scores quality and risk. Signals the curator on auto-promote gate pass.\n',
413
+ "operators/playbook-evaluator/OPERATOR.md": "---\nname: Playbook Evaluator\nid: playbook-evaluator\npersona_summary: Runs shadow vs baseline eval batches on AIP-12 playbooks. Records winRateVsBaseline, decides promote / archive based on the playbook's auto_promote gate.\nversion: \"1.0.0\"\nprofile:\n role: |\n For every shadow playbook, run eval-cases through both arms\n (overlay applied vs operator default). Score outputs via the\n rubric the playbook's evidence[].eval-case references. Record\n metrics in metadata.corpus.shadowMetrics. Trigger curator action\n when the auto_promote.threshold is met.\n voice: |\n Quantitative, dispassionate, hypothesis-driven. States the null\n hypothesis explicitly (n, threshold, observed) before\n recommending an action.\n boundaries:\n - Never activate a playbook \u2014 that's the curator's call (audit chain).\n - Never report a winRate on n < playbook.metadata.corpus.autoPromote.minSampleSize.\n - Always run identical eval-cases on both arms (same prompts, same rubric).\ngovernance:\n audit_log: \"audit:corpus/marketing/_log.md\"\n autonomy: autonomous\nskills:\n - statistics\n - source-analysis\ntools:\n - corpus-list-playbooks\n - corpus-log-event\n - knowledge-query\nparticipation:\n mode: proactive\nmemory:\n kind: operator-context\nruntime:\n kind: in-process\ntags: [marketing, evaluator, corpus, aip-12]\nmetadata:\n corpus:\n domain: marketing\n---\n\n# Playbook Evaluator\n\nDrives the playbook side of closed loop #2 (procedure). Runs nightly (via per-playbook eval-batch routines, configured per playbook). Writes back `shadowMetrics.{sampleSize, winRateVsBaseline, lastEvaluatedAt}` to PLAYBOOK.md. When gates pass, posts a `playbook.ready-for-activation` event the curator subscribes to.\n",
414
+ "operators/quality-reviewer/OPERATOR.md": '---\nname: Quality Reviewer\nid: quality-reviewer\npersona_summary: Scores analyzed candidates against the corpus\'s quality + risk rubric. Decides promotionMode (auto vs human). Flags concerns the analyst missed.\nversion: "1.0.0"\nprofile:\n role: |\n Independent second pair of eyes on every analyzed candidate.\n Adversarial-by-design \u2014 assumes the analyst was too generous\n and looks for reasons NOT to promote.\n voice: |\n Critical, concrete, fair. Cites specific clauses of the\n candidate body, not vibes. Always proposes a concrete score\n (qualityScore 0-5, riskScore 0-5).\n boundaries:\n - Never promote on the analyst\'s authority \u2014 score and route.\n - Never auto-promote a candidate flagged as restricted / personal / legal.\n - Always justify a sub-2.0 quality score in reviewerNotes.\ngovernance:\n audit_log: "audit:corpus/marketing/_log.md"\n autonomy: supervised\n policies:\n - "policy:corpus/marketing/review-policy"\nskills:\n - source-analysis\n - critical-reading\ntools:\n - corpus-flag-learning\n - knowledge-query\nparticipation:\n mode: proactive\nmemory:\n kind: operator-context\nruntime:\n kind: in-process\ntags: [marketing, reviewer, corpus]\nmetadata:\n corpus:\n domain: marketing\n---\n\n# Quality Reviewer\n\nRuns after `marketing-analyst` produces an analyzed ITEM.md. Scores against:\n\n- **qualityScore** \u2014 accuracy, transferability, evidence\n- **riskScore** \u2014 legal/brand/compliance hazards\n- **promotionMode** \u2014 auto (gates pass) vs human (needs curator)\n',
415
+ "operators/source-scout/OPERATOR.md": '---\nname: Source Scout\nid: source-scout\npersona_summary: Curates external feeds for fresh marketing source material \u2014 TikToks, blog posts, ad creative, internal performance data \u2014 and archives the worth-keeping ones into sources/.\nversion: "1.0.0"\nprofile:\n role: |\n Discover new candidate sources for the marketing corpus. Filter\n noise vs signal at the scout stage so the analyst only sees\n promising material.\n voice: |\n Efficient, terse, evidence-first. Names URLs + numbers, not\n adjectives. Reports findings as `{source: <id>, why: <reason>}`\n triples.\n boundaries:\n - Never re-archive an already-archived source (check content_hash).\n - Never archive content with PII unless explicitly sanitized.\n - Never archive paywalled / DMCA-restricted material.\ngovernance:\n audit_log: "audit:corpus/marketing/_log.md"\n autonomy: autonomous\n policies:\n - "policy:corpus/marketing/source-policy"\nskills:\n - web-research\n - source-analysis\ntools:\n - corpus-create-candidate\n - knowledge-query\n - web-search\nparticipation:\n mode: proactive\nmemory:\n kind: operator-context\nruntime:\n kind: in-process\ntags: [marketing, scout, corpus]\nmetadata:\n corpus:\n domain: marketing\n knowledgeViews:\n - corpus: marketing\n filter:\n domain: [marketing]\n---\n\n# Source Scout\n\nRuns daily (via `daily-source-scout` routine). Fetches configured feeds, hashes content, dedups against existing sources, and writes new candidates to `_candidates.yaml`. The analyst takes over from there.\n',
416
+ "playbooks/ad-angle-generation/PLAYBOOK.md": '---\nschema: playbooks/v1\nslug: ad-angle-generation\ntitle: Ad angle generation \u2014 JTBD-grounded variants\ntargets:\n - { kind: operator, ref: marketing-analyst }\nbinds_operator: marketing-analyst\nkind: overlay\nstatus: shadow\npriority: 90\nlock_check:\n - factual-grounded\nevidence:\n - kind: run\n ref: collections/eval-case/ad-angle-suite/runs/initial\n note: First eval batch, n=20 planned\n - kind: reflection\n ref: collections/corpus-gap/generic-ad-copy/ITEM.md\n note: Gap that motivated this playbook\nttl: "P90D"\nsupersedes: []\ncreated_at: "2026-05-22T14:30:00Z"\nupdated_at: "2026-05-22T14:30:00Z"\ntags: [ads, angles, jtbd]\nmetadata:\n corpus:\n authoredBy: corpus-curator\n shadowTrafficPct: 0.10\n autoPromote:\n enabled: true\n metric: winRateVsBaseline\n threshold: { gte: 0.55 }\n minSampleSize: 30\n cooldown: "7d"\n execution: sandboxed\n---\n\n## Overlay\nWhen generating ad creative, generate 3 distinct angles before refining any single one.\n\n## Procedure\n1. Identify the JTBD (job-to-be-done) the audience hires the product for.\n2. Generate one angle per axis: outcome, pain, identity.\n3. For each angle, write a hook + body in <50 words.\n4. Score each angle on specificity + audience fit; promote the highest.\n\n## Promotion gate\nPromote shadow \u2192 active when winRateVsBaseline \u2265 0.55 over n \u2265 30 evals.\n',
417
+ "playbooks/cold-email-outbound/PLAYBOOK.md": `---
418
+ schema: playbooks/v1
419
+ slug: cold-email-outbound
420
+ title: Cold email outbound \u2014 earned-attention opener
421
+ targets:
422
+ - { kind: operator, ref: marketing-analyst }
423
+ binds_operator: marketing-analyst
424
+ kind: overlay
425
+ status: shadow
426
+ priority: 70
427
+ lock_check: []
428
+ evidence:
429
+ - kind: run
430
+ ref: collections/eval-case/cold-email-suite/runs/initial
431
+ note: First eval batch planned
432
+ ttl: "P90D"
433
+ supersedes: []
434
+ created_at: "2026-05-22T14:30:00Z"
435
+ updated_at: "2026-05-22T14:30:00Z"
436
+ tags: [cold-email, outbound, sales]
437
+ metadata:
438
+ corpus:
439
+ authoredBy: corpus-curator
440
+ shadowTrafficPct: 0.10
441
+ autoPromote:
442
+ enabled: true
443
+ metric: winRateVsBaseline
444
+ threshold: { gte: 0.55 }
445
+ minSampleSize: 30
446
+ cooldown: "7d"
447
+ execution: sandboxed
448
+ ---
449
+
450
+ ## Overlay
451
+ Cold-email opener MUST earn the reader's next 5 seconds by stating something they didn't know, not by claiming a benefit.
452
+
453
+ ## Procedure
454
+ 1. Research one specific thing about the prospect (their hire, their post, their company's recent move).
455
+ 2. State that thing in <12 words as the opener.
456
+ 3. Connect it to the offer in the next sentence \u2014 NO "I noticed you\u2026" bridge.
457
+ 4. End with one specific yes/no question.
458
+
459
+ ## Promotion gate
460
+ Promote shadow \u2192 active when winRateVsBaseline \u2265 0.55 over n \u2265 30 evals.
461
+ `,
462
+ "playbooks/competitor-positioning/PLAYBOOK.md": `---
463
+ schema: playbooks/v1
464
+ slug: competitor-positioning
465
+ title: Competitor positioning \u2014 pick your axis, name the trade
466
+ targets:
467
+ - { kind: operator, ref: marketing-analyst }
468
+ binds_operator: marketing-analyst
469
+ kind: overlay
470
+ status: shadow
471
+ priority: 80
472
+ lock_check:
473
+ - factual-grounded
474
+ - brand-voice
475
+ evidence:
476
+ - kind: run
477
+ ref: collections/eval-case/positioning-suite/runs/initial
478
+ note: First eval batch planned
479
+ ttl: "P90D"
480
+ supersedes: []
481
+ created_at: "2026-05-22T14:30:00Z"
482
+ updated_at: "2026-05-22T14:30:00Z"
483
+ tags: [positioning, competitive, differentiation]
484
+ metadata:
485
+ corpus:
486
+ authoredBy: corpus-curator
487
+ shadowTrafficPct: 0.10
488
+ autoPromote:
489
+ enabled: true
490
+ metric: winRateVsBaseline
491
+ threshold: { gte: 0.55 }
492
+ minSampleSize: 30
493
+ cooldown: "7d"
494
+ execution: sandboxed
495
+ ---
496
+
497
+ ## Overlay
498
+ Positioning copy MUST name the specific competitor weakness it's trading off against. "We're faster" is noise; "We don't ship a CLI" is positioning.
499
+
500
+ ## Procedure
501
+ 1. List the top 3 competitors by ICP overlap.
502
+ 2. For each, identify one specific decision they made that we explicitly DIDN'T.
503
+ 3. Write the positioning line as: \`For [ICP], who [problem], [product] is the [category] that [specific trade-off vs competitor]\`.
504
+ 4. Lint output against the [[weak-positioning-saas]] critique.
505
+
506
+ ## Promotion gate
507
+ Promote shadow \u2192 active when winRateVsBaseline \u2265 0.55 over n \u2265 30 evals.
508
+ `,
509
+ "playbooks/landing-page-copy/PLAYBOOK.md": `---
510
+ schema: playbooks/v1
511
+ slug: landing-page-copy
512
+ title: Landing-page copy \u2014 high-conversion structure
513
+ targets:
514
+ - { kind: operator, ref: marketing-analyst }
515
+ binds_operator: marketing-analyst
516
+ kind: overlay
517
+ status: shadow
518
+ priority: 100
519
+ lock_check:
520
+ - brand-voice
521
+ - factual-grounded
522
+ evidence:
523
+ - kind: run
524
+ ref: collections/eval-case/landing-page-copy-conversion-suite/runs/2026-05-22-batch-1
525
+ note: First shadow batch, n=30 evals, winRateVsBaseline TBD
526
+ - kind: reflection
527
+ ref: collections/corpus-gap/weak-positioning-saas/ITEM.md
528
+ note: Gap that motivated this playbook
529
+ ttl: "P90D"
530
+ supersedes: []
531
+ created_at: "2026-05-22T14:30:00Z"
532
+ updated_at: "2026-05-22T14:30:00Z"
533
+ tags: [landing-page, copy, conversion]
534
+ metadata:
535
+ corpus:
536
+ authoredBy: corpus-curator
537
+ derivedFromGap: collections/corpus-gap/weak-positioning-saas/ITEM.md
538
+ shadowTrafficPct: 0.10
539
+ autoPromote:
540
+ enabled: true
541
+ metric: winRateVsBaseline
542
+ threshold: { gte: 0.55 }
543
+ minSampleSize: 30
544
+ cooldown: "7d"
545
+ shadowMetrics:
546
+ sampleSize: 0
547
+ winRateVsBaseline: null
548
+ lastEvaluatedAt: null
549
+ archiveReason: null
550
+ execution: sandboxed
551
+ ---
552
+
553
+ ## Overlay
554
+ [Markdown that gets merged into marketing-analyst's prompt at runtime when this playbook is active. The block-replacement / overlay merge logic is the runtime's concern, not this fixture's.]
555
+
556
+ ## Procedure
557
+ 1. Read brief: ICP, offer, current page.
558
+ 2. Apply principle [[specificity-beats-superlatives]] \u2014 every superlative gets a number, date, or named entity.
559
+ 3. Generate 3 hook variants using pattern [[contrarian-short-form-hooks]].
560
+ 4. Lint output against critique [[weak-positioning-saas]].
561
+ 5. Output: H1, sub-H1, 3 CTA variants, 1 social-proof block.
562
+
563
+ ## Promotion gate
564
+ Promote shadow \u2192 active when winRateVsBaseline \u2265 0.55 over n \u2265 30 evals (see metadata.corpus.autoPromote).
565
+ `,
566
+ "playbooks/social-hook-design/PLAYBOOK.md": '---\nschema: playbooks/v1\nslug: social-hook-design\ntitle: Social hook design \u2014 pattern interrupt in 5 seconds\ntargets:\n - { kind: operator, ref: marketing-analyst }\nbinds_operator: marketing-analyst\nkind: overlay\nstatus: shadow\npriority: 95\nlock_check: []\nevidence:\n - kind: run\n ref: collections/eval-case/social-hook-suite/runs/initial\n note: First eval batch planned\n - kind: reflection\n ref: entries/patterns/2026/contrarian-short-form-hooks.md\n note: Pattern this playbook operationalizes\nttl: "P90D"\nsupersedes: []\ncreated_at: "2026-05-22T14:30:00Z"\nupdated_at: "2026-05-22T14:30:00Z"\ntags: [social, hook, short-form]\nmetadata:\n corpus:\n authoredBy: corpus-curator\n shadowTrafficPct: 0.10\n autoPromote:\n enabled: true\n metric: winRateVsBaseline\n threshold: { gte: 0.55 }\n minSampleSize: 30\n cooldown: "7d"\n execution: sandboxed\n---\n\n## Overlay\nEvery short-form hook MUST earn the next 5 seconds. State a contradiction OR a specific number OR a named entity in the first sentence.\n\n## Procedure\n1. Generate 3 hooks per outline: contradiction, number, name.\n2. Score each by surprise (1-5) + relevance (1-5).\n3. Promote the highest combined score; archive the rest as alts.\n4. Output: hook + first 3 sentences + CTA.\n\n## Promotion gate\nPromote shadow \u2192 active when winRateVsBaseline \u2265 0.55 over n \u2265 30 evals.\n',
567
+ "routines/daily-source-scout/ROUTINE.md": '---\nschema: routine/v1\nid: daily-source-scout\ndescription: |\n Daily routine that runs the source-scout operator to discover new\n candidate sources across configured external feeds. Discovered sources\n are archived under sources/ and rows appended to _candidates.yaml.\nversion: "1.0.0"\nschedule:\n kind: cron\n cron: "0 9 * * *"\n timezone: "UTC"\n catchup: skip\ntarget:\n workflow: ingest-source\n inputs:\n feeds: [tiktok-curated, hubspot-blog, reddit-marketing]\n maxItemsPerRun: 50\nretry:\n max_attempts: 3\n backoff: exponential\non_failure:\n create_work_item: true\n fire_event: corpus.scout.failed\nfires_events:\n - corpus.scout.completed\n - corpus.candidate.discovered\nenabled: true\ntags: [corpus, scout, daily]\nmetadata:\n corpus:\n domain: marketing\n---\n\n# Daily Source Scout\n\nRuns every morning at 09:00 UTC. Scouts external feeds for new candidate sources, archives them, and appends to `_candidates.yaml`. The candidate event downstream triggers `analyze-candidate` workflow.\n',
568
+ "routines/monthly-eval-gap-finder/ROUTINE.md": '---\nschema: routine/v1\nid: monthly-eval-gap-finder\ndescription: |\n Monthly gap-finder run \u2014 reads the last 30 days of eval-case\n failures, clusters them, opens corpus-gap items for the scout.\n Closes loop #3 by turning observed weaknesses into next-harvest\n priorities.\nversion: "1.0.0"\nschedule:\n kind: cron\n cron: "0 8 1 * *"\n timezone: "UTC"\n catchup: skip\ntarget:\n workflow: detect-corpus-gaps\n inputs:\n windowDays: 30\n minOccurrences: 3\nretry:\n max_attempts: 2\n backoff: exponential\non_failure:\n create_work_item: true\n fire_event: corpus.gap-finder.failed\nfires_events:\n - corpus.gap-finder.completed\n - corpus.gap.opened\nenabled: true\ntags: [corpus, gaps, monthly]\nmetadata:\n corpus:\n domain: marketing\n---\n\n# Monthly Eval Gap Finder\n\nFirst day of each month, 08:00 UTC. Reads aggregated eval-case results, clusters failure modes, opens `corpus-gap/*/ITEM.md` items.\n',
569
+ "routines/quarterly-archive-cleanup/ROUTINE.md": '---\nschema: routine/v1\nid: quarterly-archive-cleanup\ndescription: |\n Quarterly storage hygiene \u2014 migrate sources older than 6 months\n to sources/cold/, hard-delete archived entries past their\n retention window, prune orphaned _candidates.yaml rows.\nversion: "1.0.0"\nschedule:\n kind: cron\n cron: "0 6 1 1,4,7,10 *"\n timezone: "UTC"\n catchup: skip\ntarget:\n workflow: corpus-archive-cleanup\nretry:\n max_attempts: 1\n backoff: fixed\non_failure:\n create_work_item: true\n fire_event: corpus.archive-cleanup.failed\nfires_events:\n - corpus.archive-cleanup.completed\nenabled: true\ntags: [corpus, archive, quarterly, maintenance]\nmetadata:\n corpus:\n domain: marketing\n---\n\n# Quarterly Archive Cleanup\n\nFirst day of every quarter at 06:00 UTC. Migrates aging sources to cold storage (still under `sources/cold/` for AIP-10 path resolvability), and prunes terminal-status candidates beyond retention.\n',
570
+ "routines/weekly-corpus-curation/ROUTINE.md": '---\nschema: routine/v1\nid: weekly-corpus-curation\ndescription: |\n Weekly curator pass \u2014 review the human-review queue, promote\n what\'s ready, deprecate what\'s stale, archive playbooks whose\n shadow eval has converged.\nversion: "1.0.0"\nschedule:\n kind: cron\n cron: "0 10 * * 1"\n timezone: "UTC"\n catchup: skip\ntarget:\n workflow: review-candidate\n inputs:\n mode: batch\n maxItems: 50\nretry:\n max_attempts: 2\n backoff: exponential\non_failure:\n create_work_item: true\n fire_event: corpus.curation.weekly-failed\nfires_events:\n - corpus.curation.weekly-completed\nenabled: true\ntags: [corpus, curation, weekly]\nmetadata:\n corpus:\n domain: marketing\n---\n\n# Weekly Corpus Curation\n\nMonday 10:00 UTC. The curator runs through the corpus-review queue, promotes approved candidates, deprecates stale entries. Pairs with `daily-source-scout` (which fills the pipeline).\n',
571
+ "sources/fresh/tiktok-hook-2026-05.md": `---
572
+ schema: knowledge.source/v1
573
+ id: tiktok-hook-2026-05
574
+ path: sources/fresh/tiktok-hook-2026-05.md
575
+ title: TikTok contrarian hook example \u2014 May 2026
576
+ captured_at: "2026-05-22T14:30:00Z"
577
+ captured_by: source-scout
578
+ content_hash: sha256:abc1234567890def1234567890abcdef1234567890abcdef1234567890abcdef
579
+ authority: secondary
580
+ language: en
581
+ tags: [tiktok, hook, short-form, contrarian]
582
+ metadata:
583
+ corpus:
584
+ originalUrl: https://example.com/tiktok/123
585
+ archiveTier: hot
586
+ archivedBy: source-scout
587
+ snapshotPath: sources/fresh/tiktok-hook-2026-05.snapshot.mhtml
588
+ ---
589
+
590
+ # TikTok hook \u2014 "Most marketers are doing X. Here's why they're wrong."
591
+
592
+ Captured from a top-performing TikTok in May 2026. The hook contradicts a widely-held belief, generates 8x average engagement on the channel, and converts at 3x baseline for the SaaS product mentioned.
593
+
594
+ ## Transcript
595
+ > Everyone says you should write listicles. But the truth is \u2014 and this took me three years to figure out \u2014 every viral piece I've ever written started with one specific contradiction\u2026
596
+
597
+ ## Performance
598
+ - Views: 1.2M
599
+ - Engagement rate: 18.4% (channel avg: 2.3%)
600
+ - CTR to product: 4.1% (channel avg: 0.8%)
601
+ `,
602
+ "workflows/analyze-candidate/WORKFLOW.md": '---\nname: Analyze Corpus Candidate\nid: analyze-candidate\ndescription: |\n Convert a discovered corpus candidate into an analyzed ITEM.md with\n expert analysis, quality score, and risk score. Triggered by the\n source-scout when it appends a row to _candidates.yaml.\nversion: "1.0.0"\ninputs:\n type: object\n required: [candidateId, sourcePath]\n properties:\n candidateId: { type: string, pattern: "^[a-z0-9][a-z0-9-]*$" }\n sourcePath: { type: string }\noutputs:\n type: object\n required: [itemPath, status]\n properties:\n itemPath: { type: string }\n status: { type: string, enum: [analyzed, rejected, needs-work] }\n qualityScore: { type: number }\n riskScore: { type: number }\nsteps:\n - id: load-source\n kind: tool\n tool: knowledge.read_source\n name: Load source bytes from sources/\n inputs: { type: object, properties: { sourceId: { type: string } } }\n next: analyze\n - id: analyze\n kind: tool\n tool: marketing-analyst.analyze\n name: Run marketing-analyst operator over the source\n next: score\n - id: score\n kind: tool\n tool: quality-reviewer.score\n name: Compute quality + risk scores\n next: gate\n - id: gate\n kind: branch\n name: Decide promotionMode (auto vs human)\n description: Check auto-promote gate against KNOWLEDGE.md.metadata.corpus.autoPromote\n branches:\n - { when: "output.qualityScore >= 4.2 && output.riskScore <= 1.5", next: "auto-promote" }\n - { when: "true", next: "human-review" }\n - id: auto-promote\n kind: tool\n tool: corpus-curator-promote\n name: Promote to AIP-10 entry\n - id: human-review\n kind: approval\n name: Queue for human curator\n prompt: Review and approve or reject this candidate.\n approvers:\n - { role: corpus-curator }\ntags: [corpus, workflow, analysis]\nmetadata:\n corpus:\n domain: marketing\n triggeredBy: source-scout\n---\n\n# Analyze Candidate workflow\n\nConverts a discovered candidate into an analyzed ITEM.md. The marketing-analyst operator runs the actual analysis; this workflow orchestrates the pipeline (load \u2192 analyze \u2192 score \u2192 gate).\n',
603
+ "workflows/detect-corpus-gaps/WORKFLOW.md": '---\nname: Detect corpus gaps\nid: detect-corpus-gaps\ndescription: |\n Scan the last 30 days of eval-case failures, cluster by\n weakness type, open corpus-gap items with priority. Drives the\n scout\'s next harvest.\nversion: "1.0.0"\ninputs:\n type: object\n properties:\n windowDays: { type: integer, minimum: 1, maximum: 365, default: 30 }\n minOccurrences: { type: integer, minimum: 1, default: 3 }\noutputs:\n type: object\n required: [gapsOpened]\n properties:\n gapsOpened: { type: integer }\n clusters: { type: array }\nsteps:\n - id: load-failures\n kind: tool\n tool: corpus-load-eval-failures\n name: Load last-N-days eval failures\n - id: cluster\n kind: tool\n tool: gap-finder-cluster\n name: Cluster failures by weakness type + recurrence\n - id: open-gaps\n kind: map\n over: "steps.cluster.output.clusters"\n steps:\n - { id: open, kind: tool, tool: corpus-open-gap }\ntags: [corpus, gaps]\nmetadata:\n corpus:\n domain: marketing\n triggeredBy: gap-finder\n---\n\n# Detect corpus gaps workflow\n\nRuns monthly. Reads eval-case results, clusters failures, opens `corpus-gap/*/ITEM.md` items for the scout to read.\n',
604
+ "workflows/evaluate-agent-output/WORKFLOW.md": `---
605
+ name: Evaluate agent output
606
+ id: evaluate-agent-output
607
+ description: |
608
+ Score an agent output against a rubric via the pluggable
609
+ IEvaluator (M9). Wins seed flagCorpusLearning candidates;
610
+ losses feed detect-corpus-gaps.
611
+ version: "1.0.0"
612
+ inputs:
613
+ type: object
614
+ required: [prompt, response, rubricSlug]
615
+ properties:
616
+ prompt: { type: string }
617
+ response: { type: string }
618
+ rubricSlug: { type: string }
619
+ operatorRef: { type: string }
620
+ conversationId: { type: string }
621
+ retrievedHits:
622
+ type: array
623
+ items: { type: object }
624
+ outputs:
625
+ type: object
626
+ required: [score]
627
+ properties:
628
+ score: { type: number }
629
+ dimensions: { type: object }
630
+ rationale: { type: string }
631
+ routedAs: { type: string, enum: [win, loss, neutral] }
632
+ steps:
633
+ - id: evaluate
634
+ kind: tool
635
+ tool: evaluator-evaluate
636
+ name: Run IEvaluator against the rubric
637
+ - id: classify
638
+ kind: branch
639
+ name: Route win / loss / neutral
640
+ branches:
641
+ - { when: "output.score >= 0.7", next: "as-win" }
642
+ - { when: "output.score < 0.4", next: "as-loss" }
643
+ - { when: "true", next: "as-neutral" }
644
+ - id: as-win
645
+ kind: tool
646
+ tool: flagCorpusLearning
647
+ name: Seed a candidate from the winning trace
648
+ - id: as-loss
649
+ kind: tool
650
+ tool: corpus-record-eval-failure
651
+ name: Add to the eval-failure log for gap-finder
652
+ - id: as-neutral
653
+ kind: tool
654
+ tool: corpus-log-event
655
+ name: Log neutral outcome (no candidate spawn)
656
+ tags: [corpus, eval, telemetry]
657
+ metadata:
658
+ corpus:
659
+ domain: marketing
660
+ requires:
661
+ pluggable: [evaluator]
662
+ ---
663
+
664
+ # Evaluate agent output workflow
665
+
666
+ Closes loop #3 (retrieval quality). Every agent output that's worth evaluating runs through this. Win / loss / neutral routing feeds the curation queue + the gap finder.
667
+ `,
668
+ "workflows/ingest-source/WORKFLOW.md": '---\nname: Ingest source\nid: ingest-source\ndescription: |\n Fetch + hash + dedup + archive a single source. Output: a new\n candidate row in _candidates.yaml (or no-op if duplicate).\nversion: "1.0.0"\ninputs:\n type: object\n required: [sourceUrl]\n properties:\n sourceUrl: { type: string }\n category: { type: string, enum: [fresh, classic, competitors, internal, performance] }\noutputs:\n type: object\n required: [outcome]\n properties:\n outcome: { type: string, enum: [archived, duplicate, rejected] }\n sourceId: { type: string }\n candidateId: { type: string }\nsteps:\n - id: fetch\n kind: tool\n tool: web-fetch\n name: Fetch source content\n - id: hash\n kind: tool\n tool: hash-content\n name: Compute sha256 content_hash\n - id: dedup\n kind: branch\n name: Dedup against existing sources\n branches:\n - { when: "output.duplicate === true", next: "done-dup" }\n - { when: "true", next: "archive" }\n - id: archive\n kind: tool\n tool: corpus-archive-source\n name: Write source frontmatter + body to sources/<category>/<slug>.md\n - id: create-candidate\n kind: tool\n tool: createCorpusCandidate\n name: Append discovered row to _candidates.yaml\n - id: done-dup\n kind: tool\n tool: corpus-log-event\n name: Log dedup hit (no-op outcome)\ntags: [corpus, ingest, scout]\nmetadata:\n corpus:\n domain: marketing\n triggeredBy: source-scout\n---\n\n# Ingest source workflow\n\nStep 1 of the corpus loop. Single-source entry point. Called by `daily-source-scout` once per discovered URL.\n',
669
+ "workflows/promote-corpus-item/WORKFLOW.md": '---\nname: Promote corpus item\nid: promote-corpus-item\ndescription: |\n Lift an approved candidate into a published AIP-10 entry. Writes\n the entry file, regenerates _index.md, ships chunks to the\n backing engine, appends a promotion event. Wraps the kit\'s\n CorpusPromoter.promote().\nversion: "1.0.0"\ninputs:\n type: object\n required: [candidateId, entrySlug, entryKind, entryPath, frontmatter, body]\n properties:\n candidateId: { type: string }\n entrySlug: { type: string }\n entryKind: { type: string, enum: [principle, example, pattern, critique, summary, timeline, playbook] }\n entryPath: { type: string }\n frontmatter: { type: object }\n body: { type: string }\n bypassGate: { type: boolean }\noutputs:\n type: object\n required: [entryPath, gatePassed]\n properties:\n entryPath: { type: string }\n versionToken: { type: string }\n chunkCount: { type: integer }\n gatePassed: { type: boolean }\n bypassed: { type: boolean }\nsteps:\n - id: promote\n kind: tool\n tool: promoteCorpusCandidate\n name: Atomic promote (lock + write + index + chunks + event)\ntags: [corpus, promote]\nmetadata:\n corpus:\n domain: marketing\n triggeredBy: corpus-curator\n---\n\n# Promote corpus item workflow\n\nStep 4 of the corpus loop. Single-step wrapper for callers that want the workflow shape; the underlying `CorpusPromoter` does the multi-file transaction.\n',
670
+ "workflows/review-candidate/WORKFLOW.md": '---\nname: Review analyzed candidate\nid: review-candidate\ndescription: |\n Score an analyzed candidate (quality + risk), set promotionMode,\n route to auto-promote or human-review queue.\nversion: "1.0.0"\ninputs:\n type: object\n required: [candidateId]\n properties:\n candidateId: { type: string }\noutputs:\n type: object\n required: [decision]\n properties:\n decision: { type: string, enum: [auto-promote, queue-review, reject] }\n qualityScore: { type: number }\n riskScore: { type: number }\nsteps:\n - id: load\n kind: tool\n tool: corpus-load-candidate\n name: Load candidate ITEM.md\n - id: score\n kind: tool\n tool: quality-reviewer-score\n name: Compute qualityScore + riskScore via reviewer operator\n - id: gate\n kind: branch\n name: Auto-promote gate\n branches:\n - { when: "output.qualityScore >= 4.2 && output.riskScore <= 1.5", next: "auto-promote" }\n - { when: "output.qualityScore < 2.0 || output.riskScore > 3.0", next: "reject" }\n - { when: "true", next: "queue-review" }\n - id: auto-promote\n kind: tool\n tool: promoteCorpusCandidate\n name: Promote without human gate\n - id: queue-review\n kind: tool\n tool: corpus-route-to-review\n name: Move ITEM.md to corpus-review collection\n - id: reject\n kind: tool\n tool: corpus-log-event\n name: Log corpus.candidate.rejected with reason\ntags: [corpus, review]\nmetadata:\n corpus:\n domain: marketing\n triggeredBy: marketing-analyst\n---\n\n# Review candidate workflow\n\nStep 3 of the corpus loop (after `analyze-candidate`). Reviewer scores and routes.\n',
671
+ "workflows/update-corpus-index/WORKFLOW.md": '---\nname: Update corpus index\nid: update-corpus-index\ndescription: |\n Regenerate _index.md (faceted catalog) from the current set of\n active entries. Triggered on promotion, deprecation, or\n status changes; can also run on demand.\nversion: "1.0.0"\ninputs:\n type: object\n properties:\n reason: { type: string, enum: [promoted, deprecated, archived, manual] }\noutputs:\n type: object\n required: [entryCount]\n properties:\n entryCount: { type: integer }\n indexBytes: { type: integer }\nsteps:\n - id: snapshot\n kind: tool\n tool: corpus-read-snapshot\n name: Read current workspace snapshot\n - id: regen\n kind: tool\n tool: corpus-regen-index\n name: Write _index.md from active entries (kind facets)\n - id: log\n kind: tool\n tool: corpus-log-event\n name: Log corpus.entry.indexed event\ntags: [corpus, index]\nmetadata:\n corpus:\n domain: marketing\n---\n\n# Update corpus index workflow\n\nMaintenance workflow \u2014 keeps `_index.md` in sync with the entries directory. The promote workflow inlines this; standalone version is for drift recovery.\n'
672
+ });
673
+
674
+ // src/marketing/index.ts
675
+ var MarketingCorpusPreset = Object.freeze({
676
+ slug: "marketing",
677
+ title: "Marketing Expert Corpus",
678
+ description: "Autonomous marketing knowledge \u2014 principles, patterns, critiques, playbooks. Composes AIP-10/12/18/9/15/41 into a closed-loop improvement system.",
679
+ files: MARKETING_PRESET_FILES
680
+ });
681
+
682
+ export { MARKETING_PRESET_FILES, MarketingCorpusPreset };
683
+ //# sourceMappingURL=index.mjs.map
684
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/marketing/files.ts","../../src/marketing/index.ts"],"names":[],"mappings":";;;;;;AAQO,IAAM,sBAAA,GAA2D,OAAO,MAAA,CAAO;AAAA,EACpF,4CAAA,EAA8C,q6DAAA;AAAA,EAC9C,0DAAA,EAA4D,+oCAAA;AAAA,EAC5D,iDAAA,EAAmD,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,EACnD,oDAAA,EAAsD,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,EACtD,sDAAA,EAAwD,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,EACxD,4CAAA,EAA8C,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,EAC9C,qDAAA,EAAuD,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,EACvD,2DAAA,EAA6D,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,EAC7D,gDAAA,EAAkD,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AAAA,EAClD,6DAAA,EAA+D,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AAAA,EAC/D,cAAA,EAAgB,uhHAAA;AAAA,EAChB,sCAAA,EAAwC,grDAAA;AAAA,EACxC,kCAAA,EAAoC,kiDAAA;AAAA,EACpC,yCAAA,EAA2C,mxDAAA;AAAA,EAC3C,0CAAA,EAA4C,wuDAAA;AAAA,EAC5C,wCAAA,EAA0C,yiDAAA;AAAA,EAC1C,oCAAA,EAAsC,wjDAAA;AAAA,EACtC,2CAAA,EAA6C,24CAAA;AAAA,EAC7C,2CAAA,EAA6C,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AAAA,EAC7C,8CAAA,EAAgD,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AAAA,EAChD,yCAAA,EAA2C,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AAAA,EAC3C,0CAAA,EAA4C,05CAAA;AAAA,EAC5C,wCAAA,EAA0C,6gCAAA;AAAA,EAC1C,6CAAA,EAA+C,i7BAAA;AAAA,EAC/C,+CAAA,EAAiD,i7BAAA;AAAA,EACjD,4CAAA,EAA8C,65BAAA;AAAA,EAC9C,sCAAA,EAAwC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,EACxC,yCAAA,EAA2C,koEAAA;AAAA,EAC3C,0CAAA,EAA4C,8qCAAA;AAAA,EAC5C,6CAAA,EAA+C,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA,CAAA;AAAA,EAC/C,qCAAA,EAAuC,ukDAAA;AAAA,EACvC,2CAAA,EAA6C,w5CAAA;AAAA,EAC7C,wCAAA,EAA0C,4mDAAA;AAAA,EAC1C,2CAAA,EAA6C;AAC/C,CAAC;;;ACvBM,IAAM,qBAAA,GAAsC,OAAO,MAAA,CAAO;AAAA,EAC/D,IAAA,EAAM,WAAA;AAAA,EACN,KAAA,EAAO,yBAAA;AAAA,EACP,WAAA,EACE,wJAAA;AAAA,EACF,KAAA,EAAO;AACT,CAAC","file":"index.mjs","sourcesContent":["/**\n * AUTO-GENERATED build artifact — DO NOT COMMIT, DO NOT EDIT.\n *\n * Regenerated from @agentproto/corpus/test/fixtures/marketing/\n * by the prebuild / precheck-types / pretest / predev hooks on\n * this package. To change the preset content, edit the fixtures.\n */\n\nexport const MARKETING_PRESET_FILES: Readonly<Record<string, string>> = Object.freeze({\n \"collections/corpus-candidate/COLLECTION.md\": \"---\\nschema: collection.schema/v1\\nname: corpus-candidate\\ntitle: Corpus Candidate\\ndescription: |\\n Candidate corpus item awaiting analysis and promotion to an AIP-10 entry.\\n Discovered candidates live in `_candidates.yaml` sidecar; materialized\\n ITEM.md files appear only after transition out of `discovered`.\\nversion: 1.0.0\\ninitialStatus: discovered\\nstatuses:\\n - { id: discovered, label: Discovered, transitionsTo: [analyzed, rejected] }\\n - { id: analyzed, label: Analyzed, transitionsTo: [approved, rejected, needs-work] }\\n - { id: needs-work, label: Needs Work, transitionsTo: [analyzed, rejected] }\\n - { id: approved, label: Approved, terminal: true }\\n - { id: rejected, label: Rejected, terminal: true }\\nidentity:\\n slugSource: id\\n filingPath: \\\"collections/corpus-candidate/{slug}/ITEM.md\\\"\\nfields:\\n - { name: sourcePath, type: string, required: true }\\n - { name: sourceUrl, type: url }\\n - { name: targetEntryPath, type: string }\\n - { name: corpusKind, type: enum, enum: [principle, example, pattern, critique, summary, timeline, playbook], required: true }\\n - { name: qualityScore, type: number }\\n - { name: riskScore, type: number }\\n - { name: promotionMode, type: enum, enum: [auto, human] }\\n - { name: contentHash, type: string }\\n - { name: reviewerNotes, type: text }\\nlints:\\n - { id: required-field-source-path, kind: required-field, appliesTo: \\\"*\\\", severity: error, params: { fields: [sourcePath] } }\\n - { id: required-field-corpus-kind, kind: required-field, appliesTo: \\\"*\\\", severity: error, params: { fields: [corpusKind] } }\\nmetadata:\\n corpus:\\n description: Used by source-scout (writes), marketing-analyst (writes), quality-reviewer (scores), corpus-curator (promotes).\\n---\\n\\n# Corpus Candidate collection\\n\\nHolds candidates discovered by the scout, analyzed by the analyst, scored by the reviewer, and promoted by the curator. State machine enforced by `statuses[].transitionsTo`.\\n\",\n \"collections/corpus-candidate/tiktok-hook-2026-05/ITEM.md\": \"---\\nschema: collection.item/v1\\ncollection: corpus-candidate\\nid: tiktok-hook-2026-05\\ntitle: TikTok contrarian hook pattern\\nstatus: analyzed\\nsourcePath: sources/fresh/tiktok-hook-2026-05.md\\nsourceUrl: https://example.com/tiktok/123\\ntargetEntryPath: entries/patterns/2026/contrarian-short-form-hooks.md\\ncorpusKind: pattern\\ncontentHash: sha256:abc1234567890def1234567890abcdef1234567890abcdef1234567890abcdef\\ntags: [short-form, hooks]\\ncreatedAt: \\\"2026-05-22T14:30:00Z\\\"\\nupdatedAt: \\\"2026-05-22T15:00:00Z\\\"\\nmetadata:\\n corpus:\\n qualityScore: 4.3\\n riskScore: 1.1\\n promotionMode: auto\\n---\\n\\n# Candidate: TikTok contrarian hook\\n\\nCandidate extracted from fresh social examples. The pattern (contrarian belief-flip in <5s hooks) generalizes across short-form channels. Analyst recommends auto-promotion.\\n\\n## Analysis\\n- Pattern present in 6 of 10 top-performing TikToks reviewed\\n- Transferable to Reels, Shorts, cold-email subject lines\\n- No risk of legal / brand misuse identified\\n\\n## Decision\\n- promotionMode: auto\\n- gates pass: qualityScore 4.3 ≥ 4.2, riskScore 1.1 ≤ 1.5, archive hash present, all required fields populated\\n\",\n \"entries/critiques/2026/weak-positioning-saas.md\": \"---\\nschema: knowledge.entry/v1\\nslug: weak-positioning-saas\\nkind: critique\\ntitle: Weak positioning — \\\"powerful platform for X\\\"\\nupdated_at: \\\"2026-05-22T14:30:00Z\\\"\\nsources:\\n - tiktok-hook-2026-05\\nconfidence: 0.85\\ntags: [positioning, anti-pattern, saas]\\nmetadata:\\n corpus:\\n status: active\\n qualityScore: 4.1\\n riskScore: 1.2\\n domain: marketing\\n funnelStage: consideration\\n temporal:\\n firstSeen: \\\"2024-08-01T00:00:00Z\\\"\\n lastSeen: \\\"2026-05-22T14:30:00Z\\\"\\n mentions:\\n - { at: \\\"2024-08-01T00:00:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 0.7 }\\n - { at: \\\"2026-05-22T14:30:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 1.0 }\\n promotionMode: human\\n promotedAt: \\\"2026-05-22T14:30:00Z\\\"\\n promotedBy: corpus-curator\\n---\\n\\n## What's wrong\\n\\\"Powerful platform for [audience]\\\" makes zero claims. It's substitutable for any competitor's homepage.\\n\\n## Why it fails\\n- No specific outcome promised\\n- No specific cost / friction acknowledged\\n- No specific audience excluded\\n- Reader can't tell if it's for them\\n\\n## How to fix\\nReplace with: \\\"[outcome] for [specific audience] without [specific pain]\\\". E.g. \\\"Ship marketing copy in 10 minutes, not 10 days — without hiring a copywriter\\\".\\n\\n## Use this critique when\\n- Reviewing landing-page hero copy\\n- Reviewing PRD positioning sections\\n- Onboarding a new marketing-analyst operator\\n\",\n \"entries/examples/2026/apple-2007-iphone-keynote.md\": \"---\\nschema: knowledge.entry/v1\\nslug: apple-2007-iphone-keynote\\nkind: example\\ntitle: Apple 2007 iPhone keynote — three-products framing\\nupdated_at: \\\"2026-05-22T14:30:00Z\\\"\\nsources:\\n - tiktok-hook-2026-05\\nconfidence: 0.92\\ntags: [keynote, framing, apple, launch]\\nmetadata:\\n corpus:\\n status: active\\n qualityScore: 4.7\\n riskScore: 0.3\\n domain: marketing\\n channel: keynote\\n funnelStage: awareness\\n temporal:\\n firstSeen: \\\"2024-01-09T00:00:00Z\\\"\\n lastSeen: \\\"2026-05-22T14:30:00Z\\\"\\n mentions:\\n - { at: \\\"2024-01-09T00:00:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 1.0 }\\n - { at: \\\"2026-05-22T14:30:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 1.0 }\\n promotionMode: human\\n promotedAt: \\\"2026-05-22T14:30:00Z\\\"\\n promotedBy: corpus-curator\\n---\\n\\n## Summary\\nJobs opened the 2007 keynote by saying Apple was launching three products: a widescreen iPod with touch controls, a revolutionary mobile phone, and a breakthrough internet communicator. After repeating the trio twice, he revealed: \\\"These are not three separate devices. This is one device. And we are calling it iPhone.\\\" The pattern earned a standing ovation before any feature was shown.\\n\\n## What's specific\\n- Three concrete categories the audience already understood (iPod, phone, internet).\\n- Deliberate repetition built rhythm; the reveal collapsed all three into one.\\n- The reveal happened on word 47 of the keynote — pre-product, pre-spec.\\n\\n## Transferable lesson\\nFor a category-creating product, don't announce the new category. Announce three known things, then collapse them.\\n\\n## Use this example when\\n- Pitching anything that's \\\"X + Y + Z combined\\\".\\n- Launching to an audience that doesn't have a mental slot for the new thing yet.\\n\\n## Avoid this pattern when\\n- The product genuinely is one thing — manufacturing a trio is fake.\\n- The audience already knows the category (then specs, not framing, win).\\n\",\n \"entries/patterns/2026/contrarian-short-form-hooks.md\": \"---\\nschema: knowledge.entry/v1\\nslug: contrarian-short-form-hooks\\nkind: pattern\\ntitle: Contrarian short-form hooks\\nupdated_at: \\\"2026-05-22T14:30:00Z\\\"\\nsources:\\n - tiktok-hook-2026-05\\nconfidence: 0.88\\nlinks:\\n - specificity-beats-superlatives\\ntags: [hooks, short-form, tiktok, contrarian]\\nmetadata:\\n corpus:\\n status: active\\n qualityScore: 4.5\\n riskScore: 1.0\\n domain: marketing\\n channel: tiktok\\n funnelStage: awareness\\n temporal:\\n firstSeen: \\\"2023-04-12T00:00:00Z\\\"\\n lastSeen: \\\"2026-05-22T14:30:00Z\\\"\\n halfLifeDays: 180\\n mentions:\\n - { at: \\\"2023-04-12T00:00:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 1.0 }\\n - { at: \\\"2026-05-22T14:30:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 1.0 }\\n promotionMode: auto\\n promotedAt: \\\"2026-05-22T14:30:00Z\\\"\\n promotedBy: corpus-curator\\n---\\n\\n## Summary\\nOpen with a popularly-held belief, then contradict it with a specific counter-claim. Forces a \\\"wait, what?\\\" pattern interrupt that buys 3-5 more seconds of attention.\\n\\n## Why it works\\nPattern-interrupt + curiosity gap. The viewer's brain treats the contradiction as a problem to resolve.\\n\\n## Transferable pattern\\n1. State a widely-held belief in 5 words\\n2. Counter with one specific contradiction\\n3. Promise the why in the next 30 seconds\\n\\n## Use when\\n- Short-form video (TikTok, Reels, Shorts)\\n- Cold-outbound email subject lines\\n- Ad creative for low-awareness audiences\\n\\n## Avoid when\\n- Branded content (feels manipulative)\\n- Audience already aligned with your stance\\n- Long-form (the hook doesn't sustain)\\n\\n## Examples\\n- \\\"Most marketers write listicles. Here's why every viral piece I've made started with a contradiction.\\\"\\n- \\\"Cold email is dead — for the 99% who do it wrong. Here's the 1%.\\\"\\n\",\n \"entries/patterns/2026/story-then-payoff.md\": \"---\\nschema: knowledge.entry/v1\\nslug: story-then-payoff\\nkind: pattern\\ntitle: Story-then-payoff structure\\nupdated_at: \\\"2026-05-22T14:30:00Z\\\"\\nsources:\\n - tiktok-hook-2026-05\\nconfidence: 0.85\\nlinks:\\n - contrarian-short-form-hooks\\n - clarity-beats-cleverness\\ntags: [storytelling, structure, copy]\\nmetadata:\\n corpus:\\n status: active\\n qualityScore: 4.3\\n riskScore: 0.8\\n domain: marketing\\n funnelStage: awareness\\n temporal:\\n firstSeen: \\\"2023-09-15T00:00:00Z\\\"\\n lastSeen: \\\"2026-05-22T14:30:00Z\\\"\\n mentions:\\n - { at: \\\"2023-09-15T00:00:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 1.0 }\\n - { at: \\\"2026-05-22T14:30:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 1.0 }\\n promotionMode: auto\\n promotedAt: \\\"2026-05-22T14:30:00Z\\\"\\n promotedBy: corpus-curator\\n---\\n\\n## Summary\\nOpen with a 1-2 sentence story (specific, sensory), then deliver the payoff (principle, product, CTA). The story buys attention; the payoff cashes it in.\\n\\n## Why it works\\nBrains are pattern-completion engines. A half-told story creates open loop tension. Closing the loop with the payoff delivers a small dopamine hit + transfers credibility from the story to the claim.\\n\\n## Transferable pattern\\n- Story: ≤2 sentences, one concrete moment.\\n- Payoff: ≤1 sentence, names the principle / product / CTA.\\n- Optional: 1 sentence connecting the two.\\n\\n## Use when\\n- Cold email openers, ad creative, landing-page heros.\\n- Audiences that don't know the product yet.\\n\\n## Avoid when\\n- Internal comms (waste of words).\\n- Audiences past consideration stage — they want specs, not stories.\\n\",\n \"entries/principles/2026/clarity-beats-cleverness.md\": \"---\\nschema: knowledge.entry/v1\\nslug: clarity-beats-cleverness\\nkind: principle\\ntitle: Clarity beats cleverness\\nupdated_at: \\\"2026-05-22T14:30:00Z\\\"\\nsources:\\n - tiktok-hook-2026-05\\nconfidence: 0.95\\ntags: [copy, clarity, conversion]\\nmetadata:\\n corpus:\\n status: active\\n qualityScore: 4.8\\n riskScore: 0.5\\n domain: marketing\\n funnelStage: awareness\\n temporal:\\n firstSeen: \\\"2022-01-01T00:00:00Z\\\"\\n lastSeen: \\\"2026-05-22T14:30:00Z\\\"\\n mentions:\\n - { at: \\\"2022-01-01T00:00:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 1.0 }\\n - { at: \\\"2026-05-22T14:30:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 1.0 }\\n promotionMode: human\\n promotedAt: \\\"2026-05-22T14:30:00Z\\\"\\n promotedBy: corpus-curator\\n---\\n\\n## Summary\\nIf the reader has to re-read a sentence, the joke is on the writer. Wordplay that's clever-but-confusing loses 100% of distracted readers.\\n\\n## Why it works\\nReading is involuntary effort. Clever copy taxes that effort; clear copy doesn't. The cheapest conversion is the one where the reader didn't have to work.\\n\\n## Transferable pattern\\n- Write at a 6th-grade reading level (Hemingway score).\\n- Replace every metaphor that doesn't add new information.\\n- One idea per sentence.\\n\\n## Use when\\n- Landing-page headlines, CTAs, ad creative.\\n- Any audience that hasn't already paid attention.\\n\\n## Avoid when\\n- Brand-content where the voice IS the product (Liquid Death, Cards Against Humanity).\\n- Inside-baseball content for an already-converted audience.\\n\",\n \"entries/principles/2026/specificity-beats-superlatives.md\": \"---\\nschema: knowledge.entry/v1\\nslug: specificity-beats-superlatives\\nkind: principle\\ntitle: Specificity beats superlatives\\nupdated_at: \\\"2026-05-22T14:30:00Z\\\"\\nsources:\\n - tiktok-hook-2026-05\\nconfidence: 0.92\\ntags: [copy, specificity, conversion]\\nmetadata:\\n corpus:\\n status: active\\n qualityScore: 4.7\\n riskScore: 0.8\\n domain: marketing\\n funnelStage: consideration\\n temporal:\\n firstSeen: \\\"2023-04-12T00:00:00Z\\\"\\n lastSeen: \\\"2026-05-22T14:30:00Z\\\"\\n mentions:\\n - { at: \\\"2023-04-12T00:00:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 1.0 }\\n - { at: \\\"2026-05-22T14:30:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 1.0 }\\n promotionMode: human\\n promotedAt: \\\"2026-05-22T14:30:00Z\\\"\\n promotedBy: corpus-curator\\n---\\n\\n## Summary\\nConcrete claims with numbers outperform superlative adjectives. \\\"3x conversion\\\" beats \\\"amazing results\\\"; \\\"287 customers in 90 days\\\" beats \\\"many happy customers\\\".\\n\\n## Why it works\\nReaders parse numbers as evidence; adjectives as marketing noise. Specificity transfers credibility because it implies the author can be checked.\\n\\n## Transferable pattern\\n- Replace every superlative with a specific number, date, or named entity\\n- If you can't substitute, the claim is probably untrue\\n\\n## Use when\\n- Writing landing-page copy\\n- Drafting ad creative\\n- Replying to objections\\n\\n## Avoid when\\n- Numbers are unverifiable (then say nothing)\\n- Aspirational brand voice required\\n\",\n \"entries/summaries/2026/short-form-hook-meta.md\": \"---\\nschema: knowledge.entry/v1\\nslug: short-form-hook-meta\\nkind: summary\\ntitle: Short-form hook meta — what's working in 2026\\nupdated_at: \\\"2026-05-22T14:30:00Z\\\"\\nsources:\\n - tiktok-hook-2026-05\\nconfidence: 0.7\\nlinks:\\n - contrarian-short-form-hooks\\n - story-then-payoff\\n - clarity-beats-cleverness\\ntags: [meta, short-form, hooks, trends]\\nmetadata:\\n corpus:\\n status: active\\n qualityScore: 4.0\\n riskScore: 1.0\\n domain: marketing\\n channel: tiktok\\n funnelStage: awareness\\n temporal:\\n firstSeen: \\\"2026-04-01T00:00:00Z\\\"\\n lastSeen: \\\"2026-05-22T14:30:00Z\\\"\\n halfLifeDays: 60\\n mentions:\\n - { at: \\\"2026-04-01T00:00:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 1.0 }\\n - { at: \\\"2026-05-22T14:30:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 1.0 }\\n promotionMode: human\\n promotedAt: \\\"2026-05-22T14:30:00Z\\\"\\n promotedBy: corpus-curator\\n---\\n\\n## Summary\\nAs of mid-2026, the dominant short-form hook patterns on TikTok / Reels / Shorts share three traits: (1) contradiction in the first 2 seconds, (2) specific number or named entity by the 5-second mark, (3) the payoff arrives before 30 seconds.\\n\\n## What's NOT working anymore\\n- Generic \\\"POV:\\\" openers — algo deprioritized them after the Q1 update.\\n- Long establishing shots — 90% drop-off before the 3-second mark.\\n- \\\"Watch till the end\\\" framing — overuse killed effectiveness.\\n\\n## Patterns that scale across channels\\n- [[contrarian-short-form-hooks]] — universal, lowest production cost.\\n- [[story-then-payoff]] — needs a sharp specific story; expensive to source.\\n\\n## Half-life\\n60 days. Re-mention via scout when a new platform algorithm update lands.\\n\",\n \"entries/timelines/2026/saas-positioning-shifts-2020-2026.md\": \"---\\nschema: knowledge.entry/v1\\nslug: saas-positioning-shifts-2020-2026\\nkind: timeline\\ntitle: SaaS positioning shifts — 2020 to 2026\\nupdated_at: \\\"2026-05-22T14:30:00Z\\\"\\nsources:\\n - tiktok-hook-2026-05\\nconfidence: 0.78\\nlinks:\\n - weak-positioning-saas\\ntags: [positioning, saas, timeline, trend]\\nmetadata:\\n corpus:\\n status: active\\n qualityScore: 4.1\\n riskScore: 1.2\\n domain: marketing\\n funnelStage: consideration\\n temporal:\\n firstSeen: \\\"2024-06-01T00:00:00Z\\\"\\n lastSeen: \\\"2026-05-22T14:30:00Z\\\"\\n halfLifeDays: 180\\n mentions:\\n - { at: \\\"2024-06-01T00:00:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 1.0 }\\n - { at: \\\"2026-05-22T14:30:00Z\\\", sourceId: tiktok-hook-2026-05, weight: 1.0 }\\n promotionMode: human\\n promotedAt: \\\"2026-05-22T14:30:00Z\\\"\\n promotedBy: corpus-curator\\n---\\n\\n## Summary\\nB2B SaaS positioning evolved through five distinct phases between 2020 and 2026, each driven by a buyer environment shift.\\n\\n## 2020 — \\\"All-in-one platform\\\"\\nBuyers consolidating tools post-COVID; positioning prized breadth.\\nResult: feature-list arms race, undifferentiated category copy.\\n\\n## 2022 — \\\"Best-in-class for X\\\"\\nStack-fatigue reversed; buyers wanted focused tools.\\nResult: \\\"the [adjective] [category] for [vertical]\\\" replaced \\\"all-in-one\\\".\\n\\n## 2023 — \\\"AI-native\\\"\\nGPT-3.5 wave; everything claimed AI even when it was a wrapper.\\nResult: skepticism by mid-2024; AI claims now require demonstrated trade-offs.\\n\\n## 2024 — \\\"Replace your [old tool]\\\"\\nDirect displacement framing. Worked for late-comers in mature categories.\\n\\n## 2026 — \\\"We don't ship a [thing]\\\"\\nReactive positioning — define yourself by what you refused to build.\\nMost credible when accompanied by a concrete reason (compliance, philosophy).\\n\\n## Pattern\\nPositioning rotates roughly every 18-24 months. The current peak narrative is the most-imitated; the next winner is usually the inverse of the saturated one.\\n\",\n \"KNOWLEDGE.md\": \"---\\nschema: knowledge.workspace/v1\\nname: marketing-corpus\\ntitle: Marketing Expert Corpus\\ndescription: |\\n Expert marketing knowledge for autonomous agents. Composes AIP-10 (knowledge),\\n AIP-12 (playbooks), AIP-18 (curation collections), AIP-9 (operators),\\n AIP-15 (workflows), and AIP-41 (routines) into an autonomous improvement loop.\\nversion: 1.0.0\\nentityTypes:\\n - { name: Principle, description: \\\"Durable expert rule\\\" }\\n - { name: Example, description: \\\"Concrete source-derived example\\\" }\\n - { name: Pattern, description: \\\"Reusable transferable mechanic\\\" }\\n - { name: Critique, description: \\\"Negative example or failure mode\\\" }\\n - { name: Summary, description: \\\"Compressed source synthesis\\\" }\\n - { name: Timeline, description: \\\"Time-sensitive trend evolution\\\" }\\n - { name: PlaybookCase, description: \\\"Documented case study of a great playbook\\\" }\\nsources:\\n retention: forever\\n signing: optional\\n hashAlgo: sha256\\n authorityDefault: secondary\\nlints:\\n - { id: require-source-on-examples, kind: require-source, appliesTo: Example, severity: error }\\n - { id: min-confidence-principles, kind: min-confidence, appliesTo: Principle, severity: warn, params: { min: 0.6 } }\\n - { id: max-age-timelines, kind: max-age, appliesTo: Timeline, severity: warn, params: { days: 730 } }\\n - { id: max-age-summaries, kind: max-age, appliesTo: Summary, severity: warn, params: { days: 180 } }\\n - { id: broken-ref-all, kind: broken-ref, appliesTo: \\\"*\\\", severity: error }\\n - { id: orphan-all, kind: orphan, appliesTo: \\\"*\\\", severity: info }\\ncuration:\\n tone: \\\"neutral, expert, source-backed\\\"\\n depth: medium\\n autoLink: byName\\n conflictResolution: authority\\nqueryHints:\\n preferRecent: true\\n preferAuthoritative: true\\nmetadata:\\n corpus:\\n version: 1\\n domain: marketing\\n autoPromote:\\n enabled: true\\n requires:\\n qualityScore: { min: 4.2 }\\n riskScore: { max: 1.5 }\\n hasArchiveHash: true\\n requiredFields: [why_it_works, transferable_pattern, use_when, avoid_when]\\n notRestricted: true\\n temporal:\\n defaultHalfLifeDays: 180\\n scoreFormula: max-mention-decay\\n retrievalBoosts:\\n qualityScore: { weight: 0.30 }\\n temporalScore: { weight: 0.20 }\\n mentionCount: { weight: 0.10 }\\n confidence: { weight: 0.15 }\\n retrievalDefaults:\\n status: active\\n minQualityScore: 3.5\\n minTemporalScore: 0.1\\n accessModes:\\n read: { allowedRoles: [\\\"*\\\"] }\\n cite: { allowedRoles: [\\\"*\\\"] }\\n flag-learning: { allowedRoles: [\\\"*\\\"], rateLimit: { perOperator: 20, window: \\\"24h\\\" } }\\n curate: { allowedRoles: [corpus-curator, admin] }\\n promote: { allowedRoles: [corpus-curator, admin] }\\n activate-playbook: { allowedRoles: [corpus-curator, admin], requireApproval: true }\\n admin-reindex: { allowedRoles: [admin] }\\n bypass-default-filters: { allowedRoles: [corpus-curator, admin], audit: true }\\n---\\n\\n# Marketing Corpus\\n\\nSource-of-truth for autonomous marketing agents. Composes AgentProto AIPs into a closed-loop knowledge-improvement system.\\n\\n## Three loops\\n- **Knowledge curation** — gap-finder → curator → entries\\n- **Playbook evolution** — gap → AIP-12 shadow playbook → evaluator → active|archived\\n- **Retrieval-quality feedback** — every query logged; `utility` + `lift` written back to entries\\n\\nAll corpus-specific policy lives under `metadata.corpus.*`. AIP amendments (A1-A8) may hoist specific fields to first-class later — strictly additive, no rip-and-replace.\\n\",\n \"operators/corpus-curator/OPERATOR.md\": \"---\\nname: Corpus Curator\\nid: corpus-curator\\npersona_summary: Promotes approved candidates to AIP-10 entries, maintains _index.md, handles deprecation + supersession. The corpus's editor-in-chief.\\nversion: \\\"1.0.0\\\"\\nprofile:\\n role: |\\n Promote candidates that pass the auto-promote gate. Review the\\n human-review queue, decide approve/reject/needs-work. Keep the\\n corpus tidy: dedupe, deprecate stale entries, resolve\\n contradictions.\\n voice: |\\n Direct, decisive, opinionated about quality bar. First-person\\n plural for company voice. Cites specific entry slugs when\\n discussing deprecation or supersession.\\n boundaries:\\n - Never promote an entry that fails the auto-promote gate without explicit bypass.\\n - Never deprecate without a written reason in metadata.corpus.archiveReason.\\n - Always preserve the audit chain — _log.md events are append-only.\\ngovernance:\\n audit_log: \\\"audit:corpus/marketing/_log.md\\\"\\n autonomy: autonomous\\n policies:\\n - \\\"policy:corpus/marketing/curation\\\"\\nskills:\\n - source-analysis\\n - taxonomy\\n - editorial-judgment\\ntools:\\n - corpus-promote-candidate\\n - corpus-activate-playbook\\n - corpus-archive-playbook\\n - corpus-log-event\\n - knowledge-query\\nparticipation:\\n mode: proactive\\nmemory:\\n kind: operator-context\\nruntime:\\n kind: in-process\\ntags: [marketing, curator, corpus]\\nmetadata:\\n corpus:\\n domain: marketing\\n overlays:\\n policy: open\\n maxActiveCount: 10\\n---\\n\\n# Corpus Curator\\n\\nRuns after the reviewer scores a candidate. Promotes auto-approved entries; queues human-review-required candidates for the team. Also drives playbook lifecycle (`activate` / `archive`).\\n\",\n \"operators/gap-finder/OPERATOR.md\": \"---\\nname: Gap Finder\\nid: gap-finder\\npersona_summary: Mines low-scoring eval-cases for systematic weaknesses in the corpus. Opens corpus-gap items so the scout knows what to look for next.\\nversion: \\\"1.0.0\\\"\\nprofile:\\n role: |\\n Read recent eval-case results, identify recurring failure modes,\\n classify them (generic-output, weak-strategy, stale-reference,\\n poor-style, missing-domain-context), and open corpus-gap items\\n with priority based on frequency.\\n voice: |\\n Diagnostic, pattern-oriented, prescriptive. Says \\\"we have N\\n failures of kind X\\\" not \\\"the agent sometimes struggles\\\".\\n Recommends a concrete next scouting target.\\n boundaries:\\n - Never open a gap on a single low-score case — require ≥3 occurrences.\\n - Never blame the operator — gaps describe missing knowledge, not bad reasoning.\\n - Always link the eval-case refs that motivated the gap.\\ngovernance:\\n audit_log: \\\"audit:corpus/marketing/_log.md\\\"\\n autonomy: autonomous\\nskills:\\n - source-analysis\\n - pattern-recognition\\ntools:\\n - corpus-log-event\\n - knowledge-query\\nparticipation:\\n mode: proactive\\nmemory:\\n kind: operator-context\\nruntime:\\n kind: in-process\\ntags: [marketing, gap-finder, corpus]\\nmetadata:\\n corpus:\\n domain: marketing\\n---\\n\\n# Gap Finder\\n\\nRuns monthly (via `monthly-eval-gap-finder` routine). Scans the last 30 days of `eval-case` results, finds clusters of failure, opens `corpus-gap/*/ITEM.md` items with `weaknessType` + `priority`. The scout reads these to prioritize the next harvest.\\n\",\n \"operators/marketing-analyst/OPERATOR.md\": \"---\\nname: Marketing Analyst\\nid: marketing-analyst\\npersona_summary: Senior marketing analyst who converts raw social/web sources into expert principles, patterns, and critiques for the marketing corpus.\\nversion: \\\"1.0.0\\\"\\nprofile:\\n role: |\\n Convert candidate sources discovered by the scout into corpus-grade\\n expert analysis: principles, patterns, critiques. Score quality and\\n risk to inform promotion gates.\\n voice: |\\n Concrete, source-backed, never superlative. Cite specific numbers and\\n named entities. First-person plural (\\\"we\\\") for company voice.\\n boundaries:\\n - Never invent quantitative claims; cite a source or mark as opinion.\\n - Never promote without quality-reviewer signoff (unless auto-promote gates pass).\\n - Never edit raw sources — only entries.\\ngovernance:\\n audit_log: \\\"audit:corpus/marketing/_log.md\\\"\\n autonomy: supervised\\n policies:\\n - \\\"policy:corpus/marketing/curation\\\"\\nskills:\\n - source-analysis\\n - copywriting\\ntools:\\n - corpus-flag-learning\\n - knowledge-query\\nparticipation:\\n mode: proactive\\nmemory:\\n kind: operator-context\\nruntime:\\n kind: in-process\\ntags: [marketing, analyst, corpus]\\nmetadata:\\n corpus:\\n domain: marketing\\n knowledgeViews:\\n - corpus: marketing\\n filter:\\n domain: [marketing]\\n minQualityScore: 3.5\\n defaultBoosts:\\n qualityScore: { weight: 0.40 }\\n temporalScore: { weight: 0.30 }\\n overlays:\\n policy: gated\\n maxActiveCount: 5\\n requireApprovalFrom: corpus-curator\\n allowedKinds: [overlay, block-replacement]\\n---\\n\\n# Marketing Analyst\\n\\nReads candidate sources from the scout, writes expert analysis as AIP-10 entries. Scores quality and risk. Signals the curator on auto-promote gate pass.\\n\",\n \"operators/playbook-evaluator/OPERATOR.md\": \"---\\nname: Playbook Evaluator\\nid: playbook-evaluator\\npersona_summary: Runs shadow vs baseline eval batches on AIP-12 playbooks. Records winRateVsBaseline, decides promote / archive based on the playbook's auto_promote gate.\\nversion: \\\"1.0.0\\\"\\nprofile:\\n role: |\\n For every shadow playbook, run eval-cases through both arms\\n (overlay applied vs operator default). Score outputs via the\\n rubric the playbook's evidence[].eval-case references. Record\\n metrics in metadata.corpus.shadowMetrics. Trigger curator action\\n when the auto_promote.threshold is met.\\n voice: |\\n Quantitative, dispassionate, hypothesis-driven. States the null\\n hypothesis explicitly (n, threshold, observed) before\\n recommending an action.\\n boundaries:\\n - Never activate a playbook — that's the curator's call (audit chain).\\n - Never report a winRate on n < playbook.metadata.corpus.autoPromote.minSampleSize.\\n - Always run identical eval-cases on both arms (same prompts, same rubric).\\ngovernance:\\n audit_log: \\\"audit:corpus/marketing/_log.md\\\"\\n autonomy: autonomous\\nskills:\\n - statistics\\n - source-analysis\\ntools:\\n - corpus-list-playbooks\\n - corpus-log-event\\n - knowledge-query\\nparticipation:\\n mode: proactive\\nmemory:\\n kind: operator-context\\nruntime:\\n kind: in-process\\ntags: [marketing, evaluator, corpus, aip-12]\\nmetadata:\\n corpus:\\n domain: marketing\\n---\\n\\n# Playbook Evaluator\\n\\nDrives the playbook side of closed loop #2 (procedure). Runs nightly (via per-playbook eval-batch routines, configured per playbook). Writes back `shadowMetrics.{sampleSize, winRateVsBaseline, lastEvaluatedAt}` to PLAYBOOK.md. When gates pass, posts a `playbook.ready-for-activation` event the curator subscribes to.\\n\",\n \"operators/quality-reviewer/OPERATOR.md\": \"---\\nname: Quality Reviewer\\nid: quality-reviewer\\npersona_summary: Scores analyzed candidates against the corpus's quality + risk rubric. Decides promotionMode (auto vs human). Flags concerns the analyst missed.\\nversion: \\\"1.0.0\\\"\\nprofile:\\n role: |\\n Independent second pair of eyes on every analyzed candidate.\\n Adversarial-by-design — assumes the analyst was too generous\\n and looks for reasons NOT to promote.\\n voice: |\\n Critical, concrete, fair. Cites specific clauses of the\\n candidate body, not vibes. Always proposes a concrete score\\n (qualityScore 0-5, riskScore 0-5).\\n boundaries:\\n - Never promote on the analyst's authority — score and route.\\n - Never auto-promote a candidate flagged as restricted / personal / legal.\\n - Always justify a sub-2.0 quality score in reviewerNotes.\\ngovernance:\\n audit_log: \\\"audit:corpus/marketing/_log.md\\\"\\n autonomy: supervised\\n policies:\\n - \\\"policy:corpus/marketing/review-policy\\\"\\nskills:\\n - source-analysis\\n - critical-reading\\ntools:\\n - corpus-flag-learning\\n - knowledge-query\\nparticipation:\\n mode: proactive\\nmemory:\\n kind: operator-context\\nruntime:\\n kind: in-process\\ntags: [marketing, reviewer, corpus]\\nmetadata:\\n corpus:\\n domain: marketing\\n---\\n\\n# Quality Reviewer\\n\\nRuns after `marketing-analyst` produces an analyzed ITEM.md. Scores against:\\n\\n- **qualityScore** — accuracy, transferability, evidence\\n- **riskScore** — legal/brand/compliance hazards\\n- **promotionMode** — auto (gates pass) vs human (needs curator)\\n\",\n \"operators/source-scout/OPERATOR.md\": \"---\\nname: Source Scout\\nid: source-scout\\npersona_summary: Curates external feeds for fresh marketing source material — TikToks, blog posts, ad creative, internal performance data — and archives the worth-keeping ones into sources/.\\nversion: \\\"1.0.0\\\"\\nprofile:\\n role: |\\n Discover new candidate sources for the marketing corpus. Filter\\n noise vs signal at the scout stage so the analyst only sees\\n promising material.\\n voice: |\\n Efficient, terse, evidence-first. Names URLs + numbers, not\\n adjectives. Reports findings as `{source: <id>, why: <reason>}`\\n triples.\\n boundaries:\\n - Never re-archive an already-archived source (check content_hash).\\n - Never archive content with PII unless explicitly sanitized.\\n - Never archive paywalled / DMCA-restricted material.\\ngovernance:\\n audit_log: \\\"audit:corpus/marketing/_log.md\\\"\\n autonomy: autonomous\\n policies:\\n - \\\"policy:corpus/marketing/source-policy\\\"\\nskills:\\n - web-research\\n - source-analysis\\ntools:\\n - corpus-create-candidate\\n - knowledge-query\\n - web-search\\nparticipation:\\n mode: proactive\\nmemory:\\n kind: operator-context\\nruntime:\\n kind: in-process\\ntags: [marketing, scout, corpus]\\nmetadata:\\n corpus:\\n domain: marketing\\n knowledgeViews:\\n - corpus: marketing\\n filter:\\n domain: [marketing]\\n---\\n\\n# Source Scout\\n\\nRuns daily (via `daily-source-scout` routine). Fetches configured feeds, hashes content, dedups against existing sources, and writes new candidates to `_candidates.yaml`. The analyst takes over from there.\\n\",\n \"playbooks/ad-angle-generation/PLAYBOOK.md\": \"---\\nschema: playbooks/v1\\nslug: ad-angle-generation\\ntitle: Ad angle generation — JTBD-grounded variants\\ntargets:\\n - { kind: operator, ref: marketing-analyst }\\nbinds_operator: marketing-analyst\\nkind: overlay\\nstatus: shadow\\npriority: 90\\nlock_check:\\n - factual-grounded\\nevidence:\\n - kind: run\\n ref: collections/eval-case/ad-angle-suite/runs/initial\\n note: First eval batch, n=20 planned\\n - kind: reflection\\n ref: collections/corpus-gap/generic-ad-copy/ITEM.md\\n note: Gap that motivated this playbook\\nttl: \\\"P90D\\\"\\nsupersedes: []\\ncreated_at: \\\"2026-05-22T14:30:00Z\\\"\\nupdated_at: \\\"2026-05-22T14:30:00Z\\\"\\ntags: [ads, angles, jtbd]\\nmetadata:\\n corpus:\\n authoredBy: corpus-curator\\n shadowTrafficPct: 0.10\\n autoPromote:\\n enabled: true\\n metric: winRateVsBaseline\\n threshold: { gte: 0.55 }\\n minSampleSize: 30\\n cooldown: \\\"7d\\\"\\n execution: sandboxed\\n---\\n\\n## Overlay\\nWhen generating ad creative, generate 3 distinct angles before refining any single one.\\n\\n## Procedure\\n1. Identify the JTBD (job-to-be-done) the audience hires the product for.\\n2. Generate one angle per axis: outcome, pain, identity.\\n3. For each angle, write a hook + body in <50 words.\\n4. Score each angle on specificity + audience fit; promote the highest.\\n\\n## Promotion gate\\nPromote shadow → active when winRateVsBaseline ≥ 0.55 over n ≥ 30 evals.\\n\",\n \"playbooks/cold-email-outbound/PLAYBOOK.md\": \"---\\nschema: playbooks/v1\\nslug: cold-email-outbound\\ntitle: Cold email outbound — earned-attention opener\\ntargets:\\n - { kind: operator, ref: marketing-analyst }\\nbinds_operator: marketing-analyst\\nkind: overlay\\nstatus: shadow\\npriority: 70\\nlock_check: []\\nevidence:\\n - kind: run\\n ref: collections/eval-case/cold-email-suite/runs/initial\\n note: First eval batch planned\\nttl: \\\"P90D\\\"\\nsupersedes: []\\ncreated_at: \\\"2026-05-22T14:30:00Z\\\"\\nupdated_at: \\\"2026-05-22T14:30:00Z\\\"\\ntags: [cold-email, outbound, sales]\\nmetadata:\\n corpus:\\n authoredBy: corpus-curator\\n shadowTrafficPct: 0.10\\n autoPromote:\\n enabled: true\\n metric: winRateVsBaseline\\n threshold: { gte: 0.55 }\\n minSampleSize: 30\\n cooldown: \\\"7d\\\"\\n execution: sandboxed\\n---\\n\\n## Overlay\\nCold-email opener MUST earn the reader's next 5 seconds by stating something they didn't know, not by claiming a benefit.\\n\\n## Procedure\\n1. Research one specific thing about the prospect (their hire, their post, their company's recent move).\\n2. State that thing in <12 words as the opener.\\n3. Connect it to the offer in the next sentence — NO \\\"I noticed you…\\\" bridge.\\n4. End with one specific yes/no question.\\n\\n## Promotion gate\\nPromote shadow → active when winRateVsBaseline ≥ 0.55 over n ≥ 30 evals.\\n\",\n \"playbooks/competitor-positioning/PLAYBOOK.md\": \"---\\nschema: playbooks/v1\\nslug: competitor-positioning\\ntitle: Competitor positioning — pick your axis, name the trade\\ntargets:\\n - { kind: operator, ref: marketing-analyst }\\nbinds_operator: marketing-analyst\\nkind: overlay\\nstatus: shadow\\npriority: 80\\nlock_check:\\n - factual-grounded\\n - brand-voice\\nevidence:\\n - kind: run\\n ref: collections/eval-case/positioning-suite/runs/initial\\n note: First eval batch planned\\nttl: \\\"P90D\\\"\\nsupersedes: []\\ncreated_at: \\\"2026-05-22T14:30:00Z\\\"\\nupdated_at: \\\"2026-05-22T14:30:00Z\\\"\\ntags: [positioning, competitive, differentiation]\\nmetadata:\\n corpus:\\n authoredBy: corpus-curator\\n shadowTrafficPct: 0.10\\n autoPromote:\\n enabled: true\\n metric: winRateVsBaseline\\n threshold: { gte: 0.55 }\\n minSampleSize: 30\\n cooldown: \\\"7d\\\"\\n execution: sandboxed\\n---\\n\\n## Overlay\\nPositioning copy MUST name the specific competitor weakness it's trading off against. \\\"We're faster\\\" is noise; \\\"We don't ship a CLI\\\" is positioning.\\n\\n## Procedure\\n1. List the top 3 competitors by ICP overlap.\\n2. For each, identify one specific decision they made that we explicitly DIDN'T.\\n3. Write the positioning line as: `For [ICP], who [problem], [product] is the [category] that [specific trade-off vs competitor]`.\\n4. Lint output against the [[weak-positioning-saas]] critique.\\n\\n## Promotion gate\\nPromote shadow → active when winRateVsBaseline ≥ 0.55 over n ≥ 30 evals.\\n\",\n \"playbooks/landing-page-copy/PLAYBOOK.md\": \"---\\nschema: playbooks/v1\\nslug: landing-page-copy\\ntitle: Landing-page copy — high-conversion structure\\ntargets:\\n - { kind: operator, ref: marketing-analyst }\\nbinds_operator: marketing-analyst\\nkind: overlay\\nstatus: shadow\\npriority: 100\\nlock_check:\\n - brand-voice\\n - factual-grounded\\nevidence:\\n - kind: run\\n ref: collections/eval-case/landing-page-copy-conversion-suite/runs/2026-05-22-batch-1\\n note: First shadow batch, n=30 evals, winRateVsBaseline TBD\\n - kind: reflection\\n ref: collections/corpus-gap/weak-positioning-saas/ITEM.md\\n note: Gap that motivated this playbook\\nttl: \\\"P90D\\\"\\nsupersedes: []\\ncreated_at: \\\"2026-05-22T14:30:00Z\\\"\\nupdated_at: \\\"2026-05-22T14:30:00Z\\\"\\ntags: [landing-page, copy, conversion]\\nmetadata:\\n corpus:\\n authoredBy: corpus-curator\\n derivedFromGap: collections/corpus-gap/weak-positioning-saas/ITEM.md\\n shadowTrafficPct: 0.10\\n autoPromote:\\n enabled: true\\n metric: winRateVsBaseline\\n threshold: { gte: 0.55 }\\n minSampleSize: 30\\n cooldown: \\\"7d\\\"\\n shadowMetrics:\\n sampleSize: 0\\n winRateVsBaseline: null\\n lastEvaluatedAt: null\\n archiveReason: null\\n execution: sandboxed\\n---\\n\\n## Overlay\\n[Markdown that gets merged into marketing-analyst's prompt at runtime when this playbook is active. The block-replacement / overlay merge logic is the runtime's concern, not this fixture's.]\\n\\n## Procedure\\n1. Read brief: ICP, offer, current page.\\n2. Apply principle [[specificity-beats-superlatives]] — every superlative gets a number, date, or named entity.\\n3. Generate 3 hook variants using pattern [[contrarian-short-form-hooks]].\\n4. Lint output against critique [[weak-positioning-saas]].\\n5. Output: H1, sub-H1, 3 CTA variants, 1 social-proof block.\\n\\n## Promotion gate\\nPromote shadow → active when winRateVsBaseline ≥ 0.55 over n ≥ 30 evals (see metadata.corpus.autoPromote).\\n\",\n \"playbooks/social-hook-design/PLAYBOOK.md\": \"---\\nschema: playbooks/v1\\nslug: social-hook-design\\ntitle: Social hook design — pattern interrupt in 5 seconds\\ntargets:\\n - { kind: operator, ref: marketing-analyst }\\nbinds_operator: marketing-analyst\\nkind: overlay\\nstatus: shadow\\npriority: 95\\nlock_check: []\\nevidence:\\n - kind: run\\n ref: collections/eval-case/social-hook-suite/runs/initial\\n note: First eval batch planned\\n - kind: reflection\\n ref: entries/patterns/2026/contrarian-short-form-hooks.md\\n note: Pattern this playbook operationalizes\\nttl: \\\"P90D\\\"\\nsupersedes: []\\ncreated_at: \\\"2026-05-22T14:30:00Z\\\"\\nupdated_at: \\\"2026-05-22T14:30:00Z\\\"\\ntags: [social, hook, short-form]\\nmetadata:\\n corpus:\\n authoredBy: corpus-curator\\n shadowTrafficPct: 0.10\\n autoPromote:\\n enabled: true\\n metric: winRateVsBaseline\\n threshold: { gte: 0.55 }\\n minSampleSize: 30\\n cooldown: \\\"7d\\\"\\n execution: sandboxed\\n---\\n\\n## Overlay\\nEvery short-form hook MUST earn the next 5 seconds. State a contradiction OR a specific number OR a named entity in the first sentence.\\n\\n## Procedure\\n1. Generate 3 hooks per outline: contradiction, number, name.\\n2. Score each by surprise (1-5) + relevance (1-5).\\n3. Promote the highest combined score; archive the rest as alts.\\n4. Output: hook + first 3 sentences + CTA.\\n\\n## Promotion gate\\nPromote shadow → active when winRateVsBaseline ≥ 0.55 over n ≥ 30 evals.\\n\",\n \"routines/daily-source-scout/ROUTINE.md\": \"---\\nschema: routine/v1\\nid: daily-source-scout\\ndescription: |\\n Daily routine that runs the source-scout operator to discover new\\n candidate sources across configured external feeds. Discovered sources\\n are archived under sources/ and rows appended to _candidates.yaml.\\nversion: \\\"1.0.0\\\"\\nschedule:\\n kind: cron\\n cron: \\\"0 9 * * *\\\"\\n timezone: \\\"UTC\\\"\\n catchup: skip\\ntarget:\\n workflow: ingest-source\\n inputs:\\n feeds: [tiktok-curated, hubspot-blog, reddit-marketing]\\n maxItemsPerRun: 50\\nretry:\\n max_attempts: 3\\n backoff: exponential\\non_failure:\\n create_work_item: true\\n fire_event: corpus.scout.failed\\nfires_events:\\n - corpus.scout.completed\\n - corpus.candidate.discovered\\nenabled: true\\ntags: [corpus, scout, daily]\\nmetadata:\\n corpus:\\n domain: marketing\\n---\\n\\n# Daily Source Scout\\n\\nRuns every morning at 09:00 UTC. Scouts external feeds for new candidate sources, archives them, and appends to `_candidates.yaml`. The candidate event downstream triggers `analyze-candidate` workflow.\\n\",\n \"routines/monthly-eval-gap-finder/ROUTINE.md\": \"---\\nschema: routine/v1\\nid: monthly-eval-gap-finder\\ndescription: |\\n Monthly gap-finder run — reads the last 30 days of eval-case\\n failures, clusters them, opens corpus-gap items for the scout.\\n Closes loop #3 by turning observed weaknesses into next-harvest\\n priorities.\\nversion: \\\"1.0.0\\\"\\nschedule:\\n kind: cron\\n cron: \\\"0 8 1 * *\\\"\\n timezone: \\\"UTC\\\"\\n catchup: skip\\ntarget:\\n workflow: detect-corpus-gaps\\n inputs:\\n windowDays: 30\\n minOccurrences: 3\\nretry:\\n max_attempts: 2\\n backoff: exponential\\non_failure:\\n create_work_item: true\\n fire_event: corpus.gap-finder.failed\\nfires_events:\\n - corpus.gap-finder.completed\\n - corpus.gap.opened\\nenabled: true\\ntags: [corpus, gaps, monthly]\\nmetadata:\\n corpus:\\n domain: marketing\\n---\\n\\n# Monthly Eval Gap Finder\\n\\nFirst day of each month, 08:00 UTC. Reads aggregated eval-case results, clusters failure modes, opens `corpus-gap/*/ITEM.md` items.\\n\",\n \"routines/quarterly-archive-cleanup/ROUTINE.md\": \"---\\nschema: routine/v1\\nid: quarterly-archive-cleanup\\ndescription: |\\n Quarterly storage hygiene — migrate sources older than 6 months\\n to sources/cold/, hard-delete archived entries past their\\n retention window, prune orphaned _candidates.yaml rows.\\nversion: \\\"1.0.0\\\"\\nschedule:\\n kind: cron\\n cron: \\\"0 6 1 1,4,7,10 *\\\"\\n timezone: \\\"UTC\\\"\\n catchup: skip\\ntarget:\\n workflow: corpus-archive-cleanup\\nretry:\\n max_attempts: 1\\n backoff: fixed\\non_failure:\\n create_work_item: true\\n fire_event: corpus.archive-cleanup.failed\\nfires_events:\\n - corpus.archive-cleanup.completed\\nenabled: true\\ntags: [corpus, archive, quarterly, maintenance]\\nmetadata:\\n corpus:\\n domain: marketing\\n---\\n\\n# Quarterly Archive Cleanup\\n\\nFirst day of every quarter at 06:00 UTC. Migrates aging sources to cold storage (still under `sources/cold/` for AIP-10 path resolvability), and prunes terminal-status candidates beyond retention.\\n\",\n \"routines/weekly-corpus-curation/ROUTINE.md\": \"---\\nschema: routine/v1\\nid: weekly-corpus-curation\\ndescription: |\\n Weekly curator pass — review the human-review queue, promote\\n what's ready, deprecate what's stale, archive playbooks whose\\n shadow eval has converged.\\nversion: \\\"1.0.0\\\"\\nschedule:\\n kind: cron\\n cron: \\\"0 10 * * 1\\\"\\n timezone: \\\"UTC\\\"\\n catchup: skip\\ntarget:\\n workflow: review-candidate\\n inputs:\\n mode: batch\\n maxItems: 50\\nretry:\\n max_attempts: 2\\n backoff: exponential\\non_failure:\\n create_work_item: true\\n fire_event: corpus.curation.weekly-failed\\nfires_events:\\n - corpus.curation.weekly-completed\\nenabled: true\\ntags: [corpus, curation, weekly]\\nmetadata:\\n corpus:\\n domain: marketing\\n---\\n\\n# Weekly Corpus Curation\\n\\nMonday 10:00 UTC. The curator runs through the corpus-review queue, promotes approved candidates, deprecates stale entries. Pairs with `daily-source-scout` (which fills the pipeline).\\n\",\n \"sources/fresh/tiktok-hook-2026-05.md\": \"---\\nschema: knowledge.source/v1\\nid: tiktok-hook-2026-05\\npath: sources/fresh/tiktok-hook-2026-05.md\\ntitle: TikTok contrarian hook example — May 2026\\ncaptured_at: \\\"2026-05-22T14:30:00Z\\\"\\ncaptured_by: source-scout\\ncontent_hash: sha256:abc1234567890def1234567890abcdef1234567890abcdef1234567890abcdef\\nauthority: secondary\\nlanguage: en\\ntags: [tiktok, hook, short-form, contrarian]\\nmetadata:\\n corpus:\\n originalUrl: https://example.com/tiktok/123\\n archiveTier: hot\\n archivedBy: source-scout\\n snapshotPath: sources/fresh/tiktok-hook-2026-05.snapshot.mhtml\\n---\\n\\n# TikTok hook — \\\"Most marketers are doing X. Here's why they're wrong.\\\"\\n\\nCaptured from a top-performing TikTok in May 2026. The hook contradicts a widely-held belief, generates 8x average engagement on the channel, and converts at 3x baseline for the SaaS product mentioned.\\n\\n## Transcript\\n> Everyone says you should write listicles. But the truth is — and this took me three years to figure out — every viral piece I've ever written started with one specific contradiction…\\n\\n## Performance\\n- Views: 1.2M\\n- Engagement rate: 18.4% (channel avg: 2.3%)\\n- CTR to product: 4.1% (channel avg: 0.8%)\\n\",\n \"workflows/analyze-candidate/WORKFLOW.md\": \"---\\nname: Analyze Corpus Candidate\\nid: analyze-candidate\\ndescription: |\\n Convert a discovered corpus candidate into an analyzed ITEM.md with\\n expert analysis, quality score, and risk score. Triggered by the\\n source-scout when it appends a row to _candidates.yaml.\\nversion: \\\"1.0.0\\\"\\ninputs:\\n type: object\\n required: [candidateId, sourcePath]\\n properties:\\n candidateId: { type: string, pattern: \\\"^[a-z0-9][a-z0-9-]*$\\\" }\\n sourcePath: { type: string }\\noutputs:\\n type: object\\n required: [itemPath, status]\\n properties:\\n itemPath: { type: string }\\n status: { type: string, enum: [analyzed, rejected, needs-work] }\\n qualityScore: { type: number }\\n riskScore: { type: number }\\nsteps:\\n - id: load-source\\n kind: tool\\n tool: knowledge.read_source\\n name: Load source bytes from sources/\\n inputs: { type: object, properties: { sourceId: { type: string } } }\\n next: analyze\\n - id: analyze\\n kind: tool\\n tool: marketing-analyst.analyze\\n name: Run marketing-analyst operator over the source\\n next: score\\n - id: score\\n kind: tool\\n tool: quality-reviewer.score\\n name: Compute quality + risk scores\\n next: gate\\n - id: gate\\n kind: branch\\n name: Decide promotionMode (auto vs human)\\n description: Check auto-promote gate against KNOWLEDGE.md.metadata.corpus.autoPromote\\n branches:\\n - { when: \\\"output.qualityScore >= 4.2 && output.riskScore <= 1.5\\\", next: \\\"auto-promote\\\" }\\n - { when: \\\"true\\\", next: \\\"human-review\\\" }\\n - id: auto-promote\\n kind: tool\\n tool: corpus-curator-promote\\n name: Promote to AIP-10 entry\\n - id: human-review\\n kind: approval\\n name: Queue for human curator\\n prompt: Review and approve or reject this candidate.\\n approvers:\\n - { role: corpus-curator }\\ntags: [corpus, workflow, analysis]\\nmetadata:\\n corpus:\\n domain: marketing\\n triggeredBy: source-scout\\n---\\n\\n# Analyze Candidate workflow\\n\\nConverts a discovered candidate into an analyzed ITEM.md. The marketing-analyst operator runs the actual analysis; this workflow orchestrates the pipeline (load → analyze → score → gate).\\n\",\n \"workflows/detect-corpus-gaps/WORKFLOW.md\": \"---\\nname: Detect corpus gaps\\nid: detect-corpus-gaps\\ndescription: |\\n Scan the last 30 days of eval-case failures, cluster by\\n weakness type, open corpus-gap items with priority. Drives the\\n scout's next harvest.\\nversion: \\\"1.0.0\\\"\\ninputs:\\n type: object\\n properties:\\n windowDays: { type: integer, minimum: 1, maximum: 365, default: 30 }\\n minOccurrences: { type: integer, minimum: 1, default: 3 }\\noutputs:\\n type: object\\n required: [gapsOpened]\\n properties:\\n gapsOpened: { type: integer }\\n clusters: { type: array }\\nsteps:\\n - id: load-failures\\n kind: tool\\n tool: corpus-load-eval-failures\\n name: Load last-N-days eval failures\\n - id: cluster\\n kind: tool\\n tool: gap-finder-cluster\\n name: Cluster failures by weakness type + recurrence\\n - id: open-gaps\\n kind: map\\n over: \\\"steps.cluster.output.clusters\\\"\\n steps:\\n - { id: open, kind: tool, tool: corpus-open-gap }\\ntags: [corpus, gaps]\\nmetadata:\\n corpus:\\n domain: marketing\\n triggeredBy: gap-finder\\n---\\n\\n# Detect corpus gaps workflow\\n\\nRuns monthly. Reads eval-case results, clusters failures, opens `corpus-gap/*/ITEM.md` items for the scout to read.\\n\",\n \"workflows/evaluate-agent-output/WORKFLOW.md\": \"---\\nname: Evaluate agent output\\nid: evaluate-agent-output\\ndescription: |\\n Score an agent output against a rubric via the pluggable\\n IEvaluator (M9). Wins seed flagCorpusLearning candidates;\\n losses feed detect-corpus-gaps.\\nversion: \\\"1.0.0\\\"\\ninputs:\\n type: object\\n required: [prompt, response, rubricSlug]\\n properties:\\n prompt: { type: string }\\n response: { type: string }\\n rubricSlug: { type: string }\\n operatorRef: { type: string }\\n conversationId: { type: string }\\n retrievedHits:\\n type: array\\n items: { type: object }\\noutputs:\\n type: object\\n required: [score]\\n properties:\\n score: { type: number }\\n dimensions: { type: object }\\n rationale: { type: string }\\n routedAs: { type: string, enum: [win, loss, neutral] }\\nsteps:\\n - id: evaluate\\n kind: tool\\n tool: evaluator-evaluate\\n name: Run IEvaluator against the rubric\\n - id: classify\\n kind: branch\\n name: Route win / loss / neutral\\n branches:\\n - { when: \\\"output.score >= 0.7\\\", next: \\\"as-win\\\" }\\n - { when: \\\"output.score < 0.4\\\", next: \\\"as-loss\\\" }\\n - { when: \\\"true\\\", next: \\\"as-neutral\\\" }\\n - id: as-win\\n kind: tool\\n tool: flagCorpusLearning\\n name: Seed a candidate from the winning trace\\n - id: as-loss\\n kind: tool\\n tool: corpus-record-eval-failure\\n name: Add to the eval-failure log for gap-finder\\n - id: as-neutral\\n kind: tool\\n tool: corpus-log-event\\n name: Log neutral outcome (no candidate spawn)\\ntags: [corpus, eval, telemetry]\\nmetadata:\\n corpus:\\n domain: marketing\\n requires:\\n pluggable: [evaluator]\\n---\\n\\n# Evaluate agent output workflow\\n\\nCloses loop #3 (retrieval quality). Every agent output that's worth evaluating runs through this. Win / loss / neutral routing feeds the curation queue + the gap finder.\\n\",\n \"workflows/ingest-source/WORKFLOW.md\": \"---\\nname: Ingest source\\nid: ingest-source\\ndescription: |\\n Fetch + hash + dedup + archive a single source. Output: a new\\n candidate row in _candidates.yaml (or no-op if duplicate).\\nversion: \\\"1.0.0\\\"\\ninputs:\\n type: object\\n required: [sourceUrl]\\n properties:\\n sourceUrl: { type: string }\\n category: { type: string, enum: [fresh, classic, competitors, internal, performance] }\\noutputs:\\n type: object\\n required: [outcome]\\n properties:\\n outcome: { type: string, enum: [archived, duplicate, rejected] }\\n sourceId: { type: string }\\n candidateId: { type: string }\\nsteps:\\n - id: fetch\\n kind: tool\\n tool: web-fetch\\n name: Fetch source content\\n - id: hash\\n kind: tool\\n tool: hash-content\\n name: Compute sha256 content_hash\\n - id: dedup\\n kind: branch\\n name: Dedup against existing sources\\n branches:\\n - { when: \\\"output.duplicate === true\\\", next: \\\"done-dup\\\" }\\n - { when: \\\"true\\\", next: \\\"archive\\\" }\\n - id: archive\\n kind: tool\\n tool: corpus-archive-source\\n name: Write source frontmatter + body to sources/<category>/<slug>.md\\n - id: create-candidate\\n kind: tool\\n tool: createCorpusCandidate\\n name: Append discovered row to _candidates.yaml\\n - id: done-dup\\n kind: tool\\n tool: corpus-log-event\\n name: Log dedup hit (no-op outcome)\\ntags: [corpus, ingest, scout]\\nmetadata:\\n corpus:\\n domain: marketing\\n triggeredBy: source-scout\\n---\\n\\n# Ingest source workflow\\n\\nStep 1 of the corpus loop. Single-source entry point. Called by `daily-source-scout` once per discovered URL.\\n\",\n \"workflows/promote-corpus-item/WORKFLOW.md\": \"---\\nname: Promote corpus item\\nid: promote-corpus-item\\ndescription: |\\n Lift an approved candidate into a published AIP-10 entry. Writes\\n the entry file, regenerates _index.md, ships chunks to the\\n backing engine, appends a promotion event. Wraps the kit's\\n CorpusPromoter.promote().\\nversion: \\\"1.0.0\\\"\\ninputs:\\n type: object\\n required: [candidateId, entrySlug, entryKind, entryPath, frontmatter, body]\\n properties:\\n candidateId: { type: string }\\n entrySlug: { type: string }\\n entryKind: { type: string, enum: [principle, example, pattern, critique, summary, timeline, playbook] }\\n entryPath: { type: string }\\n frontmatter: { type: object }\\n body: { type: string }\\n bypassGate: { type: boolean }\\noutputs:\\n type: object\\n required: [entryPath, gatePassed]\\n properties:\\n entryPath: { type: string }\\n versionToken: { type: string }\\n chunkCount: { type: integer }\\n gatePassed: { type: boolean }\\n bypassed: { type: boolean }\\nsteps:\\n - id: promote\\n kind: tool\\n tool: promoteCorpusCandidate\\n name: Atomic promote (lock + write + index + chunks + event)\\ntags: [corpus, promote]\\nmetadata:\\n corpus:\\n domain: marketing\\n triggeredBy: corpus-curator\\n---\\n\\n# Promote corpus item workflow\\n\\nStep 4 of the corpus loop. Single-step wrapper for callers that want the workflow shape; the underlying `CorpusPromoter` does the multi-file transaction.\\n\",\n \"workflows/review-candidate/WORKFLOW.md\": \"---\\nname: Review analyzed candidate\\nid: review-candidate\\ndescription: |\\n Score an analyzed candidate (quality + risk), set promotionMode,\\n route to auto-promote or human-review queue.\\nversion: \\\"1.0.0\\\"\\ninputs:\\n type: object\\n required: [candidateId]\\n properties:\\n candidateId: { type: string }\\noutputs:\\n type: object\\n required: [decision]\\n properties:\\n decision: { type: string, enum: [auto-promote, queue-review, reject] }\\n qualityScore: { type: number }\\n riskScore: { type: number }\\nsteps:\\n - id: load\\n kind: tool\\n tool: corpus-load-candidate\\n name: Load candidate ITEM.md\\n - id: score\\n kind: tool\\n tool: quality-reviewer-score\\n name: Compute qualityScore + riskScore via reviewer operator\\n - id: gate\\n kind: branch\\n name: Auto-promote gate\\n branches:\\n - { when: \\\"output.qualityScore >= 4.2 && output.riskScore <= 1.5\\\", next: \\\"auto-promote\\\" }\\n - { when: \\\"output.qualityScore < 2.0 || output.riskScore > 3.0\\\", next: \\\"reject\\\" }\\n - { when: \\\"true\\\", next: \\\"queue-review\\\" }\\n - id: auto-promote\\n kind: tool\\n tool: promoteCorpusCandidate\\n name: Promote without human gate\\n - id: queue-review\\n kind: tool\\n tool: corpus-route-to-review\\n name: Move ITEM.md to corpus-review collection\\n - id: reject\\n kind: tool\\n tool: corpus-log-event\\n name: Log corpus.candidate.rejected with reason\\ntags: [corpus, review]\\nmetadata:\\n corpus:\\n domain: marketing\\n triggeredBy: marketing-analyst\\n---\\n\\n# Review candidate workflow\\n\\nStep 3 of the corpus loop (after `analyze-candidate`). Reviewer scores and routes.\\n\",\n \"workflows/update-corpus-index/WORKFLOW.md\": \"---\\nname: Update corpus index\\nid: update-corpus-index\\ndescription: |\\n Regenerate _index.md (faceted catalog) from the current set of\\n active entries. Triggered on promotion, deprecation, or\\n status changes; can also run on demand.\\nversion: \\\"1.0.0\\\"\\ninputs:\\n type: object\\n properties:\\n reason: { type: string, enum: [promoted, deprecated, archived, manual] }\\noutputs:\\n type: object\\n required: [entryCount]\\n properties:\\n entryCount: { type: integer }\\n indexBytes: { type: integer }\\nsteps:\\n - id: snapshot\\n kind: tool\\n tool: corpus-read-snapshot\\n name: Read current workspace snapshot\\n - id: regen\\n kind: tool\\n tool: corpus-regen-index\\n name: Write _index.md from active entries (kind facets)\\n - id: log\\n kind: tool\\n tool: corpus-log-event\\n name: Log corpus.entry.indexed event\\ntags: [corpus, index]\\nmetadata:\\n corpus:\\n domain: marketing\\n---\\n\\n# Update corpus index workflow\\n\\nMaintenance workflow — keeps `_index.md` in sync with the entries directory. The promote workflow inlines this; standalone version is for drift recovery.\\n\",\n})\n","/**\n * Marketing corpus preset.\n *\n * Pure TS data — `files` is inlined from the M0 fixture workspace at\n * build time via `scripts/gen-marketing.mjs`. The M0 conformance test\n * proves every file validates against the actual AgentProto JSON\n * Schemas, so a host that writes these to disk gets a known-good\n * starter workspace.\n *\n * Usage:\n *\n * import { MarketingCorpusPreset } from \"@agentproto/corpus-presets/marketing\"\n * for (const [rel, content] of Object.entries(MarketingCorpusPreset.files)) {\n * await fs.writeFile(path.join(workspaceRoot, rel), content)\n * }\n */\n\nimport type { CorpusPreset } from \"@agentproto/corpus\"\nimport { MARKETING_PRESET_FILES } from \"./files.js\"\n\nexport const MarketingCorpusPreset: CorpusPreset = Object.freeze({\n slug: \"marketing\",\n title: \"Marketing Expert Corpus\",\n description:\n \"Autonomous marketing knowledge — principles, patterns, critiques, playbooks. Composes AIP-10/12/18/9/15/41 into a closed-loop improvement system.\",\n files: MARKETING_PRESET_FILES,\n})\n\n// Re-export the raw file map for callers that want it directly.\nexport { MARKETING_PRESET_FILES }\n"]}
package/package.json ADDED
@@ -0,0 +1,81 @@
1
+ {
2
+ "name": "@agentproto/corpus-presets",
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "@agentproto/corpus-presets — catalog of starter workspaces for the AIP-10 corpus runtime. Subpath exports per vertical (marketing, sales, …). Each preset is pure TS data — host iterates `files` and writes via FsPort. Mirrors @agentproto/role-catalog.",
5
+ "keywords": [
6
+ "agentproto",
7
+ "corpus",
8
+ "presets",
9
+ "starter",
10
+ "aip-10"
11
+ ],
12
+ "homepage": "https://agentproto.sh/docs/corpus",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/agentproto/ts",
16
+ "directory": "packages/corpus-presets"
17
+ },
18
+ "bugs": {
19
+ "url": "https://github.com/agentproto/ts/issues"
20
+ },
21
+ "license": "MIT",
22
+ "type": "module",
23
+ "main": "dist/index.mjs",
24
+ "module": "dist/index.mjs",
25
+ "types": "dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.mjs",
30
+ "default": "./dist/index.mjs"
31
+ },
32
+ "./marketing": {
33
+ "types": "./dist/marketing/index.d.ts",
34
+ "import": "./dist/marketing/index.mjs",
35
+ "default": "./dist/marketing/index.mjs"
36
+ },
37
+ "./package.json": "./package.json"
38
+ },
39
+ "agentproto-corpus-preset": {
40
+ "schema": "agentproto/corpus-preset/v1",
41
+ "presets": [
42
+ {
43
+ "slug": "marketing",
44
+ "entry": "./dist/marketing/index.mjs",
45
+ "export": "MarketingCorpusPreset",
46
+ "description": "Marketing knowledge corpus — principles, patterns, critiques, playbooks. Composes AIP-10/12/18/9/15/41 into a closed-loop improvement system."
47
+ }
48
+ ]
49
+ },
50
+ "files": [
51
+ "dist",
52
+ "README.md",
53
+ "LICENSE"
54
+ ],
55
+ "publishConfig": {
56
+ "access": "public"
57
+ },
58
+ "sideEffects": false,
59
+ "dependencies": {
60
+ "@agentproto/corpus": "0.1.0-alpha.1"
61
+ },
62
+ "devDependencies": {
63
+ "@types/node": "^25.6.2",
64
+ "tsup": "^8.5.1",
65
+ "typescript": "^5.9.3",
66
+ "vitest": "^3.2.4",
67
+ "@agentproto/tooling": "0.1.0-alpha.0"
68
+ },
69
+ "scripts": {
70
+ "predev": "node scripts/gen-marketing.mjs",
71
+ "dev": "tsup --watch",
72
+ "prebuild": "node scripts/gen-marketing.mjs",
73
+ "build": "tsup",
74
+ "clean": "rm -rf dist src/marketing/files.ts",
75
+ "precheck-types": "node scripts/gen-marketing.mjs",
76
+ "check-types": "tsc --noEmit",
77
+ "pretest": "node scripts/gen-marketing.mjs",
78
+ "test": "vitest run --passWithNoTests",
79
+ "gen:marketing": "node scripts/gen-marketing.mjs"
80
+ }
81
+ }