
Hook Generator
Generate platform-tuned, voice-aware hooks for any surface — LinkedIn, X/Threads, Instagram captions, cold-email subject lines, regulated-product copy — and the first 3 seconds of a TikTok, Reel or Short, written as what is said, what is on screen and what the first frame shows. Guidance-only: the agent's own LLM composes hooks following SKILL.md, installs from 64 source-attributed exemplars in registry/ (11 of them short videos measured against their creator's own median), and gates output with six enforcement scripts (length / AI-slop + BPR/CLP compliance / structure diversity / build-diary launch headlines / video hook / coordination) — PASS/FAIL with numbers. Recipes route on occasion first, then platform. The opener primitive that feeds post-writer, section-designer, outbound-engine and copy-engine's video script. Multilingual DE/FR/ES/RU/RO gated pending native-speaker validation.
Ask any model for ten hooks and you get ten hooks. They scan fine, and they are invented. The model returns the statistical middle of every opener it has read, which is why everyone's first line now sounds the same. I shipped a version of this skill that worked exactly that way, and the verdict I got back was one word: useless. So I inverted it. hook-generator carries 64 hook templates, each lifted from a real published post and each carrying the URL it came from. Eleven are the first 3 seconds of real short videos. I read the best and the worst video of 12 creators frame by frame: 8 of the 12 worst opened on the creator themselves, and 1 of the 12 best did. Your agent matches on platform and angle, installs the templates, and writes your topic into shapes that already ran. Then it gates itself: six scripts check length against per-platform ceilings, lint for AI-slop with a non-overridable BPR and CLP gate for regulated products, demand real variety, fail a launch headline that sells how the thing was built, and check a video hook's words, on-screen text and first frame. Eighteen templates carry a verifiable metric; the rest say pattern-level rather than carrying numbers nobody measured. It writes the opener and nothing else.
Features7
Pulls from 64 source-attributed templates instead of training data, so your opener inherits a shape that actually ran.
Writes what is said, what is on screen and what the first frame shows, from 24 real shorts where each creator's best and worst openings differed.
Contrarian, number-led, admission, story, future-shock and identity, with at least four distinct structures per set.
Promise on line one, escalating proof on line two, cut at the see-more fold. The highest-converting opener shape, from a 349k-follower creator.
Six scripts gate length, AI-slop, structure, launch headlines and video hooks, and report PASS or FAIL with the actual numbers.
Announcing something you shipped loads a launch recipe that names what the buyer can now do, not how you built it.
A non-overridable BPR and CLP lint stops 'non-toxic' and friends shipping on a biocide.
Videos1 video
DemoHook Generator Skill Demo
Demo · SpiderMediaArticles about Hook Generator2 articles
Everyone's launch post sounds like a build log. Your agent writes the other kind.
opvs.ai21 Jul 2026Everyone's launch post sounds like a build log. Your agent writes the other kind.
Ask your agent to announce something you shipped and it writes about the machinery. v1.4.0 made a launch its own occasion, with a lint that fails a headline selling the build instead of the product. v1.5.0 adds the first 3 seconds of a Reel, TikTok or Short.
AI employees with this skill3 profiles on opvs.ai/catalog
3 AI employees use Hook Generator
Videos1 video
DemoHook Generator Skill Demo
Demo · SpiderMediaArticles about Hook Generator2 articles
Showing all 2
AI employees with this skill3 profiles
Showing all 3
3 AI employees use Hook Generator
SKILL.mdthe file your agent reads
SKILL.md loads when you open this tab.
What's new12 releases · newest first · from the package's CHANGELOG
v1.5.22026-11-01Latest
- **Fixed** the structure grader rejecting capitalized command openers such as "Try this"; case-insensitive matching is scoped to the opening verb so the uppercase emphasis detector stays case-sensitive. - **Fixed** "For writers" identity hooks and "Bring" command hooks being unclassified. Near misses remain unclassified. - Kept regression tests for all three failures outside the published bundle. Registry, recipes, media and all other detectors unchanged (DAS2-34).
v1.5.12026-09-27
Marketplace card media only (propagation of 1.5.0, DAS-213). No behaviour change. - **Changed** `media.hero_image_url` to the SAY / WRITE / SHOW chalk diagram, so the card shows the 3-second video hook that 1.5.0 added. Same image as the blog cover and the `/skills-hook-generator` hero (one render, three surfaces). The previous INVENT / INSTALL hero stays in use inline on the blog. - **Kept** all 3 screenshots unchanged (same URLs, same order). - `skills/hook-generator/` content is byte-identical to 1.5.0 apart from the version line in SKILL.md and schema.yaml. - Staged from the signed live 1.5.0 bundle (sha256 `318aa83f…ef71e`, verified), not from drafts.
v1.5.02026-09-26
The 3-second VIDEO hook (DAS-213) — deferred since 1.0.0 for "no research backing yet". This is that research, and the recipe it earns: - **Added** `recipes/video-hook.md` + `references/video-hooks.md` — the first 3 seconds of a TikTok, Reel or Short, written as three channels: **say** (spoken, 0–3 s), **write** (text on screen, with its hold time) and **show** (frame 0 → 3 s). One hook maps to one row of copy-engine's `video-script` beat table and to video-director's shot 1. - **Added** 11 registry items `vid-*` (53 → 64). Each is a creator's top short at ≥ 3x their own median (5.2x–22.5x), their own post (no collab, no paid tag), read in frames. Metric = platform-reported views + the measured ratio. Install the shape; the numbers belong to the creator. - **Added** `scripts/verify-video-hook.mjs` — text present · spoken hook line within budget (EN ≤ 10 words, WARN ≤ 13) · on-screen text ≤ 3 words/s of hold · no greeting, filler or meta opener · frame 0 never opens on a logo, title card, black or fade, and names its subject (a miss only WARNs) · a set gives ≥ 3 variants, ≤ 1 question · labels video-analyst can read back. PASS/FAIL with numbers. `--single` scores one hook; `--emit-texts` feeds `lint-anti-patterns` and `lint-build-diary`. - **Added** 4 learnings: the thresholds and their sources · the promise decides, polish is table stakes · model from a creator's best against their worst · collab posts inflate view ratios. - **Evidence:** 24 videos — 12 creators × their top and low, 4 each on TikTok / Reels / Shorts — read on 2026-09-26 in words and frames with `@di-atomic/video-analyst`. A self-centred first line: tops 1/12, lows 8/12. Text on screen by 3 s: 11/12 vs 12/12 — table stakes, not the edge. The checker FAILs 0 of 11 tops and 6 of 12 lows (in-sample; the next corpus refresh is the out-of-sample test). - **Peer added (required):** `@di-atomic/video-analyst >=0.1.1` — reads a reference video's opening before writing, judges the rendered opening after. - **Wired:** SKILL.md routes short video to the new recipe; the line that said the video hook was "NOT shipped" now says thumbnails belong to `@di-atomic/thumbnail`; triggers, gate block, registry count and the composition chain updated. AGENTS.md + DEPLOYMENT.md carry the video route, output contract and consumers. schema.yaml's coordination mirror matches the new SKILL.md wording. - **Fixed — stale facts found by a whole-bundle sweep:** README said v1.2.0, 52 exemplars and "video deferred", and pointed at a `source/` folder that never ships → rewritten; attribution now lives in a root `PROVENANCE.md` (ideas only, licences reproduced). package.yaml's header claimed it was generated by `_build/build-package.mjs` → corrected (there is no generator; DAS-155). SKILL.md frontmatter version (was 1.3.0), schema.yaml version (was 1.4.0), the "v1.0.1" non-EN gate labels, DEPLOYMENT.md's "3 scripts" and "v1.1 backlog" lines, and platform-algorithm's "deferred recipe" row. - **Vendored:** `vendor-scripts.mjs` (step 0-pre) installed the canonical self-resolving coordination wrapper. - Built from the signed live 1.4.2 bundle (sha256 `984d9532…`, verified), published from a clean staged copy.
v1.4.22026-08-23
The rest of the stale card copy, which 1.4.1 should have caught in the same pass:
- **Fixed** the package `description` — it still said **52** exemplars and **three** gate
categories, and it still described the bundle as the flat `skills:[]` shape removed back in
1.2.1. Live has been nested `skills:[{id,schema}]` since then, so that line was actively
wrong about the artifact a customer installs.
- **Removed** the trailing `v1.2.0:` release note from the description. Version history belongs
in this file, not in the field that renders on the marketplace card.
- **Added** the occasion-then-platform routing rule to the description, matching SKILL.md.
- No code, recipe, registry or script changes. `skills/hook-generator/` remains byte-identical
to 1.4.0.v1.4.12026-08-23
Marketplace card copy caught up with 1.4.0 (no behaviour change): - **Fixed** `marketing.long_description` and the "Fails your copy before your audience does" feature, both of which still said **three** gate scripts. There are five as of 1.4.0 (`lint-build-diary.mjs` and `verify-coordination.mjs` were the additions). Understated rather than false, but a card that undercounts its own gates undersells the thing it is selling. - **Added** a card feature for the launch occasion recipe — 1.4.0's headline capability was not represented on the marketplace card at all. - No code, recipe, registry or script changes. `skills/hook-generator/` is byte-identical to 1.4.0. - Built by pulling the signed live 1.4.0 bundle (sha256-verified), patching only `package.yaml` and this file, and publishing from that clean staged copy — per the 1.3.0/1.3.1/1.4.0 precedent.
v1.4.02026-08-23
The launch occasion (DAS-152) — the skill can now tell a launch headline from a build diary:
- **Added** `recipes/launch-hook.md` — the skill's **first occasion recipe**. Every other recipe
answers *"which surface?"*; this one answers *"what is the moment?"*. All six existing recipes
are platforms (LinkedIn · X · Instagram · email · multilingual · regulated), so nothing told the
skill that a launch plays by different rules. Loaded **in addition to** the platform recipe: the
platform sets the length ceiling, the occasion sets the subject.
- **Added** `scripts/lint-build-diary.mjs` — the enforceable half. Fails a launch headline that
sells how the thing was built instead of what the buyer can now do. Three-level ladder:
`1·build-diary` ❌ ("I verified 158 citations. 42 failed.") · `2·symptom` ⚠ ("Why your webinar
gets great feedback and nobody buys") · `3·launch` ✅ ("Create webinars like Russell Brunson").
Builder-voice ("I verified…", "how I built…", "so your agent doesn't have to") is a hard,
non-overridable FAIL. Build vocabulary (`citations`, `pipeline`, `corpus`, `schema`, `registry`…)
fails only when the line carries no buyer signal, so "Cold email scripts that book meetings"
survives on its outcome.
- **Level 2 is the trap, and it is now gated.** It passes every other verifier in this skill —
length, slop, structure diversity all say fine — because it is a *good* headline. It just
announces nothing: a stranger reading it never learns anything shipped. It FAILS under
`--occasion launch` and PASSES under `--occasion content`. The previous fix for this defect
stopped at level 2, which is why the defect was reported twice on the same skill.
- **Added** first-launch vs upgrade branching, resolved by **registry lookup, not judgement** —
`tool_help({name})`: no earlier published version → first-launch; one exists → upgrade. Carries
the subtlety that the canonical blog slug is version-less, so an upgrade **rewrites the launch
post in place** rather than writing a new story.
- **Wired** into SKILL.md: the decision tree is now *occasion first, then platform*, and the gate
block runs the lint per surface — blog title, social openers, marketplace card headline, listing
hero. The angle propagates, and last time the defect fired all four social drafts inherited it.
- Rule source: `TACTIC-founder-epiphany-story.md` §2 — "explain the vehicle, do not tease it".
- **Fixed (found while wiring the gate, outside DAS-152's scope):** `scripts/verify-coordination.mjs`
imported `'../../../scripts/_verify-coordination-shared.mjs'`, which resolves to the bundle ROOT in
the nested layout — but the helper is vendored **beside** the script. So the file crashed with
`ERR_MODULE_NOT_FOUND` in every shipped nested bundle: one of the gate scripts had never actually
run for a customer. The file's own comment already documented the correct value
(`'./_verify-coordination-shared.mjs'`); line 23 contradicted it. Corrected to match.
- **Fixed:** with the import repaired the check ran for the first time and failed —
`skills/hook-generator/schema.yaml` (the 6-line guidance-only stub) carried no `guidance.uses:`
mirror of the `## Coordination` block. Added it, values copied **verbatim** from SKILL.md, nothing
invented. Also synced the stub's stale `version: "1.2.1"` to `1.4.0`.
- Registry (53 items) and references UNCHANGED. **All 5 gate scripts now PASS — and all 5 run.**v1.3.12026-08-22
Grader defect fix (DAS-148) — number-led titles no longer fall through to UNCLASSIFIED:
- **Fixed** `scripts/grade-against-examples.py`: the `number-led` detector gated on a fixed
eight-noun vocabulary (`things | ways | tips | patterns | reasons | lessons | hooks | types`),
so a well-formed number-led title whose noun was off-list returned **UNCLASSIFIED**. Live
repro: *"The 7 checks I run on every cold email"* — a textbook listicle title the classifier
could not see. The same hole hit `checks · files · scripts · steps · rules · gates · signals ·
questions · traps · mistakes · reviews`, i.e. most of the house register, which is built on
countable engineering artifacts.
- **Changed** the gate from vocabulary to **shape**: `<number> [modifier…] <plural-noun> <clause>`,
scanned across a 4-token window so adjectives don't break the match ("5 simple ways"). A
hardcoded list will always lag the writing; the shape does not.
- **Kept** `PLURAL_NOUNS` as a *confidence signal* rather than the gate — it now promotes
irregular plurals (`people`, `children`, `criteria`) and acronym plurals (`CFOs`, `KPIs`)
that an `-s` heuristic cannot reach. Added `NON_NOUN_S`, a stoplist that keeps
*"3 is enough"* from reading as a listicle.
- **Added** UNCLASSIFIED diagnostics — a failing hook now prints the token trail it scanned
(`"3" → scanned ['is','enough','for','anyone'] — no token read as a plural noun`), so the
next vocabulary gap is a one-minute read instead of a debugging session.
- **Added** `tests/_fixtures-number-led-nouns.json` — an 8-hook regression set carrying all four
DAS-148 fixtures plus enough structural variety to exercise the set-level gates. Exits 0.
- Detector ORDER unchanged, so narrative still beats a bare figure ("Yesterday I lost 3 clients"
→ `admission`) and "5 tips for 2026" still reads `number-led`, not `future-shock`. The
original `tests/_fixtures-cfo-hooks.json` run is **byte-identical** to its pre-fix baseline.
- Content, registry (53 items), references, recipes and the other three gate scripts UNCHANGED.
All 4 gate scripts PASS.
- Built by pulling the live 1.3.0 nested bundle from the marketplace (sha256-verified,
signature-verified) and applying the single script fix on top — the local drafts lineage was
NOT used, per the 1.3.0 precedent.v1.3.02026-08-01
Stacked two-line hook — new composition technique (field-observed enrichment): - **Added** `references/stacked-hooks.md` — the two-line opener (line 1 promise + open loop, line 2 escalating proof, cut at the see-more fold). A *composition* over any base angle, not a seventh angle, with the escalation rule + 4 anti-patterns + a grading note. - **Added** registry item `li-stacked-double-hook` (registry now **53** items) — source: Lara Acosta (@laraacostar, 349k LinkedIn followers), field-observed 2026-07 via scrapecreators-api. New tag namespace `composition:stacked-hook`. Metric honestly labelled: the "$1M" figure is copy-internal (author's claim), NOT a source-reported engagement metric. - **Wired** into SKILL.md universal loop (step 2 loads `stacked-hooks.md`; step 4 offers ≥1 stacked variant on see-more surfaces) + `psychology-of-hooks.md` (new Composition section). Corrected the registry count in SKILL.md (was 58, actually 53). - Grader UNCHANGED — stacking is applied, not detected; each line still classifies under an existing structure. All 3 gate scripts still pass. - Built by pulling the live 1.2.1 nested bundle from the marketplace (sha256-verified) and applying on top — the local drafts flat lineage was NOT used.
v1.2.02026-06-17
Guidance-only conversion (per OPVS "DEFINITIVE: does the skill DO something?" rule, 2026-06-17): - **Removed** `schema.yaml` + all method declarations + the phantom HTTP backend. hook-generator's "methods" (generateHooks / scoreHook / auditHook) were always LLM reasoning, never callable APIs — declaring `base_url` + `auth` + methods against a non-existent backend caused upstream 404s when agents tried to call them. The old `client/schema.yaml` is preserved at `source/legacy/client-v1.1.0/` for provenance. - **Changed** to the canonical guidance-only shape: `skills: []` + `peer_dependencies` (4 upstream OPVS coordination skills + voice-builder). Access pattern: `skill_search` → `skill_read` (reads SKILL.md directly out of the .tgz). Nothing to 404. - **Added** `README.md` (marketplace listing) + this `CHANGELOG.md` at bundle root (security-review required-docs check). `docs.skill_guide` → `SKILL.md`, `docs.readme` → `README.md`, `docs.changelog` → this file. - **Reframed** SKILL.md `## Methods (Tier 3)` → `## Operations (guidance-only, no callable API)`. - Content unchanged: SKILL.md router, 4 references, 5 recipes, 52-item registry, 9 learnings, 4 scripts.
v1.1.02026-06-16
- **Added** v2.2 Coordination cross-references (`## Coordination` in SKILL.md + `scripts/verify-coordination.mjs`): agentdocs + agentmemory + opvs-protocol declared USE; agentboard n/a.
v1.0.12026-06-16
- **Added** SpiderPublish-surface awareness — `references/publishing-to-spiderpublish.md` (block-fit, `dynamic_landing` per-lead LP heroes, deploy gate) + composition chains terminating at SpiderPublish + a hosting-surface learning.
v1.0.02026-06-15
Initial release (v2.1 7-layer). SKILL.md router + schema.yaml (3 methods) + 4 references + 5 recipes + 52 EN registry items (6 multilingual gated) + 8 learnings + 3 verifier scripts. Synthesis of charlie947 + coreyhaines31 MIT upstreams; wave-1 research pack (52 source URLs). Shipped 100/100.











