feat(mcp): implement graceful maintenance-drain mode (Closes #659)
Add durable per-repo drain state, allocator assignment stop, mutation deferral with a safety allowlist, observable status, and capability-gated enter/exit tools. Drain proof/restart gate remain #661. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
# MCP maintenance-drain mode (#659)
|
||||
|
||||
Graceful **maintenance drain** stops new work assignment and defers non-allowlisted
|
||||
mutations so sessions can finish critical handoffs and checkpoint before a
|
||||
restart. It is **not** a restart authorization: the drain *proof* and apply gate
|
||||
remain #661.
|
||||
|
||||
## State
|
||||
|
||||
Per repository scope (`remote`/`org`/`repo`) in the control-plane DB table
|
||||
`maintenance_drain` (schema v6):
|
||||
|
||||
| State | Meaning |
|
||||
|-------|---------|
|
||||
| `inactive` | Normal operation (also: no row) |
|
||||
| `draining` | Assignment stopped; non-allowlisted mutations deferred |
|
||||
|
||||
Enter/exit transitions are audited as `maintenance_drain_enter` /
|
||||
`maintenance_drain_exit` events.
|
||||
|
||||
## Tools
|
||||
|
||||
| Tool | Permission | Effect |
|
||||
|------|------------|--------|
|
||||
| `gitea_maintenance_drain_status` | `gitea.read` | Observe drain (every session) |
|
||||
| `gitea_enter_maintenance_drain` | `runtime.maintenance_drain` | Enter drain (capability-gated) |
|
||||
| `gitea_exit_maintenance_drain` | `runtime.maintenance_drain` | Exit drain |
|
||||
|
||||
`runtime.maintenance_drain` is intentionally **not** a `gitea.*` op, so ordinary
|
||||
author profiles cannot enter drain by accident.
|
||||
|
||||
## Enforcement
|
||||
|
||||
1. **Allocator** (`allocate_next_work`): while draining, returns `outcome=wait`
|
||||
with `reason_code=maintenance_drain_assignment_stopped` for dry-run and apply.
|
||||
2. **Mutation preflight** (`verify_preflight_purity`): non-allowlisted mutation
|
||||
tasks raise `MaintenanceDrainError` with a typed next action.
|
||||
3. **Allowlist** (safety only): heartbeats, lease release/abandon, session
|
||||
checkpoints, enter/exit drain. Reads always work.
|
||||
|
||||
## Restart relationship
|
||||
|
||||
Drain mode prepares the blast radius. Restart apply still requires a clean
|
||||
`DrainProof` (#661) or authorized break-glass. Status payloads never claim
|
||||
restart permission.
|
||||
Reference in New Issue
Block a user