Move @mcp.tool() from internal _list_open_pulls helper onto
gitea_lock_issue so author sessions can discover and call the
issue lock required by gitea_create_pr.
Add regression tests for MCP registration and create_pr lock flow.
Namespace-scoped workspace resolution prevents GITEA_AUTHOR_WORKTREE from
poisoning reviewer, merger, and reconciler purity checks. Each role uses
its own worktree env var with actionable binding-source errors and safe
reconnect guidance. Preserves #274/#475 author and control-checkout guards.
Read-only gitea_whoami calls no longer clear a valid capability proof when
whoami was already verified clean. Capability is consumed on mutation (one
resolve per mutation), and verify_preflight_purity rejects task mismatches.
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]>
_list_pr_lease_comments and gitea_list_issue_comments now fail safe to an
empty list when the comments API returns a non-list payload (e.g. an error
object), preventing KeyError: slice on the lease and listing paths.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
PR #416 introduced pr_work_lease reviewer blocks and mandatory full
40-hex expected_head_sha on mark/merge paths. Update audit, review,
permission-report, terminal hard-stop, inventory, and schema tests to
patch lease comment fetches, seed ready review decisions, and use
consistent HEAD_SHA constants so the full suite passes again.
When gitea_lock_issue adopts an existing own branch, the live tool
response now carries explicit, citable adoption-proof fields so #473-style
recovery sessions can quote the lock output directly instead of inferring
adoption from separate offline checks.
- issue_lock_adoption.py: add DECISION_LABELS + decision_label()/
safe_next_action() helpers; extend build_adoption_proof() with
adoption_decision, adopted, adopted_branch, adopted_branch_head,
matcher_summary (boundary-safe reason), competing_branch_check, and
safe_next_action for all outcomes; add build_non_adoption_lock_proof()
for adoption-free NO_MATCH metadata.
- gitea_mcp_server.py: attach adoption-free adoption_check block to normal
(non-adopt) lock responses so they cannot be misread as claiming adoption.
- docs/llm-workflow-runbooks.md: document the adoption/adoption_check
response blocks and instruct recovery reports to cite them directly.
- tests: explicit-field proof for ADOPT/BLOCK_COMPETING/NO_MATCH,
substring-collision boundary safety (issue-42 vs issue-420), non-adoption
proof, and MCP-level live-response assertions.
BLOCK_COMPETING lock attempts still fail closed (raise); no raw API
fallback, branch deletion, force-push, or manual lock seeding introduced.
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]>
Rebase onto master (#443 keyed store) and port #438 hardening: per-issue
fcntl.flock around bind_session_lock, assess_lock_freshness with dead-PID
detection, verify_lock_for_mutation before create_pr, and live lock
inventory for claim visibility.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Replace substring issue-marker matching with a numeric word-boundary
regex so issue-42 adoption is not false-blocked by unrelated issue-420
branches. Add regression tests for the #42 vs #420 collision.
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.
Reconciler profiles perform Gitea metadata mutations (close_pr) and must
not be blocked when the MCP workspace resolves to the stable control
checkout without GITEA_AUTHOR_WORKTREE. Author file mutations remain
guarded. Add regression tests for reconciler close vs author create_issue.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Update lock-issue and duplicate-recheck tests to mock branch listing,
use GITEA_ISSUE_LOCK_DIR session binding, and satisfy create_pr
provenance/worktree guards after the keyed persistent lock store landed.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Store per remote/org/repo/issue locks under GITEA_ISSUE_LOCK_DIR with
atomic writes and per-session binding. Integrate own-branch adoption for
lock recovery, update worktree-start and cleanup reconcile, and add tests
documenting the ban on manual global lock seeding.
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]>
Rebase onto master (#413/#463) requires sanctioned lock_provenance in
create_pr duplicate-recheck tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Align merge/review/audit mocks with the per-PR reviewer lease gate introduced
in #407: install owned session leases after init_review_decision_lock, stub
_fetch_pr_comments and _authenticated_username to preserve mock ordering, and
update head-SHA mismatch expectations for lease-first fail-closed paths.
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]>
Expose issue_duplicate_context_fetcher on the MCP server so lock_issue,
commit_files, and create_pr duplicate rechecks avoid live Gitea calls in
unit tests. Update affected test suites to patch the fetcher without
weakening duplicate-work gate assertions.
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]>
Share canonical workspace/repo-root resolution between gitea_get_runtime_context
and verify_preflight_purity so valid branches/ worktrees are not rejected when
the MCP process root differs from the stable control checkout. Fix relative
git-common-dir resolution and add regression tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
When Gitea credentials are missing or the queue fetch fails closed,
show "Not loaded" instead of "No open items." and keep pagination
marked unavailable. Successful empty inventories still show the empty
state with complete pagination proof.
Closes#458
Expand queue dashboard tests for stale/duplicate badges, title-linked
issues, and nav coverage; drop unused import in queue_loader.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Adds read-only /queue and /api/queue routes that load open PRs and issues
from the default registry project via gitea_auth, surface pagination proof,
and classify items with claimed/blocked/in-review/duplicate badges.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Surface short copy/paste operator prompts derived from canonical workflow
files with workflow path and SHA-256 citations. Adds /prompts, /prompts/{id},
and /api/prompts with one-click copy.
Closes#428
Expose short copy/paste operator prompts on /prompts derived from canonical
workflow files with workflow path and SHA-256 hash. Adds JSON export at
/api/prompts, copy buttons, and tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Hardens #274 branches-only guard for gitea_create_issue:
- verify_preflight_purity: validate resolved worktree exists, is a directory,
and belongs to the target repository before author mutations.
- gitea_create_issue: add worktree_path threaded into preflight guard.
- tests/test_create_issue_workspace_guard.py: stable-control-checkout rejection
and invalid-path fail-closed cases (PROJECT_ROOT simulated as control checkout).
Preserves WIP commit 8530109 implementation; test fix completes stable-checkout path.
Closes#450
Starlette read-only MVP with shared layout, /health JSON liveness, and
route stubs for projects, prompts, runtime, audit, worktrees, and leases.
Includes scripts/run-webui, docs/webui-local-dev.md, and tests.
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]>
Rebase onto current prgs/master and patch create_pr duplicate-gate test
with auth header mock to match post-rebase recheck path.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>