process-lifecycle

SkillDev tools

Use when changing subprocess execution, cancellation, process-tree cleanup, orphan reaping, or Windows child hardening.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the process-lifecycle skill

What this skill tells your AI

The instructions your AI receives, as published by kunchenguid/no-mistakes in .agents/skills/process-lifecycle/SKILL.md and read by ahel’s review.

Context, Concurrency, and Processes

  • Thread context.Context through long-running, subprocess, and networked work; prefer exec.CommandContext; use derived contexts and timeouts for cleanup and HTTP calls.
  • Route every long-lived subprocess spawned for a cancellable step or agent invocation through shellenv.ConfigureShellCommand(cmd): it creates a process-tree boundary and installs cmd.Cancel to kill the whole tree, so grandchildren (test workers, build watchers) cannot outlive cancellation and hold the next run's worktree locked.
  • cmd.Cancel covers only cancellation; on clean exit or error the group is not reaped, and leaked grandchildren accumulate until the OS OOM-kills the daemon (surfacing as daemon crashed during execution with no stack trace). Use shellenv.RunShellCommand / OutputShellCommand / CombinedOutputShellCommand for one-shot commands, or StartShellCommand plus TerminateShellCommandGroup when handling pipes manually; the helper doc comments in internal/shellenv own the details. ConfigureShellCommand also installs a 5s cmd.WaitDelay backstop so a grandchild holding an inherited pipe cannot wedge cmd.Wait forever. Regressions: TestCodexAgent_Run_ReapsLeakedGrandchildOnCleanExit, TestRunShellCommandWithEnv_ReapsGrandchildOnCleanExit, TestTerminateShellCommandGroup_*.
  • A process group is a lineage container, not a sandbox: a descendant that calls setsid(2)/setpgid(2) (agent CLIs sandboxing their tool runners, any daemonizing worker script) leaves the group, and after its parent exits nothing lineage-based can name it again - it burns CPU and holds a deleted worktree's cwd forever. internal/procreap is the identity-based backstop: it matches a process by the run worktree its cwd resolves under (deliberately never argv, which a legitimate git worktree remove also carries), never touches pid<=1/itself/its ancestors, spares worktrees whose run is still pending or running, and escalates SIGTERM to SIGKILL only after a grace period. Reach is <NM_HOME>/worktrees by path shape plus exactly the run worktrees a caller names from run records (Options.Worktrees), never a configured worktree root by shape - an operator's own directory is unmatchable unless a run row names it. Every site that removes a run worktree sweeps it first through procreap.SweepRunWorktree(s) (run cleanup and setup failure via RunManager.removeRunWorktree, startup cleanup, eject), scoped and therefore without age floor or run-active check; the unscoped startup sweep in recoverOnStartup keeps the orphanProcessMinAge floor. All best effort. Windows needs none of this - job objects contain the whole tree - so the platform layer reports an empty table. Regressions: internal/procreap, TestSweepOrphanRunProcessesReapsFinishedRunAndSparesActiveOne, TestSweepRunWorktreeProcessesReapsLeakedChildAtRunCleanup, TestTerminateShellCommandGroup_AsksBeforeKilling, TestTerminateShellCommandGroup_EscalatesWhenSIGTERMIsIgnored.
  • On Windows the daemon runs console-less, so route every console child through winproc.Harden(cmd) (no-op elsewhere, idempotent, preserves existing creation flags) or a console window flashes per child (#287). shellenv.ConfigureShellCommand already calls it; one-shot commands built directly must call it themselves. Regressions: TestHarden* in internal/winproc.
  • Protect shared mutable state with the standard sync/atomic tools, and be explicit about ownership and cleanup of goroutines, worktrees, temp dirs, and channels.

Signals

GitHub stars
8k
Forks
855
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
process-lifecycle
Source
github.com/kunchenguid/no-mistakes