feat(linkedin-studio): v3.1.0 — Endring 9 adversarial review-pakke + per-artefakt personas

Cold, adversarial review package for the long-form pipeline + configurable
per-edition personas. Motivated by Del 4 (Security Champions pivot): the
in-session editor + persona sweep shared the drafting session's framing-bias,
so the shipped version was never independently re-reviewed.

Headless package (9a/9b):
- New Step 6.5 (headless-review) in /linkedin:newsletter, after the persona
  sweep, before lock — the independence layer the in-session gates can't be.
- New standalone /linkedin:headless-review command (run in a fresh session for
  maximum isolation; reconstructs frozen draft + contract + personas from disk).
- 3 new Opus archetypes, each with a cardinal context-isolation block that
  refuses drafting-session framing as "context pollution":
  - content-reviewer (argument integrity C1–C5, ≤8 flags)
  - language-reviewer (Norwegian language L1–L5, ≤10 flags)
  - fact-reviewer (cold re-verification F1–F4, risk-sort + pivot-risk, WebSearch)
- Deliberate redundancy with fact-checker / editorial-reviewer documented so
  the pairs are never de-duplicated.

Pivot-reopen (9c):
- New /linkedin:pivot command: logs articles.NN.pivots[], resets currentPhase,
  un-locks, marks gates to re-run.
- Pivot-detection gate in Step 8 lock precondition (>20% word-count change or
  >2 new sections re-opens cleared gates). Del 4 v8→v11 worked example.

Per-artifact personas (new requirement):
- articles.NN.personas with resolution order (edition-state → series file →
  plugin library → interactive). One or more readers configurable per edition.

Schema/docs:
- edition-state.template.json: additive personas[], pivots[], headlessReview,
  headless-review phase (16 phases); personaSweep.resonance.wordCount baseline.
- 3 fasit fixtures + 3 structural lint tests (Del 4 worked cases).
- Counts: 24→26 commands, 16→19 agents, 15→16 newsletter phases.
- README + CLAUDE.md (plugin + root) + CHANGELOG synced.

Verification: 35 agent-fixture + 59 hook + 20 render tests green. Backward-
compatible (additive state); reload required before the 3 new agents resolve.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-05-29 13:01:24 +02:00
commit e69ea1f4c9
20 changed files with 2520 additions and 59 deletions

View file

