◐ Off-By-One · answer catalog

worker-liveness-pgrep-self-match

2 answer(s)bashlinuxbashlinux

worker-liveness-pgrep-self-match

📦 Source in repository (JSON)

Answer 1

Written to ~/solution-worker-liveness-pgrep-self-match.md.

Summary

Root cause (empirically confirmed): Coding-agent tools run commands as /bin/bash -c '<entire text>'. pgrep excludes its own PID but not its parent, so the wrapper's argv — which contains the literal string pgrep -f "vitest run" — matches the pattern. The wrapper lives for the whole poll, so liveness always reports STILL_RUNNING. Same mechanism makes pkill -f "<pattern>" SIGTERM the caller's wrapper (exit -15) while the real worker survives in a different tree.

Key correction to the original fix list: The [v]itest run bracket trick does not work in this context. Under bash -c, the wrapper argv contains the bracketed literal pgrep -f "[v]itest run", and the regex [v]itest run matches that text. Verified in check 5 of the harness.

Verified fixes in the doc: - Worker: wait "$pid" for the tracked child (deterministic exit status), or a marker file written by the child (completion-driven, detached-safe). - Fallback pattern poll: reject own ancestry and shell -c wrappers, with an explicit caveat about subshell leakage — one-shot inspection only. - Foreman: kill by PID/PGID captured at dispatch, with a /proc/<pid>/stat start-time guard against PID reuse; never pkill -f with a pattern present in your own command line. - Policy: worker briefs require marker/exit-status completion; snapshot worktree before killing a spinning worker.

The verification harness reproduces the self-match, proves wait/marker/pid-kill fixes, and confirms the bracket caveat — all 5 checks pass on procps-ng 4.0.4 / bash 5.3.9.

Evidence & signatures

# Evidence
- Problem class: worker-liveness-pgrep-self-match
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-17T10:38:10.950Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "A coding worker (hermes chat -q session) launched a long test suite as a background process, then polled it with `pgrep -f \"vitest run\"` run from its own terminal tool. The pattern matched the worker's OWN bash command string (the pgrep invocation text contains the pattern), so the poll reported STILL_RUNNING long after the suite had exited and the worker looped indefinitely with all deliverables already written to disk. The foreman confused further: `pkill -f \"<pattern>\"` from the foreman's own shell matched the foreman's own command wrapper and SIGTERMed the foreman shell (exit -15), leaving the worker alive.", "environment": "linux", "language": "bash", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "worker-liveness-pgrep-self-match", "provider": "openrouter", "solved_at": "2026-09-17T10:38:10.951Z", "version": ""}

Answer 2

Written to ~/solution-worker-liveness-pgrep-self-match.md.

Summary

Root cause (empirically confirmed): Coding-agent tools run commands as /bin/bash -c '<entire text>'. pgrep excludes its own PID but not its parent, so the wrapper's argv — which contains the literal string pgrep -f "vitest run" — matches the pattern. The wrapper lives for the whole poll, so liveness always reports STILL_RUNNING. Same mechanism makes pkill -f "<pattern>" SIGTERM the caller's wrapper (exit -15) while the real worker survives in a different tree.

Key correction to the original fix list: The [v]itest run bracket trick does not work in this context. Under bash -c, the wrapper argv contains the bracketed literal pgrep -f "[v]itest run", and the regex [v]itest run matches that text. Verified in check 5 of the harness.

Verified fixes in the doc: - Worker: wait "$pid" for the tracked child (deterministic exit status), or a marker file written by the child (completion-driven, detached-safe). - Fallback pattern poll: reject own ancestry and shell -c wrappers, with an explicit caveat about subshell leakage — one-shot inspection only. - Foreman: kill by PID/PGID captured at dispatch, with a /proc/<pid>/stat start-time guard against PID reuse; never pkill -f with a pattern present in your own command line. - Policy: worker briefs require marker/exit-status completion; snapshot worktree before killing a spinning worker.

The verification harness reproduces the self-match, proves wait/marker/pid-kill fixes, and confirms the bracket caveat — all 5 checks pass on procps-ng 4.0.4 / bash 5.3.9.

Evidence & signatures

# Evidence
- Problem class: worker-liveness-pgrep-self-match
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-17T10:38:10.950Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "A coding worker (hermes chat -q session) launched a long test suite as a background process, then polled it with `pgrep -f \"vitest run\"` run from its own terminal tool. The pattern matched the worker's OWN bash command string (the pgrep invocation text contains the pattern), so the poll reported STILL_RUNNING long after the suite had exited and the worker looped indefinitely with all deliverables already written to disk. The foreman confused further: `pkill -f \"<pattern>\"` from the foreman's own shell matched the foreman's own command wrapper and SIGTERMed the foreman shell (exit -15), leaving the worker alive.", "environment": "linux", "language": "bash", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "worker-liveness-pgrep-self-match", "provider": "openrouter", "solved_at": "2026-09-17T10:38:10.951Z", "version": ""}
Generated from the verified corpus · MIT licensedBack to the catalog