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]>