Isolate Gitea MCP runtime from mutable development worktrees #221

Closed
opened 2026-07-05 16:32:54 -05:00 by jcwalker3 · 3 comments
Owner

Problem

The Gitea MCP server can become unavailable when the repository worktree it runs from is left in a broken state, such as an unresolved merge conflict. This blocks identity checks, capability resolution, inventory, reviews, merges, and issue actions.

Observed failure

A reviewer queue-cleanup task could not even run whoami because the local Gitea-Tools tree was mid-merge on feat/issue-211-single-terminal-review-decision with unresolved conflicts in:

  • mcp_server.py
  • tests/test_review_proofs.py

The MCP server loaded from that tree and hit a SyntaxError at conflict markers, causing health checks to block all tool calls.

Required wall

The MCP server runtime must not depend on an actively edited feature worktree.

Required behavior

  • Run MCP tools from a clean, stable runtime checkout or installed package.
  • Reject startup if the runtime checkout has unresolved merge conflicts.
  • Reviewer sessions must not depend on author feature branches.
  • A broken feature branch must not disable Gitea identity/capability checks.
  • Health-check failures must report infra_stop, not wrong_role_stop or empty queue.

Acceptance criteria

  • Add a startup health check that detects unresolved conflict markers in runtime-loaded Python files.
  • Add a test where mcp_server.py contains conflict markers; expected result: infra_stop with clear remediation.
  • Add documentation requiring MCP servers to run from a clean stable checkout, not active branch worktrees.
  • Add a workflow guard: before starting reviewer work, verify MCP runtime source is clean and not mid-merge.
  • Add recovery instructions: abort/finish merge, restart MCP server, then retry.
## Problem The Gitea MCP server can become unavailable when the repository worktree it runs from is left in a broken state, such as an unresolved merge conflict. This blocks identity checks, capability resolution, inventory, reviews, merges, and issue actions. ## Observed failure A reviewer queue-cleanup task could not even run `whoami` because the local `Gitea-Tools` tree was mid-merge on `feat/issue-211-single-terminal-review-decision` with unresolved conflicts in: * `mcp_server.py` * `tests/test_review_proofs.py` The MCP server loaded from that tree and hit a `SyntaxError` at conflict markers, causing health checks to block all tool calls. ## Required wall The MCP server runtime must not depend on an actively edited feature worktree. ## Required behavior * Run MCP tools from a clean, stable runtime checkout or installed package. * Reject startup if the runtime checkout has unresolved merge conflicts. * Reviewer sessions must not depend on author feature branches. * A broken feature branch must not disable Gitea identity/capability checks. * Health-check failures must report `infra_stop`, not `wrong_role_stop` or empty queue. ## Acceptance criteria * Add a startup health check that detects unresolved conflict markers in runtime-loaded Python files. * Add a test where `mcp_server.py` contains conflict markers; expected result: `infra_stop` with clear remediation. * Add documentation requiring MCP servers to run from a clean stable checkout, not active branch worktrees. * Add a workflow guard: before starting reviewer work, verify MCP runtime source is clean and not mid-merge. * Add recovery instructions: abort/finish merge, restart MCP server, then retry.
Author
Owner

“Additional observed failure: two LLM sessions operated in the same Gitea-Tools worktree concurrently. During cleanup, the branch changed from 10 to 11 commits ahead because another process committed a1a7c5b in the same worktree. This caused stash/status contradictions and made PR provenance unsafe.

Required wall: add a per-worktree single-writer lock. Before any agent edits, stashes, commits, checks out branches, rebases, cleans, or pushes, it must acquire an exclusive worktree lock recording session ID, task type, branch, issue/PR, and timestamp. If another active lock exists, stop with worktree_busy_stop.

Acceptance tests:

  • two sessions try to mutate the same worktree; second is blocked;
  • read-only reviewer checks cannot stash/clean/delete branches;
  • cleanup tasks must report local workspace mutations separately from Gitea mutations;
  • stale locks require explicit operator override.”
“Additional observed failure: two LLM sessions operated in the same Gitea-Tools worktree concurrently. During cleanup, the branch changed from 10 to 11 commits ahead because another process committed `a1a7c5b` in the same worktree. This caused stash/status contradictions and made PR provenance unsafe. Required wall: add a per-worktree single-writer lock. Before any agent edits, stashes, commits, checks out branches, rebases, cleans, or pushes, it must acquire an exclusive worktree lock recording session ID, task type, branch, issue/PR, and timestamp. If another active lock exists, stop with `worktree_busy_stop`. Acceptance tests: * two sessions try to mutate the same worktree; second is blocked; * read-only reviewer checks cannot stash/clean/delete branches; * cleanup tasks must report local workspace mutations separately from Gitea mutations; * stale locks require explicit operator override.”
Author
Owner

