feat(mcp-health): MCP restart coordinator and impact analysis (Closes #658) #875

Merged
sysadmin merged 4 commits from feat/issue-658-mcp-restart-coordinator into master 2026-07-24 06:04:14 -05:00
Owner

Summary

Closes #658 — child of the restart-governance program under umbrella #655, building on the #657 restart-path inventory and #656 governance policy.

Adds a central restart coordinator that evaluates live control-plane state before any sanctioned MCP restart and returns a blast-radius impact preview (safe / unsafe / override), so operators and the web console (#642/#652) can see what a restart would disrupt before concurrent LLM work is destroyed.

Changes (purely additive)

  • restart_coordinator.py (+451) — pure, read-only classifier: evaluate_restart_impact() takes a gathered inventory (sessions, leases/locks, in-flight issue/PR work, mutations, worktrees, prior recovery attempts) and returns a structured RestartImpactReport DTO. Fails closed (incomplete inventory → deny). Never touches network/filesystem/process, so multi-session fixtures drive every branch.
  • gitea_mcp_server.py (+151) — new MCP tool gitea_request_mcp_restart (dry-run only; read-gated). Gathers the inventory from the #613 control-plane DB and calls the coordinator. Override authority is read from the process environment (GITEA_OPERATOR_RESTART_OVERRIDE_AUTHORIZATION), never self-asserted by the requesting session. Exceptions are redacted; the tool never restarts anything (apply is a later drain-gated child).
  • control_plane_db.py (+29) — read-only list_sessions() helper for restart/impact inventory; operational metadata only, no secrets.
  • docs/mcp-restart-coordinator.md (+95), docs/mcp-restart-impact-sample.json (+148), docs/mcp-tool-inventory.md (+1) — human-readable design + sample impact JSON.
  • tests/test_restart_coordinator.py (+340) — multi-session impact fixtures covering verdict/blast-radius/critical-section/fail-closed paths.

Acceptance criteria

  1. Coordinator evaluates sessions, leases, mutations, critical sections, worktrees, prior recovery.
  2. Impact report includes affected sessions/issues/PRs, mutations, leases, ack-state placeholders, blast radius, safe/unsafe/override verdict.
  3. Dry-run does not restart (apply not supported here).
  4. Multi-session fixtures deny restart when a critical section is open / inventory incomplete.
  5. Links #652 #653 #655.

Tests

venv/bin/python -m pytest tests/test_restart_coordinator.py -q → 15 passed. Full-suite classification against the current-master baseline is reported on the PR thread.

Provenance

Recovery of an already-committed, unpublished author branch. Work was committed at 2d0d8a6 by a prior author session (pid 30988, now dead); this cycle republished the branch and recovered the exact-owner durable lock under the original claimant (jcwalker3 / prgs-author) through sanctioned dead-session recovery (unpublished_claim). No re-implementation was performed.

Meta

  • Branch: feat/issue-658-mcp-restart-coordinator
  • Worktree: branches/feat-issue-658-mcp-restart-coordinator
  • Commit: 2d0d8a682b2fa26660fec90c0515e46fd39922d3
  • Base: master
  • Risk: low — new module, new dry-run read-only tool, additive DB helper; no existing code paths altered.
  • Known limitation: mutative restart apply is intentionally out of scope (drain-gated child).
## Summary Closes #658 — child of the restart-governance program under umbrella #655, building on the #657 restart-path inventory and #656 governance policy. Adds a central restart coordinator that evaluates live control-plane state before any sanctioned MCP restart and returns a blast-radius **impact preview** (`safe` / `unsafe` / `override`), so operators and the web console (#642/#652) can see what a restart would disrupt before concurrent LLM work is destroyed. ## Changes (purely additive) - `restart_coordinator.py` (+451) — pure, read-only classifier: `evaluate_restart_impact()` takes a gathered inventory (sessions, leases/locks, in-flight issue/PR work, mutations, worktrees, prior recovery attempts) and returns a structured `RestartImpactReport` DTO. Fails closed (incomplete inventory → deny). Never touches network/filesystem/process, so multi-session fixtures drive every branch. - `gitea_mcp_server.py` (+151) — new MCP tool `gitea_request_mcp_restart` (dry-run only; read-gated). Gathers the inventory from the #613 control-plane DB and calls the coordinator. Override authority is read from the process environment (`GITEA_OPERATOR_RESTART_OVERRIDE_AUTHORIZATION`), never self-asserted by the requesting session. Exceptions are redacted; the tool never restarts anything (apply is a later drain-gated child). - `control_plane_db.py` (+29) — read-only `list_sessions()` helper for restart/impact inventory; operational metadata only, no secrets. - `docs/mcp-restart-coordinator.md` (+95), `docs/mcp-restart-impact-sample.json` (+148), `docs/mcp-tool-inventory.md` (+1) — human-readable design + sample impact JSON. - `tests/test_restart_coordinator.py` (+340) — multi-session impact fixtures covering verdict/blast-radius/critical-section/fail-closed paths. ## Acceptance criteria 1. Coordinator evaluates sessions, leases, mutations, critical sections, worktrees, prior recovery. 2. Impact report includes affected sessions/issues/PRs, mutations, leases, ack-state placeholders, blast radius, safe/unsafe/override verdict. 3. Dry-run does not restart (apply not supported here). 4. Multi-session fixtures deny restart when a critical section is open / inventory incomplete. 5. Links #652 #653 #655. ## Tests `venv/bin/python -m pytest tests/test_restart_coordinator.py -q` → 15 passed. Full-suite classification against the current-master baseline is reported on the PR thread. ## Provenance Recovery of an already-committed, unpublished author branch. Work was committed at `2d0d8a6` by a prior author session (pid 30988, now dead); this cycle republished the branch and recovered the exact-owner durable lock under the original claimant (jcwalker3 / prgs-author) through sanctioned dead-session recovery (`unpublished_claim`). No re-implementation was performed. ## Meta - Branch: `feat/issue-658-mcp-restart-coordinator` - Worktree: `branches/feat-issue-658-mcp-restart-coordinator` - Commit: `2d0d8a682b2fa26660fec90c0515e46fd39922d3` - Base: `master` - Risk: low — new module, new dry-run read-only tool, additive DB helper; no existing code paths altered. - Known limitation: mutative restart apply is intentionally out of scope (drain-gated child).
jcwalker3 added 1 commit 2026-07-24 02:14:17 -05:00
Child of umbrella #655 (governed MCP restart coordination); builds on the
#657 restart-path inventory. Adds a central coordinator that evaluates live
control-plane state before a restart and returns a blast-radius impact
preview, so operators and the web console (#642/#652) can see what a restart
would disrupt before concurrent LLM work is destroyed.

Changes
- restart_coordinator.py (new) — pure classification: inventory -> impact
  report DTO (RestartImpactReport/SessionImpact/LeaseImpact). Verdicts:
  safe / unsafe / override. Never restarts anything; fails closed on an
  incomplete inventory.
- control_plane_db.py — additive ControlPlaneDB.list_sessions() read-only
  session inventory (the process-level unit a restart kills).
- gitea_mcp_server.py — new dry-run MCP tool gitea_request_mcp_restart:
  gathers sessions/leases/terminal-lock from the #613 DB, calls the
  coordinator, returns the report. Override authority is read from the
  environment, never self-asserted (#630/#710 F1 pattern). Apply is gated
  by a later drain proof (non-goal here).
- docs/mcp-restart-coordinator.md + docs/mcp-restart-impact-sample.json — doc
  and a real dry-run sample report.
- docs/mcp-tool-inventory.md — register the new tool (inventory sync).
- tests/test_restart_coordinator.py (new) — 15 tests: multi-session fixtures,
  deny-when-critical-section-open, fail-closed deny, override, terminal lock,
  stale heartbeat, JSON-serializable DTO, list_sessions.

Tests: pytest tests/test_restart_coordinator.py -> 15 passed. Full suite:
13 failed / 4753 passed; all 13 reproduce identically on clean master
@ef14622 (0 regressions). The residual test_issue_781 doc-registry failure
is a pre-existing baseline gap for gitea_rebind_dirty_same_claimant_author_session
(merged #864, undocumented on master) — out of scope for #658.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
jcwalker3 added 1 commit 2026-07-24 02:15:38 -05:00
jcwalker3 added 1 commit 2026-07-24 05:48:28 -05:00
jcwalker3 added 1 commit 2026-07-24 05:54:54 -05:00
Owner

repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #875
issue: #658
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 51196-709f0c885723
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/feat-issue-658-mcp-restart-coordinator
phase: claimed
candidate_head: fd558ce5d8
target_branch: master
target_branch_sha: ae1161524d
last_activity: 2026-07-24T10:59:51Z
expires_at: 2026-07-24T11:09:51Z
blocker: none

<!-- mcp-review-lease:v1 --> repo: Scaled-Tech-Consulting/Gitea-Tools pr: #875 issue: #658 reviewer_identity: sysadmin profile: prgs-reviewer session_id: 51196-709f0c885723 worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/feat-issue-658-mcp-restart-coordinator phase: claimed candidate_head: fd558ce5d8aafe2fcb835749934c5c76b6ebee72 target_branch: master target_branch_sha: ae1161524dae3cfa51415ef1c7c381b46d515346 last_activity: 2026-07-24T10:59:51Z expires_at: 2026-07-24T11:09:51Z blocker: none
sysadmin approved these changes 2026-07-24 06:01:36 -05:00
sysadmin left a comment
Owner

Canonical PR State

STATE: approved
WHO_IS_NEXT: merger
NEXT_ACTION: Merge PR #875 at head fd558ce5d8 onto master ae1161524d, then reconcile (delete branch + worktree, close #658).
NEXT_PROMPT:

Merge PR #875 (Closes #658) as prgs-merger at head fd558ce5d8aafe2fcb835749934c5c76b6ebee72 onto master ae1161524dae; approval by sysadmin/prgs-reviewer is valid at this exact head; confirm no new head since approval, merge, then reconcile branch/worktree cleanup and close #658; stop.

WHAT_HAPPENED: Reviewed at exact PR head fd558ce5 in worktree branches/feat-issue-658-mcp-restart-coordinator checked out at that head. Diff vs base ae1161524d is 7 files / +1215 / -0, purely additive. New tool gitea_request_mcp_restart is read-gated, dry-run only (never restarts), fails closed on incomplete inventory, redacts exceptions, reads override authority from the environment. control_plane_db.list_sessions is read-only parameterized SQL returning operational metadata only, no secrets. tests/test_restart_coordinator.py → 15 passed.
WHY: All five acceptance criteria satisfied; scope limited to #658; no existing code paths altered; no secrets; focused tests green — merge-ready.
ISSUE: 658
HEAD_SHA: fd558ce5d8
REVIEW_STATUS: approved
MERGE_READY: yes
BLOCKERS: none
VALIDATION: tests/test_restart_coordinator.py → 15 passed (venv interpreter); diff vs base ae1161524d = 7 files / +1215 / -0 additive; behind=0, mergeable, no conflicts.
LAST_UPDATED_BY: prgs-reviewer (sysadmin)

NATIVE_REVIEW_PROOF: reviewed in worktree branches/feat-issue-658-mcp-restart-coordinator checked out at fd558ce5; git diff vs base ae1161524d = 7 files / +1215 / -0 additive.

## Canonical PR State STATE: approved WHO_IS_NEXT: merger NEXT_ACTION: Merge PR #875 at head fd558ce5d8aafe2fcb835749934c5c76b6ebee72 onto master ae1161524dae, then reconcile (delete branch + worktree, close #658). NEXT_PROMPT: ```text Merge PR #875 (Closes #658) as prgs-merger at head fd558ce5d8aafe2fcb835749934c5c76b6ebee72 onto master ae1161524dae; approval by sysadmin/prgs-reviewer is valid at this exact head; confirm no new head since approval, merge, then reconcile branch/worktree cleanup and close #658; stop. ``` WHAT_HAPPENED: Reviewed at exact PR head fd558ce5 in worktree branches/feat-issue-658-mcp-restart-coordinator checked out at that head. Diff vs base ae1161524dae is 7 files / +1215 / -0, purely additive. New tool gitea_request_mcp_restart is read-gated, dry-run only (never restarts), fails closed on incomplete inventory, redacts exceptions, reads override authority from the environment. control_plane_db.list_sessions is read-only parameterized SQL returning operational metadata only, no secrets. tests/test_restart_coordinator.py → 15 passed. WHY: All five acceptance criteria satisfied; scope limited to #658; no existing code paths altered; no secrets; focused tests green — merge-ready. ISSUE: 658 HEAD_SHA: fd558ce5d8aafe2fcb835749934c5c76b6ebee72 REVIEW_STATUS: approved MERGE_READY: yes BLOCKERS: none VALIDATION: tests/test_restart_coordinator.py → 15 passed (venv interpreter); diff vs base ae1161524dae = 7 files / +1215 / -0 additive; behind=0, mergeable, no conflicts. LAST_UPDATED_BY: prgs-reviewer (sysadmin) NATIVE_REVIEW_PROOF: reviewed in worktree branches/feat-issue-658-mcp-restart-coordinator checked out at fd558ce5; git diff vs base ae1161524dae = 7 files / +1215 / -0 additive.
Owner

adopted_at: 2026-07-24T11:03:27Z
adopted_by_identity: sysadmin
adopted_by_profile: prgs-merger
adopted_from_session_id: 51196-709f0c885723
adopted_from_profile: prgs-reviewer
adopted_from_reviewer_identity: sysadmin
adopted_from_comment_id: 15693
adoption_reason: merger-handoff-approved-head

repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #875
issue: #658
reviewer_identity: sysadmin
profile: prgs-merger
session_id: 51244-a02f0d739ae9
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/feat-issue-658-mcp-restart-coordinator
phase: adopted
candidate_head: fd558ce5d8
target_branch: master
target_branch_sha: ae1161524d
last_activity: 2026-07-24T11:03:27Z
expires_at: 2026-07-24T11:13:27Z
blocker: none

<!-- mcp-review-lease-adoption:v1 --> adopted_at: 2026-07-24T11:03:27Z adopted_by_identity: sysadmin adopted_by_profile: prgs-merger adopted_from_session_id: 51196-709f0c885723 adopted_from_profile: prgs-reviewer adopted_from_reviewer_identity: sysadmin adopted_from_comment_id: 15693 adoption_reason: merger-handoff-approved-head <!-- mcp-review-lease:v1 --> repo: Scaled-Tech-Consulting/Gitea-Tools pr: #875 issue: #658 reviewer_identity: sysadmin profile: prgs-merger session_id: 51244-a02f0d739ae9 worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/feat-issue-658-mcp-restart-coordinator phase: adopted candidate_head: fd558ce5d8aafe2fcb835749934c5c76b6ebee72 target_branch: master target_branch_sha: ae1161524dae3cfa51415ef1c7c381b46d515346 last_activity: 2026-07-24T11:03:27Z expires_at: 2026-07-24T11:13:27Z blocker: none
sysadmin merged commit 67b4889984 into master 2026-07-24 06:04:14 -05:00
Owner

Stale #332 review-decision lock cleanup (#594)

Status: APPLIED

Manual deletion of session-state files is not the workflow.
This path only clears a lock when the referenced PR is merged/closed.

## Stale #332 review-decision lock cleanup (#594) Status: **APPLIED** - actor: `sysadmin` - profile: `prgs-merger` - timestamp: `2026-07-24T11:04:16.457079+00:00` - last terminal: `approve` on PR #875 - PR state: `closed` (merged=True) - merge_commit_sha: `67b4889984924e667b40c717b93577caebcf52d4` - prior live_mutations_count: `1` - prior profile_identity: `prgs-reviewer` Manual deletion of session-state files is **not** the workflow. This path only clears a lock when the referenced PR is merged/closed.
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

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