feat(linkedin): v2.4.0 — editorial-reviewer agent + Step 5.5 craft gate in /linkedin:newsletter
Endring 8 from the change spec (Del 4 production, Maskinrommet). The persona resonance sweep measures reader-response (does it land?); nothing measured prose craft or narrative architecture (is it well-made?). In Del 4 every persona reported PASS, yet the editor found 8 fresh editorial points on first reading — ~6/8 craft/architecture blind spots no agent could see. v2.4.0 adds the missing editor role. New Step 5.5 (editorial-review) runs between fact-check (Step 5) and the persona sweep (Step 6): a new editorial-reviewer agent (Opus) judges two axes — prosa-handverk (em-dash density, verbatim repetition, postulated numbers, contradictions, versal-tic) + narrativ-arkitektur (concrete instantiation, theory-anchored hypotheses, series-title symmetry, equal action per addressee, un-overloaded conclusion). Returns <=10 flags as direction (never copy), each BLOCK/REWORK/NICE, operator-gated via SendUserFile. Runs before the persona sweep so the personas measure resonance instead of stumbling on craft noise. Mirrors the Maskinrommet writing-contract section C2 (bidirectional mirror rule). - agents/editorial-reviewer.md (NEW, Opus, orange) + fasit fixture (editorial-reviewer-cases.md: Del 4 v5 gold standard, 8 points -> 2 axes + severities, 3 BLOCK / 5 REWORK, 6/8 blind spots) + structural lint (7 tests). - Step 5.5 wired into commands/newsletter.md; pipeline 14 -> 15 phases. - editorial-review phase + additive editorialReview state in config/edition-state.template.json; resumption: factcheck-sweep -> Step 5.5, editorial-review -> Step 6 (spec said fact-check; canonical key is factcheck-sweep). - persona-reviewer contract unchanged: editorial-reviewer is supplementary (one measures craft, one measures response). - All doc levels synced (plugin + root README/CLAUDE.md, CHANGELOG, plugin.json 2.3.0 -> 2.4.0; agents 15 -> 16). 94 tests green. Acceptance-criterion #8 (live run on Del 4 v5) delivered as fasit fixture: a live run needs a session reload (new agent not invokable until then) + read access to the Del 4 v5 draft in Maskinrommet. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7ebd28cb0b
commit
9df3de795c
11 changed files with 714 additions and 28 deletions
|
|
@ -71,12 +71,13 @@ 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 (14 phases)
|
||||
## Pipeline overview (15 phases)
|
||||
|
||||
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).
|
||||
prose), an **editorial craft gate** runs before the persona sweep, and the
|
||||
persona resonance sweep runs **BEFORE lock** — these are the single most
|
||||
important corrections from the Seres process (plan §0.4, principle 5; v2.1 brief
|
||||
§1 on spine-error cost; v2.4 on the editor/persona role split).
|
||||
|
||||
| Step | Phase | What | Tools |
|
||||
|------|-------|------|-------|
|
||||
|
|
@ -88,6 +89,7 @@ single most important corrections from the Seres process (plan §0.4, principle
|
|||
| 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, de-AI/voice scrub, formatting dose | inline + `references/longform-quality-rules.md` + **`voice-scrubber`** |
|
||||
| 5 | **Fact-check sweep** | risk-sorted (🔴/🟡/🟢), guilty-until-disproven, verification log | **`fact-checker` (parallel)** |
|
||||
| 5.5 | **Editorial review — BEFORE persona sweep** | editor's craft gate: prose-craft (em-dash density, verbatim repetition, postulated numbers, contradictions, versal-tic) + narrative-architecture (concrete instantiation, theory-anchored hypotheses, series-title symmetry, equal action per addressee, un-overloaded conclusion). ≤10 flags, BLOCK/REWORK/NICE. Operator-gated via `SendUserFile`. | **`editorial-reviewer`** + `SendUserFile` |
|
||||
| 6 | **Persona sweep — BEFORE lock** | reader jury, primær wins, convergence to clean YES | **`persona-reviewer`** (resonance mode) |
|
||||
| 7 | **Annotation (optional)** | render annotatable review HTML for a manual pass | `render/build-html.mjs` |
|
||||
| 7.5 | **Visual assets — BEFORE lock** | cover (+ optional inline figures) or carousel deck: behov → per-image brief → generate (mcp-image default / external `cover-raw.png`) → operator-gate (`SendUserFile`) → approve to `cover.png` → credit/caption. Runs before lock so the renderer picks the cover up. | `mcp__mcp-image__generate_image` + `SendUserFile` + (carousel) `render/build-carousel.mjs` |
|
||||
|
|
@ -95,11 +97,12 @@ single most important corrections from the Seres process (plan §0.4, principle
|
|||
| 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 14 phases (Steps 0–2.5, 3a, 3b, 4–7, 7.5, 8–10) are
|
||||
> implemented below. This command takes an edition end-to-end: load →
|
||||
> **Build status:** all 15 phases (Steps 0–2.5, 3a, 3b, 4, 5, 5.5, 6, 7, 7.5,
|
||||
> 8–10) are implemented below. This command takes an edition end-to-end: load →
|
||||
> calibration → verified research → **skeleton + section pitch (operator +
|
||||
> persona gate BEFORE prose)** → **spine prose (operator gate BEFORE full
|
||||
> expansion)** → full prose draft → consistency/quality → fact-check sweep →
|
||||
> **editorial review (craft gate, operator-gated BEFORE the persona sweep)** →
|
||||
> pre-lock persona sweep → optional annotation → **visual assets (cover/figures
|
||||
> or carousel, operator-gated BEFORE lock)** → LOCK/delivery → post-lock hook
|
||||
> gate → scheduling, persisting each phase to `edition-state.json` (machine) and
|
||||
|
|
@ -182,7 +185,8 @@ Look up `edition-state.json` → `articles.<currentArticle>` (and the top-level
|
|||
| `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) |
|
||||
| `factcheck-sweep` | Step 5.5 — Editorial review *(v2.4 — craft gate BEFORE the persona sweep)* |
|
||||
| `editorial-review` | Step 6 — Persona sweep (pre-lock) |
|
||||
| `persona-sweep-prelock` | Step 7 — Annotation (optional) → Step 7.5 |
|
||||
| `annotation` | Step 7.5 — Visual assets *(cover/figures or carousel deck, BEFORE lock)* |
|
||||
| `visual-assets` | Step 8 — LOCK → delivery |
|
||||
|
|
@ -720,9 +724,10 @@ was in fact the prime contractor — nearly a counter-example). Never trust a cl
|
|||
because it "feels" right or because it sits in your own research notes.
|
||||
|
||||
> **This sweep runs BEFORE lock.** No edition is locked (Step 8) with an
|
||||
> unresolved 🔴 claim. Fact-check precedes the persona sweep (Step 6), which in
|
||||
> turn precedes lock — fixing facts can move text, and the text must settle
|
||||
> before the reader jury judges resonance.
|
||||
> unresolved 🔴 claim. Fact-check precedes the editorial review (Step 5.5) and the
|
||||
> persona sweep (Step 6), which in turn precede lock — fixing facts can move text,
|
||||
> and the text must settle before the editor judges craft and the reader jury
|
||||
> judges resonance.
|
||||
|
||||
**Procedure:**
|
||||
|
||||
|
|
@ -781,14 +786,126 @@ Fact-check sweep complete.
|
|||
- 🟢 Verified: <N> (sources logged to edition-state.json factcheckLog)
|
||||
- Freshness flags (re-verify on publish day): <N or none>
|
||||
Gate: [PASS — zero unresolved 🔴] (else REWORK/BLOCK with the open claims)
|
||||
Next: Step 5.5 — Editorial review (craft gate, BEFORE the persona sweep).
|
||||
```
|
||||
|
||||
## Step 5.5: Editorial review — craft gate, BEFORE the persona sweep
|
||||
|
||||
The fact-checked draft now faces the **editor**: a single `editorial-reviewer`
|
||||
pass that judges **craft**, not reader-response. It asks *is this well-made?* —
|
||||
clean prose and sound narrative architecture — where Step 6 asks *does this land
|
||||
for this reader?* Two different roles; both necessary, neither sufficient alone.
|
||||
|
||||
> **Why this step exists (Del 4 diagnosis, v2.4).** In the Del 4 production the
|
||||
> persona resonance sweep returned 15 flags across three personas and **every
|
||||
> persona reported PASS / ready-to-publish**. The editor then found **eight fresh
|
||||
> editorial points on first reading**, and only ~25 % overlapped anything the
|
||||
> personas had touched. The other six — a missing theory anchor, a broken
|
||||
> series-title link, a stranded small-business addressee, verbatim repetitions,
|
||||
> em-dash over-density, an internal contradiction — were **craft and architecture
|
||||
> blind spots** no agent measured. A persona PASS was mis-reporting "ready for the
|
||||
> editor's reading"; it only ever meant "lands for the reader." That gap cost an
|
||||
> extra editorial round per article. Step 5.5 closes it.
|
||||
|
||||
> **Why BEFORE the persona sweep, not after (enforced).** The personas measure
|
||||
> *response*. If the prose is locally messy — em-dash thickets, postulated
|
||||
> numbers, a repeated phrase — the persona flags become **noise**: the reader
|
||||
> stumbles on the craft defect instead of judging mobilization. Clean the craft
|
||||
> first (here), and the Step 6 sweep measures exactly what it was built to
|
||||
> measure. So editorial review runs after fact-check (Step 5) and before the
|
||||
> persona sweep (Step 6). `[GATE]`
|
||||
|
||||
**Relationship to `persona-reviewer` (unchanged).** This step does **not** alter
|
||||
the persona sweep. `editorial-reviewer` is *supplementary*: one agent measures
|
||||
craft (this step), one measures reader-response (Step 6). The role boundary is
|
||||
sharp — `editorial-reviewer` never flags "this won't resonate" (that is Step 6)
|
||||
and `persona-reviewer` never flags em-dash density (that is this step).
|
||||
|
||||
> **Truth source — §C2.** The agent's two-axis checklist is the operationalized
|
||||
> mirror of the **Maskinrommet skrivekontrakt §C2** (the craft half of the
|
||||
> contract; §A — skeleton-before-prose — is mirrored by `longform-quality-rules.md`
|
||||
> rule 8). §C2 is the source of truth: a change on either side must be mirrored to
|
||||
> the other so the two never drift.
|
||||
|
||||
**Procedure:**
|
||||
|
||||
1. **Take the fact-checked draft** (Step 5 output → `currentPhase: "factcheck-sweep"`).
|
||||
The body must already be fact-clean (no open 🔴) — editorial review runs on the
|
||||
settled text, not on a draft still moving under fact fixes.
|
||||
|
||||
2. **Run `editorial-reviewer` (single foreground `Task` call).** Invoke
|
||||
`subagent_type: linkedin-thought-leadership:editorial-reviewer` from THIS
|
||||
command layer in the foreground (principle 4), passing the draft path
|
||||
(`<serie>/NN-utkast.md`) and — when the edition is part of a series — the
|
||||
series title (for the A3 series-title-symmetry check). The agent returns a
|
||||
craft report: **≤10 flags** across two axes — **prosa-håndverk** (P1 em-dash
|
||||
density · P2 verbatim repetition · P3 postulated numbers without source/hedge ·
|
||||
P4 internal contradiction · P5 versal-tic) and **narrativ-arkitektur** (A1
|
||||
concrete instantiation · A2 theory-anchored hypotheses · A3 series-title
|
||||
symmetry · A4 equally-usable action per addressee · A5 un-overloaded
|
||||
conclusion) — each flag carrying a **quote/line reference**, a **direction**
|
||||
(never rewritten copy), and a **severity: BLOCK / REWORK / NICE**.
|
||||
|
||||
This is one foreground call (not a parallel fan-out): one editor reads the
|
||||
whole draft. The agent has `Read` + `Grep` — the mechanical prose checks are
|
||||
grep-able, the architecture checks need a read.
|
||||
|
||||
3. **Surface the report to the operator (`SendUserFile` — the Endring-5 pattern).**
|
||||
The flags are surfaced to KTG as a **markdown report**, the same operator-gate
|
||||
shape the visual-assets step (7.5) uses for candidates and Steps 2.5/3a use for
|
||||
annotation:
|
||||
1. Write the agent's report to `<serie>/NN-editorial-review.md` (NN = the same
|
||||
zero-padded edition number; new suffix, a first-class artifact alongside
|
||||
`NN-skjelett.md`).
|
||||
2. `SendUserFile` it (else a markdown `file://` link) so KTG can read the flags
|
||||
sorted BLOCK → REWORK → NICE and **decide which fold in**.
|
||||
3. **KTG gates.** The agent's severity ranking is a *recommendation*; the
|
||||
operator holds the gate. A BLOCK is the agent's strongest "must fix before
|
||||
Step 6", not an automatic pipeline halt. `[OPERATØR]`
|
||||
|
||||
4. **Fold in the approved flags by tightening, → v(n+1).** Fold the flags KTG
|
||||
approved into `<serie>/NN-utkast.md` **by tightening** (rule 6 of
|
||||
`references/longform-quality-rules.md` — close the gap, hold the length flat;
|
||||
never expand to paper over a craft defect). The result is the next draft
|
||||
iteration. The editor (this session) holds the pen — never paste the agent's
|
||||
direction as copy.
|
||||
|
||||
5. **Optionally re-run `editorial-reviewer` on the cleaned version.** If the
|
||||
fold-in was substantive (especially any BLOCK), re-run the agent on v(n+1) to
|
||||
confirm the flags cleared and no new craft defect was introduced by the edit.
|
||||
This loop is cheap and is the point of the gate — every craft round saved here
|
||||
is a KTG round saved at first reading.
|
||||
|
||||
6. **Persist + checkpoint state.** Once the editorial pass is folded in (and any
|
||||
re-run confirms clean):
|
||||
- Record the editorial report + which flags were folded vs. waived in
|
||||
`edition-state.json` → `articles.NN.editorialReview` (the durable,
|
||||
machine-readable record — what was flagged, severity, fold-in decision).
|
||||
- Set `currentPhase: "editorial-review"` in `edition-state.json` (the marker
|
||||
that Step 5.5 is complete and the operator-gate has passed).
|
||||
- Write an "editorial review complete (craft clean) → next: persona sweep
|
||||
(BEFORE lock)" line to `<serie>/STATE.md` (overwrite).
|
||||
|
||||
```
|
||||
Editorial review (craft gate, BEFORE persona sweep) — complete.
|
||||
- Flags: <N> (≤10) prosa-håndverk: <N> narrativ-arkitektur: <N>
|
||||
- Severity: <N> BLOCK · <N> REWORK · <N> NICE
|
||||
- Surfaced to operator: <serie>/NN-editorial-review.md (via SendUserFile) [OPERATØR]
|
||||
- Folded in (by tightening): <N> Waived (operator): <N>
|
||||
- Re-run on v(n+1): clean (or: skipped — fold-in non-substantive)
|
||||
- Length delta vs. fact-checked draft: <flat/±N words> (target: flat — rule 6)
|
||||
Gate: [PASS — craft clean, operator approved] (else: BLOCK flags open — loop)
|
||||
Next: Step 6 — Persona sweep (reader jury, BEFORE lock).
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Persona sweep — reader jury, BEFORE lock
|
||||
|
||||
The fact-checked draft now faces the **reader jury**: the personas selected in
|
||||
Step 1 read it read-only and judge whether it *lands* — not whether it is correct
|
||||
(that was Step 5), not whether it is original. This is the **single most
|
||||
The editorially-cleaned, fact-checked draft now faces the **reader jury**: the
|
||||
personas selected in Step 1 read it read-only and judge whether it *lands* — not
|
||||
whether it is correct (that was Step 5), not whether it is well-made (that was
|
||||
Step 5.5), not whether it is original. This is the **single most
|
||||
important ordering rule in the whole pipeline.** In the Seres production this
|
||||
sweep was originally run *after* the texts were locked (Step 8), which forced
|
||||
reopening locked texts — the biggest single process error of the series (plan
|
||||
|
|
@ -1218,12 +1335,13 @@ Edition complete. Visible in /linkedin:calendar; mark live via /linkedin:calenda
|
|||
|
||||
## Reference Files
|
||||
|
||||
- `${CLAUDE_PLUGIN_ROOT}/config/edition-state.template.json` — edition-state schema (14 phases including v2.1 skeleton + spine-prose gates and v2.3 visual-assets)
|
||||
- `${CLAUDE_PLUGIN_ROOT}/config/edition-state.template.json` — edition-state schema (15 phases including v2.1 skeleton + spine-prose gates, v2.3 visual-assets, and v2.4 editorial-review)
|
||||
- `${CLAUDE_PLUGIN_ROOT}/config/edition-config.template.json` — static delivery metadata schema (calendar, freshness, credit, captions) — Step 8
|
||||
- `${CLAUDE_PLUGIN_ROOT}/config/image-credit-caption.template.md` — cover motif + credit + caption table (honest-about-AI credit) — Step 7.5
|
||||
- `${CLAUDE_PLUGIN_ROOT}/config/edition-delingstekst.template.md` — distribution-copy grammar (`## Del N —` / `## Samle`) — Steps 8/9
|
||||
- `${CLAUDE_PLUGIN_ROOT}/config/personas.template.md` — reusable reader personas + "primær trumfer" rule
|
||||
- `${CLAUDE_PLUGIN_ROOT}/agents/fact-checker.md` — Step 5 fact-check agent (risk-sorted, guilty-until-disproven)
|
||||
- `${CLAUDE_PLUGIN_ROOT}/agents/editorial-reviewer.md` — Step 5.5 editor's craft gate (prose-craft + narrative-architecture, BLOCK/REWORK/NICE; mirrors Maskinrommet §C2)
|
||||
- `${CLAUDE_PLUGIN_ROOT}/agents/persona-reviewer.md` — Step 2.5/6/9 reader jury (skeleton + resonance + conversion modes)
|
||||
- `${CLAUDE_PLUGIN_ROOT}/agents/voice-scrubber.md` — Step 4 de-AI / Norwegian-chronicle voice scrub (gold standard = approved Norwegian editions, NOT the English post corpus)
|
||||
- `${CLAUDE_PLUGIN_ROOT}/commands/react.md` — multi-source synthesis discipline (reused in Step 2)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue