Enforce native MCP-first paths for Gitea mutations with fail-closed
assessment helpers, shell spawn circuit breaker tracking, and MCP tools
for operation-path assessment and shell health reporting.
Closes#270
Add assess_reconcile_inventory_report verifier to block complete queue scan
and all-already-landed claims without final-page metadata, requested page size,
pages fetched, per-page counts, and no-next-page proof. Wire into
build_final_report and export from review_proofs.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Already-landed PR reconciliation could prove a PR should be closed but
stop silently when gitea.pr.close was unavailable, even with comment
capability present. Adopt Option B (comment-then-stop) as the durable
policy and enforce it:
- resolve_partial_reconciliation_plan maps proven capabilities to one
of four outcomes: FULL_RECONCILE_CLOSE_ALLOWED (close_pr proven),
PARTIAL_RECONCILE_COMMENT_THEN_STOP (comment_pr proven, close_pr
missing; one reconciliation comment with PR head SHA, target branch
SHA, ancestor proof, linked issue status, and the missing capability,
then stop), RECOVERY_HANDOFF_ONLY (no comment capability; no Gitea
mutation), and GATE_NOT_PROVEN (no ancestry proof; no mutation
regardless of capability). Missing capability dicts fail closed.
- assess_partial_reconciliation_report requires final reports to
explain why the comment was or was not posted, name the missing
capability, and state the close result or that no mutation ran.
- workflows/reconcile-landed-pr.md gains section 12A documenting the
policy; the workflow contract test locks the new markers.
Tests cover close capability present, close missing with comment
allowed, comment capability missing, all capabilities missing,
unproven ancestry, fail-closed capability dict, and report checks for
each outcome.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add assess_reconciliation_handoff to review_proofs: already-landed PR
reconciliation runs must emit a dedicated handoff schema (selected PR,
live state, candidate head SHA, target branch + SHA, ancestor proof,
linked issue + live status, eligibility class
ALREADY_LANDED_RECONCILE_REQUIRED, capability proofs, per-category
mutation ledger, blocker, safe next action, no-review/merge
confirmation) instead of author or reviewer fields. Stale fields (PR
number opened, Pinned reviewed head, Scratch worktree used, Workspace
mutations, Issue lock proof, Claim/comment status) fail validation, a
wrong eligibility class fails, and an observed git fetch/pull must be
reported under Git ref mutations rather than claimed none. Fails
closed on a missing Controller Handoff section. Tests cover blocked
reconciliation, successful PR close, comment-only, no-op
already-closed, missing linked-issue proof, wrong eligibility class,
each stale field, and unreported observed fetch.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add author_mutation_worktree assessment and integrate it into MCP
preflight so author mutations fail closed outside branches/ session
worktrees, with tests for control-checkout and branches-path cases.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add assess_reconcile_linked_issue_report verifier to block open/closed/resolved
linked issue status claims without gitea_view_issue proof in the current session,
require not-verified wording when the issue is missing, and gate recommended
issue close/reopen/comment actions on exact capability proof. Wire into
build_final_report and export from review_proofs.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add assess_already_landed_handoff_report verifier to block Pinned reviewed
head, Scratch worktree used, legacy Mutations/Workspace mutations None when
git fetch or other mutations occurred, and narrative/handoff drift after the
already-landed gate fires. Wire into build_final_report and review_proofs.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Structured claim/progress heartbeats post on issue claim and via
gitea_post_heartbeat. Read-only gitea_reconcile_issue_claims inventories
active, stale, phantom, and PR-backed claims; gitea_cleanup_stale_claims
supports dry-run cleanup of reclaimable labels.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add assess_inventory_worktree_report verifier to reject partial PR inventory
claims, exactly-full first pages without finality proof, legacy scratch-worktree
flags that contradict branches/ review worktrees, and contradictory checkout
wording. Wire into build_final_report and export from review_proofs.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add assess_already_landed_report_wording to review_proofs: when the
already-landed gate fires, final reports and controller handoffs must
use the reconciliation wording (Oldest open PR requiring action,
Eligibility class: ALREADY_LANDED_RECONCILE_REQUIRED, Candidate head
SHA, Reviewed head SHA: none, Review worktree used: false) and must not
use the legacy fields (oldest/next eligible PR, Pinned reviewed head,
Scratch worktree used) or claim a reviewed head SHA. In
non-already-landed reports, a populated Pinned reviewed head or
Reviewed head SHA fails unless validation and diff review actually
passed this session. Fails closed. Tests cover the correct
reconciliation wording, each forbidden legacy field, missing required
fields, populated reviewed SHA, normal reviewed reports, blocked-infra
reports, and validation-failed reports.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
A reviewer workflow approved and attempted to merge PR #278 although its
head commit was already an ancestor of master, ending in a Gitea 405 and
manual reconciliation. Add the missing pre-mutation gate:
- assess_already_landed_review_gate classifies the pinned candidate
head against the fetched target branch: NORMAL_REVIEW_CANDIDATE,
ALREADY_LANDED_RECONCILE_REQUIRED, or GATE_NOT_PROVEN (fail closed).
Already-landed PRs block approval and the merge API, allow
request-changes only for a real blocker, and require a reconciliation
handoff (PR number/title, candidate head SHA, target branch + SHA,
ancestor proof, linked issue status, recommended action, capability
proof for close/comment mutations). Unchecked ancestry, invalid or
missing SHAs, and a head changed since pinning all fail closed.
Mergeability stays a separate gate.
- assess_already_landed_report_state rejects APPROVED / MERGED /
READY_TO_MERGE wording and missing ALREADY_LANDED_RECONCILE_REQUIRED
state when the session's gate fired, complementing the text-marker
rules from #327 which need the report to admit the landed state.
Tests cover already-landed, normal, non-mergeable, changed-head,
unchecked-ancestry, and invalid-SHA gate paths plus all report-state
verdicts.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Stop PR queue advancement when infra_stop blocks capability and require
CONTROL-CHECKOUT REPAIR MODE handoffs with infra diagnostics.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
gitea_lock_issue is profile-gated via task_capability_map
(gitea.issue.comment); without GITEA_ALLOWED_OPERATIONS the call
fail-closes before the artifact-warning logic runs, so the test
asserted success on a permission block. Seed the environment in
setUp/tearDown exactly like tests/test_mcp_server.py::TestIssueLocking
and complete the mocked git state with base_equivalent,
inspected_git_root, and base_branch so the newer lock-worktree
base-equivalence gate passes. The test still verifies the artifact
warning fires for '?? _emit_payload.py'. Full suite now passes with
zero failures.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Block file edits in PR validation worktrees, require separate diagnostic
scratch worktrees with explicit labeling, and reject contradictory
File edits by reviewer: none claims.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Approving a PR whose full test suite fails is now gated behind complete
baseline proof. New assess_full_suite_failure_approval_gate:
- Full-suite pass: approval allowed, no baseline required.
- Full-suite failure: default action is REQUEST_CHANGES; approval is
blocked unless the #325 baseline validation proof passes (branches/
worktree, pinned baseline/PR SHAs, matching failure signatures,
clean before/after) and the proof also carries the PR and baseline
full-suite commands, evidence that new/changed tests passed, and a
non-empty explanation of why the failures are unrelated to the PR.
- Unknown/unproven full-suite result blocks approval.
- Main-checkout baseline comparison is rejected.
- Vague "same as master" claims without proof are rejected via the
existing pre-existing-failure claim detection.
- Non-approve decisions are never blocked; the gate only reports the
request-changes default.
Tests cover matching baseline failures, mismatched signatures,
incomplete proof (missing commands, new-test evidence, explanation),
main-checkout baseline, unknown suite result, vague claims, and
full-suite pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add assess_linked_issue_consistency to review_proofs: reviewer final
reports must report a "Linked issue status" that matches the issue(s)
the selected PR was live-verified to link this session. Without live
proof the field may only say "not verified in this session"; with
proof, every linked issue must be named, and any other "Issue #N"
mention anywhere in the report fails as stale leakage from a previous
PR (the PR #280 / Issue #260-vs-#275 incident). Missing field fails
closed. Tests cover correct linked issue, stale previous issue in both
the status field and diagnostics, missing proof, unverified wording,
multiple linked issues, and PR-number mentions not being mistaken for
issue mentions.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Separate official PR-head validation from post-edit diagnostic runs in
reviewer reports. Block treating diagnostic passes as official validation
and require contaminated sessions to report recovery-required status.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Merge prgs/master into feat/issue-330-proof-wording-enforcement and keep
both assess_proof_wording (#330) and git ref mutation reporting (#297).
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add assess_merge_simulation_report to reject local merge simulations listed
as read-only diagnostics and require Worktree/index mutations documentation
with worktree path, pre/merge/abort/post-clean proof when simulation
commands appear in the session log.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>