feat(linkedin-studio): N24 — promo-post-motor (hook-forge + shareability-gate) [skip-docs]
Step 9 (post-lock distribution gate) får to tillegg, begge scoped til utgave-promo: 1. Hook-forge (E#7): 5-8 krok-varianter for delingsteksten. 110-140-båndet håndheves PER VARIANT og MÅLES (perl -CSD; awk length/wc -c teller bytes og lyver på æ/ø/å). Utenfor båndet = diskvalifisert, ikke rangert lavere. Settet må spenne minst tre krok-typer, ellers er det omskrivinger, ikke valg. Hver variant må spores til en påstand kroppen faktisk gjør (ingen bait). Ingen predicted-engagement score — et tall som påstår å vite hva som sprer seg er oppfunnet (N22-defektklassen); operatøren rangerer. Valgt variant går GJENNOM randsone-gaten, aldri utenom. 2. Shareability-gate (E#8): konverter-modus får en ANDRE binær — deling. «Hvem deler dette til en kollega, og hvorfor?» + RESHARE/SAVE/SEND. Svaret må navngi en rolle og et avsender-motiv; «nyttig for alle i tech» er NEI. Blokkerende: to mislykkede omramminger => operatørvalg (pivot eller registrert foldIn), aldri en stille passering. Ti suiter grønne: test-runner 300/0 (287->300, +13 ubetingede; floor 268->281) · trends 300 · analytics 202 · hooks 191 · brain 134 · editions 72 · render 63 · specifics-bank 45 · tests 35 · contract-gate 33. Begge nye compound-predikater mutasjonstestet mot faktisk fil (fjernet literal => rød). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RvtDSvQDUmjd5bXdAxUu6D
This commit is contained in:
parent
af80150019
commit
77426135a5
7 changed files with 337 additions and 56 deletions
|
|
@ -171,7 +171,7 @@ contains ONLY the cold-contract inputs. Map `--type` to archetypes:
|
|||
| `language` | `linkedin-studio:language-reviewer` | — | frozen draft + contract |
|
||||
| `fact` | `linkedin-studio:fact-reviewer` | — | frozen draft + contract |
|
||||
| `persona-resonance` | `linkedin-studio:persona-reviewer` | `mode: resonans`, one call **per active persona** | frozen draft + persona block |
|
||||
| `persona-conversion` | `linkedin-studio:persona-reviewer` | `mode: konverter`, **primær only** (hook only) | distribution hook / first two lines |
|
||||
| `persona-conversion` | `linkedin-studio:persona-reviewer` | `mode: konverter`, **primær only** (klikk + deling) | distribution copy: hook / first two lines + the promise it makes |
|
||||
|
||||
`all` = every row above (resonance fans out one call per active persona;
|
||||
conversion runs the primær). **Cold-prompt template** for each call:
|
||||
|
|
@ -215,7 +215,7 @@ yourself or pick winners between reviewers — surface them, the operator gates.
|
|||
| # | F-kat | 🔴/🟡/🟢 | Påstand | Kilde / retning |
|
||||
… + Pivot-risk: <claims that look freshly added, or "none">
|
||||
### persona-resonance — <per persona: JA/NEI + ≤5 flags>
|
||||
### persona-conversion — <primær JA/NEI on the hook>
|
||||
### persona-conversion — <primær klikk JA/NEI on the hook + deling JA/NEI (forwarder role, motive, RESHARE/SAVE/SEND)>
|
||||
|
||||
## Cross-archetype signal
|
||||
- BLOCK / 🔴 total: <N> REWORK total: <N> primær resonance: JA/NEI primær conversion: JA/NEI
|
||||
|
|
|
|||
|
|
@ -877,7 +877,7 @@ Next: Step 2.5 — Skeleton + section pitch (operator + persona gate BEFORE pros
|
|||
`<serie>/NN-skjelett.md`, and **`mode: skjelett`** (the before-prose mode —
|
||||
five spine axes, ≤3 flags as direction, HOLDER/TVILER/MANGLER scoring).
|
||||
This is NOT resonans mode (Step 6 — that runs on full prose) and NOT
|
||||
konverter mode (Step 9 — that judges the hook only).
|
||||
konverter mode (Step 9 — that judges the distribution copy: klikk + deling).
|
||||
|
||||
8. **Collect skjelett verdicts and gate.** Each call returns per-axis flags
|
||||
(HOLDER/TVILER/MANGLER), ≤3 direction-only flags, a section-pitch check
|
||||
|
|
@ -1617,7 +1617,7 @@ command runs — see `${CLAUDE_PLUGIN_ROOT}/commands/headless-review.md` for the
|
|||
- `linkedin-studio:language-reviewer` — language quality (L1–L5; grades against `edition-state.language`, Norwegian-specific rules when `language: no`)
|
||||
- `linkedin-studio:fact-reviewer` — cold re-verification (F1–F4, 🔴/🟡/🟢, incl. pivot premises)
|
||||
- `linkedin-studio:persona-reviewer` `mode: resonans` — **one call per active persona**
|
||||
- `linkedin-studio:persona-reviewer` `mode: konverter` — **primær only** (hook)
|
||||
- `linkedin-studio:persona-reviewer` `mode: konverter` — **primær only** (hook + share; advisory here, blocking at Step 9)
|
||||
|
||||
Each call's prompt carries ONLY the cold-contract inputs (frozen draft path,
|
||||
`language`, contract path if it ships, persona for the persona modes) + the
|
||||
|
|
@ -2061,18 +2061,22 @@ Next: Step 9 — Hook / conversion gate (post-lock).
|
|||
The locked edition still has to earn the feed. Before it ships, the
|
||||
**feed-facing surfaces** the reader actually meets — the **delingstekst hook**,
|
||||
the **samle post**, the **carousel slide text**, and the **edition title** —
|
||||
face two final gates: a **randsone fact + language gate** (so nothing false or
|
||||
clumsy reaches the feed in the most-read, most-requoted copy — C-4/C-9) and the
|
||||
**hook conversion binary** (would the primær persona, scrolling, actually stop
|
||||
and open this?). Both operate on **distribution copy only** — the post-lock
|
||||
sweep, distinct from the pre-lock resonance sweep (Step 6), never the locked
|
||||
body. Until N9 only the hook's click-worth was judged; the hook's *truth and
|
||||
language*, the samle post, the carousel slides and the title reached the feed
|
||||
ungated.
|
||||
face a **hook-forge** (the krok competes against alternatives instead of shipping
|
||||
the one the draft happened to end on) and three gates: a **randsone fact +
|
||||
language gate** (so nothing false or clumsy reaches the feed in the most-read,
|
||||
most-requoted copy — C-4/C-9), the **hook conversion binary** (would the primær
|
||||
persona, scrolling, actually stop and open this?), and the **shareability gate**
|
||||
(would that reader pass it on — and to whom?). All operate on **distribution copy
|
||||
only** — the post-lock sweep, distinct from the pre-lock resonance sweep (Step 6),
|
||||
never the locked body. Until N9 only the hook's click-worth was judged; the hook's
|
||||
*truth and language*, the samle post, the carousel slides and the title reached
|
||||
the feed ungated — and until N24 the hook shipped unchallenged and nobody asked
|
||||
who would forward the edition.
|
||||
|
||||
> **Order assertion (enforced).** This gate (Step 9) runs AFTER lock (Step 8) — it
|
||||
> operates on the **distribution copy** of an already-locked edition and must never
|
||||
> reopen the locked body. Both the randsone fact/language gate and the hook binary
|
||||
> reopen the locked body. The hook-forge, the randsone fact/language gate, the hook
|
||||
> binary and the shareability gate all
|
||||
> revise only distribution surfaces (delingstekst, samle, carousel text,
|
||||
> distribution title) and re-render via Step 8's `build-linkedin.mjs` /
|
||||
> `build-carousel.mjs` — never the edition text. A defect that traces into the
|
||||
|
|
@ -2101,7 +2105,38 @@ lock invariant without breaking phase order.
|
|||
- the **edition title** — the edition's own headline (its distribution / feed
|
||||
title), never strength-gated before now.
|
||||
|
||||
2. **Randsone fact + language gate (scoped — C-4/C-9).** Run two scoped reviewers
|
||||
2. **Hook-forge — forge the alternatives before gating one (E#7).** The hook that
|
||||
exists is the one the draft happened to end on; it has never competed against
|
||||
anything. Forge **five to eight hook variants** for the delingstekst krok, then
|
||||
let the operator choose — the gates below judge the chosen krok, not the accident.
|
||||
- **Measure the band, per variant.** Each variant's opening line must land in
|
||||
**110–140 characters** (the mobile "…see more" cutoff — the hook rule the
|
||||
short-form surfaces already hold). Measure it, never estimate it:
|
||||
`perl -CSD -ne 'chomp; printf "%d\n", length($_)'`. Norwegian æ/ø/å are
|
||||
multibyte, so `awk length` and `wc -c` count BYTES and over-report. A variant
|
||||
outside the band is **disqualified, not ranked lower** — the cutoff is
|
||||
physical, not a preference, and it is enforced per variant, never on the set.
|
||||
- **Span the hook types.** Name each variant's type from
|
||||
`${CLAUDE_PLUGIN_ROOT}/references/engagement-frameworks.md`. The surviving set
|
||||
must cover **at least three distinct hook types** — otherwise the forge
|
||||
produced rewordings of one idea and the operator has no real choice.
|
||||
- **Trace every variant to the locked body.** A variant must rest on
|
||||
**a claim the locked body actually makes**. One that promises what the
|
||||
edition does not deliver is disqualified — it is bait, and the randsone fact
|
||||
gate below would 🔴 it anyway.
|
||||
- **Carry only what can be checked.** Each variant ships with its measured
|
||||
length, its hook type and its body-trace — and
|
||||
**no predicted-engagement score**. A number claiming to know which krok will
|
||||
travel is invented; the ranking is the operator's, on variants the plugin can
|
||||
honestly describe.
|
||||
- **Fewer than five survivors → forge again.** Presenting three survivors as
|
||||
"the set" hides that the band or the body constrained the forge.
|
||||
- The operator picks one via `AskUserQuestion` — the gate that already exists
|
||||
here. The chosen variant becomes the delingstekst hook and goes
|
||||
**through the randsone gate, never around it**: the same fact, language and
|
||||
length rules as any other distribution copy. `[GATE]`
|
||||
|
||||
3. **Randsone fact + language gate (scoped — C-4/C-9).** Run two scoped reviewers
|
||||
over *only* these surfaces (never the locked body), issued from THIS command
|
||||
layer in the foreground, `subagent_type` namespaced:
|
||||
- `linkedin-studio:fact-reviewer` — **F1** (verifiable claims) + **F3** (number
|
||||
|
|
@ -2114,7 +2149,7 @@ lock invariant without breaking phase order.
|
|||
Pass each reviewer only the four surfaces + the sources they cite + `language`.
|
||||
This is a **scoped mini-pass**, not a re-review of the article. `[GATE]`
|
||||
|
||||
3. **Title-strength gate (C-9).** The edition's own title was never strength-gated —
|
||||
4. **Title-strength gate (C-9).** The edition's own title was never strength-gated —
|
||||
only the hook's two lines were. Judge the **title-strength** of the **edition
|
||||
title** here: does it earn the open on its own, or is it a generic label? The
|
||||
strongest candidate becomes the distribution title. The verdict is **binding on
|
||||
|
|
@ -2122,7 +2157,7 @@ lock invariant without breaking phase order.
|
|||
canonical (locked) title** — changing that is a body edit → STOP, run
|
||||
`/linkedin:pivot`; never edit the locked title in place.
|
||||
|
||||
4. **Resolve the randsone gate.**
|
||||
5. **Resolve the randsone gate.**
|
||||
- **Fact 🔴 / L-BLOCK on a distribution surface** → revise that surface **by
|
||||
tightening** (hook, samle, carousel text, or distribution title — all
|
||||
distribution copy), **re-render** the affected artifact (POST.html via Step 8's
|
||||
|
|
@ -2132,32 +2167,63 @@ lock invariant without breaking phase order.
|
|||
pivot: STOP, run `/linkedin:pivot`. The randsone gate never reopens the locked
|
||||
body in place — the same invariant as the conversion loop. `[GATE]`
|
||||
|
||||
5. **Run the hook conversion binary** (`subagent_type:
|
||||
linkedin-studio:persona-reviewer`, **`mode: konverter`** — the after-lock,
|
||||
hook-only mode, NOT resonans) for the **primær** persona only. The agent returns
|
||||
a single binary verdict, **JA / NEI**, on «would YOU click?» — no axis scoring,
|
||||
no flags, no rewritten copy (the jury judges, the editor writes).
|
||||
- **JA** → the hook converts. Proceed to Step 10.
|
||||
6. **Run the distribution binaries** (`subagent_type:
|
||||
linkedin-studio:persona-reviewer`, **`mode: konverter`** — the after-lock
|
||||
distribution mode, NOT resonans) for the **primær** persona only, on the chosen
|
||||
forge variant. The agent returns **two binary verdicts** — **klikk** («would YOU
|
||||
click?») and **deling** (item 7) — no axis scoring, no flags, no rewritten copy
|
||||
(the jury judges, the editor writes; the forge is the editor's pen).
|
||||
- **JA** → the hook converts. Proceed to the shareability gate.
|
||||
- **NEI** → revise the **delingstekst hook only** (sharpen the krok by tightening,
|
||||
body frozen), **re-render POST.html** via `build-linkedin.mjs`, and re-run the
|
||||
conversion check. Loop until JA. `[GATE]`
|
||||
or take the next forge variant — body frozen), **re-render POST.html** via
|
||||
`build-linkedin.mjs`, and re-run the conversion check. Loop until JA. `[GATE]`
|
||||
|
||||
6. **Persist.** Record the randsone-gate result in `edition-state.json` →
|
||||
7. **Shareability gate — «hvem deler dette til en kollega, og hvorfor?» (E#8).**
|
||||
A click is one reader; a forward is peer acknowledgement, and it is the signal
|
||||
the edition was written to earn. The `konverter` call's second binary is the
|
||||
**deling verdict**: judged by the primær persona on the same distribution copy —
|
||||
**who forwards this to a colleague, and why** — plus which action the edition
|
||||
actually earns from that reader: **RESHARE / SAVE / SEND**.
|
||||
- **A plausible answer names a role and a motive.** It must name a role the
|
||||
reader could actually point at, and what forwarding does *for the sender* —
|
||||
signals their judgment, saves a colleague a decision, settles a running
|
||||
argument. «Useful for anyone in tech» names nobody: that is a **NEI**.
|
||||
- **NEI → revise the distribution copy** (the promise may simply be framed for a
|
||||
reader nobody forwards to), re-render, re-check. Body frozen, as everywhere in
|
||||
this step.
|
||||
- **Two failed re-framings → stop; do not lower the bar.** If the honest reason
|
||||
is that the edition offers nothing a reader would pass on, that is a
|
||||
body-level finding, not a copy problem: put it to the operator as a choice —
|
||||
run `/linkedin:pivot`, or ship and record it as an `articles.NN.foldIns` row
|
||||
for the Step 11 retro. There is **never a silent pass**: this gate is resolved
|
||||
by a fix or by a recorded operator decision, never by re-reading the same copy
|
||||
more generously. `[GATE]`
|
||||
|
||||
8. **Persist.** Record the forge in `edition-state.json` →
|
||||
`articles.NN.hookForge` (each variant with its measured length, hook type,
|
||||
body-trace and disqualification reason if any, plus which one the operator
|
||||
chose), the randsone-gate result in
|
||||
`articles.NN.randsoneGate` (per-surface fact/language verdicts + title-strength +
|
||||
what was revised) and the conversion verdict in
|
||||
`articles.NN.personaSweep.conversion`; set `currentPhase: "hook-conversion-gate"`.
|
||||
what was revised), the click verdict in
|
||||
`articles.NN.personaSweep.conversion` and the share verdict in
|
||||
`articles.NN.personaSweep.deling` (verdict + the named forwarder role + the
|
||||
RESHARE/SAVE/SEND action, or the recorded operator decision);
|
||||
set `currentPhase: "hook-conversion-gate"`.
|
||||
**↳ Phase transition** — run the protocol (Step 0) for `hook-conversion-gate`,
|
||||
`--next "Step 10 — scheduling"`.
|
||||
|
||||
```
|
||||
Randsone + conversion gate (post-lock, distribution copy only).
|
||||
Forge + randsone + conversion + shareability gate (post-lock, distribution copy only).
|
||||
- Hook-forge: <N> forged / <N> disqualified (band <N>, body-trace <N>) · types spanned: <N> → chose #<k> (<measured> chars, <type>)
|
||||
- Surfaces gated: delingstekst hook · samle post · carousel slide text · edition title
|
||||
- Fact (F1/F3): <N> 🔴 → resolved (or pivot if it traces to the body)
|
||||
- Language (L1/L2): <N> BLOCK → tightened
|
||||
- Title-strength: <verdict> (distribution title sharpened; canonical-title weakness → pivot)
|
||||
- Conversion (primær, konverter): JA (else: NEI — revise hook, re-render, re-check)
|
||||
- Deling (primær, konverter): JA — <role> sends it to <role> because <motive> · action: RESHARE|SAVE|SEND
|
||||
(else: NEI — reframe the copy; twice failed → operator decision, never a silent pass)
|
||||
- Body: untouched (locked in Step 8)
|
||||
Gate: [PASS — randsone clean + JA] (else loop on distribution copy, or pivot)
|
||||
Gate: [PASS — randsone clean + klikk JA + deling JA] (else loop on distribution copy, or pivot)
|
||||
Next: Step 10 — Scheduling.
|
||||
```
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue