---
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, manual).** 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).
2. **Layer 1b — background run (`--background`, equal isolation, no seam).** The
   drafting session spawns this package as a **background agent** with its own
   context window, which writes the consolidated report to a file; the drafting
   session then reads that file from disk. The background agent gets only the
   cold-contract inputs — it cannot see the parent's transcript — so the
   isolation matches a fresh session, with **no copy-paste** of the report back
   into the drafting session and no manual session switch. See "Background run"
   below. This is the default recommendation for the Step 6.5 gate.
3. **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:<name>`
> (`linkedin-studio:content-reviewer`, `…:language-reviewer`,
> `…:fact-reviewer`, `…:persona-reviewer`). A bare `<name>` 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   <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)
  --background                                (run the package in a background agent
                                               that writes --output; caller reads the file)
```

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).

### Background run (`--background`)

With `--background`, do **not** fan the archetypes out here. Spawn **one**
background agent that runs Steps 1–5 of this command itself, and let it write the
report:

- Launch it with `run_in_background: true` and a prompt carrying **only** the
  cold-contract inputs — draft path, contract path, persona names + block path,
  `--type`, and the absolute `--output` path — plus the instruction to write the
  consolidated report to `--output` and return that path.
- **Never** put drafting history, version notes, or "what we changed" in that
  prompt. The background agent has its own context window; the only way session
  framing reaches it is if you type it in.
- When it completes, `Read` the report at `--output` and continue at Step 5
  (surface + persist). The drafting session sees the *report*, not the reviewers'
  reasoning, and the reviewers never see the drafting session — the same
  independence a fresh session gives, with **no copy-paste seam** between them.
- If background execution is unavailable, say so plainly and fall back to the
  inline fan-out (Step 3) — never silently downgrade the isolation.

## 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:
   `<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.
4. **Personas.** Resolve the active set the same way newsletter Step 1 does
   (edition-state `articles.NN.personas` → `<serie>/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 <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.

```markdown
# 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

1. Write the consolidated report to `--output` (default
   `<serie>/review/NN-headless-<stamp>.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: <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)
- Isolation: background agent (report read from disk)  |  fresh session  |  inline fan-out (fallback)
- Persisted: edition-state.json articles.NN.headlessReview (or: standalone, not persisted)
Operator gates the fold-in. For maximum independence with no manual seam, run with --background.
```

## 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 recommended path is `--background`: full
  isolation, the report read from disk, and no manual step between the review and
  the fold-in. A fresh session remains available and is equally cold. 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
