feat: enforce reconciler PR-close proof fields in final reports (Closes #306) #423

Merged
sysadmin merged 1 commits from feat/issue-306-reconciler-close-proof into master 2026-07-08 21:32:33 -05:00
Owner

Summary

Closes #306.

Reconciler runs could close already-landed PRs via gitea_reconcile_already_landed_pr but final reports were not required to carry the four close proofs (capability, ancestor, PR close result, linked-issue result). This PR adds validator enforcement so comment-only reconciliations stay unaffected while any reported PR close must prove all required fields.

Changes

  • final_report_validator.py — new rule reconcile.close_proof_fields with reconciler_close_lock session support
  • reconcile-landed-pr.md — §18A documents the enforced close-proof checklist
  • tests/test_final_report_validator.py — 6 regression cases for close proof enforcement

Validation

pytest tests/ -k reconciler -q

31 passed

Worktree

branches/issue-306-reconciler-close-proof @ b9e5cd0

## Summary Closes #306. Reconciler runs could close already-landed PRs via `gitea_reconcile_already_landed_pr` but final reports were not required to carry the four close proofs (capability, ancestor, PR close result, linked-issue result). This PR adds validator enforcement so comment-only reconciliations stay unaffected while any reported PR close must prove all required fields. ## Changes - `final_report_validator.py` — new rule `reconcile.close_proof_fields` with `reconciler_close_lock` session support - `reconcile-landed-pr.md` — §18A documents the enforced close-proof checklist - `tests/test_final_report_validator.py` — 6 regression cases for close proof enforcement ## Validation ``` pytest tests/ -k reconciler -q ``` **31 passed** ## Worktree `branches/issue-306-reconciler-close-proof` @ `b9e5cd0`
jcwalker3 added 1 commit 2026-07-07 12:04:36 -05:00
Closes #306.

The dedicated reconciler close path (profile, gated close tool, ancestor
proof, tests) already shipped across #301/#304/#309/#310, but the
final-report validator did not require a reconciler close to prove itself.
A handoff could report `PRs closed: #N` while omitting the close
capability, ancestor proof, or linked-issue result and still grade A.

This adds the missing report-time enforcement.

Changes:
- final_report_validator.py — new `reconcile.close_proof_fields` rule
  (`_rule_reconcile_close_proof`). Fires only when a PR close is reported
  (via the `PRs closed` field or a `reconciler_close_lock`), then blocks
  unless the handoff carries close capability proof (gitea.pr.close),
  ancestor proof, PR close result, and linked-issue result. Comment-only
  and blocked reconciliations are unaffected. New optional
  `reconciler_close_lock` kwarg on `assess_final_report_validator`.
- tests/test_final_report_validator.py — TestReconcilerCloseProof (6 cases):
  full-proof close passes; missing capability / ancestor / linked-issue
  result each block; session close lock requires proof; comment-only
  needs no close proof.
- reconcile-landed-pr.md — §18A documents the enforced gate.

Validation:

  venv/bin/python -m pytest tests/test_final_report_validator.py \
    tests/test_reconciler_close_gate.py tests/test_already_landed_reconcile.py \
    tests/test_reconcile_already_landed_pr_tool.py \
    tests/test_reconciliation_workflow.py tests/test_review_proofs.py -q

289 passed.

Worktree: branches/issue-306-reconciler-close-proof

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Owner

repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #423
issue: #306
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 65181-76421c4b5e4e
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr-423
phase: claimed
candidate_head: b9e5cd0f57
target_branch: master
target_branch_sha: b7e0c537f3
last_activity: 2026-07-09T02:28:20Z
expires_at: 2026-07-09T04:28:20Z
blocker: none

<!-- mcp-review-lease:v1 --> repo: Scaled-Tech-Consulting/Gitea-Tools pr: #423 issue: #306 reviewer_identity: sysadmin profile: prgs-reviewer session_id: 65181-76421c4b5e4e worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr-423 phase: claimed candidate_head: b9e5cd0f573a0ced3a1a84ee2ce8e3a255a20846 target_branch: master target_branch_sha: b7e0c537f3f958bf578e8a483497c21bfd41761c last_activity: 2026-07-09T02:28:20Z expires_at: 2026-07-09T04:28:20Z blocker: none
sysadmin approved these changes 2026-07-08 21:30:59 -05:00
sysadmin left a comment
Owner

APPROVE — independent review from isolated worktree branches/review-pr-423 @ b9e5cd0.

Scope: clean. 1 commit, 3 files (+159), all on-topic for #306:

  • final_report_validator.py — new _rule_reconcile_close_proof (rule reconcile.close_proof_fields) + reconciler_close_lock threaded through assess_final_report_validator
  • skills/llm-project-workflow/workflows/reconcile-landed-pr.md — §18A close-proof checklist
  • tests/test_final_report_validator.py — 6 close-proof cases

Correctness: rule fires only when a PR close is actually reported (via PRs closed field or session close lock) — comment-only reconciliations stay unaffected, exactly per #306. Enforces the four required proofs: close capability (gitea.pr.close), ancestor landing, PR-close result, linked-issue result. Pure function, no side effects.

Validation (worktree, root venv):

  • py_compile final_report_validator.py → OK
  • pytest tests/test_final_report_validator.py -q → 39 passed, 3 subtests
  • pytest tests/ -k reconcile -q → 90 passed

No secrets, no unrelated files, no server-behavior change beyond the validator rule. Mergeable=true. Reviewer identity sysadmin ≠ author jcwalker3 (no self-review).

APPROVE — independent review from isolated worktree `branches/review-pr-423` @ `b9e5cd0`. **Scope:** clean. 1 commit, 3 files (+159), all on-topic for #306: - `final_report_validator.py` — new `_rule_reconcile_close_proof` (rule `reconcile.close_proof_fields`) + `reconciler_close_lock` threaded through `assess_final_report_validator` - `skills/llm-project-workflow/workflows/reconcile-landed-pr.md` — §18A close-proof checklist - `tests/test_final_report_validator.py` — 6 close-proof cases **Correctness:** rule fires only when a PR close is actually reported (via `PRs closed` field or session close lock) — comment-only reconciliations stay unaffected, exactly per #306. Enforces the four required proofs: close capability (`gitea.pr.close`), ancestor landing, PR-close result, linked-issue result. Pure function, no side effects. **Validation (worktree, root venv):** - `py_compile final_report_validator.py` → OK - `pytest tests/test_final_report_validator.py -q` → 39 passed, 3 subtests - `pytest tests/ -k reconcile -q` → 90 passed No secrets, no unrelated files, no server-behavior change beyond the validator rule. Mergeable=true. Reviewer identity sysadmin ≠ author jcwalker3 (no self-review).
sysadmin merged commit 9a2e585a9e into master 2026-07-08 21:32:33 -05:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Scaled-Tech-Consulting/Gitea-Tools#423