Additional observed failure/risk: concurrent writer on the same worktree

During PR #214 author remediation, another Claude session was actively editing the same worktree. File mtimes and diff hashes changed within 14 seconds, reflog showed recent amend/rebase activity, and six other Claude sessions were running. The agent correctly stopped before becoming a second writer.

Required wall: per-worktree single-writer lock

Any task that may edit, stash, checkout, rebase, commit, push, clean, or delete branches/worktrees must acquire the lock first. If another active writer owns the worktree, stop with worktree_busy_stop.

Required reporting change

Mutation reporting must distinguish:

  1. Gitea mutations (API-side: reviews, merges, comments, issues, pushes)
  2. Working-tree mutations (file edits, stash, checkout, rebase, commit)
  3. Local git metadata mutations (e.g. git fetch updating remote-tracking refs)

Evidence detail from the observed run

  • Two snapshots 14 seconds apart: tests/test_mcp_server.py mtime advanced and git diff content hash changed (08e1629e…40674895…) — active writer confirmed.
  • Reflog on feat/issue-211-single-terminal-review-decision: amend at 17:40:55, rebase onto prgs/master finished 17:43:50, not performed by the reporting session.
  • Local branch ahead 5 / behind 4 vs the PR head (6e9b95b), dirty tree covering exactly the files of the in-flight remediation (mcp_server.py, review_pr.py, review_proofs.py, tests).
  • The reporting session performed zero working-tree mutations; its only local git metadata mutation was one git fetch (remote-tracking refs update) — exactly the category split proposed above.
## Additional observed failure/risk: concurrent writer on the same worktree During PR #214 author remediation, another Claude session was actively editing the same worktree. File mtimes and diff hashes changed within 14 seconds, reflog showed recent amend/rebase activity, and six other Claude sessions were running. The agent correctly stopped before becoming a second writer. ### Required wall: per-worktree single-writer lock Any task that may **edit, stash, checkout, rebase, commit, push, clean, or delete branches/worktrees** must acquire the lock first. If another active writer owns the worktree, stop with `worktree_busy_stop`. ### Required reporting change Mutation reporting must distinguish: 1. **Gitea mutations** (API-side: reviews, merges, comments, issues, pushes) 2. **Working-tree mutations** (file edits, stash, checkout, rebase, commit) 3. **Local git metadata mutations** (e.g. `git fetch` updating remote-tracking refs) ### Evidence detail from the observed run - Two snapshots 14 seconds apart: `tests/test_mcp_server.py` mtime advanced and `git diff` content hash changed (`08e1629e…` → `40674895…`) — active writer confirmed. - Reflog on `feat/issue-211-single-terminal-review-decision`: amend at 17:40:55, rebase onto `prgs/master` finished 17:43:50, not performed by the reporting session. - Local branch ahead 5 / behind 4 vs the PR head (`6e9b95b`), dirty tree covering exactly the files of the in-flight remediation (`mcp_server.py`, `review_pr.py`, `review_proofs.py`, tests). - The reporting session performed zero working-tree mutations; its only local git metadata mutation was one `git fetch` (remote-tracking refs update) — exactly the category split proposed above.
Author
Owner

“Observed during PR #214 review: reviewer run killed multiple local mcp_server.py processes with kill -9 to register/reload tools, causing MCP client EOF. This is a local infrastructure mutation during review and invalidates the reviewer session. Reviewer tasks must not kill/restart MCP servers or alter runtime infrastructure unless explicitly assigned an infra task. If a tool is missing or MCP returns EOF, the workflow must stop with infra_stop; the next attempt must start a fresh reviewer session and rerun identity, capability, inventory, head pinning, validation, and final decision gates from scratch.”

Also add: “A failed git diff --check is a hard validation blocker. Reviewer must submit REQUEST_CHANGES or stop, not proceed to APPROVE/MERGE.”

“Observed during PR #214 review: reviewer run killed multiple local `mcp_server.py` processes with `kill -9` to register/reload tools, causing MCP client EOF. This is a local infrastructure mutation during review and invalidates the reviewer session. Reviewer tasks must not kill/restart MCP servers or alter runtime infrastructure unless explicitly assigned an infra task. If a tool is missing or MCP returns EOF, the workflow must stop with `infra_stop`; the next attempt must start a fresh reviewer session and rerun identity, capability, inventory, head pinning, validation, and final decision gates from scratch.” Also add: “A failed `git diff --check` is a hard validation blocker. Reviewer must submit REQUEST_CHANGES or stop, not proceed to APPROVE/MERGE.”
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

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