Addresses REQUEST_CHANGES review 460 on PR #743 @ 22d0fdd.
reviewer_pr_lease._TERMINAL_PHASES gained "abandoned" for owner-session merger
finalization, but pr_work_lease._TERMINAL_REVIEWER_PHASES did not. The two
modules parse the same append-only lease markers, so the same comment read as
terminal through reviewer_pr_lease and active through pr_work_lease, leaving
the conflict-fix acquire and PR-sync inventory readers with a stale active
lease after an abandoned finalization.
Fix: add "abandoned" to pr_work_lease._TERMINAL_REVIEWER_PHASES, with a comment
recording that the two sets must stay mirrored.
Reproduced before the fix (single abandoned marker):
reviewer_pr_lease active=False, pr_work_lease active=True
After: both False; released/blocked/done unchanged in both modules.
Tests: new TestCrossModuleTerminalPhaseAgreement in
tests/test_merger_lease_finalization.py proves the abandoned marker is inactive
in pr_work_lease, that both modules agree for released/blocked/done/abandoned,
that claimed/validating stay active in both, that the two phase sets are
mirrored, that the default 'released' finalization outcome and reason are
unchanged, and that finalization appends without rewriting or deleting the
prior marker.
Separately pinned, NOT fixed here: on a claim-then-terminal ledger,
pr_work_lease.find_active_reviewer_lease skips the terminal marker and walks
back to the older claim, so it still reports an active lease. That newest-wins
gap is pre-existing on clean baseline a8d2087 for released, blocked, and done
alike — the #577 fix landed in reviewer_pr_lease only — and is out of scope for
this bounded remediation. test_abandoned_matches_preexisting_terminal_phases_on_full_ledger
pins that "abandoned" introduces no behavior of its own, so all four phases can
be reconciled in one separate change.
Validation: focused TestCrossModuleTerminalPhaseAgreement 7 passed / 9 subtests;
tests/test_merger_lease_finalization.py 45 passed / 20 subtests; related
pr_work_lease + reviewer/merger lease + adoption + provenance + capability-map +
anti-stomp + report-validator suites 261 passed / 41 subtests; full suite 3312
passed, 6 skipped, 2 failed. Both failures (test_issue_702_review_findings_f1_f6
F1 recovery, reconciler supersession close) reproduce identically on clean
baseline master a8d2087 and are pre-existing #737 org/repo-forwarding drift.
git diff --check clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Fixes the final-report validator defects from Issue #698 (original lead
plus the independent reproduction recorded during the PR #703 formal
review, comment 11246):
- Legacy fields: the review/merger required-field tables no longer demand
'Pinned reviewed head', 'Scratch worktree used', 'Worktree path',
'Worktree dirty', 'Mutations', 'Next', 'Issue/PR', 'Branch/SHA', or
'Files changed' — names the canonical review-merge-final-report schema
forbids or replaces. The canonical names ('Reviewed head SHA', 'Review
worktree path/dirty', 'Safe next action', mutation categories) are
required instead, with backward-compatible aliases where the schema
permits them.
- Structured proof: workflow-load helper results are recognized in
colon, key=value, and JSON renderings; validation pass proof is
accepted anywhere in the Validation field value (for example
'focused 50 passed; full 2665 passed').
- Mutation inference: review mutations are inferred only from
authoritative evidence (performed=true and not gated); read-only
diagnostics and pre-API rejections no longer count as mutations.
- Lease release vs cleanup: canonical reviewer lease release (release
tool call or terminal phase=released marker) is lease lifecycle, not
post-merge cleanup, and no longer triggers the branch/worktree cleanup
checklist; genuine delete/remove claims still require full proof.
- Blocked reports: a legitimately blocked run that states an explicit
'Reviewed/Candidate head SHA: none' with no verdict, merge, or started
validation owes no head proofs; approval-time and merge-time live-head
proofs are demanded only once the corresponding phase begins, and a
report that states no head at all still fails closed.
- action_log robustness: malformed (non-dict) entries and non-list logs
are reported as clear sanitized findings (position and type only, no
content echo) instead of crashing with AttributeError; a defective
validator rule now fails closed with a sanitized block finding rather
than raising a secondary exception.
27 new regression tests, including canonical fixtures modeled on the
PR #703 formal-review handoff and the blocked preflight report from the
prior #698 reproductions. Two legacy-field test fixtures updated to the
canonical schema. Full suite: 2663 passed, 6 skipped, 161 subtests.
Co-Authored-By: Claude Fable 5 <[email protected]>