feat(linkedin-studio): wire contract-gate + ratify into newsletter Step 4.5 (fix #1 slice 3)
Slice 3 of fix #1 (§C2 bindende + akkumulerende): wire the deterministic §B/§C1 contract-gate into the long-form pipeline as a pre-handoff step, so mechanical violations die deterministically BEFORE the costly AI gates and never reach the operator at a judgment gate ("rettelser fester seg"). Newsletter pipeline: - New Step 4.5 (between Step 4 consistency/quality and Step 5 fact-check): (1) ratify the gate (rules.ts <-> §E-manifest 1:1; DRIFT escalates to operator, not a draft fix) and (2) gate the draft (exit 0 PASS / exit 1 BLOCK -> fix by tightening + re-run; WARN = direction, never blocks). Adopter-safe: no-op when contract-gate deps / the maskinrommet contract are absent. - Pipeline phase count 16 -> 17 across every LIVE surface (overview table + build-status + narrative + banner + schema pointer in newsletter.md; command-table rows in CLAUDE.md and README). Historical version-narrative entries left untouched. - edition-state.template.json: new "contract-gate" phase string (Step 4.5), between consistency-quality and factcheck-sweep. JSON valid; phases 16->17. CI integration (test-runner.sh, Section 14 — new): - 14a: contract-gate suite stays green (npm test exit 0) with a 33-test case-count floor (anti-erosion). - 14b: ratify invariant — rules.ts bound 1:1 to the §E-manifest. - Both KTG-internal and adopter-safe (warn/skip, never fail, when deps or the contract are absent). set +e inside the test command-substitution keeps a red suite from aborting the runner; ratify exit 1 captured via if-subshell. - SC6 anti-erosion section renumbered 14 -> 15; header comment updated. Verification: - Structure lint 81 -> 83/0/0 (contract-gate suite + ratify both green). - Documented Step 4.5 command smoke-tested on a real draft (serier/silvija-seres-motsvar/utkast/04-utkast.md): 0 BLOCK / 2 WARN -> "Gate passert", exit 0. - edition-state.template.json valid JSON; phases array = 17. foldIns capture into the pipeline phases deferred to a later slice (scope A). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ff3467de79
commit
e26d9fb659
5 changed files with 131 additions and 15 deletions
|
|
@ -22,9 +22,10 @@ allowed-tools:
|
|||
# LinkedIn Newsletter — Long-Form Content Engine
|
||||
|
||||
> **⏱ Before you start — this is a campaign, not a post.** Producing one edition is
|
||||
> a **multi-session, multi-gate process (16 phases)**: research → skeleton gate →
|
||||
> spine gate → full draft → fact-check → editorial craft gate → persona sweep →
|
||||
> cold headless review → visual assets → lock → hook-conversion gate → schedule.
|
||||
> a **multi-session, multi-gate process (17 phases)**: research → skeleton gate →
|
||||
> spine gate → full draft → contract-gate → fact-check → editorial craft gate →
|
||||
> persona sweep → cold headless review → visual assets → lock → hook-conversion
|
||||
> gate → schedule.
|
||||
> Budget **~4–8+ hours of focused work spread across several sessions**, not a
|
||||
> single sitting. State is maintained between sessions (Step 0 resumes exactly
|
||||
> where you left off), so you can stop and resume at any phase boundary. If you
|
||||
|
|
@ -81,7 +82,7 @@ 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 (16 phases)
|
||||
## Pipeline overview (17 phases)
|
||||
|
||||
The phase order is fixed. Two gates run **BEFORE prose** (skeleton + spine
|
||||
prose), an **editorial craft gate** runs before the persona sweep, the persona
|
||||
|
|
@ -100,6 +101,7 @@ split; v3.1 / Endring 9 on adversarial independence + framing-bias).
|
|||
| 3a | **Spine prose — BEFORE full expansion** | one paragraph per section carrying that section's pitch, nothing more. ~20–30 % 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, de-AI/voice scrub, formatting dose | inline + `references/longform-quality-rules.md` + **`voice-scrubber`** |
|
||||
| 4.5 | **Contract-gate — BEFORE the AI sweeps** | deterministic §B/§C1 rule-gate on the draft: ratify `rules.ts` ↔ §E-manifest (KTG invariant) → gate the draft (BLOCK = fix by tightening + re-run; WARN = direction). Mechanical violations die here, before the costly AI gates. | `scripts/contract-gate` (`node --import tsx src/cli.ts`) |
|
||||
| 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) |
|
||||
|
|
@ -110,11 +112,11 @@ split; v3.1 / Endring 9 on adversarial independence + framing-bias).
|
|||
| 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 16 phases (Steps 0–2.5, 3a, 3b, 4, 5, 5.5, 6, 6.5, 7,
|
||||
> 7.5, 8–10) are implemented below. This command takes an edition end-to-end:
|
||||
> **Build status:** all 17 phases (Steps 0–2.5, 3a, 3b, 4, 4.5, 5, 5.5, 6, 6.5,
|
||||
> 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 →
|
||||
> expansion)** → full prose draft → consistency/quality → **contract-gate (deterministic §B/§C1)** → fact-check sweep →
|
||||
> **editorial review (craft gate, operator-gated BEFORE the persona sweep)** →
|
||||
> pre-lock persona sweep → **headless adversarial review (cold review package,
|
||||
> operator-gated BEFORE lock)** → optional annotation → **visual assets
|
||||
|
|
@ -735,7 +737,7 @@ modell-/navne-katalog collapse) to the operator. Voice-MATCH remains
|
|||
non-self-certified — that verdict stays with the Step 6 persona sweep / operator.
|
||||
|
||||
After the pass, set `currentPhase: "consistency-quality"` in `edition-state.json`
|
||||
and write a "quality pass complete → next: fact-check sweep" line to
|
||||
and write a "quality pass complete → next: contract-gate" line to
|
||||
`<serie>/STATE.md` (overwrite).
|
||||
|
||||
```
|
||||
|
|
@ -746,6 +748,74 @@ Consistency + quality pass complete.
|
|||
- AI-slop phrases removed: <N>
|
||||
- Formatting dose: <within bounds/trimmed>
|
||||
- Length delta vs. draft: <flat/±N words> (target: flat)
|
||||
Next: Step 4.5 — Contract-gate (deterministic §B/§C1 binding, BEFORE the AI sweeps).
|
||||
```
|
||||
|
||||
## Step 4.5: Contract-gate — deterministic §B/§C1 binding (BEFORE the AI sweeps)
|
||||
|
||||
Before any AI gate touches the draft — fact-check (Step 5), editorial craft (Step
|
||||
5.5), persona sweep (Step 6), headless review (Step 6.5) — run the **deterministic
|
||||
contract-gate** over the consistency-passed draft. It is pure regex/literal matching
|
||||
(no model in the loop): the same mechanical §B/§C1 violation is caught and fixed the
|
||||
same way every time, so it **never reaches the operator at a judgment gate**. This is
|
||||
the machine half of the "corrections that stick" goal — the cheap, deterministic pass
|
||||
runs first so the costly AI gates spend their judgment on resonance and truth, not on
|
||||
mechanical noise.
|
||||
|
||||
> **Truth source — §B/§C1 vs §C2.** The gate's ruleset is `scripts/contract-gate/
|
||||
> src/rules.ts` (data, not code), bound **1:1** to the Maskinrommet skrivekontrakt
|
||||
> **§E gate-bindings-manifest** by `ratify` (id ↔ ref ↔ severity bijection). It is the
|
||||
> *mechanical* half of the contract (§B structure + §C1 mechanical gate); the *craft*
|
||||
> half (§C2) is the `editorial-reviewer` at Step 5.5. This Step does not restate the
|
||||
> rules — `rules.ts` is the single source of truth, and ratify proves it stays bound
|
||||
> to the contract. Distinct from Step 4's `references/longform-quality-rules.md`,
|
||||
> which is the §A/quality reference applied by reasoning.
|
||||
|
||||
> **Adopter note.** The gate is a KTG-internal tool: it needs the contract-gate deps
|
||||
> (`scripts/contract-gate/node_modules` — run `npm install` there once) and, for
|
||||
> ratify, the maskinrommet contract. If either is absent (a plain adopter ships
|
||||
> neither), this Step is a **no-op** and the §B/§C1 discipline falls back to the Step 4
|
||||
> quality-pass reasoning. It never blocks an adopter.
|
||||
|
||||
**Procedure:**
|
||||
|
||||
1. **Ratify the gate (invariant — confirm it is still bound to the contract).** Before
|
||||
trusting any verdict, confirm the ruleset is in 1:1 sync with the contract
|
||||
§E-manifest:
|
||||
```
|
||||
cd "${CLAUDE_PLUGIN_ROOT}/scripts/contract-gate" && \
|
||||
node --import tsx src/cli.ts --ratify
|
||||
```
|
||||
- **exit 0** → `rules.ts` bound 1:1 to §E → proceed.
|
||||
- **exit 1 (DRIFT)** → a **tooling/contract inconsistency** (a rule changed on one
|
||||
side only). This is NOT a draft fix — **escalate to the operator**; the §E
|
||||
accumulation procedure (promote → ratify) reconciles it. `[GATE]`
|
||||
- contract or deps absent → skip with a one-line note (adopter); the draft-gate
|
||||
below still runs if the deps are present.
|
||||
|
||||
2. **Gate the draft.** Run the gate over the edition draft. The gate runs from its own
|
||||
dir (where `tsx` lives), so pass the draft's **absolute** path:
|
||||
```
|
||||
cd "${CLAUDE_PLUGIN_ROOT}/scripts/contract-gate" && \
|
||||
node --import tsx src/cli.ts "<absolutt sti til serie-mappe>/NN-utkast.md"
|
||||
```
|
||||
- **exit 0** → PASS. Surface any **WARN** violations as direction (operator
|
||||
judgment — WARN never blocks).
|
||||
- **exit 1** → BLOCKED. Show each BLOCK violation (ruleId · ref · line · message),
|
||||
fix **by tightening** (the Step 4 rule still holds — swap weaker for sharper, do
|
||||
not expand), and **re-run until exit 0**. `[GATE]`
|
||||
- **exit 2** → usage error (e.g. wrong path) — diagnose; do not treat as a content
|
||||
flag.
|
||||
|
||||
3. **Persist + checkpoint state.** Set `currentPhase: "contract-gate"` in
|
||||
`edition-state.json` and write a "contract-gate passed → next: fact-check sweep"
|
||||
line to `<serie>/STATE.md` (overwrite).
|
||||
|
||||
```
|
||||
Contract-gate complete.
|
||||
- Ratify: <in sync (10 rules 1:1) / DRIFT escalated / skipped (adopter)>
|
||||
- BLOCK violations: <0 / fixed N by tightening>
|
||||
- WARN violations: <N surfaced as direction>
|
||||
Next: Step 5 — Fact-check sweep (guilty-until-disproven, BEFORE lock).
|
||||
```
|
||||
|
||||
|
|
@ -1572,7 +1642,7 @@ the honest decision surface; it sells nothing.
|
|||
|
||||
## Reference Files
|
||||
|
||||
- `${CLAUDE_PLUGIN_ROOT}/config/edition-state.template.json` — edition-state schema (16 phases including v2.1 skeleton + spine-prose gates, v2.3 visual-assets, v2.4 editorial-review, and v3.1 headless-review + per-article `personas` + `pivots`)
|
||||
- `${CLAUDE_PLUGIN_ROOT}/config/edition-state.template.json` — edition-state schema (17 phases including the deterministic §B/§C1 contract-gate (Step 4.5), v2.1 skeleton + spine-prose gates, v2.3 visual-assets, v2.4 editorial-review, and v3.1 headless-review + per-article `personas` + `pivots`)
|
||||
- `${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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue