Master-parity previously compared only the daemon's startup commit against the
local on-disk HEAD. When the checkout was not pulled, parity reported green even
though the live remote master had advanced, so a stale daemon could claim a
mutation-safe result while running outdated capability gates (observed during
PR #592 recovery, where the resolver correctly required restart but parity said
in_parity=true).
Changes:
- master_parity_gate.assess_master_parity() gains an optional live_remote_head
and reports the three commits distinctly (daemon_start_head, local_head,
live_remote_head) plus live_known / live_stale / mutation_safe. A result is
mutation_safe only when daemon, local checkout, and live remote all agree.
- parity_block_reasons() now blocks mutations on live-staleness too; read-only
operations remain unblocked (non-goal: never block diagnostics offline).
- New parity_resolver_disagreement(): typed fail-closed blocker naming the
capability resolver as authoritative when it requires restart but parity
looks locally green.
- New read_remote_master_head(): best-effort `git ls-remote` for the live
target, cached with a 60s TTL (bounded offline latency, no network probe per
gate call); env override GITEA_TEST_LIVE_REMOTE_HEAD keeps tests hermetic.
- Server: _current_master_parity() reads the live remote head;
gitea_assess_master_parity and runtime_context surface the distinguished
SHAs, mutation_safe, and resolver-authoritative guidance.
Tests: 13 new cases (live-remote parity, live-stale blocking + typed blocker,
remote-head reader + TTL cache, server wiring). Full suite: 2423 passed; the 8
remaining failures (test_config TestAuthIntegration, test_credentials
TestGetCredentials) are baseline-proven keychain/env failures identical on the
unmodified base.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Delivers #529 acceptance criterion 6: controller issue closure must be
blocked when the closure report calls a non-zero test-suite exit an
"expected pre-existing"/baseline failure without pre-merge proof.
- controller_closure_baseline_proof.py: assess_controller_closure_baseline_proof
reuses the #533 pre-merge baseline verifier; empty report -> skipped/allowed,
clean pass -> allowed, proven baseline -> allowed, unproven baseline -> block.
- gitea_close_issue: optional closure_report param; fails closed (no state PATCH)
when the gate blocks.
- final_report_validator: new controller_close task kind (alias close_issue)
wired to the pre-merge baseline proof rule so a closure can be pre-checked.
- Tests: tests/test_controller_closure_baseline_proof.py plus two
gitea_close_issue gate tests.
Scope: criteria 2/3 (non-zero exit not a clean pass; baseline claims need
proof) are already enforced on master via premerge_baseline_proof (#533) and
the reviewer schema rules. Criteria 1/4/5 (post-merge moot canonical wording
and validation:* process-state labels) remain follow-up work.
Validation: full suite 2365 passed, 6 skipped; the 9 remaining failures
(tests/test_config.py TestAuthIntegration, tests/test_credentials.py
TestGetCredentials, test_issue_540 reviewer-role) are baseline-proven —
identical failures on clean prgs/master 6913ac9 (keychain/env dependent),
unrelated to this change.
Refs #529
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Durable review-decision locks (#559) can outlive the PR they protect.
When the last terminal mutation references a PR that is already
merged/closed, expose gitea_cleanup_stale_review_decision_lock so a
reviewer can clear the lock with identity/profile gates and a durable
audit trail — without weakening #332 for open PRs or deleting
session-state files by hand.
Also auto-clear same-profile locks after a successful merge of the
approved PR, and document allowed vs forbidden cleanup.
Closes#594
#530's remote/repo guard blocked mcp_get_control_plane_guide(remote=prgs)
because the bare default resolves to Timesheet while local git is
Gitea-Tools, and remediation told callers to pass org/repo on a tool that
did not accept those parameters.
- Accept optional org/repo on mcp_get_control_plane_guide
- Prefer local git remote org/repo when bare defaults mismatch (read-only guide)
- Keep mutation tools fail-closed on bare mismatch
- Align remediation text with tools that accept org/repo
Closes#588
Add a pre-create content gate to gitea_create_issue that fails closed with
BLOCKED + DIAGNOSE when the title/body is a vague reference to out-of-band
draft content ("the drafted issue", "the prepared issue", "the issue we
discussed", "the previous draft") and no durable source pointer (existing
issue/PR/comment, checked-in file, URL, or scratchpad path) is present.
- issue_content_gate.py: assess_issue_content / pre_create_issue_content_gate
with vague-phrase detection, durable-source-pointer escape hatch, and a
domination check so long specific bodies are not falsely blocked.
- gitea_create_issue: runs the gate after preflight purity, before duplicate
search; new allow_incomplete_content override (off by default). Title-only
creation stays allowed (no empty-body requirement) to preserve behavior.
- tests/test_issue_content_gate.py: unit + MCP integration coverage.
- create-issue.md: documents the enforced preflight with valid/invalid
prompt examples.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Surface lease_proof_source / recovery reason from sanctioned session
provenance on gitea_merge_pr results, and block final reports that claim
manual/seeded/injected lease proof without MCP adoption evidence.
Closes#535
_authenticated_username expects a host for auth/API calls. Lease
acquire/adopt/gate/release paths passed the remote alias (prgs), so
identity resolved empty and same-identity release fail-closed across
sessions — blocking author conflict-fix pushes after REQUEST_CHANGES.
Pass resolved host h from _resolve into _authenticated_username.
Add categorize-and-probe helpers for shell spawn failures, expose
gitea_diagnose_terminal, and fail closed on mutation capability resolve
when the terminal launcher is unhealthy (BLOCKED + DIAGNOSE). Document
the operator path in the workflow runbooks.
Discover branches/review-pr<N>[-submit] worktrees separately from author
cleanup, fail closed on dirty trees / open PRs / active reviewer leases,
and remove only assessed-safe scratch paths via reconcile.
Add canonical_comment_validator and wire it into issue comments, PR review
bodies, reconcile post_comment, and structured comment helpers. Workflow-changing
comments without complete next-action state are rejected before any API call.
Includes unit/MCP integration tests, runbook docs, and a final-report rule
blocking false "comment posted" claims when validation failed.
Expose gitea-workflow / llm-project-workflow / git-pr-workflows as one
workflow router in mcp_list_project_skills, add preflight + Codex install
script, and document multi-runtime skill name parity.