--- name: linkedin:headless-review description: | 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". allowed-tools: - Read - Glob - Grep - Bash - AskUserQuestion - Task - Write --- # 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: 1. **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. 2. **Layer 2 — subagent isolation.** Each archetype is a `Task` subagent, 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:` > (`linkedin-studio:content-reviewer`, `…:language-reviewer`, > `…:fact-reviewer`, `…:persona-reviewer`). A bare `` does not resolve and > the `Task` call 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 (required; e.g. /04-utkast.md) --type content | language | fact | persona-resonance | persona-conversion | all (default: all) --persona (persona modes only; default: the primær) --article NN (optional; persist into edition-state.json) --output (default: /review/NN-headless-.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) 1. **Draft.** Use `--draft`. It must be a long-form draft `.md` (the same `NN-utkast.md` the newsletter pipeline produces). If `--draft` is missing and you can find an `edition-state.json`, use the `currentArticle`'s `NN-utkast.md`; otherwise ask once for the path. 2. **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 resolved `personas` (Step 1 of newsletter), the series title (for language/content series checks), and — if `--article` is set — where to persist. Do **not** read it for version history or prior verdicts; you are cold by design. 3. **Writing contract.** Resolve the craft/quality reference in this order: `/../../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. 4. **Personas.** Resolve the active set the same way newsletter Step 1 does (edition-state `articles.NN.personas` → `/linkedin/personas.md` → plugin `personas.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): ```bash cd && 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: - contract: [- persona: (block at ) | mode: ] 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. ```markdown # Headless review — (COLD / independent · archetypes) **Frozen draft:** review/NN-frozen-.md **Contract:** **Archetypes run:** content · language · fact · persona-resonance () · persona-conversion () ## 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: ### persona-resonance — ### persona-conversion — ## Cross-archetype signal - BLOCK / 🔴 total: REWORK total: 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 1. Write the consolidated report to `--output` (default `/review/NN-headless-.md`). 2. Surface it to the operator via `SendUserFile` (else a markdown `file://` 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. 3. **If `--article NN` was given**, record the run in `edition-state.json` → `articles.NN.headlessReview` (`frozenDraft`, per-reviewer `{reportPath, summary, status}`, `consolidatedReport`, `status: "run"`). When the operator folds flags in, set `foldedIn`/`waived` and `status: "folded"`. Standalone (no `--article`) just emits the report. ``` Headless review complete (COLD). - Archetypes: run in parallel converged flags: - BLOCK/🔴: REWORK: primær resonance: JA/NEI conversion: JA/NEI - Report: /review/NN-headless-.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:newsletter`** invokes 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-review` in 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-reviewer` overlaps `fact-checker` (Step 5) and `language-reviewer` overlaps `editorial-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.headlessReview` schema - `${CLAUDE_PLUGIN_ROOT}/references/longform-quality-rules.md` — fallback writing contract