feat(linkedin-studio): wire lived-specifics extraction into newsletter pipeline (fix #2 slice 3)
Wire the kilde-så-draft binding (slices 1–2) into the live /linkedin:newsletter pipeline so a draft is grounded in the operator's real material BEFORE any prose. - New Step 1.5 "Lived-specifics extraction" BETWEEN brief (1) and research (2): query the bank → 3–5 sharp elicitation questions (vagueness refused, never fabricated — invariant 3) → `add` to the specifics-bank → populate the articles.NN.livedSpecifics slot-map → render the NN-kilder.md ledger. First phase to write machine state (persists brief + personas + binding). - Deterministic binding-gate (`validate-binding`, exit 1 = BLOCK) wired as a new step 5 of the Step 2.5 skeleton-gate (renumbered 5→9): no prose is written on an unresolved load-bearing claim; livedSpecifics → "bound" on pass. - Step 2 re-scoped BY the binding: research fills the ekstern/unresolved slots + verifies the operator's own numbers (regel 6/7) → flips bank unverified→verified → re-renders NN-kilder.md, instead of re-sourcing what is already grounded. - Pipeline 17 → 18 phases: new `lived-specifics` phase id in edition-state _doc.phases; resumption table + pipeline overview + CLAUDE.md + README updated. - Lint: new Section 15 "Specifics-Bank Binding" wires the specifics-bank suite into CI (suite green + case-count floor 28, KTG-only/adopter-skip); the assertion-count anti-erosion floor moves to Section 16. Verification: structure gate 84/0/0 (was 83), specifics-bank 28/28, contract-gate ratify 1:1, edition-state template valid JSON (18 phases), gitleaks clean on all 5 files. Design record: docs/fix2/slice2-binding.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
33f18c35e6
commit
527391ab47
5 changed files with 255 additions and 44 deletions
|
|
@ -22,7 +22,8 @@ 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 (17 phases)**: research → skeleton gate →
|
||||
> a **multi-session, multi-gate process (18 phases)**: lived-specifics extraction →
|
||||
> 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.
|
||||
|
|
@ -82,7 +83,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 (17 phases)
|
||||
## Pipeline overview (18 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
|
||||
|
|
@ -96,7 +97,8 @@ split; v3.1 / Endring 9 on adversarial independence + framing-bias).
|
|||
|------|-------|------|-------|
|
||||
| 0 | **Load context** | edition-state + `<serie>/STATE.md`, 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)** |
|
||||
| 1.5 | **Lived-specifics extraction — BEFORE research** | elicitation interview (3–5 sharp questions, **vagueness refused**) → `add` lived material to the specifics-bank + populate `articles.NN.livedSpecifics` slot-map (each load-bearing key-point bound specific/abstrakt/ekstern/unresolved) → render `NN-kilder.md`. The grounded-sourcing layer (Fix #2, kilde-så-draft; never fabricated — invariant 3). | `AskUserQuestion` + `scripts/specifics-bank` (`node --import tsx src/cli.ts`) |
|
||||
| 2 | **Research — scoped by the binding** | parallel scoped mandates → verified notes; triangulation. Fills the `ekstern`/`unresolved` slots + verifies your own numbers (regel 6/7) | **`Task` fan-out (foreground)** |
|
||||
| 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. ~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` |
|
||||
|
|
@ -112,9 +114,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 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 +
|
||||
> **Build status:** all 18 phases (Steps 0, 1, 1.5, 2, 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 → **lived-specifics extraction (elicitation + bank binding,
|
||||
> BEFORE research)** → verified research (scoped by the binding) → **skeleton + section pitch (operator +
|
||||
> persona gate BEFORE prose)** → **spine prose (operator gate BEFORE full
|
||||
> expansion)** → full prose draft → consistency/quality → **contract-gate (deterministic §B/§C1)** → fact-check sweep →
|
||||
> **editorial review (craft gate, operator-gated BEFORE the persona sweep)** →
|
||||
|
|
@ -206,7 +210,8 @@ 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 |
|
||||
| `brief-calibration` | Step 1.5 — Lived-specifics extraction *(Fix #2 — elicitation + bank binding BEFORE research)* |
|
||||
| `lived-specifics` | Step 2 — Research *(scoped by the binding)* |
|
||||
| `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 |
|
||||
|
|
@ -281,7 +286,8 @@ Settle these dimensions (most should come from context, not questions):
|
|||
(accept it), but a *primær* NO is never accepted (revise until a clean YES).
|
||||
**Persist** the resolved set to `edition-state.json` →
|
||||
`articles.NN.personas` (each entry: name, tier, the five fields, source) at the
|
||||
Step 2 checkpoint — it is then stable across sessions and is the single source
|
||||
**Step 1.5 checkpoint** (the first machine-state write; Step 2 then adds the
|
||||
research notes) — it is then stable across sessions and is the single source
|
||||
every later sweep reads. See `config/personas.template.md` →
|
||||
"Per-artifact personas".
|
||||
- **Key points** — the 2–4 load-bearing claims the edition must make.
|
||||
|
|
@ -305,6 +311,128 @@ Edition brief
|
|||
- Leader-takeaway: <one takeaway + one action>
|
||||
```
|
||||
|
||||
## Step 1.5: Lived-specifics extraction — BEFORE research
|
||||
|
||||
> **The grounded-sourcing layer (Fix #2, kilde-så-draft).** Sourcing, not styling,
|
||||
> is where authenticity is won. A draft that starts from your real number / named
|
||||
> case / what-actually-broke is forwardable; a draft that invents plausible filler
|
||||
> is hollow, and every downstream voice gate then only polishes hollow content. So
|
||||
> BEFORE research and BEFORE prose, each load-bearing claim is bound to real
|
||||
> material — or you *consciously* decide it does not need a concrete instance. This
|
||||
> step is that binding; **vagueness is refused** (drømme-spec G4). The plugin never
|
||||
> invents lived experience (invariant 3).
|
||||
|
||||
> **Order assertion (enforced).** Step 1.5 runs AFTER the brief (Step 1) and BEFORE
|
||||
> research (Step 2). It populates the slot-map and renders the `NN-kilder.md`
|
||||
> ledger; the BLOCKing «vaghet avvises» gate (`validate-binding`) is enforced at
|
||||
> the **Step 2.5 skeleton-gate**, once the spine is visible. Research (Step 2) is
|
||||
> then scoped BY this binding — it fills the `ekstern`/`unresolved` gaps and
|
||||
> verifies your own numbers, instead of re-sourcing what is already grounded. `[GATE]`
|
||||
|
||||
> **Adopter note.** This step uses the KTG-internal specifics-bank
|
||||
> (`${CLAUDE_PLUGIN_ROOT}/scripts/specifics-bank` — run `npm install` there once).
|
||||
> If its deps are absent (a plain adopter ships none), this Step is a **no-op**:
|
||||
> skip to Step 2 and supply specifics inline during drafting. It never blocks an
|
||||
> adopter.
|
||||
|
||||
**Procedure:**
|
||||
|
||||
1. **Surface inventory you already have.** Derive the edition's topic tags from the
|
||||
brief (Step 1 angle + key points), and query the bank for lived material that
|
||||
already matches — so the interview asks only for what is genuinely missing. The
|
||||
CLI runs from its own dir (where `tsx` lives):
|
||||
|
||||
```bash
|
||||
cd "${CLAUDE_PLUGIN_ROOT}/scripts/specifics-bank" && \
|
||||
node --import tsx src/cli.ts query --tags "<tag1,tag2,…>"
|
||||
```
|
||||
|
||||
Show the hits to the operator; each is a candidate binding for a load-bearing
|
||||
key-point.
|
||||
|
||||
2. **Elicitation interview — 3–5 sharp questions, vagueness refused.** For each
|
||||
load-bearing key-point (Step 1) NOT already covered by inventory, ask one tight
|
||||
question that demands a *concrete instance*, not a generality. Pick the shape the
|
||||
claim needs (one per question):
|
||||
- a **number** you measured ("how many / how much / how long — your figure"),
|
||||
- a **named case** ("which project / tool / team — name it"),
|
||||
- a **what-broke** ("what actually failed, concretely"),
|
||||
- a **contrarian** point ("where do you disagree with the consensus, and why"),
|
||||
- a **mind-change** ("what did you used to believe and stop — what flipped it").
|
||||
|
||||
**Refuse vagueness.** If the answer is a generality ("it's generally faster",
|
||||
"people struggle with this"), push back once for the concrete instance. If the
|
||||
operator genuinely has none, that key-point becomes an `abstrakt` slot (with a
|
||||
stated rationale) or an `ekstern` slot (research will source it) — **never a
|
||||
fabricated specific** (invariant 3). The plugin elicits your raw material; it
|
||||
does not invent it.
|
||||
|
||||
3. **Fold elicited material into the bank.** For each concrete answer, `add` it so
|
||||
it is reusable across editions (content-hash dedupe + tag-union are automatic):
|
||||
|
||||
```bash
|
||||
cd "${CLAUDE_PLUGIN_ROOT}/scripts/specifics-bank" && \
|
||||
node --import tsx src/cli.ts add \
|
||||
--type <number|named-case|what-broke|contrarian|mind-change|other> \
|
||||
--content "<verbatim — the operator's own words>" --tags "<tags>" \
|
||||
[--source "<where it came from>"] [--verification <verified|unverified|n/a>]
|
||||
```
|
||||
|
||||
A figure the operator states from memory is `--verification unverified` — it
|
||||
stays guilty-until-checked, and Step 2 verifies it (regel 6/7).
|
||||
|
||||
4. **Populate the slot-map.** Write `articles.NN.livedSpecifics` in
|
||||
`edition-state.json` — one `kind: "key-point"` slot per load-bearing claim, each
|
||||
bound to exactly one of:
|
||||
- `{ type: "specific", specificId: "<bank id>" }` — grounded in lived material;
|
||||
- `{ type: "abstrakt", rationale: "<why no concrete instance is needed here>" }`;
|
||||
- `{ type: "ekstern", source?: "<research ref — Step 2 fills it>" }` — to be
|
||||
sourced, not lived;
|
||||
- `{ type: "unresolved" }` — a temporary placeholder only; this is the vagueness
|
||||
the Step 2.5 gate BLOCKs, so resolve it before then.
|
||||
|
||||
Set `status: "pending"` (Step 2.5 flips it to `"bound"` when the gate passes).
|
||||
The shape is documented in `${CLAUDE_PLUGIN_ROOT}/config/edition-state.template.json`
|
||||
(`_doc.livedSpecifics`).
|
||||
|
||||
5. **Render the `NN-kilder.md` ledger.** Deterministically render the read-only
|
||||
sources artifact from the slot-map + bank (NN = the same zero-padded edition
|
||||
number as `NN-utkast.md`). Pass absolute paths:
|
||||
|
||||
```bash
|
||||
cd "${CLAUDE_PLUGIN_ROOT}/scripts/specifics-bank" && \
|
||||
node --import tsx src/cli.ts render-kilder \
|
||||
--edition "<abs>/linkedin/edition-state.json" \
|
||||
--out "<abs>/linkedin/NN-kilder.md"
|
||||
```
|
||||
|
||||
It is regenerated like POST.html, never hand-edited. Surface it to the operator
|
||||
so the binding is visible (coverage by type + the numbers-to-verify line).
|
||||
|
||||
6. **Persist + checkpoint state.** Step 1.5 is the **first phase that writes machine
|
||||
state**, so:
|
||||
- If `edition-state.json` does not exist yet (fresh edition), initialize it from
|
||||
the template schema (`${CLAUDE_PLUGIN_ROOT}/config/edition-state.template.json`).
|
||||
- Persist the resolved **brief** (Step 1) and **personas** (the set + primær)
|
||||
into `articles.NN` — this is the first durable write of both (Step 2 then adds
|
||||
the research notes).
|
||||
- Write `articles.NN.livedSpecifics` (the slot-map above, `status: "pending"`).
|
||||
- Set `currentPhase: "lived-specifics"` in `edition-state.json`.
|
||||
- Write a "lived-specifics bound → next: research (scoped by the binding)" line
|
||||
to `<serie>/STATE.md` (overwrite).
|
||||
|
||||
```
|
||||
Lived-specifics extraction (BEFORE research) — complete.
|
||||
- Inventory hits reused: <N> New material elicited + added to bank: <N>
|
||||
- Slot-map: <total> slots — levd <N> · abstrakt <N> · ekstern <N> · uavklart <N>
|
||||
- Numbers to verify (regel 6/7): <N> (carried to Step 2)
|
||||
- Ledger rendered: <serie>/linkedin/NN-kilder.md
|
||||
- Vagueness refused: <N or none> (never fabricated — invariant 3)
|
||||
Next: Step 2 — Research (scoped by the binding: fill ekstern/unresolved, verify numbers).
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Research — parallel `Task` fan-out (foreground)
|
||||
|
||||
> **This is the load-bearing phase.** Quality long-form needs verified, triangulated
|
||||
|
|
@ -313,12 +441,22 @@ Edition brief
|
|||
|
||||
**Procedure:**
|
||||
|
||||
1. **Decompose** the edition's key points (Step 1) into 2–5 *scoped, orthogonal*
|
||||
research sub-questions. Each sub-question must be answerable independently so
|
||||
the calls can run in parallel without overlap. Reuse the multi-source synthesis
|
||||
discipline from `commands/react.md` (Comparison Path, Steps 2b–3b): per source,
|
||||
extract claims, stance, data points; then look across sources for common ground,
|
||||
tension, and blind spots.
|
||||
0. **Scope by the binding, not the raw key points (Fix #2 re-scope).** Read
|
||||
`articles.NN.livedSpecifics` (Step 1.5). Research targets the **gaps the binding
|
||||
names** — slots bound `ekstern` (and any still `unresolved` at entry): the claims
|
||||
that explicitly need an external source. Slots bound to a `specific` are already
|
||||
grounded in lived material; do **not** re-source their substance (you may
|
||||
corroborate, but it is not the gap). Every **`unverified-number`** warning from
|
||||
the Step 1.5 binding is also a research target: confirm the operator's own figure
|
||||
against a primary source (regel 6/7). This is what makes research *fill* the
|
||||
draft instead of re-deriving what the operator already knows.
|
||||
|
||||
1. **Decompose** the binding's `ekstern`/`unresolved` slots + unverified numbers
|
||||
(step 0) into 2–5 *scoped, orthogonal* research sub-questions. Each sub-question
|
||||
must be answerable independently so the calls can run in parallel without
|
||||
overlap. Reuse the multi-source synthesis discipline from `commands/react.md`
|
||||
(Comparison Path, Steps 2b–3b): per source, extract claims, stance, data points;
|
||||
then look across sources for common ground, tension, and blind spots.
|
||||
|
||||
2. **Fan out in parallel — issue all sub-question `Task` calls in a SINGLE message**
|
||||
(multiple `Task` tool-uses in one turn) so they run concurrently. Each call gets
|
||||
|
|
@ -353,21 +491,27 @@ Edition brief
|
|||
source(s) and a confidence marker. Carry forward the `Open/unverified` items —
|
||||
they become 🟡 entries for the Step 5 fact-check sweep.
|
||||
|
||||
5. **Persist + checkpoint state.** Write the resolved brief (Step 1), the
|
||||
resolved **per-article personas** (`articles.NN.personas` — the set + primær
|
||||
confirmed/defined in Step 1), and the verified research notes into the
|
||||
edition's `edition-state.json` (`currentPhase: "research"`, article status
|
||||
`in-progress`) and append a
|
||||
5. **Persist + checkpoint state.** Write the verified research notes into
|
||||
`edition-state.json` (the brief + personas were first persisted at the Step 1.5
|
||||
checkpoint — re-affirm them here if calibration changed). **Update the binding
|
||||
from what research resolved:** when a sub-question sources an `ekstern` slot, set
|
||||
its `source`; when it confirms an operator figure, flip the bank specific
|
||||
`unverified → verified` (the bank's `add`/verify path), then **re-render
|
||||
`NN-kilder.md`** so the ledger stays current (a number that could not be verified
|
||||
stays `unverified` and is carried to the Step 5 fact-check sweep as 🟡 — never
|
||||
silently asserted). Set `currentPhase: "research"`, article status
|
||||
`in-progress`, and append a
|
||||
"research complete → next: skeleton + section pitch (BEFORE prose)" next-step
|
||||
line to `<serie>/STATE.md` (overwrite). 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).
|
||||
line to `<serie>/STATE.md` (overwrite). If somehow no `edition-state.json` exists
|
||||
yet (Step 1.5 was a no-op for an adopter), initialize it 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.
|
||||
- Sub-questions: <N> (ran in parallel)
|
||||
- Sub-questions: <N> (ran in parallel; scoped to ekstern/unresolved slots + numbers)
|
||||
- Verified notes: <N> by key point
|
||||
- Binding updated: ekstern slots sourced <N> · numbers verified <N> → NN-kilder.md re-rendered
|
||||
- Carried to fact-check (🟡 unverified): <N>
|
||||
State written: <serie>/linkedin/edition-state.json (phase: research)
|
||||
Next: Step 2.5 — Skeleton + section pitch (operator + persona gate BEFORE prose).
|
||||
|
|
@ -386,10 +530,11 @@ Next: Step 2.5 — Skeleton + section pitch (operator + persona gate BEFORE pros
|
|||
|
||||
> **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
|
||||
> spine prose — until the operator says JA on the skeleton, the **deterministic
|
||||
> binding-gate** passes (every load-bearing claim grounded — Fix #2), 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]`
|
||||
> Maskinrommet writing-contract §A discipline (skeleton + sources before prose)
|
||||
> into the pipeline. `[GATE]`
|
||||
|
||||
**Procedure:**
|
||||
|
||||
|
|
@ -454,17 +599,47 @@ Next: Step 2.5 — Skeleton + section pitch (operator + persona gate BEFORE pros
|
|||
JA proceed, or another round?». `AskUserQuestion` (JA / REVIDER / NEI) is
|
||||
also the **fallback** gate when rendering is unavailable; it is not the
|
||||
primary flow:
|
||||
- **JA** — proceed to the persona-skjelett-sweep (step 5).
|
||||
- **JA** — proceed to the binding-gate (step 5), then the
|
||||
persona-skjelett-sweep (step 6).
|
||||
- **REVIDER** — another annotation round; revise and re-render.
|
||||
- **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.
|
||||
|
||||
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]`
|
||||
advance to Step 3a (spine prose) until this operator-gate, the deterministic
|
||||
binding-gate, AND the persona-skjelett-sweep below all pass. `[OPERATØR]`
|
||||
|
||||
5. **Persona-skjelett-sweep — fan out `persona-reviewer` in skjelett-mode.**
|
||||
5. **Binding-gate — deterministic «vaghet avvises» (Fix #2, BEFORE the persona
|
||||
sweep).** Now that the spine is visible, enforce the Step 1.5 binding: every
|
||||
load-bearing slot must resolve to a real specific, a justified `abstrakt`, or an
|
||||
`ekstern` source — no `unresolved` slot, no `specific` pointing at a missing bank
|
||||
id. It is pure/deterministic (no model in the loop), so the same vagueness is
|
||||
caught the same way every time. Run it from the package dir; pass the edition
|
||||
state's **absolute** path:
|
||||
|
||||
```bash
|
||||
cd "${CLAUDE_PLUGIN_ROOT}/scripts/specifics-bank" && \
|
||||
node --import tsx src/cli.ts validate-binding \
|
||||
--edition "<abs>/linkedin/edition-state.json"
|
||||
```
|
||||
|
||||
- **exit 0** → PASS. Surface any **WARN** (`unverified-number`, regel 6/7) as
|
||||
direction — a number still unverified after Step 2 research is carried to the
|
||||
Step 5 fact-check sweep as 🟡, never silently asserted.
|
||||
- **exit 1** → BLOCKED. The output names each blocking slot (`unresolved` /
|
||||
`dangling-specific` / `unjustified-abstrakt`). Resolve it — elicit the missing
|
||||
specific (loop back to Step 1.5 step 2), fix the dangling id, or give the
|
||||
`abstrakt` escape a real rationale — then **re-render `NN-kilder.md`** and
|
||||
re-run until exit 0. No prose is written on an unresolved load-bearing
|
||||
claim. `[GATE]`
|
||||
- deps/contract absent (adopter — Step 1.5 was a no-op) → skip with a one-line
|
||||
note; the persona-skjelett-sweep below still runs.
|
||||
|
||||
When the gate passes, set `articles.NN.livedSpecifics.status: "bound"` in
|
||||
`edition-state.json`.
|
||||
|
||||
6. **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-studio:persona-reviewer`, from THIS command layer in
|
||||
|
|
@ -474,7 +649,7 @@ Next: Step 2.5 — Skeleton + section pitch (operator + persona gate BEFORE pros
|
|||
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
|
||||
7. **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:
|
||||
|
|
@ -493,17 +668,19 @@ Next: Step 2.5 — Skeleton + section pitch (operator + persona gate BEFORE pros
|
|||
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
|
||||
8. **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:
|
||||
9. **Persist + checkpoint state.** Once the skeleton is JA from the operator, the
|
||||
binding-gate passed, AND the persona-skjelett-sweep returns a clean primær JA,
|
||||
record:
|
||||
|
||||
- The final skeleton + pitches in `<serie>/NN-skjelett.md` (already written
|
||||
in step 3, with any in-loop revisions applied).
|
||||
- `articles.NN.livedSpecifics.status: "bound"` (set by the binding-gate, step 5).
|
||||
- Per-persona skjelett verdicts in
|
||||
`edition-state.json` → `articles.NN.personaSweep.skeleton` (or alongside
|
||||
resonance/conversion under the same `personaSweep` object).
|
||||
|
|
@ -517,10 +694,11 @@ 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)
|
||||
- Binding-gate (vaghet avvises): PASS — all load-bearing slots bound; livedSpecifics → "bound" (else BLOCK: <N> unresolved/dangling)
|
||||
- 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)
|
||||
Gate: [PASS — primær JA + binding bound, ready for spine prose] (else REWORK/BLOCK)
|
||||
Next: Step 3a — Spine prose (one paragraph per section, BEFORE full expansion).
|
||||
```
|
||||
|
||||
|
|
@ -1642,7 +1820,8 @@ the honest decision surface; it sells nothing.
|
|||
|
||||
## Reference Files
|
||||
|
||||
- `${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-state.template.json` — edition-state schema (18 phases including Fix #2 lived-specifics extraction (Step 1.5) + `articles.NN.livedSpecifics`, 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}/scripts/specifics-bank/` — lived-specifics store + per-edition binding (Fix #2, kilde-så-draft): `query`/`add` (Step 1.5), `validate-binding` (Step 2.5 gate), `render-kilder` (`NN-kilder.md` ledger). Design record: `docs/fix2/slice2-binding.md`
|
||||
- `${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