Add premerge_baseline_proof.py distinguishing four validation outcomes
(clean pass / current-master failure reproduced / pre-merge baseline-proven
failure / unresolved regression risk). A non-zero exit may only be labeled
"baseline"/"pre-existing" with pre-merge proof: the failure reproduced on the
PR's pre-merge base commit, or a documented known-failure record predating the
PR. Current-master (post-merge) reproduction is explicitly rejected as
sufficient baseline proof.
- premerge_baseline_proof.py: assess_premerge_baseline_proof + labels
- final_report_validator.py: reviewer.premerge_baseline_proof rule on
review_pr and reconcile_already_landed tasks
- skills/llm-project-workflow/templates/review-pr.md: baseline proof section
requiring base commit, tested commit, command, exit status, failure signature
- tests/test_premerge_baseline_proof.py: reject current-master-only proof,
accept pre-merge base proof and documented known-failure records
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Document the narrow controller-authorized path for landing MCP workflow
fixes when live daemons cannot canonically review themselves, with
required audits, allowed/forbidden actions, and post-land restart steps.
Resolve PR via pulls API before fetching lease comments so
gitea_assess_conflict_fix_push fails closed with actionable reasons
instead of surfacing HTTP 500 when Gitea returns not-found errors.
Add regression tests and document assessment-failure handoff in work-issue.
Bare remote=prgs resolved to the hardcoded REMOTES default
Scaled-Tech-Consulting/Timesheet instead of the Gitea-Tools repository
the local git remote points at, causing false 404s and risking mutation
of a different repository.
Add remote_repo_guard.assess_remote_repo_match (pure) + formatter, wired
into gitea_mcp_server._resolve so every read/lookup/mutation tool fails
closed when the MCP-resolved org/repo disagrees with the local git remote
URL and the caller did not pass explicit org/repo. The guard is
best-effort: it skips when both org and repo are explicit, when the local
remote URL is unavailable, and is bypassed under pytest unless
GITEA_FORCE_REMOTE_REPO_CHECK is set.
Add tests/test_remote_repo_guard.py (pure-function cases + server wiring
proving a lookup tool cannot silently query a different repository), and
update author/reviewer/merger handoff templates to require explicit
remote/org/repo.
Closes#530
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add mcp_native_cleanup_proof verifier that blocks raw git branch deletion and
raw API comment deletion scripts as cleanup proof, requires authorized
reconciler MCP tools in cleanup mutation ledgers, and separates merge from
cleanup mutations in controller handoffs.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Extend the review workflow load gate with pre-review command classification,
boundary violation tracking, and structured helper-result requirements in
final reports. Adds gitea_record_pre_review_command MCP tool.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Merge prgs/master into feat/issue-405-mutation-capability-proof and keep
both reviewer mutation-capability proof and post-merge cleanup proof rules.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Replace manual in-process _SESSION_LEASE seeding with an auditable
gitea_adopt_merger_pr_lease tool that posts durable adoption proof and
records sanctioned session provenance. Mutation gates now reject bare
record_session_lease calls without provenance from acquire/adopt/heartbeat.
Closes#536
Stale worktrees accumulate under branches/ when runs stop early, race a
sibling session, hit a validation failure, or lose cwd state, making later
workflow decisions harder and riskier.
Changes:
- worktree_cleanup_audit.py — ownership metadata, safety-first classifier
(active_open_pr, active_issue_work, dirty_local_worktree,
clean_stale_removable, detached_review_leftover, unsafe_unknown), TTL
expiry, per-worktree removal proof, and success-completion cleanup plan.
Only clean_stale_removable and detached_review_leftover are removable;
dirty/PR/leased/protected/unknown worktrees are never auto-deleted.
- gitea_audit_worktree_cleanup — read-only MCP tool that classifies every
branches/ entry, fetches live open-PR heads (fails closed if unavailable),
and returns counts, removable candidates, and git worktree list proof.
- work-issue.md 22A + review-merge-pr.md 28 — cleanup/TTL workflow rules.
- tests/test_worktree_cleanup_audit.py — 30 cases covering all nine
acceptance scenarios plus inference, metadata, TTL, and report accuracy.
Validation:
/Users/jasonwalker/Development/Gitea-Tools/venv/bin/python \
-m unittest tests.test_worktree_cleanup_audit tests.test_merged_cleanup_reconcile -q
38 passed.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Normal author work is unchanged: gitea_lock_issue still requires the worktree
to be base-equivalent to master/main/dev, and gitea_create_pr still targets a
normal base branch. A *stacked* PR (based on another unmerged PR's branch) is a
new explicit, proof-backed path — it never bypasses the issue lock.
- stacked_pr_support.py: pure policy. Approve a non-master base only when it is
declared AND owned by a live OPEN PR whose number matches; reject arbitrary,
mismatched, or stale (merged/closed) branches; require the PR body to document
the stack (base branch, stacked-on PR, merge ordering).
- issue_lock_worktree.py: read_worktree_git_state / _find_matching_base_ref gain
an opt-in extra_bases arg so an approved stacked base can anchor
base-equivalence in addition to master/main/dev (empty by default = unchanged).
- gitea_mcp_server.py:
- gitea_lock_issue gains stacked_base_branch + stacked_base_pr. When declared,
it verifies the open PR owns the branch, anchors base-equivalence to it, and
records approved_stacked_base = {branch, pr_number, verified_open} on the lock.
- gitea_create_pr validates a non-master base against the lock's approved
stacked base, re-checks the dependency PR is still open, and enforces the
stacked-PR body fields. Master-based path untouched.
- Docs: llm-workflow-runbooks.md and work-issue.md document when stacked PRs are
allowed and the required PR-body wording.
Tests: test_stacked_pr_support.py (18 policy cases), stacked base-equivalence in
test_issue_lock_worktree.py, approved_stacked_base persistence round-trip in
test_issue_lock_store.py. Existing lock/create_pr regressions still pass.
The #482 -> #479/#478 case motivates this: create_pr previously could not open a
stacked PR because the lock required a master-equivalent worktree.
Closes#484.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add merge_approval_gate assessment so gitea_merge_pr fails closed when
visible APPROVED reviews do not pin the live head SHA. Expose
approval_at_current_head and stale_approval_block_reason in review
feedback. Document re-review requirement in canonical merge workflow.
Closes#471.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Merge current prgs/master into feat/issue-399-conflict-fix-leases.
Preserve reviewer PR lease gate (#407) before conflict-fix stale-head
gate (#399); document both as §26B and §26C. Align MCP and validator
tests with mandatory expected_head_sha and stale-head proof fields.
Add audit vs cleanup phase tracking so reconciliation audits stay read-only
unless cleanup is explicitly authorized with delete capability proof, safety
proof, and before/after snapshots. Block gitea_delete_branch and merged-cleanup
execution during audit phase, validate final reports for false no-mutations
claims, and document the boundary in the reconcile-landed-pr workflow.
Adds mutation-capability table validation so review_pr cannot authorize
merge or delete mutations without their own exact capability rows.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Adds post_merge_cleanup_proof validation so cleanup claims must carry the
branch deletion and worktree removal checklists, or report CLEANUP_SKIPPED
with an exact blocker.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Structured PR-thread leases with acquire/heartbeat MCP tools and
mutation-time enforcement so reviewers cannot race the same PR queue.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add lock_provenance metadata on gitea_lock_issue writes and fail closed at
gitea_create_pr when provenance is missing. Final-report validation now
requires explicit External-state mutations disclosure for issue-lock
read/write/delete and blocks mixed author PR creation with reviewer approval.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Rebased onto current prgs/master; merged with #396 validation failure
history by keeping both validator rules and workflow handoff fields.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Extract issue_work_duplicate_gate for open PR, remote branch, and active
claim checks; wire it into lock_issue, commit_files recheck, and create_pr
recheck. Add gitea_assess_work_issue_duplicate read-only preflight, work-issue
report outcome validation, and workflow section 10A.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
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]>
Introduce validation_status_vocabulary with proof-path binding for baseline-
equivalent, merge-simulation-resolved, and transient-pass labels. Wire the
assessor into final_report_validator and document the taxonomy in the
review-merge workflow.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add assess_validation_failure_history_report so reviewer final reports must
document every validation failure observed during a session, not only the
final passing result. Wire the verifier into final_report_validator,
gitea_validate_review_final_report, and the review-merge workflow template.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Adds canonical pr-queue-cleanup workflow, report verifier, reviewer-only task
routing, and runbook guidance so operators can drain open PRs one canonical
review at a time with fail-closed boundaries on batching and unauthorized merges.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
- Map work_issue/work-issue to author role and gitea.pr.create in resolver
- Route work-issue sessions through role_session_router before mutations
- Expose work_issue in runtime context task capabilities
- Add work-issue workflow source verifier and canonical routing docs
- Tests for resolver, router, and final-report verifier
Closes#139
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>