feat(linkedin): v2.1.0 — skeleton + spine-prose gates BEFORE prose in /linkedin:newsletter

Two new pipeline phases gate the spine before any prose is written:

- Step 2.5 — Skeleton + section pitch: writes <serie>/NN-skjelett.md with
  the five-line spine (premiss / problem / anbefaling / gevinst / vei
  videre) + one-line section pitches. Operator-gate (JA / REVIDER / NEI)
  AND parallel persona-skjelett-sweep must both return JA before the
  pipeline can advance.
- Step 3a — Spine prose: one paragraph per section against the gated
  skeleton, ~20-30% of final edition length. Operator-gate on whether the
  axis lands now that there is prose on it. Old Step 3 (Draft) split into
  3a (spine) and 3b (full expansion); 3b owns the multi-session
  draft-cursor logic.

Third persona-reviewer mode added: skjelett (alongside resonans + konverter).
Five spine axes scored HOLDER / TVILER / MANGLER, max 3 direction-only flags,
per-pitch section-pay-in check. Reads the skeleton + pitches only.

Pipeline grows from 11 to 13 phases; commands (24) and agents (14) counts
unchanged. Encodes the Maskinrommet writing-contract section A discipline
(premiss / problem / anbefaling / gevinst / vei videre) into the pipeline.

Empirically motivated by the Seres-serien Del 3 + Del 4 production:
a spine error caught at the skeleton stage costs 5-15 min, the same
error caught at Step 6 (resonance) costs 4-12 h, post-lock it costs a
day of cascading rework (delingstekst, hooks, carousel, doc refs).

Backward-compatible: existing editions stop at currentPhase: "research"
and now resume at Step 2.5 instead of Step 3 — an intended deterministic
improvement, never a contract break. Steps 1, 2, 4-10 bit-for-bit
unchanged. Renderers (build-html.mjs, build-linkedin.mjs) untouched.

New phase strings in edition-state.template.json _doc.phases:
- skeleton-pitch (between research and draft)
- spine-prose (between skeleton-pitch and draft)

Files changed (10):
- plugin.json: 2.0.0 -> 2.1.0
- CHANGELOG.md: new [2.1.0] entry
- CLAUDE.md (plugin + marketplace): pipeline 11->13 phases noted
- README.md (plugin + marketplace): What's New v2.1.0 + version row
- agents/persona-reviewer.md: third mode skjelett added; resonans + konverter unchanged
- commands/newsletter.md: Step 2.5 + 3a + 3b sections, resumption + pipeline tables
- config/edition-state.template.json: 11 -> 13 phases in _doc.phases
- references/longform-quality-rules.md: Rule 8 (Skjelett foer prosa)

Verification: 9/9 criteria PASS pre-commit. Phase strings consistent
across template + command + resumption table. Renderer files git-untouched.
All 11 original step headings preserved (Step 0/1/2/4-10).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-05-28 10:09:47 +02:00
commit 2a27a7cd6a
10 changed files with 615 additions and 141 deletions

View file

@ -9,7 +9,7 @@ plugins/
ai-psychosis/ v1.0.0 — Interaction awareness (sycophancy, reinforcement loops)
config-audit/ v3.1.0 — Configuration intelligence (health, opportunities, auto-fix, whats-active)
graceful-handoff/ v2.1.0 — Auto-trigger handoff via Stop hook (skill + JSON pipeline + 4-step model-aware context resolution)
linkedin-thought-leadership/ v2.0.0 — Full-spectrum LinkedIn content engine (short-form feed + long-form newsletter). v2.0.0 consolidated surface (27→24 commands, 16→14 agents) + added `/linkedin:newsletter` orchestrator with fact-check + persona-sweep gates BEFORE lock. Render pipeline migrated in-plugin (self-hosted OFL-1.1 fonts). Built across 21 Voyage sessions.
linkedin-thought-leadership/ v2.1.0 — Full-spectrum LinkedIn content engine (short-form feed + long-form newsletter). v2.0.0 consolidated surface (27→24 commands, 16→14 agents) + added `/linkedin:newsletter` orchestrator with fact-check + persona-sweep gates BEFORE lock. v2.1.0 adds skeleton-gate BEFORE prose (Step 2.5 + Step 3a) to `/linkedin:newsletter` + third `persona-reviewer` mode (`skjelett`); pipeline 11→13 phases; commands/agents unchanged in count (24, 14). Render pipeline self-hosted (OFL-1.1 fonts).
llm-security/ v7.7.2 — Security scanning, auditing, threat modeling. HTML report output for all 18 skill commands (render-report CLI + canonical ESM module mirrored bit-identical into the playground). v7.7.2 translated the remaining Norwegian surface text in the playground UI, the canonical renderer, the agent prompts, and the README/CLAUDE.md state sections to English. v7.7.1 stripped the playground to the catalog as the only routable surface.
ms-ai-architect/ v1.15.0 — Microsoft AI architecture (Cosmo Skyberg persona) + manual KB-refresh slash command + v3 project-view (sidebar med 17 artifacts + main + import-modal overlay, v2-surface fjernet i v1.15.0)
okr/ v1.0.0 — OKR guidance for Norwegian public sector

View file

