--- id: "bug-1448" status: "fixed" status_updated: "2026-09-24" status_note: "" component: "build" severity: "unknown" timestamp: "2026-07-18T01:54:00Z" last_seen: "2026-09-19T09:00:00Z" occurrences: 1 files: ["src/tools/xce-build.sh (skill invocation pattern", "not the script itself); .claude/skills/xce-build/SKILL.md's 'Always dispatch the build via the Agent tool' instruction"] tags: ["xce-build", "Agent-tool", "run_in_background", "nohup", "setsid", "disown", "subagent-teardown", "kiro-validate-impl", "ha-heartbeat-committed-propagation", "process-detach"] related: [] legacy: true gitea_issue: 33 gitea_synced_status: "fixed" --- # bug-1448: /kiro-validate-impl ha-heartbeat-committed-propagation: the xce-build skill's own documented… ## Description /kiro-validate-impl ha-heartbeat-committed-propagation: the xce-build skill's own documented pattern ("dispatch via a plain Agent-tool call, run_in_background: false, wait for it") produced an INCOMPLETE build -- ninja log ends with 'ninja: build stopped: interrupted by user.' at 85/192 targets, roughly 14 minutes after launch with zero nix/meson/ninja processes still running and no error in the log. The synchronous Agent call returned to the caller almost immediately (~38s) with text claiming 'The build is running in the background... I'll wait for it to complete' -- i.e. the subagent itself spawned an internal Bash run_in_background job and then ended its own turn, rather than blocking until the command finished. ## Environment _Not recorded (migrated from buglog.json)._ ## Reproduction _Not recorded (migrated from buglog.json)._ ## Root cause Same defect family as the already-documented xce-test-ha/run-ha-soak.sh 'context: fork' SIGHUP-teardown bug (fixed 2026-07-08), but manifesting through a DIFFERENT mechanism: xce-build's skill doc explicitly avoids 'context: fork' and claims a plain Agent-tool dispatch is safe -- but that safety claim implicitly assumes the subagent's own Bash tool call blocks synchronously for the whole build. In practice the subagent chose to run the long nix/meson/ninja command via its OWN internal run_in_background Bash call and then finished its turn, un-detached (no setsid/nohup/disown) -- so when that subagent's session/turn ended, the still-attached background job's process group got interrupted (ninja saw SIGINT/SIGHUP-equivalent, logged literally as 'interrupted by user'). A second SendMessage asking the same agent to 'wait for it now' resumed a session with nothing left alive to wait for. ## Fix Relaunched the build via a fresh Agent dispatch whose ONLY instruction was to run `setsid nohup nix develop ./src --command bash src/tools/xce-build.sh controller asan LOG 2>&1 & disown` and return immediately (fire-and-forget), then polled LOG/binary-mtimes independently from the main session via the Monitor tool. That build completed cleanly in ~10 minutes (85/85 ninja targets, clean link, meson test suite started normally) with no interruption. General fix for any long shell command dispatched through the Agent tool that must outlive the dispatching subagent's own turn: always explicit setsid+nohup+disown, never rely on the subagent's internal run_in_background alone or on run_in_background:false at the Agent-tool-call level to guarantee synchronous blocking all the way through. ## Verification _Not recorded (migrated from buglog.json)._ ## References - Gitea: #33