fde95b9266e8d610c8400e0290b04e0e0201a822
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
fde95b9266 |
fix(mcp): chain-scoped newest-wins reviewer lease reads in pr_work_lease (#742)
Second author remediation on PR #743. Fixes the full-ledger defect surfaced by the first remediation. Root cause: pr_work_lease.find_active_reviewer_lease iterated the reviewer markers newest-first and used `continue` on a terminal marker. On a realistic append-only ledger (claimed -> validating -> terminal) it therefore stepped over the terminal marker and returned the older claim of the very chain that marker had just ended. reviewer_pr_lease got strict newest-wins under #577; pr_work_lease never did, so the two modules disagreed for released, blocked, done, and abandoned alike, and merger owner finalization did not leave "no active lease" for pr_work_lease consumers (conflict-fix acquire, PR sync inventory). Fix: a claim is skipped when a later marker terminates its own chain. Chain identity is (repo, pr_number, candidate_head, session_id, reviewer_identity, profile) via the new _reviewer_chain_key; _chain_terminated_after scans only markers appended after the candidate. Consequences: - a valid terminal marker ends its matching earlier claim (no resurrection); - a foreign-session, wrong-repo, wrong-PR, wrong-head, wrong-identity, or wrong-profile terminal marker cannot cancel another session's active lease, which strict newest-wins alone would have allowed; - a malformed terminal marker has no provable chain key, so it cancels nothing and cannot hide a valid active claim; - expiry, freshness, phase sets, ownership and integrity checks, both parsers, and find_active_conflict_fix_lease are untouched; - history stays append-only; no marker is deleted or rewritten. Reviewer lease markers carry no token field, so token-fingerprint validation remains where it already lives (session provenance, merger finalization) and is not weakened here. Tests: new TestFullLedgerNewestWins in tests/test_merger_lease_finalization.py covers claimed->released/blocked/done/abandoned, claimed->validating->terminal, foreign-session and mismatched repo/PR/head/identity/profile terminals, the malformed terminal marker, a newer active chain surviving an older terminated chain, newest-valid-chain selection across multiple histories, all-chains- terminated, single-marker parity between the two modules across eight phases, expired-claim/freshness non-regression, and the real ledger written by gitea_release_merger_pr_lease reading as terminal in both modules with the prior marker preserved. TestCrossModuleTerminalPhaseAgreement's scope-limited placeholder test is replaced by a real both-modules full-ledger assertion. Verified 10 of the new tests fail at the prior head |
||
|
|
7ae5f3a541 |
fix(mcp): mirror abandoned terminal phase into pr_work_lease (#742 review 460)
Addresses REQUEST_CHANGES review 460 on PR #743 @ |
||
|
|
ee90a5e7a2 |
fix(validator): align final-report validator with canonical schema (Closes #698)
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]> |
||
|
|
87beb44394 |
feat: add conflict-fix leases and stale-head protection (Closes #399)
Introduce structured PR work leases so author conflict-fix pushes cannot race reviewer validation, approval, or merge on a moving head SHA. - pr_work_lease.py: parse/acquire leases, push and reviewer mutation gates - gitea_acquire_conflict_fix_lease, gitea_assess_conflict_fix_push MCP tools - Enforce reviewed head SHA on mark_final_review_decision, submit_pr_review, merge_pr - Final-report rules and workflow sections 20A / 26B - tests/test_pr_work_lease.py (14 cases) |