@ -206,14 +206,15 @@ Key commands: `/architect`, `/architect:ros`, `/architect:security`, `/architect
---
### [LinkedIn Thought Leadership](plugins/linkedin-thought-leadership/) `v2.0.0`
### [LinkedIn Thought Leadership](plugins/linkedin-thought-leadership/) `v2.1.0`
Build authentic LinkedIn authority through algorithmic understanding, strategic consistency, and AI-assisted content creation.
v2.0.0 is a full-spectrum content engine: short-form feed posts AND long-form newsletter editions in one cohesive surface, with net-fewer commands and net-stronger pipeline. Updated for the January 2026 360Brew algorithm change, which validates your creator profile before distributing content.
v2.1.0 adds a **skeleton gate BEFORE prose** to `/linkedin:newsletter` — two new pipeline phases (Step 2.5 skeleton + section pitch, Step 3a spine prose) each with their own operator-gate, plus a third `persona-reviewer` mode (`skjelett`) that judges the five-line spine before any prose is written. Empirically motivated by the Seres-serien Del 3 + Del 4 production: a spine error caught at the skeleton stage costs 515 minutes; the same error caught at the resonance stage (Step 6) costs 412 hours; post-lock it costs a day. The pipeline grows from 11 to 13 phases; command and agent counts (24, 14) are unchanged. v2.0.0's full-spectrum surface (short-form feed posts AND long-form newsletter editions) is preserved bit-for-bit. Updated for the January 2026 360Brew algorithm change, which validates your creator profile before distributing content.
- **Long-form `/linkedin:newsletter` orchestrator** — multi-session pipeline (research → draft → fact-check sweep → persona sweep → lock → delivery → hook-gate) with maintained edition-state. Newsletter editions, essays, series articles
- **Two new longform-quality gates**`fact-checker` (Opus, verifies every claim against primary sources) and `persona-reviewer` (Opus, reader-persona resonance + hook conversion). Both run BEFORE lock
- **Skeleton gate BEFORE prose (v2.1)**`/linkedin:newsletter` Step 2.5 writes a five-line spine (premiss / problem / anbefaling / gevinst / vei videre) + one-line section pitches to `<serie>/NN-skjelett.md`. Operator-gate AND parallel persona-skjelett-sweep must both return JA before the pipeline can advance. Step 3a follows with spine prose (one paragraph per section) and its own operator-gate. Encodes the Maskinrommet writing-contract §A discipline into the pipeline.
- **Long-form `/linkedin:newsletter` orchestrator** — multi-session 13-phase pipeline (research → **skeleton + persona-skjelett-sweep****spine prose** → full prose draft → fact-check sweep → persona sweep → lock → delivery → hook-gate) with maintained edition-state. Newsletter editions, essays, series articles
- **Three longform-quality gate agent modes**`fact-checker` (Opus, verifies every claim against primary sources) and `persona-reviewer` (Opus) with three modes: **`skjelett`** (Step 2.5, before prose), **`resonans`** (Step 6, before lock), **`konverter`** (Step 9, after lock)
- **Render pipeline in-plugin**`build-html.mjs`, `build-pdf.mjs`, `build-linkedin.mjs`, `build-carousel.mjs` with self-hosted Newsreader/Inter/JetBrains Mono under OFL-1.1
- **Guided onboarding**`/linkedin:onboarding` walks new users through profile → setup → first post in one flow
- **360Brew profile optimization** — audit your profile against LinkedIn's creator validation criteria

View file

@ -1,7 +1,7 @@
{
"name": "linkedin-thought-leadership",
"version": "2.0.0",
"description": "Full-spectrum LinkedIn content engine — feed posts, carousels, video scripts, and long-form newsletter editions — with the January 2026 360Brew algorithm baked in. Net-fewer commands, net-stronger pipeline.",
"version": "2.1.0",
"description": "Full-spectrum LinkedIn content engine — feed posts, carousels, video scripts, and long-form newsletter editions — with the January 2026 360Brew algorithm baked in. v2.1 adds skeleton + spine-prose gates BEFORE prose to /linkedin:newsletter.",
"author": {
"name": "Kjell Tore Guttormsen"
},

View file

@ -5,6 +5,30 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.1.0] - 2026-05-28
### Summary
Skeleton gate before prose in `/linkedin:newsletter`. Two new pipeline phases (Step 2.5 — Skeleton + section pitch; Step 3a — Spine prose) split the old Step 3 into pre-prose / spine-prose / full-prose stages, each with an operator-gate. Adds a third `persona-reviewer` mode (`skjelett`) that judges the five-line skeleton + section pitches BEFORE prose is written. Empirically motivated by the Seres-serien Del 3 + Del 4 production: spine errors caught post-prose cost ~1 day; the same error caught at the skeleton stage costs 515 minutes. Backward-compatible: existing editions stop at `currentPhase: "research"` and now resume at Step 2.5 instead of Step 3 — an intended deterministic improvement, never a contract break.
### Added
- **Step 2.5 — Skeleton + section pitch** in `commands/newsletter.md`. Writes `<serie>/NN-skjelett.md` with the five-line spine (premiss / problem / anbefaling / gevinst / vei videre) + one-line section pitches. Operator-gate (JA / REVIDER / NEI) AND parallel persona-skjelett-sweep must both return JA before the pipeline advances. Encodes the Maskinrommet writing-contract §A discipline into the pipeline itself.
- **Step 3a — Spine prose** in `commands/newsletter.md`. One paragraph per section against the gated skeleton, ~2030 % of final edition length. Operator-gate on whether the axis lands now that there is prose on it. Cheap second checkpoint before full expansion.
- **Step 3b — Full prose expansion** in `commands/newsletter.md`. Splits the old Step 3 (Draft) into spine prose (3a) and full prose expansion (3b). 3b owns the existing draft-cursor logic for multi-session expansion; 3a is short enough to restart on interruption.
- **`persona-reviewer` skjelett-mode** (third mode alongside `resonans` and `konverter`). Five spine axes (Premiss / Problem / Anbefaling / Gevinst / Vei videre) scored HOLDER / TVILER / MANGLER, ≤3 direction-only flags, per-pitch section-pay-in check, gate ladder PASS / REWORK / BLOCK. Caller passes `mode: skjelett`.
- **`skeleton-pitch` + `spine-prose` phase strings** in `config/edition-state.template.json` `_doc.phases` — 11 → 13 phases. Resumption table in `commands/newsletter.md` extended with deterministic rows for both new phases.
- **Rule 8 — Skjelett før prosa** in `references/longform-quality-rules.md`. Documents the skeleton-before-prose pre-condition that all other rules implicitly rely on, with the same five-slot format the pipeline enforces.
### Changed
- **`/linkedin:newsletter` pipeline overview** — 11 → 13 phases; pipeline tables in `commands/newsletter.md` and `CLAUDE.md` reflect the new ordering (0, 1, 2, **2.5**, **3a**, **3b**, 410).
- **Resumption table** in `commands/newsletter.md``currentPhase: "research"` now resumes at Step 2.5 (was Step 3). Two new rows added for `skeleton-pitch` (→ Step 3a) and `spine-prose` (→ Step 3b). Draft-cursor note clarifies that the cursor applies only to Step 3b.
- **`agents/persona-reviewer.md` description, principles, and anti-patterns** — extended to cover the third mode (skjelett). Existing resonans + konverter modes unchanged in contract.
- **`CLAUDE.md` header + persona-reviewer row + newsletter command row** — reflect v2.1.0 surface.
### Not changed (explicit non-deltas)
- **Step 1, Step 2, Steps 410** in `/linkedin:newsletter` — bit-for-bit unchanged in contract.
- **Renderers**`render/build-html.mjs` and `render/build-linkedin.mjs` untouched; both still consume `NN-utkast.md` (3a writes the spine state, 3b overwrites with the full state, but only `currentPhase: "draft"` triggers rendering).
- **Hooks, scripts, command count (24), agent count (14)** — all unchanged.
## [2.0.0] - 2026-05-28
### Summary

View file

@ -1,6 +1,6 @@
# LinkedIn Thought Leadership Plugin (v2.0.0)
# LinkedIn Thought Leadership Plugin (v2.1.0)
Full-spectrum LinkedIn content engine — short-form feed posts, carousels, video scripts, and long-form newsletter editions — with the January 2026 360Brew algorithm baked in. v2.0.0 consolidated the surface (27 commands → 24, 16 agents → 14) while adding the long-form `/linkedin:newsletter` orchestrator + two longform-quality gate agents (`fact-checker`, `persona-reviewer`).
Full-spectrum LinkedIn content engine — short-form feed posts, carousels, video scripts, and long-form newsletter editions — with the January 2026 360Brew algorithm baked in. v2.0.0 consolidated the surface (27 commands → 24, 16 agents → 14) while adding the long-form `/linkedin:newsletter` orchestrator + two longform-quality gate agents (`fact-checker`, `persona-reviewer`). **v2.1.0** adds two new gates BEFORE prose to `/linkedin:newsletter` — Step 2.5 (skeleton + section pitch with operator-gate + persona-skjelett-sweep) and Step 3a (spine prose with operator-gate) — plus a third `persona-reviewer` mode (`skjelett`), encoding the Maskinrommet writing-contract §A discipline (premiss / problem / anbefaling / gevinst / vei videre) into the pipeline itself. Pipeline grows from 11 to 13 phases; commands and agents unchanged in count (24, 14).
## Architecture
@ -46,7 +46,7 @@ All content commands (post, quick, react, pipeline, first-post, video, multiplat
| `/linkedin:post` | Full post creation (10-15 min) |
| `/linkedin:quick` | 5-minute quick post (3-line formula) + 8 post-type templates |
| `/linkedin:pipeline` | Full end-to-end content pipeline |
| `/linkedin:newsletter` | Long-form orchestrator: newsletter edition / essay / series article — multi-session pipeline with fact-check + persona-sweep BEFORE lock |
| `/linkedin:newsletter` | Long-form orchestrator: newsletter edition / essay / series article — multi-session 13-phase pipeline with **skeleton + spine-prose gates BEFORE prose (v2.1)** and fact-check + persona-sweep BEFORE lock |
| `/linkedin:batch` | Create a full week of content |
| `/linkedin:calendar` | View/manage post scheduling queue + publish action (mark scheduled posts as published) |
| `/linkedin:carousel` | Structured multi-slide carousel generator |
@ -80,7 +80,7 @@ All content commands (post, quick, react, pipeline, first-post, video, multiplat
| `post-feedback-monitor` | Haiku | Lime | Post-publish 48h monitoring |
| `video-scripter` | Sonnet | Violet | Video script creation with pacing |
| `fact-checker` | Opus | Brown | Factual-claim verification against primary sources (longform) |
| `persona-reviewer` | Opus | Olive | Reader-persona resonance + hook-conversion gate (longform) |
| `persona-reviewer` | Opus | Olive | Reader-persona skeleton (v2.1, before prose) + resonance (before lock) + hook-conversion (after lock) gate (longform) |
**Rule:** Always read `assets/voice-samples/` before generating content.

View file

@ -6,7 +6,7 @@
*AI-generated: all code produced by Claude Code through dialog-driven development. [Full disclosure →](../../README.md#ai-generated-code-disclosure)*
![Version](https://img.shields.io/badge/version-2.0.0-blue)
![Version](https://img.shields.io/badge/version-2.1.0-blue)
![Platform](https://img.shields.io/badge/platform-Claude_Code_Plugin-purple)
![Commands](https://img.shields.io/badge/commands-24-green)
![Agents](https://img.shields.io/badge/agents-14-orange)
@ -14,12 +14,13 @@
![Reference Docs](https://img.shields.io/badge/reference_docs-24-teal)
![License](https://img.shields.io/badge/license-MIT-lightgrey)
A comprehensive Claude Code plugin that turns LinkedIn from a chore into a full-spectrum content engine — short-form feed posts, carousels, video scripts, and long-form newsletter editions. v2.0.0 consolidated the surface (27 → 24 commands, 16 → 14 agents) and added `/linkedin:newsletter` as a multi-session long-form orchestrator with fact-check + persona-sweep gates BEFORE lock. 24 slash commands, 14 specialized agents, 9 automated hooks, and a 24-document knowledge base grounded in LinkedIn's actual algorithm signals. Updated for the January 2026 **360Brew** algorithm change, where LinkedIn now validates your profile before distributing content.
A comprehensive Claude Code plugin that turns LinkedIn from a chore into a full-spectrum content engine — short-form feed posts, carousels, video scripts, and long-form newsletter editions. v2.0.0 consolidated the surface (27 → 24 commands, 16 → 14 agents) and added `/linkedin:newsletter` as a multi-session long-form orchestrator with fact-check + persona-sweep gates BEFORE lock. **v2.1.0** adds two more gates BEFORE prose to `/linkedin:newsletter` — a skeleton gate (Step 2.5) and a spine-prose gate (Step 3a) — encoding the Maskinrommet writing-contract §A discipline (premiss / problem / anbefaling / gevinst / vei videre) into the pipeline itself, so spine errors get caught in minutes at the skeleton stage instead of hours at the resonance stage or a full day post-lock. 24 slash commands, 14 specialized agents, 9 automated hooks, and a 24-document knowledge base grounded in LinkedIn's actual algorithm signals. Updated for the January 2026 **360Brew** algorithm change, where LinkedIn now validates your profile before distributing content.
---
## Table of Contents
- [What's New in v2.1.0](#whats-new-in-v210)
- [What's New in v2.0.0](#whats-new-in-v200)
- [What Is This?](#what-is-this)
- [Quick Start](#quick-start)
@ -39,6 +40,20 @@ A comprehensive Claude Code plugin that turns LinkedIn from a chore into a full-
---
## What's New in v2.1.0
**Skeleton gate before prose** in `/linkedin:newsletter` — the single most expensive failure mode in long-form (spine errors caught post-prose) is now gated before the first sentence is written. Empirically motivated by the Seres-serien Del 3 + Del 4 production (~1 day lost to spine rework that a 15-minute skeleton gate would have caught).
- **New Step 2.5 — Skeleton + section pitch** — writes `<serie>/NN-skjelett.md` with the five-line spine (premiss / problem / anbefaling / gevinst / vei videre) + one-line section pitches. Operator-gate (JA / REVIDER / NEI) AND parallel persona-skjelett-sweep must both return JA before the pipeline can advance. No prose is written until the spine is right.
- **New Step 3a — Spine prose** — one paragraph per section against the gated skeleton, ~2030 % of final edition length. Operator-gate on whether the axis lands now that there is prose on it. The old Step 3 (Draft) is split into 3a (spine) and 3b (full expansion); 3b owns the multi-session draft-cursor logic, 3a is short enough to restart on interruption.
- **New `persona-reviewer` mode: `skjelett`** — third mode alongside `resonans` (before lock) and `konverter` (after lock). Five spine axes (Premiss / Problem / Anbefaling / Gevinst / Vei videre) scored HOLDER / TVILER / MANGLER, ≤3 direction-only flags, per-pitch section-pay-in check. Reads the skeleton + pitches only — no prose.
- **Two new phase strings** in `edition-state.template.json``skeleton-pitch` + `spine-prose`. The pipeline grows from 11 to 13 phases; resumption is deterministic across every new phase boundary.
- **Rule 8 — Skjelett før prosa** in `references/longform-quality-rules.md` — codifies the skeleton-before-prose pre-condition that all other quality rules implicitly rely on.
Backward-compatible: existing editions with `currentPhase: "research"` now resume at Step 2.5 (was Step 3) — an intended deterministic improvement; the contract on every other phase is bit-for-bit unchanged.
---
## What's New in v2.0.0
**Full-spectrum content engine** — feed posts AND long-form newsletter editions in one cohesive surface, with net-fewer commands.
@ -202,7 +217,7 @@ The plugin delegates specialized work to 14 purpose-built agents. Each agent has
| `post-feedback-monitor` | Haiku | Lime | Post-publish 48h monitoring and real-time interventions |
| `video-scripter` | Sonnet | Violet | Video script creation with pacing and visual cues |
| `fact-checker` | Opus | Brown | Factual-claim verification against primary/credible sources (longform) |
| `persona-reviewer` | Opus | Olive | Reader-persona resonance + hook-conversion gate (longform) |
| `persona-reviewer` | Opus | Olive | Reader-persona **skeleton** (v2.1, before prose) + **resonance** (before lock) + **hook-conversion** (after lock) gate (longform) |
### Content Pipeline
@ -220,7 +235,7 @@ trend-spotter --> content-planner --> differentiation-checker --> content-optimi
Parallel support agents: `strategy-advisor`, `analytics-interpreter`, `network-builder`, `content-repurposer`, `video-scripter`.
Longform quality gates (newsletter): `fact-checker``persona-reviewer` run BEFORE lock.
Longform quality gates (newsletter): **`persona-reviewer` (skjelett) run BEFORE prose** (v2.1, Step 2.5) → `fact-checker` (Step 5)`persona-reviewer` (resonance) run BEFORE lock (Step 6) → `persona-reviewer` (conversion) run AFTER lock on the hook (Step 9).
> **Note (agent invocation + reload):** Commands invoke agents by their **namespaced**
> type — `subagent_type: linkedin-thought-leadership:<name>`, never the bare name. And a
@ -530,6 +545,7 @@ Scheduled posts are tracked in `assets/drafts/queue.json`:
| Version | Date | Highlights |
|---------|------|-----------|
| **2.1.0** | 2026-05-28 | Skeleton gate BEFORE prose in `/linkedin:newsletter`. New Step 2.5 (skeleton + section pitch, operator-gate + persona-skjelett-sweep) and Step 3a (spine prose, operator-gate) split the old Step 3 into pre-prose stages with their own gates. New `persona-reviewer` mode (`skjelett`). Pipeline grows 11 → 13 phases; commands and agents unchanged in count (24, 14). Encodes the Maskinrommet writing-contract §A discipline (premiss / problem / anbefaling / gevinst / vei videre) into the pipeline. Empirically motivated by the Seres-serien Del 3 + Del 4 spine-rework cost. |
| **2.0.0** | 2026-05-28 | Full-spectrum content engine. `/linkedin:newsletter` long-form orchestrator with multi-session edition-state, fact-check + persona-sweep gates BEFORE lock. New agents: `fact-checker`, `persona-reviewer` (both Opus). Render pipeline migrated in-plugin with self-hosted OFL-1.1 fonts. Net-fewer surface: 27 → 24 commands (5 removed, 2 added), 16 → 14 agents (4 merged, 2 added). Router gating on monetize/outreach (unlocks at ~1K). `/linkedin:import` delegates analysis to `/linkedin:report`. |
| **1.2.0** | 2026-04-11 | Friction reduction release. Auto-clipboard on all content commands, reduced interactive steps (max 2 per post), deterministic state management (`state-updater.mjs`), MCP image carousel pipeline, progressive onboarding, iCal calendar integration for batch scheduling, auto-prune content history (90 days). |
| **1.1.0** | 2026-04-08 | Q2 feature release. 27 commands (+onboarding, +carousel). Week-rollover automation, voice drift scoring, industry content matrix, multi-URL react, day-of-week heatmap, month-over-month reports. |

View file

@ -1,21 +1,25 @@
---
name: persona-reviewer
description: |
Read a draft as ONE named reader persona and judge whether it lands — not
whether it is correct. Returns at most five flags as direction (never
rewritten copy): the jury judges, the editor writes. Two modes: resonance
(before lock, all six axes) and conversion (after lock, binary "would YOU
click?" on the hook only).
Read a draft (or its pre-prose skeleton) as ONE named reader persona and
judge whether it lands — not whether it is correct. Returns direction as
flags, never rewritten copy: the jury judges, the editor writes. Three
modes: skeleton (before prose, five spine axes, ≤3 flags), resonance
(before lock, all six axes, ≤5 flags), and conversion (after lock, binary
"would YOU click?" on the hook only).
Use when the user says:
- "does this skeleton argue what it claims to argue?", "skeleton check"
- "does this land for [persona]?", "read this as my reader"
- "persona check", "resonance check", "will this resonate?"
- "would my reader click this?", "conversion check on the hook"
- "is the takeaway clear for a leader?", "does the hook hold?"
- "run the persona sweep", "judge this draft as the primær reader"
- "does this section pitch pay in?", "is the spine right?"
Triggers on: "persona check", "resonance check", "does this land",
"would they click", "conversion check", "persona sweep", "resonans",
Triggers on: "skeleton check", "skjelett-sjekk", "persona check",
"resonance check", "does this land", "would they click",
"conversion check", "persona sweep", "skjelett", "resonans",
"konverter", "read as my reader".
model: opus
color: olive
@ -24,11 +28,13 @@ tools: ["Read"]
# Persona Reviewer Agent
You are a reader's stand-in. You read a finished or near-finished draft **as one
named reader persona** and judge whether it *lands* for that reader — whether the
hook holds, the point resonates, the tone fits, the claim is believed, the
takeaway is actionable, and the piece keeps moving. You do not judge whether the
text is factually correct (that is `fact-checker`) or original (that is
You are a reader's stand-in. You read a finished draft, a near-finished draft,
or a pre-prose **skeleton + section pitches** — **as one named reader persona**
— and judge whether it *lands* for that reader. At the skeleton stage you judge
whether the argument-line *would* land if the prose delivered it faithfully; at
the resonance stage you judge whether the realized prose lands; at the
conversion stage you judge the hook only. You do not judge whether the text is
factually correct (that is `fact-checker`) or original (that is
`differentiation-checker`). You judge whether it **works for this reader**.
## Your Mission
@ -47,26 +53,41 @@ clean JA. A *sekundær* NO caused by a role mismatch or an expertise ceiling
(«this I already know cold») is a SIGNAL that the gate works — report it, do not
distort the text to chase it.
## Two Modes
## Three Modes
Both modes run the same persona. The caller passes the mode; you adapt scope and
output accordingly.
All three modes run the same persona. The caller passes the mode; you adapt
scope and output accordingly. The modes are listed in pipeline order — skjelett
runs first (Step 2.5, before prose), resonans next (Step 6, before lock),
konverter last (Step 9, after lock).
### Skjelett-modus (before prose)
Runs at the long-form pipeline's pre-prose skeleton gate (Step 2.5), against the
**five-line skeleton** (premiss / problem / anbefaling / gevinst / vei videre)
plus the **section pitches**. There is no prose yet — only the argument-line and
the section-level promise of what each section will do for that argument. Judge
on the **five spine axes** (below) and return **at most three flags** as
direction, each tracked **HOLDER / TVILER / MANGLER**. Produce a per-persona
verdict (JA / NEI). The gate question is: *would this argument-line land for
this reader if the prose delivered it faithfully?* This is the cheapest place to
catch a spine error — fixing one here costs minutes; fixing it after prose costs
hours; fixing it after lock costs a day.
### Resonans-modus (before lock)
Runs at the long-form pipeline's pre-lock resonance sweep. Judge the draft on
**all six axes** (below) and return **at most five flags** as direction, each
tracked **LØST / DELVIS / IKKE**. Produce a per-persona verdict (JA / NEI) and a
gate decision (PASS / REWORK / BLOCK). This is where the draft earns the right to
be locked.
Runs at the long-form pipeline's pre-lock resonance sweep (Step 6). Judge the
realized prose draft on **all six axes** (below) and return **at most five
flags** as direction, each tracked **LØST / DELVIS / IKKE**. Produce a
per-persona verdict (JA / NEI) and a gate decision (PASS / REWORK / BLOCK). This
is where the draft earns the right to be locked.
### Konverter-modus (after lock)
Runs at the post-lock conversion sweep. Judge the **hook only**, binary:
«would YOU click?» — **JA / NEI**. No axis scoring, no flags, no copy. Return the
click verdict and a single concrete reason in the reader's own voice ("I'd scroll
past — the first line is machinery, not me"). The body is already locked; the
only open question is whether this reader stops the scroll.
Runs at the post-lock conversion sweep (Step 9). Judge the **hook only**,
binary: «would YOU click?» — **JA / NEI**. No axis scoring, no flags, no copy.
Return the click verdict and a single concrete reason in the reader's own voice
("I'd scroll past — the first line is machinery, not me"). The body is already
locked; the only open question is whether this reader stops the scroll.
## Review Process
@ -77,31 +98,90 @@ Read the named persona from `config/personas.template.md` (or the project's
**overbeviser**, **ekspertise**, **sjargong**. Judge as that reader — not as
yourself, not as a generic audience. One run = one persona.
### Step 2: Read the draft as that reader
### Step 2: Read the input as that reader
Read the draft top to bottom, read-only, once, the way this reader actually would
— skimming the hook on mobile, stopping where `avkobler` triggers, leaning in
where `overbeviser` lands. Note where this specific reader would disengage.
Read top to bottom, read-only, once, the way this reader actually would.
### Step 3: Judge on the six axes (resonance mode)
- **Skjelett-modus:** read the five-line skeleton + section pitches as the
reader would skim an outline — does each line earn its keep for THIS reader,
does the argument-line stand on its own, does any section pitch fail to pay
in? There is no prose to disengage from yet — you are judging the *promise*,
not the delivery.
- **Resonans-modus:** read the prose draft as the reader would on mobile —
skimming the hook, stopping where `avkobler` triggers, leaning in where
`overbeviser` lands. Note where this specific reader would disengage.
- **Konverter-modus:** read the first two lines of the distribution hook only —
the body is locked; only the krok is in play.
Score each axis as **LØST** (lands), **DELVIS** (partly), or **IKKE** (fails),
each with a one-line reason grounded in the persona's fields. Do not invent a
seventh axis; do not skip one.
### Step 3: Judge on axes (mode-dependent)
### Step 4: Sort to at most five flags
- **Skjelett-modus** — score each of the **five spine axes** (Premiss / Problem /
Anbefaling / Gevinst / Vei videre) as **HOLDER** (lands as-is), **TVILER**
(lands only partly — this reader hesitates), or **MANGLER** (does not land —
missing or wrong for this reader), each with a one-line reason grounded in the
persona's fields. Vei videre may be N/A if the edition is not part of a series
(record `HOLDER (N/A)` and move on). Do not invent a sixth axis; do not skip
one (Vei-videre N/A excepted).
- **Resonans-modus** — score each of the **six axes** (below) as **LØST**
(lands), **DELVIS** (partly), or **IKKE** (fails), each with a one-line reason
grounded in the persona's fields. Do not invent a seventh axis; do not skip
one.
- **Konverter-modus** — no axis scoring. Skip to Step 5.
Surface the flags that matter most to THIS reader — IKKE before DELVIS, the
primær's blockers before a sekundary's nice-to-haves. **Cap at five.** The axis
that passes cleanest does not need a flag. Each flag is a *direction*, phrased so
the editor knows where to dig — never a line of replacement copy.
### Step 4: Sort to flags (mode-dependent cap)
Surface the flags that matter most to THIS reader — the worst grade before the
softer grade (MANGLER before TVILER in skjelett; IKKE before DELVIS in
resonans), the primær's blockers before a sekundary's nice-to-haves.
- **Skjelett-modus:** **cap at three.** The spine should be tight; if more than
three things are wrong, the skeleton itself needs rethinking — surface the
three load-bearing problems and stop.
- **Resonans-modus:** **cap at five.** The axis that passes cleanest does not
need a flag.
- **Konverter-modus:** no flags. Only the binary verdict + one reason.
Each flag is a *direction*, phrased so the editor knows where to dig — never a
line of replacement copy.
### Step 5: Verdict + convergence
Give the per-persona verdict (JA / NEI) and the gate decision. If NEI, the editor
revises and you **re-judge** the same axes against the revision (LØST / DELVIS /
IKKE again). Loop until the primær returns a clean JA. You re-judge every round;
you never write the fix.
Give the per-persona verdict (JA / NEI) and the gate decision per the mode's
gate ladder (see Verdict Tokens below).
- **Skjelett-modus convergence:** if NEI, the editor revises the **skeleton +
pitches** (not prose — there is none yet), and you re-judge the same five
spine axes against the revision. Loop until the primær returns a clean JA.
The cycle is fast (minutes per round) and is the point of the gate.
- **Resonans-modus convergence:** if NEI, the editor revises the prose and you
re-judge the same six axes. Loop until the primær returns a clean JA. You
re-judge every round; you never write the fix.
- **Konverter-modus:** no convergence within this agent — the editor revises
the **distribution hook only** between calls; you re-judge JA / NEI on the
revised hook when called again.
## The Five Spine Axes (skjelett mode)
These axes mirror the five-line skeleton structure 1:1. There is no prose
yet — you judge the *argument-line* and the *promise* of each section, not
hook quality, tone, formatting, or length (those belong to resonans-modus once
prose exists).
| # | Axis | The question for THIS reader |
|---|------|------------------------------|
| 1 | **Premiss** | Does the premise hold for this reader — given `avkobler` / `overbeviser` — or is it a premise they cannot accept? |
| 2 | **Problem** | Is the problem concretely named in language this reader recognizes, or is it abstract / mis-aimed for their domain? |
| 3 | **Anbefaling** | Is the recommendation a clear direction this reader can apply, or does it dissolve into platitude? |
| 4 | **Gevinst** | Does this reader see the upside in their own context, or does the payoff land for someone else? |
| 5 | **Vei videre** | If part of a series: does the forward-pointer cohere with where the series is going (and where THIS reader needs it to go)? N/A for standalone editions. |
### Section-pitch check (skjelett mode addendum)
In addition to scoring the five spine axes, scan each **section pitch** — does
this section's one-line promise actually pay into the spine? Flag any pitch
that does not earn its keep (it reads as filler, restates a prior section, or
points away from the recommendation). A pitch failure counts toward the
three-flag cap.
## The Six Axes (resonance mode)
@ -116,9 +196,28 @@ you never write the fix.
## Verdict Tokens & Gate Logic
**Per-axis flag:** LØST (lands) · DELVIS (partly lands) · IKKE (fails for this reader).
**Per-axis flag (mode-dependent):**
**Per-persona verdict:** JA (the draft lands for this reader) · NEI (it does not).
- *Skjelett-modus:* HOLDER (lands as-is) · TVILER (lands partly — reader
hesitates) · MANGLER (does not land — missing or wrong for this reader).
- *Resonans-modus:* LØST (lands) · DELVIS (partly lands) · IKKE (fails for this
reader).
**Per-persona verdict (all modes):** JA (it lands for this reader) · NEI (it
does not).
**Gate decision (skjelett mode):**
- **PASS** — primær = JA, no sekundær MANGLER on Premiss or Anbefaling. The
argument-line is sound for this reader; the editor can proceed to spine
prose (Step 3a).
- **REWORK** — primær = NEI, or a fixable TVILER/MANGLER the editor should
address. Provide the (≤3) flags as direction; editor revises skeleton +
pitches and re-runs the sweep. *Never let prose start on a REWORK skeleton —
the entire point of this gate is to catch spine errors before prose.*
- **BLOCK** — primær = MANGLER on Premiss or Anbefaling (the reader cannot
accept the premise, or there is no actionable direction). Must be reworked
before any prose; this is the dangerous failure mode the gate exists for.
**Gate decision (resonance mode):**
@ -135,13 +234,51 @@ and one reason.
## Convergence Loop
Re-run per persona until the primær returns a clean JA. Each round: the editor
revises, you re-judge the same six axes against the new draft, re-emit ≤5 flags.
A sekundær that stays IKKE on a known ceiling is accepted (signal, not failure);
a primær that stays NEI keeps the loop open. The jury never writes the revision —
it only re-judges whether the revision now lands.
revises, you re-judge the same axes against the new input, re-emit flags within
the mode's cap. A sekundær that stays in the worst grade (MANGLER / IKKE) on a
known ceiling is accepted (signal, not failure); a primær that stays NEI keeps
the loop open. The jury never writes the revision — it only re-judges whether
the revision now lands.
The loop is cheap in skjelett-modus (skeleton edits take minutes) and the place
where you want the bulk of convergence to happen — every round saved at the
skeleton stage is hours saved at the prose stage.
## Output Format
### Skeleton mode
```
## Persona Skeleton Review — [persona name] ([primær | sekundær])
**Mode:** skjelett (before prose)
**Read as:** [rolle, one line]
**Input:** five-line skeleton + N section pitches (no prose yet)
### Spine Axis Judgments
| # | Axis | Flag | Why (for this reader) |
|---|------|------|------------------------|
| 1 | Premiss | HOLDER/TVILER/MANGLER | [one line grounded in avkobler/overbeviser] |
| 2 | Problem | … | … |
| 3 | Anbefaling | … | … |
| 4 | Gevinst | … | … |
| 5 | Vei videre | HOLDER/TVILER/MANGLER (or N/A — standalone edition) | … |
### Section-Pitch Check
[For each pitch — does it pay into the spine? Flag any that do not.
List only failures; passes are silent.]
- Pitch N "[…]" — [why it fails to pay in, for this reader]
### Flags (≤3, direction only — NO rewritten copy)
1. [axis or pitch] — [where this reader loses it + which direction to fix]
2. …
### Verdict: [JA | NEI]
### Gate: [PASS | REWORK | BLOCK]
[If REWORK/BLOCK: which flags are the priority directions. The editor revises
the skeleton + pitches (NOT prose — there is none yet) and re-runs this sweep.]
```
### Resonance mode
```
@ -183,31 +320,45 @@ it only re-judges whether the revision now lands.
## Key Principles
1. **The jury judges; the editor writes.** Return direction, never rewritten
copy. Handing back edited text is the single worst failure of this role.
copy. Handing back edited text is the single worst failure of this role —
in every mode, including skjelett (do not hand back a fixed skeleton).
2. **One persona per run.** Judge as that named reader, with their fields — not as
yourself, not as a generic audience.
3. **Primær trumfer.** A primær NO keeps the loop open; a sekundær ceiling-NO is a
signal the gate works, not a defect to chase.
4. **Land, don't correct.** You judge whether it *works for this reader* — not
whether it is true (fact-checker) or original (differentiation-checker).
5. **At most five flags.** Surface what matters most to this reader; let the
cleanest axis pass unflagged.
5. **Flag cap matches the mode.** Skjelett ≤ 3, resonans ≤ 5, konverter = 0
(binary verdict + one reason). Tighter caps in earlier modes are deliberate
— the spine should be tight.
6. **Ground every flag in the persona.** "Hits `avkobler`" beats "weak hook."
Tie each judgment to rolle / avkobler / overbeviser / ekspertise / sjargong.
7. **Conversion is binary.** In konverter-modus, judge the hook only — JA/NEI and
one reason. No axes, no flags, no copy.
8. **Skjelett judges the promise, not the prose.** There is no prose yet. Do
not flag hook quality, formatting, or length — those belong to resonans-modus.
Do flag a premise the reader cannot accept, a recommendation that dissolves
into platitude, or a section pitch that does not pay in.
## Anti-Patterns
- Rewrite the draft or hand back replacement copy (that is the editor's pen)
- Rewrite the draft (or skeleton) or hand back replacement copy (that is the
editor's pen)
- Judge as yourself instead of as the named persona
- Distort the text to chase a sekundær ceiling-NO
- Accept a primær NEI as "good enough"
- Exceed five flags, or invent a seventh axis
- Exceed the mode's flag cap (3 / 5 / 0), or invent an extra axis (sixth in
skjelett, seventh in resonans)
- Score factual accuracy or originality (wrong agent)
- Give vague flags ("make it punchier") instead of persona-grounded direction
- Run axis scoring in konverter-modus, or skip the binary click verdict
- Soften a primær BLOCK (Krok/Leder-takeaway IKKE) to REWORK to be agreeable
- Use resonans axes (Krok, Tone, Lengde/driv) in skjelett-modus — there is no
prose to judge them against
- Soften a primær BLOCK (skjelett: Premiss/Anbefaling MANGLER; resonans: Krok/
Leder-takeaway IKKE) to REWORK to be agreeable
- Let prose drafting start on a skjelett-REWORK (the gate exists exactly to
catch this; bypassing it reproduces the spine-error failure mode the gate
was built to prevent)
- Mix two personas in one run
## References

View file

@ -59,17 +59,21 @@ 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 (11 phases)
## Pipeline overview (13 phases)
The phase order is fixed. The persona sweep runs **BEFORE** lock — this is the
single most important correction from the Seres process (plan §0.4, principle 5).
The phase order is fixed. Two gates run **BEFORE prose** (skeleton + spine
prose), 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).
| Step | Phase | What | Tools |
|------|-------|------|-------|
| 0 | **Load context** | edition-state/HANDOVER, voice profile, persona library, series brief | `Read` |
| 1 | **Brief + calibration** | angle, voice, audience personas (mark primær), key points, tone, leader-takeaway. ≤3 questions | `AskUserQuestion` |
| 2 | **Research** | parallel scoped mandates → verified notes; triangulation | **`Task` fan-out (foreground)** |
| 3 | **Draft** | dramaturgical order, voice-matched; may span sessions | `content-repurposer` + `Task` |
| 2.5 | **Skeleton + section pitch — BEFORE prose** | five-line skeleton (premiss/problem/anbefaling/gevinst/vei videre) + per-section one-line pitch. Operator-gate JA/NEI/REVIDER. Persona-skjelett-sweep before any prose is written. | `AskUserQuestion` + **`persona-reviewer`** (skjelett mode) |
| 3a | **Spine prose — BEFORE full expansion** | one paragraph per section carrying that section's pitch, nothing more. ~2030 % of final length. Operator-gate on whether the axis is right now that there is prose on it. | inline drafting + `content-repurposer` |
| 3b | **Full prose expansion** | expand each section with argument, examples, anchors from research; may span sessions | `content-repurposer` + `Task` |
| 4 | **Consistency + quality** | threads, premise→conclusion arc, leader-takeaway, AI-slop removal, formatting dose | inline + `references/longform-quality-rules.md` |
| 5 | **Fact-check sweep** | risk-sorted (🔴/🟡/🟢), guilty-until-disproven, verification log | **`fact-checker` (parallel)** |
| 6 | **Persona sweep — BEFORE lock** | reader jury, primær wins, convergence to clean YES | **`persona-reviewer`** (resonance mode) |
@ -78,12 +82,23 @@ single most important correction from the Seres process (plan §0.4, principle 5
| 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 11 phases (Steps 010) are implemented below. This
> command takes an edition end-to-end: load → calibration → verified research →
> draft → consistency/quality → fact-check sweep → pre-lock persona sweep →
> optional annotation → LOCK/delivery → post-lock hook gate → scheduling,
> persisting each phase to `edition-state.json` and the HANDOVER and stopping
> cleanly between sessions.
> **Build status:** all 13 phases (Steps 02.5, 3a, 3b, 410) 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 → pre-lock persona
> sweep → optional annotation → LOCK/delivery → post-lock hook gate →
> scheduling, persisting each phase to `edition-state.json` and the HANDOVER
> 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
> spine-prose stage 3060 min, at the resonance stage (Step 6) 412 h, and
> post-lock a whole day of cascading rework (delingstekst, hooks, carousel,
> doc references). Steps 2.5 and 3a exist to force the spine to be **explicit,
> visible, and confirmed** before a single full-prose sentence is written —
> they encode the discipline that already lives in the Maskinrommet writing
> contract §A.
---
@ -144,7 +159,9 @@ Look up `edition-state.json` → `articles.<currentArticle>` (and the top-level
| *(no state file)* | **NEW edition** → Step 1 (init state at end of Step 2) |
| `load-context` | Step 1 — Brief + calibration |
| `brief-calibration` | Step 2 — Research |
| `research` | Step 3 — Draft |
| `research` | Step 2.5 — Skeleton + section pitch *(v2.1 — skeleton gate BEFORE prose)* |
| `skeleton-pitch` | Step 3a — Spine prose *(v2.1 — one paragraph per section, BEFORE full expansion)* |
| `spine-prose` | Step 3b — Full prose expansion |
| `draft` | Step 4 — Consistency + quality *(see draft-cursor note)* |
| `consistency-quality` | Step 5 — Fact-check sweep |
| `factcheck-sweep` | Step 6 — Persona sweep (pre-lock) |
@ -160,12 +177,19 @@ Steps below write exactly these strings. If `currentPhase` is missing or
unrecognized, do NOT guess — read the edition-HANDOVER §6 next-session pointer and
confirm with the operator before proceeding.
**Draft-cursor note (Step 3 only).** `draft` is the one phase that can be
*partial*: if Step 3 stopped mid-draft it records a section-level cursor in
`edition-state.json` and a "draft resumes at section <X>" pointer in HANDOVER §6.
On resume with `currentPhase: "draft"`, check for that cursor first — if present,
re-enter **Step 3** at the cursor and finish the draft before Step 4; only when the
HANDOVER records "draft complete" do you resume at **Step 4**.
**Draft-cursor note (Step 3b only).** `draft` is the one phase that can be
*partial* — full prose expansion (Step 3b) is the only sub-step long enough to
exceed a single session's context budget. If Step 3b stopped mid-prose, it
records a section-level cursor in `edition-state.json` and a "draft resumes at
section <X>" pointer in HANDOVER §6. On resume with `currentPhase: "draft"`,
check for that cursor first — if present, re-enter **Step 3b** at the cursor and
finish the prose expansion before Step 4; only when the HANDOVER records "draft
complete" (no open cursor) do you resume at **Step 4**.
Step 3a (spine prose) is short enough that it does NOT need a cursor: if 3a
is interrupted, `currentPhase` stays at `skeleton-pitch` and the resume point
is "Step 3a — restart from section 1" (one short paragraph per section against
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
@ -272,9 +296,11 @@ Edition brief
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
"research complete → next: draft" pointer to the edition-HANDOVER §6. If this
is a fresh edition, initialize `edition-state.json` from the template schema
first. Then stop cleanly — drafting (Step 3) begins in the next session.
"research complete → next: skeleton + section pitch (BEFORE prose)" pointer to
the edition-HANDOVER §6. If this is a fresh edition, initialize
`edition-state.json` from the template schema first. Stop cleanly here if
context budget is tight — Step 2.5 begins in the next session; otherwise
Step 2.5 may run inline (it is short and operator-interactive).
```
Research phase complete.
@ -282,64 +308,289 @@ Research phase complete.
- Verified notes: <N> by key point
- Carried to fact-check (🟡 unverified): <N>
State written: <serie>/linkedin/edition-state.json (phase: research)
Next session: Step 3 — Draft.
Next: Step 2.5 — Skeleton + section pitch (operator + persona gate BEFORE prose).
```
---
## Step 3: Draft — dramaturgical order, voice-matched
## Step 2.5: Skeleton + section pitch — BEFORE prose (operator + persona gate)
Turn the verified research notes (Step 2) into a full draft. This is a
*long-form* draft, not a feed post: it has an arc, not a hook-and-three-bullets.
> **This is the cheapest gate in the pipeline (v2.1 brief §6).** A spine error
> caught here costs 515 min to fix; the same error caught at Step 6 costs
> 412 h; post-lock it costs a day of cascading rework (delingstekst, hooks,
> carousel, doc references). The whole reason this step exists is to force the
> argument-line to be **explicit, visible, and confirmed** before a single
> full-prose sentence is written.
> **This phase may span multiple sessions.** A long edition can exceed a single
> session's context budget. If you approach the budget mid-draft, stop cleanly,
> write the partial draft to the series root as `<serie>/NN-utkast.md` (the
> canonical draft path — see step 4), record `currentPhase: "draft"`
> with a section-level cursor in `edition-state.json`, and append a precise
> "draft resumes at section <X>" pointer to the edition-HANDOVER §6. The next
> session re-reads Step 0, picks up the cursor, and continues. Never start the
> consistency pass (Step 4) on a half-written draft.
> **Order assertion (enforced).** Step 2.5 runs AFTER research (Step 2) and
> BEFORE any prose (Step 3a). No section of the draft is written — not even
> spine prose — until the operator says JA on the skeleton and the
> persona-skjelett-sweep returns a clean primær JA. This ordering encodes the
> Maskinrommet writing-contract §A discipline (skeleton before prose) into the
> pipeline. `[GATE]`
**Procedure:**
1. **Re-read the voice profile** (`assets/voice-samples/`) before writing a single
sentence — this is the existing LTL rule and it is not optional for long-form.
The draft must read as the author, not as generic LinkedIn prose.
1. **Propose the five-line skeleton.** Synthesize from the resolved brief
(Step 1) + verified research notes (Step 2). The format is fixed — five
lines, one per slot, each one sentence:
2. **Lay out the dramaturgical order** from the brief (Step 1) and notes (Step 2):
- **Ingress + first paragraph** establish ONE clear premise (this is the front
half of the premise→conclusion arc enforced in Step 4).
- **Body** develops the 24 key points in the order that builds tension, each
anchored to a verified note. Carry each note's source marker inline as a
comment so the Step 5 fact-check sweep can find it.
- **Conclusion** grips the premise concretely and twists it forward (direction +
one concrete grip) — it does not merely summarize.
- **Premiss** — what must the reader accept for the rest to land?
- **Problem** — what stands in the way, concretely named?
- **Anbefaling** — what should the reader think or do differently?
- **Gevinst** — what do they win?
- **Vei videre** — what does the next article cover, or what does the rest
of the series do with this? (N/A for standalone editions — say so
explicitly.)
3. **Draft with the `content-repurposer` muscle.** Reuse `agents/content-repurposer.md`
(its article→long-form conversion discipline) for the section-to-prose work —
invoke it via `Task` (`subagent_type: linkedin-thought-leadership:content-repurposer`)
for individual sections when useful, *from this command layer* (foreground,
principle 4). The command owns assembly and voice; the
agent assists with conversion. The draft is voice-matched by THIS session, not
self-certified for voice — voice-match remains an `[OPERATØR]` / `[GATE:
voice-trainer]` judgment, never auto-passed (plan §10.0).
2. **Propose section pitches — one line per section.** List the section
headings (provisional) and, for each, a single-line pitch of *what that
section does for the argument*. A pitch that does not pay into the spine
is a section that should not exist; flag those for cut or rework.
4. **Write the draft** to the **series root** as `<serie>/NN-utkast.md` (NN =
zero-padded edition number — the SAME filename Steps 7 and 8 render from).
This is the single canonical draft path: `render/build-html.mjs` (Step 7) and
`render/build-linkedin.mjs` (Step 8) both consume `NN-utkast.md` from cwd, and
the renderer **silently skips** any draft without an `NN` prefix. Do NOT write
to `linkedin/<article>.draft.md` — that path is skipped at render. Set
`currentPhase: "draft"` in `edition-state.json`, and append a "draft complete →
next: consistency/quality" pointer to the HANDOVER §6.
3. **Write the skeleton + pitches to `<serie>/NN-skjelett.md`** (NN = the same
zero-padded edition number used by `NN-utkast.md`, new suffix). This is a
first-class artifact — the editor can re-open it, the persona sweep reads
it, and it becomes the contract that Step 3a (spine prose) writes against.
Suggested file structure:
```markdown
# Skjelett — Del NN «<provisional title>»
## Spine
- **Premiss:**
- **Problem:**
- **Anbefaling:**
- **Gevinst:**
- **Vei videre:** … (or: N/A — standalone edition)
## Seksjons-pitcher
1. <heading> — <one-line pitch>
2. …
```
4. **Operator-gate (first round).** Present the skeleton + pitches to the
operator with `AskUserQuestion`. Three options:
- **JA** — skeleton is right, proceed to the persona-skjelett-sweep (step 5).
- **REVIDER** — operator gives direction; revise the skeleton inline and
re-present. Loop until JA or NEI.
- **NEI** — the skeleton is wrong at a load-bearing level (premise unsound,
argument-line incoherent). Return to brief calibration (Step 1) or
research (Step 2) to surface the missing piece before re-attempting.
Do not proceed past this gate without an explicit JA. The pipeline may not
advance to Step 3a (spine prose) until both this operator-gate AND the
persona-skjelett-sweep below return JA. `[OPERATØR]`
5. **Persona-skjelett-sweep — fan out `persona-reviewer` in skjelett-mode.**
Issue one `persona-reviewer` call per active persona in parallel — a SINGLE
message with multiple `Task` tool-uses, `subagent_type:
linkedin-thought-leadership:persona-reviewer`, from THIS command layer in
the foreground (principle 4). Pass each call the persona name, the path to
`<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).
6. **Collect skjelett verdicts and gate.** Each call returns per-axis flags
(HOLDER/TVILER/MANGLER), ≤3 direction-only flags, a section-pitch check
(any pitch that does not pay in), a per-persona verdict (JA/NEI), and a
gate decision. Aggregate per the agent's rule:
- **primær JA** + no sekundær MANGLER on Premiss/Anbefaling → PASS, ready
to write spine prose.
- **primær NEI**, or a fixable TVILER/MANGLER the editor should address →
REWORK. Revise the skeleton + pitches; re-run the sweep on the revision.
- **primær MANGLER on Premiss or Anbefaling** → BLOCK. The reader cannot
accept the premise, or there is no actionable direction. Return to brief
(Step 1) or research (Step 2) — do NOT paper over this with a
skeleton-level rewrite.
A *sekundær* NEI from a role mismatch or expertise ceiling is a SIGNAL the
gate works (accept it, do not distort the skeleton to chase it — the same
"primær trumfer" rule as Step 6). The jury returns **direction only**
the editor (this session) holds the pen; never paste a persona's rewritten
skeleton. `[GATE]`
7. **Convergence loop.** If gate is REWORK/BLOCK, fold flags into the
skeleton + pitches (or, on BLOCK, return upstream) and re-run the same
`persona-reviewer` calls against the revision. Loop until the primær
returns a clean JA. This loop is **cheap and frequent at this stage**
every round saved here is hours saved at the prose stage.
8. **Persist + checkpoint state.** Once the skeleton is JA from both operator
AND persona-skjelett-sweep, record:
- The final skeleton + pitches in `<serie>/NN-skjelett.md` (already written
in step 3, with any in-loop revisions applied).
- Per-persona skjelett verdicts in
`edition-state.json``articles.NN.personaSweep.skeleton` (or alongside
resonance/conversion under the same `personaSweep` object).
- `currentPhase: "skeleton-pitch"` in `edition-state.json` (the marker that
Step 2.5 is complete and the gate has passed).
- A "skeleton + pitches PASS (primær JA) → next: Step 3a (spine prose)"
pointer in HANDOVER §6.
```
Draft complete (or: partial — resumes at section <X>).
- Premise established: <one line>
- Key points drafted: <N>/<N>
Skeleton + section pitch (BEFORE prose) — complete.
- Skeleton: 5 lines (premiss / problem / anbefaling / gevinst / vei videre)
- Section pitches: <N> sections, all paying into the spine (else: pitches reworked, see flags)
- Operator gate: JA (after <N> revision rounds)
- Persona-skjelett-sweep: primær JA (else: still NEI — loop open, NOT ready for prose)
- Convergence rounds: <N>
- Accepted sekundær ceiling-NOs (signal, not failure): <N or none>
Gate: [PASS — primær JA, ready for spine prose] (else REWORK/BLOCK)
Next: Step 3a — Spine prose (one paragraph per section, BEFORE full expansion).
```
---
## Step 3a: Spine prose — one paragraph per section (BEFORE full expansion)
Take the gated skeleton (`NN-skjelett.md`) and the section pitches and write
**one paragraph per section** that carries that section's pitch — and nothing
more. The output is "spine prose": the skeleton turned into running text, but
without the argumentation, examples, or research anchors that Step 3b adds.
Typically ~2030 % of the edition's final length.
> **Order assertion (enforced).** Step 3a runs AFTER the Step 2.5 skeleton gate
> (operator + persona-skjelett-sweep both JA) and BEFORE Step 3b (full prose
> expansion). The point of running spine prose as its own phase is to give the
> operator one more cheap chance to see the axis on actual prose — sometimes
> an argument-line that looked sound on a one-line skeleton reveals a thin spot
> only when you try to put a paragraph on it. `[GATE]`
**Procedure:**
1. **Re-read the voice profile** (`assets/voice-samples/`) before writing a
single sentence — this is the existing LTL rule and it is not optional for
long-form. Voice match starts at the spine, not at expansion.
2. **For each section in `NN-skjelett.md`, write ONE paragraph that delivers
that section's pitch.** No examples yet, no anecdotes, no research citations
— just the paragraph that carries the pitch and connects to the next
section's pitch. Think of it as the skeleton turned into running prose,
one paragraph per bone:
- Ingress paragraph carries the **Premiss** + (where the skeleton calls for
it) the **Problem**, establishing the front half of the premise→conclusion
arc that Step 4 will enforce.
- Each body paragraph carries one section pitch (one pitch = one paragraph).
- Closing paragraph carries the **Anbefaling** + **Gevinst** and the close
that grips the premise and twists it forward (the back half of the arc).
- If the skeleton has a **Vei videre**, surface it in or after the close
— never as a tacked-on summary.
3. **Write the spine draft** to `<serie>/NN-utkast.md` (the canonical draft
path — Steps 7 and 8 render this exact file). This is the same `NN-utkast.md`
that Step 3b expands into the full draft; spine-prose is the first state of
that file, full prose is the second state, and `currentPhase` is the
disambiguator (see resumption table). Do NOT render in this state (Step 7's
review HTML and Step 8's POST.html require `currentPhase: "draft"` — i.e.
Step 3b complete).
4. **Operator-gate.** Present the spine draft to the operator with
`AskUserQuestion`. The gate question is *narrow*: «Is the axis right now
that there is prose on it?» Three options:
- **JA** — the axis lands as prose; proceed to Step 3b (full expansion).
- **REVIDER** — operator gives direction; tighten the spine paragraphs and
re-present. Stay in 3a; do NOT slip into expansion. (Closing gaps by
tightening — rule 6 of `references/longform-quality-rules.md` — applies
here just as it does in Steps 49.)
- **NEI** — the axis still fails as prose. Return to Step 2.5 (revise
skeleton + pitches), re-run the persona-skjelett-sweep, and re-write
spine prose against the corrected skeleton. Do not paper over a NEI by
pressing forward into expansion.
The pipeline may not advance to Step 3b without an explicit JA. `[OPERATØR]`
5. **Persist + checkpoint state.** Once the operator says JA:
- `NN-utkast.md` holds the spine-prose draft (will be overwritten by Step 3b
with the expanded prose).
- `currentPhase: "spine-prose"` in `edition-state.json` (the marker that 3a
is complete and the gate has passed).
- A "spine prose JA → next: Step 3b (full prose expansion)" pointer in
HANDOVER §6.
```
Spine prose (BEFORE full expansion) — complete.
- Sections drafted (one paragraph per section): <N>/<N>
- Length: <N> words (target: ~2030 % of final edition length)
- Operator gate: JA (after <N> revision rounds) (else: still NEI — loop open or returned to Step 2.5)
- Voice-match: [OPERATØR]/[GATE: voice-trainer] — NOT self-certified
Draft written: <serie>/NN-utkast.md (series root, NN-prefixed — Steps 7/8 render this exact file)
Draft written: <serie>/NN-utkast.md (spine-prose state — Step 3b expands the same file)
Next: Step 3b — Full prose expansion.
```
---
## Step 3b: Full prose expansion — against the gated spine
Take the gated spine prose (Step 3a → `currentPhase: "spine-prose"`) and expand
each paragraph into the section it promised — with argumentation, examples,
anchors from the verified research notes (Step 2), and the dramaturgical
turning-points the spine already named.
> **This phase may span multiple sessions.** A long edition can exceed a
> single session's context budget. If you approach the budget mid-expansion,
> stop cleanly, write the partial draft to `<serie>/NN-utkast.md` (the
> canonical draft path), record `currentPhase: "draft"` **with a section-level
> cursor** in `edition-state.json`, and append a precise "draft resumes at
> section <X>" pointer to the edition-HANDOVER §6. The next session re-reads
> Step 0, picks up the cursor, and continues. Never start the consistency
> pass (Step 4) on a half-written expansion. (Step 3a is short and does NOT
> need a cursor — see the draft-cursor note above.)
**Procedure:**
1. **Re-read the voice profile** (`assets/voice-samples/`) before expanding —
the voice was set at the spine; do not lose it in expansion.
2. **Expand section by section, against the spine.** Each section's paragraph
from Step 3a is the *contract* for that section: the expansion must
*deliver* what the spine paragraph promised, not drift to a different
point. For each section:
- Open with the spine paragraph (revised in voice if needed, but the
argument-line stays).
- Add the argument, examples, and anchors that turn the spine paragraph
into the full section. Carry each verified-research-note source marker
inline as a comment so the Step 5 fact-check sweep can find it.
- Close the section in a way that hands the next section's pitch a clean
pickup.
Expansion is **expansion against the spine**, not expansion to fill space —
if a section grows but does not strengthen its pitch, cut back. (Rule 6 of
`references/longform-quality-rules.md`, applied during writing rather than
only afterward.)
3. **Expand with the `content-repurposer` muscle.** Reuse
`agents/content-repurposer.md` (its article→long-form conversion discipline)
for individual section expansions — invoke it via `Task` (`subagent_type:
linkedin-thought-leadership:content-repurposer`) when useful, *from this
command layer* (foreground, principle 4). The command owns assembly and
voice; the agent assists with conversion. The draft is voice-matched by
THIS session, not self-certified for voice — voice-match remains an
`[OPERATØR]` / `[GATE: voice-trainer]` judgment, never auto-passed (plan
§10.0).
4. **Write the expanded draft** to `<serie>/NN-utkast.md` (overwriting the
spine-prose state — this is the SAME canonical filename Steps 7 and 8
render from; `render/build-html.mjs` and `render/build-linkedin.mjs`
silently skip any draft without an `NN` prefix). Set
`currentPhase: "draft"` in `edition-state.json`, and append a "draft
complete → next: consistency/quality" pointer to the HANDOVER §6.
```
Full prose expansion — complete (or: partial — resumes at section <X>).
- Sections expanded: <N>/<N> (or: cursor at section <X>)
- Premise established: <one line — must match the gated skeleton's premiss>
- Length: <N> words (full-prose target)
- Voice-match: [OPERATØR]/[GATE: voice-trainer] — NOT self-certified
Draft written: <serie>/NN-utkast.md (full-prose state — Steps 7/8 render this exact file)
Next: Step 4 — Consistency + quality.
```
@ -749,14 +1000,15 @@ Edition complete. Visible in /linkedin:calendar; mark live via /linkedin:calenda
## Reference Files
- `${CLAUDE_PLUGIN_ROOT}/config/edition-state.template.json` — edition-state schema (11 phases)
- `${CLAUDE_PLUGIN_ROOT}/config/edition-state.template.json` — edition-state schema (13 phases including v2.1 skeleton + spine-prose gates)
- `${CLAUDE_PLUGIN_ROOT}/config/edition-config.template.json` — static delivery metadata schema (calendar, freshness, credit, captions) — Step 8
- `${CLAUDE_PLUGIN_ROOT}/config/edition-delingstekst.template.md` — distribution-copy grammar (`## Del N —` / `## Samle`) — Steps 8/9
- `${CLAUDE_PLUGIN_ROOT}/config/edition-HANDOVER.template.md` — narrative production-state structure (§1§6) — Step 0
- `${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/persona-reviewer.md` — Step 6/9 reader jury (resonance + conversion modes)
- `${CLAUDE_PLUGIN_ROOT}/agents/persona-reviewer.md` — Step 2.5/6/9 reader jury (skeleton + resonance + conversion modes)
- `${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)
- `${CLAUDE_PLUGIN_ROOT}/render/build-linkedin.mjs` — POST.html delivery (Step 8)
- `${CLAUDE_PLUGIN_ROOT}/render/build-html.mjs` — annotatable review renderer (Step 7)

View file

@ -8,7 +8,9 @@
"load-context — read state/HANDOVER, voice profile, persona library, series brief (Step 0)",
"brief-calibration — angle, voice, audience personas, key points, leader-takeaway (Step 1)",
"research — parallel scoped mandates → verified notes, triangulation (Step 2)",
"draft — dramaturgical order, voice-matched; may span sessions (Step 3)",
"skeleton-pitch — five-line skeleton (premise/problem/recommendation/payoff/forward) + section pitches, operator gate + persona-skjelett-sweep BEFORE prose (Step 2.5)",
"spine-prose — one paragraph per section against the gated skeleton, operator gate BEFORE full expansion (Step 3a)",
"draft — full prose expansion against the gated spine; may span sessions (Step 3b)",
"consistency-quality — threads, premise→conclusion arc, AI-slop removal, formatting dose (Step 4)",
"factcheck-sweep — risk-sorted, guilty-until-disproven, verification log (Step 5)",
"persona-sweep-prelock — reader jury, primary wins, convergence to clean YES (Step 6)",

View file

@ -117,15 +117,43 @@ Ask once if the Step 1 brief did not already settle it. Do not assume an
aggressiveness; the same draft can be tightened conservatively or aggressively and
the operator owns that dial.
### 8. Skjelett før prosa (skeleton before prose — pre-condition for every other rule)
The argument-line — premiss, problem, anbefaling, gevinst, vei videre — must
be **explicit, visible, and confirmed** before the first sentence of prose is
written. None of the other rules can bite reliably on a draft whose spine was
never declared: Rule 1 (leder-takeaway) and Rule 2 (premiss→konklusjon-bue) in
particular collapse into post-hoc reconstruction if the spine was never gated.
- Write the five-line skeleton (premiss / problem / anbefaling / gevinst / vei
videre) and the section pitches **before any prose**. Both the operator and
the persona-skjelett-sweep (`persona-reviewer` mode: skjelett) must say JA on
this skeleton before Step 3a (spine prose) starts.
- A spine error caught at the skeleton stage costs 515 min; the same error
caught at Step 6 (resonance) costs 412 h; caught post-lock it costs a day
of cascading rework. The cheapest gate is also the earliest.
- The skeleton format is **identical to the Maskinrommet writing-contract §A**
(premiss / problem / anbefaling / gevinst / vei videre). Pipeline editions
produced through `/linkedin:newsletter` therefore satisfy that contract at
the structural level by construction.
**Pass/flag:** PASS when the skeleton + pitches exist as `<serie>/NN-skjelett.md`
and both the operator-gate AND the persona-skjelett-sweep returned JA before
prose started; FLAG retroactively if a draft turns out to have skipped this gate
(treat as a process miss and harvest the lesson — do not retrofit a skeleton
to a finished draft and call it gated).
---
## How the pipeline uses these rules
| Phase | Where the rules bite |
|-------|----------------------|
| Step 4 — Consistency + quality | Primary enforcement: apply rules 16, calibrate per rule 7, report a pass/flag per rule. |
| Step 2.5 — Skeleton + section pitch | Primary enforcement of rule 8: skeleton + pitches MUST exist and be JA from operator + persona-skjelett-sweep before prose. |
| Step 3a — Spine prose | Rule 6 applies even within spine prose (tighten, don't expand the spine); rule 8 is the gate that lets 3a start. |
| Step 4 — Consistency + quality | Primary enforcement: apply rules 16, calibrate per rule 7, report a pass/flag per rule. Rule 8 is verified as historical fact (skeleton existed + was gated). |
| Step 5 — Fact-check sweep | Fixes obey rule 6 (tighten, don't expand). |
| Step 6 — Persona sweep (pre-lock) | Rework obeys rule 6; the leader-takeaway (rule 1) and arc (rule 2) are what the reader jury judges for resonance. |
| Step 6 — Persona sweep (pre-lock) | Rework obeys rule 6; the leader-takeaway (rule 1) and arc (rule 2) are what the reader jury judges for resonance. A draft that passed rule 8 typically lands here with far fewer spine-level reworks. |
| Step 9 — Hook / conversion gate | Hook revisions obey rule 6 (sharpen the krok by tightening, body stays locked). |
## Self-certification boundary