You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
agent investigate loses the investigation record when stdout closes mid-run #44
With the streaming agent investigate from #39, closing the command's stdout mid-run loses the investigation record. For example, pipe cloudfall agent investigate ... into a reader that exits after the first lines. A decision the model already proposed stays on disk, but no investigation record is saved, and the command exits 0.
Before #39 the same run kept the record. The review of #39 reproduced this both on its branch and on main (#39 (comment)). The maintainer chose to merge #39 first and fix this in a follow-up (#39 (comment)).
Expected
A run cut short still leaves an investigation record, and the exit code says the run didn't finish.
Options raised in the review
When the generator is closed, it returns its record, and the record gets a new status (say stopped) in the investigation record schema. This changes stored state, so it goes through the design gate
No schema change: when the reader goes away, save the record with its current status and exit non-zero
Triage: implement, once #39 merges and the design is settled. Waits on #39 and on your decision in the next comment.
The streaming code this fixes is on #39's branch, not on main yet, so no fix can branch from main before #39 lands. The fix changes stored state (the investigation record), so it goes through the design gate. No decisions log exists yet.
@romamo Decision needed: when the reader closes stdout mid-run, how should agent investigate record the run it couldn't finish?
A new stopped status (recommended): the record is saved as stopped, and the command exits non-zero. Anyone reading why or the record can see the run was cut short. Additive schema value; agent investigate hasn't been released, so no stored record depends on the old set
No schema change: save the record with whatever status it had when the reader went away, and exit non-zero. Smaller, but the saved record may look like a run that is still going or that ended normally
Reply here with a number or your own answer; shipmill takes this up on the tick after your reply.
Triage: implement, taking up the answer above (option 1), recorded as D-3 in #51. #39 merged (8:13 UTC), so the fix branches from main.
Plan: when the stream's reader goes away (a closed stdout, or the generator closed), agent investigate saves the investigation record with a new stopped status (additive enum value in agent-investigation.schema.json) and exits non-zero. Decisions already proposed stay on disk as they are. A regression test closes the reader after the first lines and checks the saved record and the exit code.
#50 also changes investigation.py and the same schema; the same implementer builds both on separate branches.
PR: #54. When the reader closes stdout mid-run, the investigation is saved as stopped and the command exits 94 INVESTIGATION_STOPPED, with nothing more written to stdout and no traceback on stderr. Trade-offs: treaty gives a streaming handler no say in the exit code once stdout closes, so cloudfall.cli maps treaty's 0/141 to 94 through a process-wide flag; an exit-code hook in treaty would replace that. A run ended by Ctrl-C, SIGTERM or a timeout is now also saved as stopped, and keeps treaty's exit code for that case. If stdout closes exactly while the final record line is written, the record is already saved with its real status but the exit stays 0.
Correction to the PR comment above: the review of #54 found that a run stopped by Ctrl-C, SIGTERM or a timeout while it waits on the model exits with treaty's code (130 for Ctrl-C) and leaves no record. treaty closes the stream only once the handler's current step returns, and the process exits first. The PR's CHANGELOG entry now says so. Only a reader closing stdout is recorded stopped, which is what D-3 covers.
One gap the review found, filed separately: if saving the stopped record itself fails, the run still exits 0 (as it did before #54).
Activity
shipmill-romamo commentedon Oct 9, 2026
Triage: implement, once #39 merges and the design is settled. Waits on #39 and on your decision in the next comment.
The streaming code this fixes is on #39's branch, not on
mainyet, so no fix can branch frommainbefore #39 lands. The fix changes stored state (the investigation record), so it goes through the design gate. No decisions log exists yet.shipmill-romamo commentedon Oct 9, 2026
@romamo Decision needed: when the reader closes stdout mid-run, how should
agent investigaterecord the run it couldn't finish?stoppedstatus (recommended): the record is saved asstopped, and the command exits non-zero. Anyone readingwhyor the record can see the run was cut short. Additive schema value;agent investigatehasn't been released, so no stored record depends on the old setReply here with a number or your own answer; shipmill takes this up on the tick after your reply.
romamo commentedon Oct 9, 2026
1 — a new
stoppedstatus: save the record asstoppedand exit non-zero(decision by @romamo, given in chat; posted by Claude on his behalf)
shipmill-romamo commentedon Oct 9, 2026
Triage: implement, taking up the answer above (option 1), recorded as D-3 in #51. #39 merged (8:13 UTC), so the fix branches from
main.Plan: when the stream's reader goes away (a closed stdout, or the generator closed),
agent investigatesaves the investigation record with a newstoppedstatus (additive enum value inagent-investigation.schema.json) and exits non-zero. Decisions already proposed stay on disk as they are. A regression test closes the reader after the first lines and checks the saved record and the exit code.#50 also changes
investigation.pyand the same schema; the same implementer builds both on separate branches.shipmill-romamo commentedon Oct 9, 2026
PR: #54. When the reader closes stdout mid-run, the investigation is saved as
stoppedand the command exits 94INVESTIGATION_STOPPED, with nothing more written to stdout and no traceback on stderr. Trade-offs: treaty gives a streaming handler no say in the exit code once stdout closes, socloudfall.climaps treaty's 0/141 to 94 through a process-wide flag; an exit-code hook in treaty would replace that. A run ended by Ctrl-C, SIGTERM or a timeout is now also saved asstopped, and keeps treaty's exit code for that case. If stdout closes exactly while the final record line is written, the record is already saved with its real status but the exit stays 0.romamo commentedon Oct 9, 2026
Decision by @romamo, given in chat; posted by Claude on his behalf.
1. A new
stoppedstatus: the record is saved asstoppedand the command exits non-zero.shipmill-romamo commentedon Oct 9, 2026
Correction to the PR comment above: the review of #54 found that a run stopped by Ctrl-C, SIGTERM or a timeout while it waits on the model exits with treaty's code (130 for Ctrl-C) and leaves no record. treaty closes the stream only once the handler's current step returns, and the process exits first. The PR's CHANGELOG entry now says so. Only a reader closing stdout is recorded
stopped, which is what D-3 covers.One gap the review found, filed separately: if saving the stopped record itself fails, the run still exits 0 (as it did before #54).
Record a stopped investigation when its reader goes away
shipmill-romamo commentedon Oct 9, 2026
Released in v0.6.0rc9.