@ -71,13 +71,15 @@ delegate the fan-out to a nested background agent.
> only layer that can reliably spawn parallel sub-agents. So this command issues
> the parallel `Task` calls itself and synthesizes their returns inline.
## Pipeline overview (15 phases)
## Pipeline overview (16 phases)
The phase order is fixed. Two gates run **BEFORE prose** (skeleton + spine
prose), an **editorial craft gate** runs before the persona sweep, and the
persona resonance sweep runs **BEFORE lock** — these are the single most
important corrections from the Seres process (plan §0.4, principle 5; v2.1 brief
§1 on spine-error cost; v2.4 on the editor/persona role split).
prose), an **editorial craft gate** runs before the persona sweep, the persona
resonance sweep runs **BEFORE lock**, and a **cold adversarial review package**
(Step 6.5) runs after the in-session persona sweep and before lock — these are
the single most important corrections from the Seres process (plan §0.4,
principle 5; v2.1 brief §1 on spine-error cost; v2.4 on the editor/persona role
split; v3.1 / Endring 9 on adversarial independence + framing-bias).
| Step | Phase | What | Tools |
|------|-------|------|-------|
@ -91,22 +93,25 @@ important corrections from the Seres process (plan §0.4, principle 5; v2.1 brie
| 5 | **Fact-check sweep** | risk-sorted (🔴/🟡/🟢), guilty-until-disproven, verification log | **`fact-checker` (parallel)** |
| 5.5 | **Editorial review — BEFORE persona sweep** | editor's craft gate: prose-craft (em-dash density, verbatim repetition, postulated numbers, contradictions, versal-tic) + narrative-architecture (concrete instantiation, theory-anchored hypotheses, series-title symmetry, equal action per addressee, un-overloaded conclusion). ≤10 flags, BLOCK/REWORK/NICE. Operator-gated via `SendUserFile`. | **`editorial-reviewer`** + `SendUserFile` |
| 6 | **Persona sweep — BEFORE lock** | reader jury, primær wins, convergence to clean YES | **`persona-reviewer`** (resonance mode) |
| 6.5 | **Headless adversarial review — BEFORE lock** | COLD review package on a frozen draft, no drafting-session context: content-reviewer (argument) + language-reviewer (Norwegian) + fact-reviewer (cold re-verification incl. pivot premises) + persona-reviewer resonance/conversion. Consolidated, operator-gated via `SendUserFile`. The independence layer the in-session gates can't be. | **`content-reviewer` + `language-reviewer` + `fact-reviewer` + `persona-reviewer`** (parallel) + `SendUserFile` |
| 7 | **Annotation (optional)** | render annotatable review HTML for a manual pass | `render/build-html.mjs` |
| 7.5 | **Visual assets — BEFORE lock** | cover (+ optional inline figures) or carousel deck: behov → per-image brief → generate (mcp-image default / external `cover-raw.png`) → operator-gate (`SendUserFile`) → approve to `cover.png` → credit/caption. Runs before lock so the renderer picks the cover up. | `mcp__mcp-image__generate_image` + `SendUserFile` + (carousel) `render/build-carousel.mjs` |
| 8 | **LOCK → delivery** | POST.html "all in one place" | `render/build-linkedin.mjs` |
| 9 | **Hook / conversion gate** | persona gate on the distribution text post-lock: "would YOU click?" | **`persona-reviewer`** (conversion mode) |
| 10 | **Scheduling** | register the edition in the plugin queue/state for native scheduling | `hooks/scripts/queue-manager.mjs` |
> **Build status:** all 15 phases (Steps 02.5, 3a, 3b, 4, 5, 5.5, 6, 7, 7.5,
> 810) are implemented below. This command takes an edition end-to-end: load →
> calibration → verified research → **skeleton + section pitch (operator +
> **Build status:** all 16 phases (Steps 02.5, 3a, 3b, 4, 5, 5.5, 6, 6.5, 7,
> 7.5, 810) are implemented below. This command takes an edition end-to-end:
> load → calibration → verified research → **skeleton + section pitch (operator +
> persona gate BEFORE prose)** → **spine prose (operator gate BEFORE full
> expansion)** → full prose draft → consistency/quality → fact-check sweep →
> **editorial review (craft gate, operator-gated BEFORE the persona sweep)**
> pre-lock persona sweep → optional annotation → **visual assets (cover/figures
> or carousel, operator-gated BEFORE lock)** → LOCK/delivery → post-lock hook
> gate → scheduling, persisting each phase to `edition-state.json` (machine) and
> `<serie>/STATE.md` (narrative) and stopping cleanly between sessions.
> pre-lock persona sweep → **headless adversarial review (cold review package,
> operator-gated BEFORE lock)** → optional annotation → **visual assets
> (cover/figures or carousel, operator-gated BEFORE lock)** → LOCK/delivery →
> post-lock hook gate → scheduling, persisting each phase to `edition-state.json`
> (machine) and `<serie>/STATE.md` (narrative) and stopping cleanly between
> sessions.
> **Why two gates BEFORE prose (v2.1).** Spine errors are the dearest failure
> mode in long-form: catching one at the skeleton stage costs 515 min, at the
@ -157,9 +162,18 @@ the edition left off before doing anything.
4. **Read the voice profile**`assets/voice-samples/authentic-voice-samples.md`
and anything else under `assets/voice-samples/`. Long-form must match the
author's voice; this is the reference for every drafting and review phase.
5. **Read the persona library**`${CLAUDE_PLUGIN_ROOT}/config/personas.local.md`
if it exists, else `${CLAUDE_PLUGIN_ROOT}/config/personas.template.md`. You
will select the active personas + mark the primær in Step 1.
5. **Resolve the active personas (per-artifact).** Personas are configured **per
edition**, not from one fixed global file. Resolve the set for
`articles.<currentArticle>` in this order (Step 1 finalizes + persists it):
1. **`edition-state.json``articles.NN.personas`** — if already populated
(a resumed edition), use it as-is.
2. **`<serie>/linkedin/personas.md`** — a per-series persona file, if present.
3. **`${CLAUDE_PLUGIN_ROOT}/config/personas.local.md`** (else
`personas.template.md`) — the plugin library; select a subset.
4. **None / insufficient** — Step 1 will **define personas interactively**.
Exactly one persona is the **primær**. The resolved set feeds BOTH the Step 6
resonance sweep AND the Step 6.5 headless package; see
`config/personas.template.md` → "Per-artifact personas".
6. **Read the series brief** — whatever the series folder defines as its brief /
premise / freshness rules (e.g. `<serie>/brief.md`, or the resolved brief
recorded in `edition-state.json`). This anchors angle and scope.
@ -187,7 +201,8 @@ Look up `edition-state.json` → `articles.<currentArticle>` (and the top-level
| `consistency-quality` | Step 5 — Fact-check sweep |
| `factcheck-sweep` | Step 5.5 — Editorial review *(v2.4 — craft gate BEFORE the persona sweep)* |
| `editorial-review` | Step 6 — Persona sweep (pre-lock) |
| `persona-sweep-prelock` | Step 7 — Annotation (optional) → Step 7.5 |
| `persona-sweep-prelock` | Step 6.5 — Headless adversarial review *(v3.1 — cold review package, BEFORE lock)* |
| `headless-review` | Step 7 — Annotation (optional) → Step 7.5 |
| `annotation` | Step 7.5 — Visual assets *(cover/figures or carousel deck, BEFORE lock)* |
| `visual-assets` | Step 8 — LOCK → delivery |
| `lock-delivery` | Step 9 — Hook / conversion gate |
@ -216,8 +231,8 @@ the gated skeleton — typically minutes, not session-length work).
> **Resumption is the deterministic test (plan §10, archetype E).** Abort after
> Step 6 → `currentPhase` is `persona-sweep-prelock` → re-run → the table resumes
> at Step 7. No operator question, no re-doing the persona sweep. The same holds
> at every row.
> at Step 6.5 (headless adversarial review). No operator question, no re-doing the
> persona sweep. The same holds at every row.
Then display a short status:
@ -242,11 +257,20 @@ Settle these dimensions (most should come from context, not questions):
- **Angle** — the one premise this edition argues.
- **Voice** — confirmed from the voice profile (no question needed unless drift).
- **Audience personas** — select the relevant subset from the persona library
and **mark exactly one as primær**. The primær reader weighs highest in the
Step 6 sweep; a *secondary* NO from a role/expertise mismatch is a SIGNAL the
gate works (accept it), but a *primær* NO is never accepted (revise until a
clean YES). See `config/personas.template.md` → "How the library is used".
- **Audience personas (per-artifact)** — finalize the **one or more personas for
THIS edition** from the Step 0 resolution, and **mark exactly one as primær**.
If the resolution found a set (edition-state / series file / plugin library),
confirm or trim it; if it found none — or the operator wants a reader the
library does not cover — **define personas interactively** here (name + the
five fields: rolle, avkobler, overbeviser, ekspertise, sjargong). The primær
reader weighs highest in the Step 6 sweep AND the Step 6.5 headless package; a
*secondary* NO from a role/expertise mismatch is a SIGNAL the gate works
(accept it), but a *primær* NO is never accepted (revise until a clean YES).
**Persist** the resolved set to `edition-state.json`
`articles.NN.personas` (each entry: name, tier, the five fields, source) at the
Step 2 checkpoint — it is then stable across sessions and is the single source
every later sweep reads. See `config/personas.template.md`
"Per-artifact personas".
- **Key points** — the 24 load-bearing claims the edition must make.
- **Tone** — respected-peer vs. teaching-down; calibrated to the primær.
- **Leader-takeaway** — the ONE takeaway + ONE concrete action the reader leaves
@ -316,9 +340,11 @@ Edition brief
source(s) and a confidence marker. Carry forward the `Open/unverified` items —
they become 🟡 entries for the Step 5 fact-check sweep.
5. **Persist + checkpoint state.** Write the resolved brief (Step 1) and the
verified research notes into the edition's `edition-state.json`
(`currentPhase: "research"`, article status `in-progress`) and append a
5. **Persist + checkpoint state.** Write the resolved brief (Step 1), the
resolved **per-article personas** (`articles.NN.personas` — the set + primær
confirmed/defined in Step 1), and the verified research notes into the
edition's `edition-state.json` (`currentPhase: "research"`, article status
`in-progress`) and append a
"research complete → next: skeleton + section pitch (BEFORE prose)" next-step
line to `<serie>/STATE.md` (overwrite). If this is a fresh edition, initialize
`edition-state.json` from the template schema first. Stop cleanly here if
@ -951,9 +977,13 @@ reopening locked texts — the biggest single process error of the series (plan
5. **Persist + checkpoint state.** Record the final per-persona verdicts and the
resolved flags in `edition-state.json``articles.NN.personaSweep.resonance`
(where the old HANDOVER §5 calibration now lives), set
`currentPhase: "persona-sweep-prelock"`, and write a "persona sweep
PASS (primær JA) → next: lock/delivery" line to `<serie>/STATE.md` (overwrite).
(where the old HANDOVER §5 calibration now lives). **Also record the cleared
draft's word count** as `articles.NN.personaSweep.resonance.wordCount`
(`wc -w <serie>/NN-utkast.md`) — this is the **baseline** the pivot-detection
heuristic (Step 8 / `/linkedin:pivot`) compares against to catch a late pivot.
Set `currentPhase: "persona-sweep-prelock"`, and write a "persona sweep
PASS (primær JA) → next: headless adversarial review (Step 6.5, BEFORE lock)"
line to `<serie>/STATE.md` (overwrite).
```
Persona sweep complete (BEFORE lock).
@ -961,8 +991,115 @@ Persona sweep complete (BEFORE lock).
- Convergence rounds: <N>
- primær verdict: JA (else: still NEI — loop open, NOT ready to lock)
- Accepted sekundær ceiling-NOs (signal, not failure): <N or none>
- Cleared word count recorded: <N> (pivot-detection baseline)
Gate: [PASS — primær JA, ready to lock] (else REWORK/BLOCK)
Next: Step 7 — Annotation (optional), then Step 8 — LOCK → delivery.
Next: Step 6.5 — Headless adversarial review (cold review package, BEFORE lock).
```
---
## Step 6.5: Headless adversarial review — cold review package, BEFORE lock
The persona-passed draft now faces a **cold, adversarial review package**: five
independent archetypes read the *finished* text with **none of this session's
context** — no version history, no "deliberately omitted" list, no pivot
narrative, no record of who approved what. They are the independence layer the
in-session gates (`fact-checker` Step 5, `editorial-reviewer` Step 5.5,
`persona-reviewer` Step 6) structurally cannot be, because those share the
drafting session's framing-bias.
> **Why this step exists (Del 4 diagnosis, Endring 9).** In Del 4 the editor and
> the persona sweep ran in the same session as drafting. They shared the
> conversation history, so they carried framing-bias and were not adversarial:
> the resonance sweep effectively judged an early version, editor-approval was
> single-source, and the fact-check was post-hoc relative to a late pivot. This
> step answers KTG's question — *how do I start sessions with no context from the
> main session, to review both content and language?* — by running the review on
> a **frozen** draft through agents that refuse session framing.
> **Order assertion (enforced).** Step 6.5 runs AFTER the in-session persona
> sweep (Step 6) and BEFORE lock (Step 8), on a **frozen snapshot** of the
> publish-ready draft. Any flag the operator folds in is re-touched **before**
> lock — never reopen a locked text (the cardinal Seres lesson). If a pivot
> changes the draft after this gate, `/linkedin:pivot` re-opens the pipeline and
> this package re-runs on the pivoted version. `[GATE]`
**Relationship to the in-session gates (deliberate redundancy).** `fact-reviewer`
overlaps `fact-checker` and `language-reviewer` overlaps `editorial-reviewer`'s
prose axis **on purpose** — the cold re-read catches what the framing-biased
in-session pass hid. `content-reviewer` is genuinely new (argument integrity,
which no in-session gate measures). Do NOT collapse the pairs.
**Procedure** (this is the same package the standalone `/linkedin:headless-review`
command runs — see `commands/headless-review.md` for the full cold contract):
1. **Freeze the draft.** Snapshot the persona-passed `NN-utkast.md` so the
reviewers judge a stable artifact and the report names exactly what was read:
```bash
cd <serie-mappe> && cp NN-utkast.md "review/NN-frozen-$(date +%Y%m%d-%H%M).md"
```
Record the frozen path; pass *that* path (not the live draft) to every reviewer.
2. **Resolve the cold inputs.** The writing contract (`<serie>/../../docs/skrivekontrakt.md`
→ plugin mirror → `references/longform-quality-rules.md`) and the active
personas (`articles.NN.personas`, primær identified). Nothing else.
3. **Fan out the five archetypes in parallel** — issue them in a SINGLE message
(multiple `Task` tool-uses) from THIS command layer in the foreground
(principle 4), `subagent_type` namespaced:
- `linkedin-studio:content-reviewer` — argument integrity (C1C5)
- `linkedin-studio:language-reviewer` — Norwegian language (L1L5)
- `linkedin-studio:fact-reviewer` — cold re-verification (F1F4, 🔴/🟡/🟢, incl. pivot premises)
- `linkedin-studio:persona-reviewer` `mode: resonans` — **one call per active persona**
- `linkedin-studio:persona-reviewer` `mode: konverter`**primær only** (hook)
Each call's prompt carries ONLY the cold-contract inputs (frozen draft path,
contract path, persona for the persona modes) + the instruction to ignore any
framing about prior versions / cuts / pivots. **Never** paste history or
summarize "what we changed" into a reviewer prompt — that is the context
pollution the package exists to eliminate.
> **Maximum-independence path.** The strongest isolation is the operator
> running `/linkedin:headless-review --draft <frozen> --article NN` in a
> **fresh session** (the parent then has no drafting transcript at all) and
> pasting the consolidated report back. The inline fan-out here is the
> single-session path; both use the same agents.
4. **Degradation gate.** Confirm each call returned structured, populated output
(real flags / a verification log), not empty or a hedged paragraph. Re-run any
degraded archetype — do not proceed with a missing reviewer. `[GATE]`
5. **Consolidate + surface (`SendUserFile`).** Merge the returns into one report
at `<serie>/review/NN-headless-<stamp>.md`, grouped by archetype → severity,
with a cross-archetype signal line. **Mark ⚑ converged** any passage two
independent cold reviewers flag — independent agreement with no shared session
is the package's strongest signal. `SendUserFile` it (else a `file://` link)
so KTG decides which flags fold in. You do not resolve flags or pick winners;
the operator gates. `[OPERATØR]`
6. **Fold in by tightening, → v(n+1).** Fold the flags KTG approved into
`NN-utkast.md` **by tightening** (rule 6 — close the gap, hold the length flat).
The editor (this session) holds the pen; never paste a reviewer's direction as
copy. If the fold-in was substantive, re-run the affected archetype on v(n+1).
All of this happens **before** lock, so the body is never reopened post-lock.
7. **Persist + checkpoint state.** Record the run in `edition-state.json`
`articles.NN.headlessReview` (`frozenDraft`, per-reviewer `{reportPath,
summary, status}`, `consolidatedReport`, `foldedIn`/`waived`, `status:
"folded"`), set `currentPhase: "headless-review"`, and write a "headless review
complete (cold, converged flags folded) → next: annotation/lock" line to
`<serie>/STATE.md` (overwrite).
```
Headless adversarial review (cold, BEFORE lock) — complete.
- Frozen draft: <serie>/review/NN-frozen-<stamp>.md
- Archetypes: content · language · fact · persona-resonance (<N> personas) · persona-conversion (primær)
- Converged flags (independent agreement): <N>
- BLOCK/🔴: <N> → folded/waived REWORK: <N> primær resonance: JA conversion: JA
- Surfaced to operator: <serie>/review/NN-headless-<stamp>.md (via SendUserFile) [OPERATØR]
- Folded in (by tightening, pre-lock): <N> Waived: <N>
Gate: [PASS — operator approved, body re-touched pre-lock]
Next: Step 7 — Annotation (optional), then Step 7.5 — Visual assets, then Step 8 — LOCK.
```
---
@ -1175,19 +1312,38 @@ produces the editor's single delivery artifact — `POST.html`, the
(delingstekst) copy, ready to paste into LinkedIn.
> **Order assertion (enforced).** Lock (Step 8) runs AFTER the pre-lock persona
> sweep (Step 6) and BEFORE the hook/conversion gate (Step 9). Reversing lock
> and the pre-lock sweep reproduces the exact Seres failure (reopening locked
> texts) — see Step 6. The post-lock hook-gate (Step 9) judges only the
> distribution hook and never reopens the locked body. `[GATE]`
> sweep (Step 6) AND the headless adversarial review (Step 6.5), and BEFORE the
> hook/conversion gate (Step 9). Reversing lock and the pre-lock sweeps
> reproduces the exact Seres failure (reopening locked texts) — see Step 6. The
> post-lock hook-gate (Step 9) judges only the distribution hook and never
> reopens the locked body. `[GATE]`
**Procedure:**
1. **Confirm lock preconditions.** In `edition-state.json`: the article's
`factcheckLog` has no open 🔴, `personaSweep.resonance` recorded a primær JA,
and `visualAssets` is gated — for `standard` format the approved
`linkedin/NN/cover.png` exists (Step 7.5); for `carousel` format the approved
`carousel.pdf`/`carousel.html` exists. If any is missing, STOP — return to the
relevant step (5/6/7.5). Do not lock past an open gate.
`headlessReview.status` is `folded` (or `run` with no open BLOCK/🔴 the
operator left unaddressed — Step 6.5), and `visualAssets` is gated — for
`standard` format the approved `linkedin/NN/cover.png` exists (Step 7.5); for
`carousel` format the approved `carousel.pdf`/`carousel.html` exists. If any is
missing, STOP — return to the relevant step (5/6/6.5/7.5). Do not lock past an
open gate.
**Pivot-detection gate (Endring 9c — enforced).** Before locking, compare the
current draft against the version that last cleared Step 6:
- **word count:** `wc -w <serie>/NN-utkast.md` vs
`articles.NN.personaSweep.resonance.wordCount` (the recorded baseline);
- **new sections:** top-level headings now present that were absent then
(`grep -c '^## '` delta is a fair proxy).
If the draft has drifted **> 20 % in word count OR gained > 2 sections** since
Step 6 cleared, the text pivoted after its gates — **STOP, do not lock.** Run
`/linkedin:pivot --article NN --reason "<what changed>"`, which re-opens the
pipeline so fact-check (5) → editorial (5.5) → persona (6) → headless (6.5)
re-run on the pivoted version. Likewise, if `articles.NN.pivots[]` has an entry
whose `gatesToRerun` gates have not since re-passed, STOP — the pivot's
re-review is incomplete. (This is exactly the Del 4 v8→v11 case: +42 %, 2 new
sections → the gate would have fired and forced the re-sweep.) `[GATE]`
2. **Confirm the delivery inputs in the series folder.**
`render/build-linkedin.mjs` reads, relative to cwd (`<serie>/linkedin/`):
@ -1335,15 +1491,20 @@ Edition complete. Visible in /linkedin:calendar; mark live via /linkedin:calenda
## Reference Files
- `${CLAUDE_PLUGIN_ROOT}/config/edition-state.template.json` — edition-state schema (15 phases including v2.1 skeleton + spine-prose gates, v2.3 visual-assets, and v2.4 editorial-review)
- `${CLAUDE_PLUGIN_ROOT}/config/edition-state.template.json` — edition-state schema (16 phases including v2.1 skeleton + spine-prose gates, v2.3 visual-assets, v2.4 editorial-review, and v3.1 headless-review + per-article `personas` + `pivots`)
- `${CLAUDE_PLUGIN_ROOT}/config/edition-config.template.json` — static delivery metadata schema (calendar, freshness, credit, captions) — Step 8
- `${CLAUDE_PLUGIN_ROOT}/config/image-credit-caption.template.md` — cover motif + credit + caption table (honest-about-AI credit) — Step 7.5
- `${CLAUDE_PLUGIN_ROOT}/config/edition-delingstekst.template.md` — distribution-copy grammar (`## Del N —` / `## Samle`) — Steps 8/9
- `${CLAUDE_PLUGIN_ROOT}/config/personas.template.md` — reusable reader personas + "primær trumfer" rule
- `${CLAUDE_PLUGIN_ROOT}/agents/fact-checker.md` — Step 5 fact-check agent (risk-sorted, guilty-until-disproven)
- `${CLAUDE_PLUGIN_ROOT}/agents/editorial-reviewer.md` — Step 5.5 editor's craft gate (prose-craft + narrative-architecture, BLOCK/REWORK/NICE; mirrors Maskinrommet §C2)
- `${CLAUDE_PLUGIN_ROOT}/agents/persona-reviewer.md` — Step 2.5/6/9 reader jury (skeleton + resonance + conversion modes)
- `${CLAUDE_PLUGIN_ROOT}/agents/persona-reviewer.md` — Step 2.5/6/9 reader jury (skeleton + resonance + conversion modes); also resonance + conversion in the Step 6.5 headless package
- `${CLAUDE_PLUGIN_ROOT}/agents/voice-scrubber.md` — Step 4 de-AI / Norwegian-chronicle voice scrub (gold standard = approved Norwegian editions, NOT the English post corpus)
- `${CLAUDE_PLUGIN_ROOT}/agents/content-reviewer.md` — Step 6.5 cold argument-integrity review (C1C5; headless, no session context)
- `${CLAUDE_PLUGIN_ROOT}/agents/language-reviewer.md` — Step 6.5 cold Norwegian-language review (L1L5; headless)
- `${CLAUDE_PLUGIN_ROOT}/agents/fact-reviewer.md` — Step 6.5 cold re-verification (F1F4, 🔴/🟡/🟢; catches pivot premises Step 5 missed)
- `${CLAUDE_PLUGIN_ROOT}/commands/headless-review.md` — the Step 6.5 cold review package as a standalone command (run in a fresh session for maximum isolation)
- `${CLAUDE_PLUGIN_ROOT}/commands/pivot.md` — re-opens the pipeline after a late pivot so Steps 56.5 re-run on the changed version before lock
- `${CLAUDE_PLUGIN_ROOT}/commands/react.md` — multi-source synthesis discipline (reused in Step 2)
- `${CLAUDE_PLUGIN_ROOT}/assets/voice-samples/authentic-voice-samples.md` — voice matching
- `${CLAUDE_PLUGIN_ROOT}/references/longform-quality-rules.md` — canonical long-form rules (Steps 2.5, 3a, 3b, 49 all reference)