feat: enforce canonical reconciliation handoff schema (Closes #307) #387

Merged
sysadmin merged 1 commits from feat/issue-307-canonical-reconciliation-handoff into master 2026-07-07 10:09:51 -05:00
Owner

Summary

Closes #307.

Already-landed PR reconciliation reports still fell back to stale author/reviewer Controller Handoff fields (Mutations: None, PR number opened: 278, Issue lock proof, Claim/comment status) even though the narrative section was correct. This PR makes the reconcile_already_landed final-report validator enforce the full canonical reconciliation handoff schema and nothing else.

Changes

  • final_report_validator.py

    • _RECONCILE_REQUIRED_FIELDS expanded from 5 fields to the full 27-field canonical schema from the issue: Task, Repo, Role/profile, Identity, Selected PR, PR live state, Candidate head SHA, Target branch, Target branch SHA, Ancestor proof, Linked issue, Linked issue live status, Eligibility class, Capabilities proven, Missing capabilities, PR comments posted, Issue comments posted, PRs closed, Issues closed, Git ref mutations, Worktree mutations, MCP/Gitea mutations, External-state mutations, Read-only diagnostics, Blocker, Safe next action, No review/merge confirmation. Any missing field downgrades with a per-field reason.
    • _RECONCILE_STALE_FIELDS gains issue lock proof, claim/comment status, and workspace mutations — the exact stale fields observed in the issue now block, joining pr number opened, pinned reviewed head, scratch worktree used, review decision, and merge result.
    • PR number opened rejection is now conditional: a new session_pr_opened keyword on assess_final_report_validator (default False, threaded through rule kwargs) permits the field only when a PR was actually opened in that session; otherwise it blocks as before.
    • Git-fetch reporting gap closed in _rule_reviewer_git_fetch_readonly: a fetch observed only in the action_log (with no mention in the report text) previously fell through when Git ref mutations claimed none; it now downgrades until the fetch is recorded under Git ref mutations. Read-only misclassification still blocks.
  • tests/test_final_report_validator.py

    • _reconcile_handoff fixture upgraded to the full canonical schema with a drop= parameter for missing-field tests.
    • New TestCanonicalReconcileSchema (11 tests): comment-only reconciliation passes, successful-close reconciliation passes, blocked reconciliation (no comment capability) passes, missing Missing capabilities field downgrades, missing Ancestor proof/Candidate head SHA downgrade, Issue lock proof blocks, Claim/comment status blocks, Workspace mutations: None blocks without observed mutations, PR number opened allowed with session_pr_opened=True, blocked without it, and action-log-only git fetch requires a Git ref mutations entry.

Acceptance criteria mapping (#307)

  • Reconciliation handoffs using stale author/reviewer fields fail validation.
  • git fetch is reported as a Git ref mutation (including fetches proven only by the action log).
  • No reconciliation report can say PR number opened unless a PR was actually opened in that session (session_pr_opened proof kwarg).
  • Tests cover blocked reconciliation, successful reconciliation, comment-only reconciliation, and missing close capability.

Validation

pytest tests/ in the issue worktree (base 0fe8f57): 1292 passed, 1 failed, 6 skipped, 20 subtests passed.

The single failure, test_final_report_validator.py::TestReviewPrRules::test_clean_reviewer_report_passes, is pre-existing: it fails identically on the clean master checkout without this diff (verified this session) and is already reported in the handoffs of PRs #367, #373, #375, and #379.

🤖 Generated with Claude Code

## Summary Closes #307. Already-landed PR reconciliation reports still fell back to stale author/reviewer Controller Handoff fields (`Mutations: None`, `PR number opened: 278`, `Issue lock proof`, `Claim/comment status`) even though the narrative section was correct. This PR makes the `reconcile_already_landed` final-report validator enforce the full canonical reconciliation handoff schema and nothing else. ## Changes - `final_report_validator.py` - `_RECONCILE_REQUIRED_FIELDS` expanded from 5 fields to the full 27-field canonical schema from the issue: Task, Repo, Role/profile, Identity, Selected PR, PR live state, Candidate head SHA, Target branch, Target branch SHA, Ancestor proof, Linked issue, Linked issue live status, Eligibility class, Capabilities proven, Missing capabilities, PR comments posted, Issue comments posted, PRs closed, Issues closed, Git ref mutations, Worktree mutations, MCP/Gitea mutations, External-state mutations, Read-only diagnostics, Blocker, Safe next action, No review/merge confirmation. Any missing field downgrades with a per-field reason. - `_RECONCILE_STALE_FIELDS` gains `issue lock proof`, `claim/comment status`, and `workspace mutations` — the exact stale fields observed in the issue now block, joining `pr number opened`, `pinned reviewed head`, `scratch worktree used`, `review decision`, and `merge result`. - `PR number opened` rejection is now conditional: a new `session_pr_opened` keyword on `assess_final_report_validator` (default `False`, threaded through rule kwargs) permits the field only when a PR was actually opened in that session; otherwise it blocks as before. - Git-fetch reporting gap closed in `_rule_reviewer_git_fetch_readonly`: a fetch observed only in the `action_log` (with no mention in the report text) previously fell through when `Git ref mutations` claimed `none`; it now downgrades until the fetch is recorded under `Git ref mutations`. Read-only misclassification still blocks. - `tests/test_final_report_validator.py` - `_reconcile_handoff` fixture upgraded to the full canonical schema with a `drop=` parameter for missing-field tests. - New `TestCanonicalReconcileSchema` (11 tests): comment-only reconciliation passes, successful-close reconciliation passes, blocked reconciliation (no comment capability) passes, missing `Missing capabilities` field downgrades, missing `Ancestor proof`/`Candidate head SHA` downgrade, `Issue lock proof` blocks, `Claim/comment status` blocks, `Workspace mutations: None` blocks without observed mutations, `PR number opened` allowed with `session_pr_opened=True`, blocked without it, and action-log-only git fetch requires a Git ref mutations entry. ## Acceptance criteria mapping (#307) - [x] Reconciliation handoffs using stale author/reviewer fields fail validation. - [x] `git fetch` is reported as a Git ref mutation (including fetches proven only by the action log). - [x] No reconciliation report can say `PR number opened` unless a PR was actually opened in that session (`session_pr_opened` proof kwarg). - [x] Tests cover blocked reconciliation, successful reconciliation, comment-only reconciliation, and missing close capability. ## Validation `pytest tests/` in the issue worktree (base 0fe8f57): **1292 passed, 1 failed, 6 skipped, 20 subtests passed**. The single failure, `test_final_report_validator.py::TestReviewPrRules::test_clean_reviewer_report_passes`, is pre-existing: it fails identically on the clean master checkout without this diff (verified this session) and is already reported in the handoffs of PRs #367, #373, #375, and #379. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jcwalker3 added 1 commit 2026-07-07 08:33:01 -05:00
Reconciliation final reports must emit only the canonical reconciliation
handoff schema:

- Expand _RECONCILE_REQUIRED_FIELDS from 5 to the full 27-field canonical
  schema (Task through No review/merge confirmation), so incomplete
  reconciliation handoffs downgrade with per-field reasons.
- Add 'issue lock proof', 'claim/comment status', and 'workspace mutations'
  to _RECONCILE_STALE_FIELDS so stale author/reviewer fields block.
- Make the 'PR number opened' rejection conditional on a new
  session_pr_opened proof kwarg: the field is allowed only when a PR was
  actually opened in the session.
- Close the git-fetch reporting gap: a fetch observed only in the action
  log (not report text) now requires a Git ref mutations entry as well.
- Update the reconciliation handoff fixture to the canonical schema and
  add TestCanonicalReconcileSchema covering blocked, successful-close,
  and comment-only reconciliation plus missing-close-capability,
  stale-field, and conditional PR-number-opened paths.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
sysadmin approved these changes 2026-07-07 10:09:41 -05:00
sysadmin left a comment
Owner

Manual review of changed files and test suite validation passed. The new final-report validator rules correctly enforce the full canonical reconciliation handoff schema and reject stale author/reviewer fields, resolving issue #307. The unit test failure on the branch head is pre-existing and resolved when merged with master. All tests pass cleanly on the merged code. Approved.

Manual review of changed files and test suite validation passed. The new final-report validator rules correctly enforce the full canonical reconciliation handoff schema and reject stale author/reviewer fields, resolving issue #307. The unit test failure on the branch head is pre-existing and resolved when merged with master. All tests pass cleanly on the merged code. Approved.
sysadmin merged commit 9f4dd4c39b into master 2026-07-07 10:09:51 -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#387