Skip to content

Investigate preventing shell-enabled agents from terminating Code Puppy #607

Description

@mpfaffenberger

Problem

An agent with access to agent_run_shell_command can potentially terminate the Code Puppy host process (or a parent/process tree that takes Code Puppy down with it). That lets the agent accidentally or intentionally kill its own runtime, losing the active run and potentially leaving child processes or terminal state behind.

We should determine whether Code Puppy can place a non-optional guard around shell execution that protects its own process and required ancestors without breaking legitimate command management.

Current architecture / likely interception point

  • code_puppy/tools/command_runner.py::run_shell_command() invokes the run_shell_command callback before launching foreground or background commands.
  • code_puppy/plugins/destructive_command_guard/ already uses that hook for dangerous filesystem/git/container commands.
  • The current destructive detector does not appear to cover process termination (kill, pkill, taskkill, Stop-Process, API calls from scripts, etc.).
  • A command-string regex alone is not a complete boundary: an agent can write or invoke Python/PowerShell/C/native code, use aliases or indirection, target a process tree, or launch a delayed/background killer.

Investigation goals

  1. Map the process topology on Windows, Linux, and macOS:
    • Code Puppy host PID;
    • terminal/shell ancestors whose termination would also take down or corrupt the session;
    • shell-tool child process groups/jobs;
    • detached/background commands.
  2. Define the protected set precisely. At minimum, protect the active Code Puppy process; determine whether selected ancestors and helper processes must also be protected.
  3. Evaluate enforcement options and document their guarantees and bypasses:
    • mandatory run_shell_command policy guard for obvious direct attempts;
    • stripping/protecting PID information passed to children where practical;
    • OS-level isolation or reduced credentials/capabilities for shell children;
    • Windows process security descriptors/restricted tokens/job objects;
    • Linux/macOS separate UID, namespace/container, sandbox, seccomp, or equivalent mechanisms;
    • watchdog/supervisor recovery if prevention cannot be made portable;
    • behavior for MCP/plugin-provided shell-like tools, which may bypass the built-in runner.
  4. Decide what can be guaranteed cross-platform versus what is only best-effort defense in depth.
  5. Produce an implementation plan with a testable threat model before coding the guard.

Requirements / expected behavior

  • Direct attempts to terminate the protected Code Puppy process or protected process tree are blocked before execution with a clear explanation.
  • The self-protection guard is not disabled by YOLO mode, normal dangerous-command approval, or model/provider-specific safety bypasses. This is runtime integrity, not user confirmation policy.
  • Legitimate management of shell-tool children (Ctrl+C, kill-all, timeout handling, backgrounding, and explicit cleanup) continues to work.
  • Foreground, background, chained, delayed, and nested/interpreter-launched attempts are considered.
  • Failure should be safe and understandable; do not silently rewrite commands in ways that alter unrelated behavior.
  • Avoid claiming complete protection if same-user arbitrary code execution makes that impossible without privilege/process isolation. Clearly document residual risk.

Acceptance criteria

  • A short design/threat-model document explains the protected process set, attack paths, platform differences, and chosen enforcement boundary.
  • A decision is made between hard prevention, process isolation, watchdog recovery, or an explicitly documented defense-in-depth combination.
  • Direct process-kill attempts are covered on Windows and POSIX platforms.
  • Tests cover PID targeting, process-name targeting, parent/tree targeting, shell chaining, interpreter/script indirection, delayed/background execution, and false positives against legitimate child cleanup.
  • Tests prove YOLO mode and ordinary approval paths cannot bypass the mandatory self-protection policy.
  • Shell-like execution paths outside agent_run_shell_command (plugins/MCP/custom tools) are audited and either covered or called out as residual risk.
  • Any unavoidable limitations are documented honestly.

Non-goal

This issue does not need to prevent every destructive command on the machine. Its narrow purpose is to stop—or, where the OS makes that impossible, robustly mitigate and recover from—the agent terminating the Code Puppy runtime that is executing it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions