Repository navigation
Stop orphaned commands, fix relative paths on macOS, and close IPC/hook gaps - #125
Open
parth-lyzr wants to merge 3 commits into
Open
parth-lyzr wants to merge 3 commits into
parth-lyzr wants to merge 3 commits into
Conversation
added 3 commits
October 28, 2026 18:17
- IPC: turn_end usage and session_end costs come from core's run report, which includes sub-agent model calls (their events are disabled, so the streamed model_text totals left them out). Requests add the report's subagent_turns; a turn without a report (aborted, errored) falls back to the streamed calls. Teardown usage is counted the same way. - IPC: a resumable session (resume: true) takes an exclusive advisory lock on .gitagent/sessions/<id>/lock for the process's life. A second process opening the same sessionId gets system/error + session_end and exits 2 instead of loading and later overwriting the other's conversation. - Loader: a hook marked compliance: true or fail_open: false that cannot be loaded (missing or escaping script, bad timeout, unknown event) now fails loading, so the run refuses to start. A compliance hook may not set fail_open: true. Ordinary hooks keep warn-and-skip.
…rker cwd - Terminal: on macOS the end marker line can end in \r\n, so the parsed cwd kept a trailing \r and relative read_file/apply_patch paths failed. The marker line is now trimmed of \r before parsing. - Terminal: Session::kill (end of run, --timeout-s, IPC abort/kill/closed stdin, Terminal drop) only hung up the shell. Job control puts the running command and each background job in its own process group, so they survived with ppid 1. kill now sends SIGTERM (and SIGCONT) to every process group in the shell's session, waits up to 1 s, then SIGKILLs what is left, the shell included. Groups are listed from /proc on Linux (by session id) and with `ps -t <pty>` on macOS, plus the foreground group and the shell's own group. - Terminal: a finished background session and the "did not stop on Ctrl-C" fallback only hang up (SIGTERM/SIGKILL to the foreground command, SIGHUP to the shell), so `nohup` servers started there keep running as before. --linger is unchanged: it never calls kill. - IPC: SIGTERM/SIGINT now drop the session (and its shells) before exiting with 128+signal, instead of dying with the commands still running.
The shell passes its SIGHUP on to every job, and nohup ignores SIGHUP only once it runs. A background session whose last command was 'nohup server &' was hung up the moment its end marker arrived, so the SIGHUP reached the job while it was still being forked and killed it. hang_up now waits 200 ms first when the shell has jobs (stop::let_jobs_start), so nohup and disowned jobs survive; plain jobs still die with the shell. kill/drop are unchanged.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Live runs of v3 showed five harness bugs. Each one reproduced with two different models, so they come from the harness, not the model. This PR fixes all five. Each fix has a regression test.
Fixes
read_file/apply_patchfail after any shell command (cannot read calc.py). The cwd from the end marker kept a trailing\r(.../pytest\r/calc.py).crates/terminal/src/buffer.rs: trim\rfrom the marker line before parsing it.abort()and--timeout-sall left the running command alive with ppid 1.kill()sent SIGHUP to bash only, and with job control on the command is in its own process group.crates/terminal/src/stop.rs: SIGTERM, then SIGKILL after up to 1 s, to every process group in the shell's session. Groups come from/procon Linux andps -t <pty>on macOS.--ipcnow handles SIGTERM/SIGINT (exit 143/130) instead of dying without cleanup.turn_end.usage/session_end.costsleft out sub-agent spend: it summed only the parent's streamed calls.crates/cli/src/ipc.rs: build usage from core'sRunReport.usage, which already includes children.requestsaddssubagent_turns.resumesessionId both ran, and the last save silently replaced the other conversation.ipc.rs: exclusiveflockon.gitagent/sessions/<id>/lock, taken beforeready. The second opener getssystem/errorand exits 2.fail_open: falsehook that could not load (for example, a missing script) was skipped with a warning, so the command it should block ran.crates/loader/src/agent_hooks.rs:loadreturns an error for these hooks, so the run refuses to start. A compliance hook can no longer setfail_open: true. Ordinary hooks still warn and get skipped.The new tests also exposed an older race. When a finished background session is hung up, bash's SIGHUP could reach a
nohupjob beforenohuphad set SIGHUP to ignore, killing the server.hang_up()now waits up to 200 ms first, but only if the session still has other process groups (stop.rslet_jobs_start).Effect on
--bench--ipcconflicts with--bench, and the bench profile has no hooks.bench_prompt_and_tools_match_the_published_runpasses.\rtrim and the terminal stop changes.--lingeris unchanged: it never callskill(), so lingering servers survive.Testing
cargo test --workspace: 366 passed, 0 failed.cargo clippyon the touched crates: no warnings.openai:gpt-6-lunaagainst this branch, all passing:cannot readerrors and no\rin paths;psafterwards;nohupserver: reachable with curl, then cleaned up at the end;--lingerserver: still reachable afterrun_end./procprocess-group lookup compiles, and its parse test passes on macOS. It has not been run on Linux.