From 75a5dd08ad50da136785dd0e01e1df2444d74fb0 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Mon, 16 Mar 2026 19:20:09 -0400 Subject: [PATCH] fix: add anti-pattern rule against bash with & to prevent agent hangs (#733) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bash tool waits for stdout/stderr file descriptors to close. When the LLM runs 'python -m http.server 8080 &', the backgrounded process inherits stdout and keeps it open — the bash call hangs indefinitely. The bg_shell tool exists for exactly this purpose (detached process groups, readiness detection, lifecycle management). The system prompt already said to use bg_shell for servers but didn't explicitly warn against bash with &. Added: - Explicit anti-pattern: 'Never use bash with & to background a process' - Expanded background processes section explaining why & hangs - Both reference bg_shell start as the correct alternative --- src/resources/extensions/gsd/prompts/system.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/resources/extensions/gsd/prompts/system.md b/src/resources/extensions/gsd/prompts/system.md index 7281f8535..8d0a9775d 100644 --- a/src/resources/extensions/gsd/prompts/system.md +++ b/src/resources/extensions/gsd/prompts/system.md @@ -154,7 +154,7 @@ Templates showing the expected format for each artifact type are in: **External facts:** Use `search-the-web` + `fetch_page`, or `search_and_read` for one-call extraction. Use `freshness` for recency. Never state current facts from training data without verification. -**Background processes:** Use `bg_shell` with `start` + `wait_for_ready` for servers, watchers, and daemons. Never poll with `sleep`/retry loops — `wait_for_ready` exists for this. For status checks, use `digest` (~30 tokens), not `output` (~2000 tokens). Use `highlights` (~100 tokens) when you need significant lines only. Use `output` only when actively debugging. +**Background processes:** Use `bg_shell` with `start` + `wait_for_ready` for servers, watchers, and daemons. Never use `bash` with `&` or `nohup` to background a process — the `bash` tool waits for stdout to close, so backgrounded children that inherit the file descriptors cause it to hang indefinitely. Never poll with `sleep`/retry loops — `wait_for_ready` exists for this. For status checks, use `digest` (~30 tokens), not `output` (~2000 tokens). Use `highlights` (~100 tokens) when you need significant lines only. Use `output` only when actively debugging. **One-shot commands:** Use `async_bash` for builds, tests, and installs. The result is pushed to you when the command exits — no polling needed. Use `await_job` to block on a specific job. @@ -169,6 +169,7 @@ Templates showing the expected format for each artifact type are in: - Never use `cat` to read a file you might edit — `read` gives you the exact text `edit` needs. - Never `grep` for a function definition when `lsp` go-to-definition is available. - Never poll a server with `sleep 1 && curl` loops — use `bg_shell` `wait_for_ready`. +- Never use `bash` with `&` to background a process — it hangs because the child inherits stdout. Use `bg_shell` `start` instead. - Never use `bg_shell` `output` for a status check — use `digest`. - Never read files one-by-one to understand a subsystem — use `rg` or `scout` first. - Never guess at library APIs from training data — use `get_library_docs`.