Share review-workflow-load and review-decision-lock state across MCP
daemon process pools via a user-private durable store keyed by profile
identity (not host-global /tmp), with TTL and fail-closed profile checks.
Enter terminal mode when review_pr/merge_pr capability is denied. Block
reviewer queue tools (list_prs, eligibility checks) and add report-purity
validators for forbidden PR selection, fallback, and empty-queue claims.
Closes#197
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Addresses the sysadmin REQUEST_CHANGES on PR #203 (reviewed head
10d2644790):
1. Lock redesigned; /tmp file removed entirely. The mutation authority is
now an in-process record (_MUTATION_AUTHORITY) plus an environment
session lock (GITEA_SESSION_PROFILE_LOCK) exported at server launch:
- in-process record cannot be spoofed by other local processes, cannot
go stale across sessions, and cannot race concurrent agents;
- the env lock is inherited by child CLI processes, so review_pr.py can
refuse an ad-hoc GITEA_MCP_PROFILE role escalation without any shared
file; a missing env lock (direct operator CLI use) stays allowed;
- silent except-pass writes are gone; an unresolvable profile fails
closed.
2. Standard reviewer workflow unbroken: verify_mutation_authority seeds
itself from the live config-resolved context at the first mutation gate
(approved preflight path whoami -> eligibility -> review/merge), and now
runs as the final gate after eligibility, reusing the identity that
eligibility proved (no extra /user call).
3. Trailing whitespace removed from review_pr.py (git diff --check clean).
4. Module-global verify_mutation_authority no-op bypass removed from
tests/test_mcp_server.py; replaced with a tests/conftest.py autouse
fixture that only resets per-process state (_MUTATION_AUTHORITY,
_IDENTITY_CACHE, session lock env) between tests — the gate itself
stays live in every test.
5. Tests rewritten for the new design: seeding on first verify, unresolved
profile fails closed, remote/profile/identity mismatches fail closed,
session-lock env mismatch rejected, foreign-pid authority reseeded,
unauthorized author->reviewer pivot blocked, authorized pivot allowed;
CLI: mismatch blocked, match allowed, no-lock allowed.
6. Rebased onto current master (c6fd0fd).
Closes#199
Refs #194
Co-Authored-By: Claude Fable 5 <[email protected]>