Block manual MCP daemon process killing as workflow recovery #630

Open
opened 2026-07-10 14:35:32 -05:00 by jcwalker3 · 1 comment
Owner

Problem

A session attempted to recover MCP connectivity by running pkill -f mcp_server.py, then waited for the IDE to restart the daemons. This bypasses sanctioned reconnect/restart tooling, can kill unrelated namespaces, can contaminate runtime proof, and makes later review/merge/closure decisions untrustworthy.

Observed behavior

  • Session ran ps aux | grep mcp_server.
  • Session ran pkill -f mcp_server.py.
  • Session later called MCP tools after daemons restarted.
  • Same session closed Issue #601.
  • The run also touched root .env state and reported local commits without clear PR/merge proof.

Impact

  • Unrelated MCP namespaces can be killed as collateral damage.
  • Session-local runtime proof becomes untrustworthy after host process manipulation.
  • Close/review/merge actions performed after contaminated recovery may appear clean while lacking a sanctioned recovery chain.
  • Operators cannot distinguish IDE-mediated reconnect from LLM-initiated process kills.
  • Partial detectors already exist (native_mcp_preference.py kill/pkill pattern; review_workflow_boundary.py classifies pkill as MCP repair activity) but do not fully fail-closed on post-kill mutations or final-report cleanliness.

Required behavior

  • Workflow recovery must use sanctioned reconnect/restart tooling only (host auto-reconnect, operator-owned restart paths, or explicit sanctioned restart tools — not ad-hoc shell process kills).
  • Manual host process killing must be detected and classified as workflow contamination unless explicitly operator-authorized.
  • Any review, merge, close, or proof following manual daemon process killing must be blocked pending controller/reconciler audit.
  • The final report must identify process manipulation and forbid treating the session as clean.

Scope

  1. Detect manual daemon kill/restart markers where possible (shell command patterns, session audit markers, process-lifecycle anomalies relative to sanctioned restart).
  2. Classify pkill -f mcp_server.py, kill of MCP pids, broad pkill -f mcp, and equivalents as contaminated recovery unless operator authorization proof is present.
  3. Fail closed for issue close, PR review, and merge tools when the same session has recorded contaminated runtime recovery.
  4. Final-report / validation ledger rules: contaminated recovery must surface explicitly; clean-session claims must be rejected.
  5. Docs: clearly distinguish sanctioned reconnect/restart from forbidden host process manipulation.

Related issues (not duplicates)

  • #584 — transport closed recovery via host auto-reconnect (sanctioned/verify-only; contrasts with pkill).
  • #591 — auto-restart namespaces when master advances (sanctioned path; closed).
  • #531 — detect stale MCP runtime before mutation (closed; incomplete for process-kill contamination).
  • #610 — resolver vs master-parity stale-runtime disagreement (open; related runtime safety, different fault).
  • #558 — block unsanctioned direct imports/raw API mutation paths (closed; complementary trust-boundary work).
  • #539 — reviewer session performed unauthorized mutations / API bypass (closed; contamination class, different vector).

Acceptance criteria

  1. Workflow tools detect manual daemon kill/restart markers where possible.
  2. Reports must classify pkill -f mcp_server.py or equivalent as contaminated recovery unless explicitly authorized.
  3. Issue close/review/merge tools fail closed after contaminated runtime recovery in the same session.
  4. Tests cover manual process kill, sanctioned reconnect, stale runtime restart, and contaminated post-restart mutation.
  5. Documentation clearly distinguishes sanctioned reconnect/restart from forbidden host process manipulation.

