v0.6.0
Targeted-revision discipline. Closes the three drift sources
identified in docs/V0.6_PLAN.md: full-rewrite revisor on
MAJOR_REVISION, parallel-revisor write race in self-attack, and
unconstrained paper_drafter re-dispatch in the iterative phase.
Validated end-to-end on paper 3bc58e8d (2026-05-22, 38 min,
$12.36 est., Sonnet via Claude Code CLI).
Lane A — Pipeline
- New
patch_revisorspecialist + deterministic merger.
Replaces the pre-v0.6revisorin every dispatch site. Writes
structured edits topaper_draft.tex.edits.json; the merger
(src/core/strategist/patch_merger.py) validates each edit's
targetagainst the work order'sFindinglist, applies
in-scope edits topaper_draft.tex, and emits
paper_draft.tex.applied.diffas a unified-diff audit
artifact. One edit type supported in v0.6:replace_text
withfind/replace/find_must_be_unique. Target
schema:section:<name>/table:<label>/references/
abstract/paper:full. Edits whose target isn't in the
findings are rejected before any text is touched. - Structured
Findingdataclass + three collectors. New
src/core/strategist/findings.pyintroduces the
Finding(source, source_detail, target, severity, problem, suggested_fix)frozen dataclass that every revision source
emits:collect_self_attack_findings,
collect_verify_numbers_findings,collect_review_findings.
combine_findingssorts severity-desc with source priority
(verify_numbers > self_attack > review on ties — numerical
mismatches are the most mechanical to fix). - MAJOR_REVISION wired through
patch_revisor. Replaces the
pre-v0.6 free-text-rationale path. Combines review findings +
(when present) verify_numbers findings, serialises them as a
JSON block in the work order'sfocus, dispatches
patch_revisor, callsmerge_patch_file. fully_applied →
COMPLETED; missing patch file or failed edits → REJECTED with
the first 3 failures named inlast_error. Edge case:
MAJOR_REVISION with no actionable findings short-circuits to
COMPLETED without dispatching (avoids wasted spend). - Self-attack critical findings wired through
patch_revisor.
Eliminates the pre-v0.6 parallel-revisor write race. Top-3
critical findings are batched into ONE patch_revisor call.
Patch failures at this phase are advisory (logged, do NOT
REJECT) — the downstream review phase catches what remains. verify_numbersauto-patch loop (proactive gate). Pre-v0.6
the gate was defensive: critical mismatch → REJECTED. v0.6
closes the detect → patch → re-detect loop: critical mismatch →
dispatchpatch_revisorwith the mismatch findings → re-run
verify_numberson the patched draft → REJECTED only if the
second pass still has criticals. Bounded by
_VERIFY_NUMBERS_AUTO_PATCH_BUDGET = 1(single attempt) so a
drafter that consistently disagrees with the source JSON
doesn't loop. The persistednumber_verification.json
reflects the post-patch state.- Iterative-phase guard against
paper_drafterre-dispatch.
Two-layer defence:- Soft: strategist's system prompt instructs it to use
section_writer(scoped to asection:<name>focus) on
iterations 2+, neverpaper_drafter. Validated on the live
run — strategist usedsection_writer3× in iter 2. - Hard:
_dispatchdropspaper_drafterwork orders when
self._iteration >= 2, logging a warning. Catches the
strategist if it ignores the soft instruction. iteration 0
(initial) and iteration 1 (first iterative) still allow
paper_drafterlegitimately.
- Soft: strategist's system prompt instructs it to use
patch_revisorloads three skills.writing/scoped-revision
(new — defines the patch-file shape with worked examples for
verify_numbers and self_attack findings),
writing/cite-numbers-by-source(v0.5 — same discipline as
the drafter),writing/personal-style,reasoning/anti-slop.- Five architecture invariants pinned. Each step has a
primary regression test;tests/pipeline/integration/test_v0_6_invariants.py
documents all five in one place and adds cross-step
assertions (legacyrevisornever dispatched by v0.6 runner
paths; both source types reachpatch_revisor's focus when
review + verify_numbers both have findings; merger
scope-enforcement holds across dispatch sites).
Test counts
- Mocked suite: 521 passed (was 422 in v0.5.0; +99 in v0.6).
- New test modules:
test_findings.py,test_patch_merger.py,
test_patch_revision_wiring.py,test_self_attack_patch_wiring.py,
test_verify_numbers_auto_patch.py,test_iterative_phase_guard.py,
test_v0_6_invariants.py.
Known follow-ups (deferred to v0.6.1)
- The legacy
revisorspecialist is no longer dispatched by v0.6
runner code paths, but the strategist may still freely dispatch
it from_run_iterative_phase. Surfaced by the 2026-05-22 live
run (one revisor call in iterative phase). Candidate fix:
extend the iterative-phase guard to also droprevisoron
iterations 2+, OR update the strategist prompt to discourage
it explicitly.