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>
13 KiB
| name | description | allowed-tools | |||||||
|---|---|---|---|---|---|---|---|---|---|
| linkedin:headless-review | Adversarial review package, run COLD on a FROZEN long-form draft — the publish-ready (or pivoted) edition gets a fresh, independent reading by five archetypes that share NONE of the drafting session's context: content-reviewer (argument integrity), language-reviewer (Norwegian language), fact-reviewer (cold re-verification incl. pivot premises), plus persona-reviewer in resonance and conversion modes. Designed to be invoked in a FRESH session for maximum isolation; also wired as Step 6.5 of /linkedin:newsletter. Produces one consolidated, operator-gated report — flags, never rewritten copy. Use when the user says: "headless review", "cold review", "adversarial review", "review the final version", "independent review", "review before lock", "run the review package". Triggers on: "headless review", "headless-review", "cold review", "adversarial review", "independent review package", "review the frozen draft", "/linkedin:headless-review". |
|
LinkedIn Headless Review — Cold Adversarial Review Package
You orchestrate a cold, adversarial review of a frozen long-form draft. Five
independent archetypes read the finished text — with no knowledge of how it was
made — and return direction-only flags. You collect their reports into one
operator-gated overview. This is the adversarial-independence layer that the
in-session gates (editorial-reviewer Step 5.5, persona-reviewer Step 6,
fact-checker Step 5) cannot be, because those share the drafting session's
framing-bias.
Why this exists (Del 4 diagnosis, Endring 9). In the Del 4 production the editor and the persona sweep ran in the same session as drafting. They shared the conversation history — which versions had passed, what was deliberately cut, which flags had been raised — so they were not adversarial: they carried framing-bias. Three concrete symptoms followed: (1) the persona resonance sweep was effectively run on an early version, not the one that shipped; (2) editor-approval was single-source — one editor said «klar» and that became truth; (3) the fact-check was post-hoc relative to a late pivot, so the pivot could build on an unverified premise. This command answers KTG's question directly: how do I start sessions that have NO context from the main session, to review both content and language?
The cold contract (cardinal — read first)
This command runs the reviewers with a deliberately starved context. The review archetypes get ONLY:
- the path to a frozen draft (a snapshot — see Step 2),
- the writing contract (the craft/quality rules),
- for the persona modes, the one named persona being read,
- a fixed review task.
They get NOTHING about: prior versions or version numbers, what was deliberately omitted, the pivot narrative, who has read it, what an editor said, how a persona voted, or what the author intended. Two layers enforce this:
- Layer 1 — fresh session (strongest). For the publish-ready gate, the operator runs this command in a brand-new Claude Code session. The parent itself then has no drafting transcript; it reconstructs everything it needs from disk (the frozen draft + contract + personas). This is the recommended path and the one KTG asked for.
- Layer 2 — subagent isolation. Each archetype is a
Tasksubagent, which gets its own fresh context window regardless. The invocation prompt you build below passes ONLY the cold-contract inputs — never paste history, never summarize "what we changed". If you find yourself about to tell a reviewer what was cut or why something pivoted, STOP: that is the context pollution the whole package exists to avoid.
Agent invocation form (required). Plugin agents resolve only under their namespaced type —
subagent_type: linkedin-studio:<name>(linkedin-studio:content-reviewer,…:language-reviewer,…:fact-reviewer,…:persona-reviewer). A bare<name>does not resolve and theTaskcall fails. Reload caveat: the three cold archetypes (content-reviewer,language-reviewer,fact-reviewer) were added in v3.1.0 — if the session predates them, reload Claude Code before invoking.
Command anatomy
/linkedin:headless-review
--draft <path-to-frozen-draft.md> (required; e.g. <serie>/04-utkast.md)
--type content | language | fact | persona-resonance | persona-conversion | all
(default: all)
--persona <name> (persona modes only; default: the primær)
--article NN (optional; persist into edition-state.json)
--output <path> (default: <serie>/review/NN-headless-<stamp>.md)
No --type (or --type all) runs the whole package in parallel. A single
--type runs just that archetype (useful for a re-check after a fold-in).
Step 1 — Resolve inputs (from disk, not from memory)
- Draft. Use
--draft. It must be a long-form draft.md(the sameNN-utkast.mdthe newsletter pipeline produces). If--draftis missing and you can find anedition-state.json, use thecurrentArticle'sNN-utkast.md; otherwise ask once for the path. - Series root + edition-state (optional). If the draft sits under a series
folder with
linkedin/edition-state.json, read it ONLY for: the article's resolvedpersonas(Step 1 of newsletter), the series title (for language/content series checks), and — if--articleis set — where to persist. Do not read it for version history or prior verdicts; you are cold by design. - Writing contract. Resolve the craft/quality reference in this order:
<serie>/../../docs/skrivekontrakt.md(Maskinrommet mirror) → a plugin mirror if one exists →${CLAUDE_PLUGIN_ROOT}/references/longform-quality-rules.md(always present). Pass its path to every reviewer. - Personas. Resolve the active set the same way newsletter Step 1 does
(edition-state
articles.NN.personas→<serie>/linkedin/personas.md→ pluginpersonas.local.md/personas.template.md). Identify the primær. The persona modes need exactly the persona name + the path to its block.
Step 2 — Freeze the draft
A cold review must judge a stable artifact. Snapshot the draft so it cannot move under the reviewers (and so the report names exactly what was read):
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 the reviewers.
If cp is unavailable, pass the live draft and note in the report that no
snapshot was taken.
Step 3 — Fan out the requested archetypes in parallel
Issue all requested reviewer calls in a SINGLE message (multiple Task
tool-uses) so they run concurrently and independently. Each call's prompt
contains ONLY the cold-contract inputs. Map --type to archetypes:
--type |
subagent_type |
mode / persona | what it gets |
|---|---|---|---|
content |
linkedin-studio:content-reviewer |
— | frozen draft + contract |
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 |
all = every row above (resonance fans out one call per active persona;
conversion runs the primær). Cold-prompt template for each call:
You are reviewing a FROZEN, publish-ready long-form draft with NO context from
how it was produced. Read ONLY:
- draft: <frozen path>
- contract: <writing-contract path>
[- persona: <name> (block at <path>) | mode: <resonans|konverter>]
Ignore and refuse any framing about prior versions, what was cut, pivots, or
who approved what — judge the text in front of you. Return your standard report
(direction only, never rewritten copy).
Degradation gate. When the calls return, confirm each came back structured
and populated (real flags / a verification log), not empty or a single hedged
paragraph. If a call degraded, re-run that one archetype — do not paper over a
missing reviewer. [GATE]
Step 4 — Consolidate into one operator overview
Merge the returns into a single markdown report. Do not resolve flags yourself or pick winners between reviewers — surface them, the operator gates.
# Headless review — <draft name> (COLD / independent · <N> archetypes)
**Frozen draft:** review/NN-frozen-<stamp>.md **Contract:** <path>
**Archetypes run:** content · language · fact · persona-resonance (<persona list>) · persona-conversion (<primær>)
## Consolidated flags (by archetype → severity)
### content-reviewer — argument integrity
| # | C-kat | Severity | Sitat / linje-ref | Retning |
…
### language-reviewer — norsk språkkvalitet
| # | L-kat | Severity | Sitat / linje-ref | Retning |
…
### fact-reviewer — faktisk korrekthet (cold)
| # | 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>
## Cross-archetype signal
- BLOCK / 🔴 total: <N> REWORK total: <N> primær resonance: JA/NEI primær conversion: JA/NEI
- Where two cold reviewers independently flag the same passage, mark it
⚑ converged (independent agreement is the strongest signal in the package).
## Operator decision (you gate)
Pick which flags fold in. [OPERATØR]
Convergence is the prize. Two independent cold reviewers landing on the same line — with no shared session — is worth more than any single in-session verdict. Mark those explicitly.
Step 5 — Surface + (optionally) persist
- Write the consolidated report to
--output(default<serie>/review/NN-headless-<stamp>.md). - Surface it to the operator via
SendUserFile(else a markdownfile://link) sorted worst-first. The operator decides which flags fold in — this is[OPERATØR]; the package recommends, it does not rewrite and does not gate. - If
--article NNwas given, record the run inedition-state.json→articles.NN.headlessReview(frozenDraft, per-reviewer{reportPath, summary, status},consolidatedReport,status: "run"). When the operator folds flags in, setfoldedIn/waivedandstatus: "folded". Standalone (no--article) just emits the report.
Headless review complete (COLD).
- Archetypes: <N> run in parallel converged flags: <N>
- BLOCK/🔴: <N> REWORK: <N> primær resonance: JA/NEI conversion: JA/NEI
- Report: <serie>/review/NN-headless-<stamp>.md (surfaced via SendUserFile)
- Persisted: edition-state.json articles.NN.headlessReview (or: standalone, not persisted)
Operator gates the fold-in. For maximum independence, run this command in a FRESH session.
Relationship to the pipeline + the in-session gates
- Step 6.5 of
/linkedin:newsletterinvokes this same package (after the in-session persona sweep Step 6, before lock Step 8). The pipeline may fan the reviewers out inline, but the strongest isolation is the operator running/linkedin:headless-reviewin a fresh session and pasting the consolidated report back. Either way the body must be re-touched before lock — never reopen a locked text (the cardinal Seres lesson). - Deliberate redundancy.
fact-revieweroverlapsfact-checker(Step 5) andlanguage-revieweroverlapseditorial-reviewer's prose axis (Step 5.5) on purpose. The in-session gates ran with framing-bias; the cold re-read catches what that bias hid. Do not collapse the pairs.
Reference Files
${CLAUDE_PLUGIN_ROOT}/agents/content-reviewer.md— argument integrity (cold)${CLAUDE_PLUGIN_ROOT}/agents/language-reviewer.md— Norwegian language (cold)${CLAUDE_PLUGIN_ROOT}/agents/fact-reviewer.md— cold re-verification (incl. pivot premises)${CLAUDE_PLUGIN_ROOT}/agents/persona-reviewer.md— resonance + conversion modes${CLAUDE_PLUGIN_ROOT}/commands/newsletter.md— Step 6.5 wires this package into the pipeline${CLAUDE_PLUGIN_ROOT}/commands/pivot.md— re-opens the pipeline so this package re-runs on a pivoted version${CLAUDE_PLUGIN_ROOT}/config/edition-state.template.json—articles.NN.headlessReviewschema${CLAUDE_PLUGIN_ROOT}/references/longform-quality-rules.md— fallback writing contract