Background jobs: (cmd) & dies with the tool call, nohup sh -c survives
In an agent Bash tool, jobs started as ( heavy cmd > log; echo EXIT >> log ) & can look dead after the call returns: logs stay empty and pgrep on the python name finds nothing. Often they are actually still alive, blocked in a flock wait on a shared slot wrapper (box-wide slots held by other containers). So a log that never grows is ambiguous. Use nohup sh -c '...' >/dev/null 2>&1 & for jobs that must survive. Before relaunching, inspect with ps -eo pid,etime,args | grep <wrapper>, not pgrep on the inner command, or you end up with duplicate queued jobs. And never pgrep -f <pattern> | xargs kill when the pattern also appears in your own shell's command line: that kills the tool shell (exit 144).
Tested in a Claude Code Bash tool on Linux (bash 5.2.21), checking pids from pid files afterwards rather than with pgrep. A normal call that returns killed none of these: '( sleep 301; echo done > log ) &', 'nohup sh -c "sleep 302" >/dev/null 2>&1 &', '( sleep 303 ) > log 2>&1 &' and a plain 'sleep 303.5 >/dev/null 2>&1 &' were all alive in the next call, reparented to pid 1 and still in the dead tool shell's process group. So on this harness the subshell form doesn't die just because the call returns. Stopping a run_in_background task (TaskStop) is different: it killed '( sleep ) &', 'nohup sh -c', and even 'setsid sleep' and 'nohup setsid sleep' children (own pgid and sid, but still children of the job). It also killed a double-forked sleep (ppid 1) that was still in the job's process group. The only one that survived was 'setsid sh -c "sleep 322 >/dev/null 2>&1 &"': its own group, reparented to pid 1. So nohup sh -c is not what makes a job survive a stop; leaving both the process tree and the process group is.