S11 hardening of /linkedin:pivot. Class: pure state-mutation/orchestration command, NOT post-emitting, invokes no agents — re-opens a long-form edition so cleared gates re-run before lock. Feed-post predicates N/A. BUG (P4, cross-file off-by-one): newsletter's resumption table treats currentPhase as the LAST COMPLETED phase and resumes at the NEXT step (draft->Step 4, consistency-quality->Step 5, factcheck-sweep->Step 5.5). The moderate pivot default set to-phase: factcheck-sweep "so the new claims get verified" — which resumes at Step 5.5 and SKIPS the Step 5 fact-check the moderate pivot exists to run, violating the command's own invariant that a pivot always invalidates the fact-check. FIX (4 surgical edits, commands/pivot.md only): 1. moderate default factcheck-sweep -> consistency-quality (resumes Step 5) 2. structural label "(Step 3b)" -> "Step 4 (consistency)" 3. off-by-one guard callout explaining to-phase = currentPhase (last-completed) 4. anatomy enum drops factcheck-sweep -> draft | consistency-quality gatesToRerun list + worked example unchanged (both correct). 4-axis verdict: a/b/c/d all PASS post-fix, 0 deferrals -> FIXED. Gate: test-runner 81/0/0 · counts 29/19/26 unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016qgzo6rxthw7KuxHjn5vyE
8.6 KiB
| name | description | allowed-tools | ||||||
|---|---|---|---|---|---|---|---|---|
| linkedin:pivot | Re-open a long-form edition after a substantive late change (a "pivot") so the already-cleared quality gates re-run on the changed version before lock. Logs the pivot in edition-state, moves currentPhase back to the right earlier step, un-locks if needed, and marks which gates (fact-check, editorial, persona, headless) must re-pass. Includes the pivot-detection heuristic (>20% word-count change or >2 new sections). Use when the user says: "pivot", "I changed the angle", "I added a section", "re-open the edition", "the article changed after it was approved", "re-run the gates", "this needs re-review". Triggers on: "pivot", "linkedin pivot", "re-open edition", "added a section", "changed the angle", "pivot-reopen", "/linkedin:pivot". |
|
LinkedIn Pivot — re-open a cleared edition for re-review
A pivot is a substantive change to a long-form draft made after a gate had already cleared it — a new argument anchor, a new section, a changed thesis. The problem this command solves: the pipeline's gates (fact-check Step 5, editorial Step 5.5, persona Step 6, headless Step 6.5) ran on the pre-pivot version, so the changed text was never validated. Without an explicit re-open, a pivoted edition can sail into lock carrying an unverified premise or an unread argument.
Why this exists (Del 4, Endring 9c). Del 4 was LOCK-ready on an early version (v8). Then a "Security Champions" pivot added a ~260-word section and a ~270-word role-description section — roughly +42 % length, two new sections, a new axis. The pipeline had no pivot-mode, so the whole post-lock chain had to be re-opened by hand. This command makes the re-open a named ritual, not a manual scramble.
Command anatomy
/linkedin:pivot
--article NN (required; the edition article that changed)
--reason "<one line>" (required; e.g. "Security Champions-anker")
--to-phase draft | consistency-quality (optional; default from scope — see Step 2)
The pivot-detection heuristic
Compare the current draft against the version that last cleared Step 6 (persona-sweep-prelock). A pivot-reopen is suggested/required when either:
- word-count change > 20 %, or
- > 2 new sections (top-level headings added since the cleared version).
This heuristic is also checked as a lock precondition in Step 8 of
/linkedin:newsletter: if the draft has drifted past these bounds since Step 6
cleared, the lock STOPS and points the operator here. (Length-band drift itself
— soft/hard caps — is logged friction F1, not yet a gate.)
Worked example (acceptance test — Del 4 v8 → v11). At v8 the persona sweep had cleared a ~1 400-word draft. The Security Champions message pushed it to ~1 992 words (+42 %, > 20 %) and added 2 sections (a new anchor + a role-description) — at the boundary of the "> 2 new sections" rule and well past the 20 % rule. The heuristic fires:
/linkedin:pivot --article 04 --reason "Security Champions-anker"would log the pivot, movecurrentPhaseback todraft(structural change → full re-treatment), and require fact-check + editorial + persona + headless to re-pass on v11 before lock. That is exactly the re-sweep the manual Del 4 run had to improvise.
Step 1 — Load state + locate the article
- Resolve the series root and read
<serie>/linkedin/edition-state.json. Findarticles.NNfor the--articlevalue. If it does not exist, stop and report. - Read the current draft
<serie>/NN-utkast.mdand notecurrentPhaseandlocked.
Step 2 — Measure the pivot scope
- Current word count:
cd <serie-mappe> && wc -w NN-utkast.md. - Baseline word count: the word count of the version that last cleared
Step 6, recorded by newsletter Step 6 in
articles.NN.personaSweep.resonance.wordCount. If that field is absent (older state), ask the operator for the cleared-version word count, or treat the pivot as structural by default. - Compute
deltaPct = round((current - baseline) / baseline * 100)and countnewSections= top-level headings now present that were not in the cleared version (agrep -c '^## 'delta is a reasonable proxy; confirm with the operator if ambiguous). - Classify scope (drives the default
--to-phase):- Structural (deltaPct > 20 % OR newSections > 2, or a new axis/thesis) →
default
to-phase: draftso newsletter resumes at Step 4 (consistency-quality) — the changed prose is re-threaded, then fact-check (5) → editorial (5.5) → persona (6) → headless (6.5) re-run on it. - Moderate (new examples/claims, no new sections, deltaPct ≤ 20 %) →
default
to-phase: consistency-qualityso newsletter resumes at Step 5 (fact-check) and the new claims get verified, then editorial (5.5) → persona (6) → headless (6.5) re-run. - The operator may override with explicit
--to-phase.
- Structural (deltaPct > 20 % OR newSections > 2, or a new axis/thesis) →
default
Why these specific phases (the off-by-one trap).
to-phaseis written ascurrentPhase, which records the last completed phase;/linkedin:newsletter's resumption table (Step 0) then resumes at the step after it. Sodraftresumes at Step 4 andconsistency-qualityresumes at Step 5 (the fact-check). A pivot therefore never resets tofactcheck-sweep— that would resume at Step 5.5 and skip the fact-check, violating this command's invariant that a pivot always invalidates the fact-check (Step 3,gatesToRerun).
Step 3 — Log the pivot + reset the phase (the ritual)
- Append a pivot entry to
articles.NN.pivots[]:{ "timestamp": "<ISO-8601>", "reason": "<--reason>", "fromPhase": "<currentPhase before this command>", "toPhase": "<resolved to-phase>", "wordCountBefore": <baseline>, "wordCountAfter": <current>, "deltaPct": <deltaPct>, "newSections": <newSections>, "gatesToRerun": ["factcheck-sweep", "editorial-review", "persona-sweep-prelock", "headless-review"] }gatesToRerunalways spans every gate from the reset phase through Step 6.5 — a pivot invalidates the fact-check, the editorial craft pass, the persona resonance verdict, AND the headless package, because all of them judged the pre-pivot text. - Reset
currentPhaseto the resolvedtoPhase, and set the article'sphaseto match. - Un-lock if needed. If
articles.NN.lockedwastrue, setlocked: falseandstatus: "in-progress"— a pivot means the edition is no longer locked. Surface this plainly (the priorPOST.htmlis now stale and will be re-rendered at the next lock). - Invalidate the downstream verdicts so they cannot be mistaken for current:
set
personaSweep.resonance,editorialReview, andheadlessReview.statusback to a re-run state (e.g.headlessReview.status: "pending"), and note in each that they were invalidated by pivot<timestamp>. Leave thepivots[]log andfactcheckLoghistory intact (history is durable). - Update
updatedAtand writeedition-state.json.
Step 4 — Point the next step
Write a precise next-step line to <serie>/STATE.md (overwrite, ONE-system):
PIVOT logged (<reason>, +<deltaPct>%, <newSections> new sections) →
currentPhase reset to <toPhase>. Resume /linkedin:newsletter; it will re-run
fact-check (5) → editorial (5.5) → persona (6) → headless (6.5) on the pivoted
version BEFORE lock. Headless package: /linkedin:headless-review --article NN.
Do not run the gates yourself — /linkedin:newsletter owns the pipeline and will
resume deterministically from the reset currentPhase and re-run every gate in
gatesToRerun before it permits lock.
Pivot logged.
- Article NN: <reason>
- Scope: <structural|moderate> (Δ <deltaPct>%, <newSections> new sections)
- currentPhase: <fromPhase> → <toPhase> locked: <true→false | unchanged>
- Gates to re-run before lock: fact-check (5) · editorial (5.5) · persona (6) · headless (6.5)
Next: resume /linkedin:newsletter (re-runs the gates) → then lock.
Reference Files
${CLAUDE_PLUGIN_ROOT}/commands/newsletter.md— the pipeline this re-opens; Step 8 lock-precondition runs the same heuristic; the resumption table replays from the resetcurrentPhase${CLAUDE_PLUGIN_ROOT}/commands/headless-review.md— the cold review package that must re-pass on the pivoted version${CLAUDE_PLUGIN_ROOT}/config/edition-state.template.json—articles.NN.pivotsschema + the heuristic notes