Non-goals

  • Do not forbid operator-authorized host maintenance outside LLM workflow sessions when explicitly authorized and recorded.
  • Do not replace IDE/host auto-reconnect with a new process-kill path.
  • Do not re-open #601 lifecycle work; use it only as observed-evidence context.
  • Do not solve unrelated stale-runtime parity (#610) inside this issue unless needed to wire contamination markers.

Evidence note

Issue #601 closure in a session that performed pkill -f mcp_server.py is a concrete contamination example. Treat it as evidence of the class of defect, not as sole implementation scope.

Label note

Requested labels contamination and type:bug are not present on the repository label set. Applied closest existing set: type:guardrail, bug, workflow-hardening, stale-runtime, mcp-health, anti-stomp, status:ready. Controllers may add contamination / type:bug after taxonomy extension (#603).

## Problem A session attempted to recover MCP connectivity by running `pkill -f mcp_server.py`, then waited for the IDE to restart the daemons. This bypasses sanctioned reconnect/restart tooling, can kill unrelated namespaces, can contaminate runtime proof, and makes later review/merge/closure decisions untrustworthy. ## Observed behavior * Session ran `ps aux | grep mcp_server`. * Session ran `pkill -f mcp_server.py`. * Session later called MCP tools after daemons restarted. * Same session closed Issue #601. * The run also touched root `.env` state and reported local commits without clear PR/merge proof. ## Impact * Unrelated MCP namespaces can be killed as collateral damage. * Session-local runtime proof becomes untrustworthy after host process manipulation. * Close/review/merge actions performed after contaminated recovery may appear clean while lacking a sanctioned recovery chain. * Operators cannot distinguish IDE-mediated reconnect from LLM-initiated process kills. * Partial detectors already exist (`native_mcp_preference.py` kill/pkill pattern; `review_workflow_boundary.py` classifies `pkill` as MCP repair activity) but do not fully fail-closed on post-kill mutations or final-report cleanliness. ## Required behavior * Workflow recovery must use **sanctioned reconnect/restart tooling only** (host auto-reconnect, operator-owned restart paths, or explicit sanctioned restart tools — not ad-hoc shell process kills). * Manual host process killing must be detected and classified as **workflow contamination** unless explicitly operator-authorized. * Any review, merge, close, or proof following manual daemon process killing must be **blocked pending controller/reconciler audit**. * The final report must identify process manipulation and **forbid treating the session as clean**. ## Scope 1. Detect manual daemon kill/restart markers where possible (shell command patterns, session audit markers, process-lifecycle anomalies relative to sanctioned restart). 2. Classify `pkill -f mcp_server.py`, `kill` of MCP pids, broad `pkill -f mcp`, and equivalents as contaminated recovery unless operator authorization proof is present. 3. Fail closed for issue close, PR review, and merge tools when the same session has recorded contaminated runtime recovery. 4. Final-report / validation ledger rules: contaminated recovery must surface explicitly; clean-session claims must be rejected. 5. Docs: clearly distinguish sanctioned reconnect/restart from forbidden host process manipulation. ## Related issues (not duplicates) * #584 — transport closed recovery via **host auto-reconnect** (sanctioned/verify-only; contrasts with pkill). * #591 — auto-restart namespaces when master advances (sanctioned path; closed). * #531 — detect stale MCP runtime before mutation (closed; incomplete for process-kill contamination). * #610 — resolver vs master-parity stale-runtime disagreement (open; related runtime safety, different fault). * #558 — block unsanctioned direct imports/raw API mutation paths (closed; complementary trust-boundary work). * #539 — reviewer session performed unauthorized mutations / API bypass (closed; contamination class, different vector). ## Acceptance criteria 1. Workflow tools detect manual daemon kill/restart markers where possible. 2. Reports must classify `pkill -f mcp_server.py` or equivalent as contaminated recovery unless explicitly authorized. 3. Issue close/review/merge tools fail closed after contaminated runtime recovery in the same session. 4. Tests cover manual process kill, sanctioned reconnect, stale runtime restart, and contaminated post-restart mutation. 5. Documentation clearly distinguishes sanctioned reconnect/restart from forbidden host process manipulation. ## Non-goals * Do not forbid operator-authorized host maintenance outside LLM workflow sessions when explicitly authorized and recorded. * Do not replace IDE/host auto-reconnect with a new process-kill path. * Do not re-open #601 lifecycle work; use it only as observed-evidence context. * Do not solve unrelated stale-runtime parity (#610) inside this issue unless needed to wire contamination markers. ## Evidence note Issue #601 closure in a session that performed `pkill -f mcp_server.py` is a concrete contamination example. Treat it as evidence of the class of defect, not as sole implementation scope. ## Label note Requested labels `contamination` and `type:bug` are not present on the repository label set. Applied closest existing set: `type:guardrail`, `bug`, `workflow-hardening`, `stale-runtime`, `mcp-health`, `anti-stomp`, `status:ready`. Controllers may add `contamination` / `type:bug` after taxonomy extension (#603).
Author
Owner

Canonical Issue State

STATE:
ready-for-author

WHO_IS_NEXT:
author

NEXT_ACTION:
Keep this issue scoped to pkill/contamination detection; integrate with umbrella #655 (not a duplicate); coordinator/break-glass live under #655–#669

NEXT_PROMPT:

AUTHOR prgs Gitea-Tools: Issue #630 remains the contamination detector for manual daemon kills.
Governed restart coordination is umbrella #655 (children #656–#669). Implement #630 without inventing a full coordinator—link to #655 for authorized restart paths.
Vision #652 · Roadmap #653.

WHAT_HAPPENED:
Linked #630 as complementary to #655 restart governance program.

WHY:
Avoid duplicate ownership; pkill ban ≠ full drain/coordinator.

RELATED_ISSUES:
#655 #657 #664 #665 #652 #653

RELATED_PRS:
none

BLOCKERS:
none

VALIDATION:
not a duplicate of #655

LAST_UPDATED_BY:
jcwalker3 / prgs-author / author / 2026-07-10

## Canonical Issue State STATE: ready-for-author WHO_IS_NEXT: author NEXT_ACTION: Keep this issue scoped to pkill/contamination detection; integrate with umbrella #655 (not a duplicate); coordinator/break-glass live under #655–#669 NEXT_PROMPT: ```text AUTHOR prgs Gitea-Tools: Issue #630 remains the contamination detector for manual daemon kills. Governed restart coordination is umbrella #655 (children #656–#669). Implement #630 without inventing a full coordinator—link to #655 for authorized restart paths. Vision #652 · Roadmap #653. ``` WHAT_HAPPENED: Linked #630 as complementary to #655 restart governance program. WHY: Avoid duplicate ownership; pkill ban ≠ full drain/coordinator. RELATED_ISSUES: #655 #657 #664 #665 #652 #653 RELATED_PRS: none BLOCKERS: none VALIDATION: not a duplicate of #655 LAST_UPDATED_BY: jcwalker3 / prgs-author / author / 2026-07-10
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

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