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]>
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]>
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_prior_blocker_skip_proof to validate reviewer reports document
live REQUEST_CHANGES blocker proof for skipped earlier open PRs, reject
stale-memory skips when head changed after blocker, and require
BLOCKER_STATUS_UNVERIFIED when review feedback cannot be fetched.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Reviewer controller handoffs must now report the precise mutation
categories (File edits by reviewer, Worktree/index mutations, Git ref
mutations, MCP/Gitea mutations, Review mutations, Merge mutations,
Cleanup mutations, External-state mutations, Read-only diagnostics)
instead of the ambiguous legacy "Workspace mutations" field.
- assess_controller_handoff(role="review") no longer requires
"Workspace mutations" and fails closed when any legacy
"Workspace mutations:" line is present, regardless of value.
- New HANDOFF_REVIEW_MUTATION_FIELDS makes the nine precise categories
required fields for review-role handoffs, matching the canonical
schemas/review-merge-final-report.md field set.
- Tests cover approval, request-changes, merge, worktree cleanup,
fetch-only, and blocked handoffs, plus rejection of
"Workspace mutations: none" and non-none values.
- Author/create-issue/inventory roles keep their existing contracts.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add assess_workspace_mutation_consistency to review_proofs: final
reports fail validation when they claim "Workspace mutations: none"
while worktree mutations (reset --hard, checkout, clean, worktree
add/remove, stash, merge, rebase, ...) occurred — either observed in
the workflow command log or self-reported in the report's own
"Worktree mutations" field. Observed worktree and git ref mutations
must be reported under their precise category fields; reports pass
when they say "File edits by reviewer: none" alongside a non-none
"Worktree mutations" entry. Tests cover reset, checkout, worktree add,
clean, fetch-only, and no-op cases.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add assess_non_mergeable_skip_proof to validate reviewer reports document
head SHA, mergeability result, conflict proof command, conflicting files,
and head-change status for each skipped non-mergeable PR, or classify
MERGEABILITY_UNVERIFIED when proof cannot be retrieved.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add assess_reviewer_baseline_validation_proof to block test-suite runs in
the main checkout and require complete baseline worktree proof when reports
claim pre-existing master failures.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add assess_queue_status_report and assess_proof_wording to reject
contradictory queue-status-only reports: passed gates without a selected
PR, prior diagnostic conflict proof, pagination assumptions, and
blocker contradictions. Wire into build_final_report and document the
queue-status-only schema path.
Closes#339
Add assess_proof_wording to reject unsupported phrases such as
inventory complete, live proof, same as master, and file edits none
unless matching evidence is present. Wire into build_final_report and
add doc-contract tests.
Closes#330
Reviewer reports treated 'git fetch prgs master' as read-only
diagnostics while claiming 'Git/worktree mutations: None'. Fetch edits
no files but updates remote-tracking refs, so hiding it under
diagnostics understates what the run mutated.
Add git_ref_mutating_commands() classifying fetch, pull, push, merge,
update-ref, remote update, branch -d/-D, and reset --hard as git ref
mutations, and assess_git_ref_mutation_report() which fails a report
when ref-updating commands ran but the report lacks a non-none 'Git ref
mutations' entry, omits 'fetched <remote>/<branch>' for a targeted
fetch, still claims 'Git/worktree mutations: None', or lists the
command under read-only diagnostics.
Tests cover fetch-only review, missing ledger entry, missing fetch
target, contradictory none-claim, read-only misclassification, worktree
creation (not a ref mutation), merge, cleanup branch deletion,
no-mutation blocked handoff, and dict command-log entries.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Return wrapped {prs, pagination} from gitea_list_prs with has_more,
inventory_complete, and page traversal via api_fetch_page. Route
gitea_review_pr inventory through gitea_list_prs so trust gates can
prove pagination finality. Add assess_list_prs_pagination_proof verifier.
Closes#340
Extend review_proofs with assess_create_issue_final_report to enforce
workflow-source proof, create-issue handoff schema fields, and rejection
of work-issue/review-merge cross-mode handoff fields.
Closes#337
Introduce assess_mutation_ledger_report so reviewer final reports cannot
claim no file edits when the action log records performed mutations.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Workflow reports included the authenticated user's personal email even
when username/profile identity was sufficient (observed: 'Identity:
jcwalker3 / [email protected]' in a reconciliation handoff).
Add format_identity_summary() producing the canonical no-email identity
line ('<username> / <profile>' with optional role/remote, reducing an
email passed in the username slot to its local part), and
assess_email_disclosure() flagging personal email addresses in report
text unless the report itself justifies the disclosure (tool proof,
explicit request, or identity disambiguation).
Tests cover no-email summaries for author and reviewer identities,
role/remote suffixes, email-in-username reduction, clean reports,
single and multiple unjustified disclosures, and justified
disambiguation.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Introduce assess_request_changes_approval_proof in review_proofs.py so
review workflows can fail closed when approving an unchanged head after a
prior REQUEST_CHANGES unless explicit override proof is provided.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The forbidden-mutation loop in assess_issue_filing_mutation_scope never
appended reasons; align aggregation with issue-selection handoff checks.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Operators can supply an active PR backlog for one repo while agents
inventory another and falsely report trusted_empty. reconcile_queue_target
locks the target repo from operator context/backlog before list_prs runs;
pr_inventory_trust_gate blocks target_repo_mismatch and unresolved locks.
assess_reviewer_queue_inventory wires the lock into the canonical path.
Tests cover Gitea-Tools backlog vs mcp-control-plane inventory mismatch,
ambiguous dual-repo context, conflicting directive vs backlog, and final-
report field requirements.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add assess_empty_queue_report to block empty-queue claims without
pr_inventory_trust_gate.status == trusted_empty, reject weak merge-commit
corroboration, extend inventory handoff fields, and wire the gate into
build_final_report and capability-stop terminal validation.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>