Skip to content

agent investigate exits 0 when saving a stopped investigation fails #56

Closed

Description

@shipmill-romamo

What happens

Found in the review of #54 (#44). When agent investigate streams and the reader closes stdout mid-run, the run saves the investigation as stopped and exits 94 INVESTIGATION_STOPPED. If that save fails (repro: make investigations/ a file instead of a folder, then close the reader after the first line), treaty prints a traceback on stderr and the command exits 0. The stream_stopped flag is never set because the save raised first.

That breaks D-3 (docs/decisions.md): a run that couldn't finish must exit non-zero. Before #54 the same case also exited 0, so this isn't a regression.

Expected

A failed save of the stopped record exits non-zero with no traceback, probably with the code the repo already uses when the investigation store can't be written. Code: sdk/src/cloudfall/app.py, the GeneratorExit handler in agent_investigate.

Activity

  1. shipmill-romamo commented on Oct 9, 2026

    @shipmill-romamo
    ContributorAuthor

    Triage: implement, once the exit code is settled. Waits on your decision in the next comment.

    Confirmed on main (after #54): InvestigationStore.save (sdk/src/cloudfall/investigation.py) lets an OSError from the write escape unwrapped, so it isn't only the stopped path: any run whose record can't be written ends in treaty's HANDLER_CRASHED traceback. In the stopped path the crash happens before stream_stopped is set, so the exit stays 0, which breaks D-3. A fix wraps the write error in the store and maps it in agent_investigate, which needs an exit code (a contract).

  2. shipmill-romamo commented on Oct 9, 2026

    @shipmill-romamo
    ContributorAuthor

    @romamo Decision needed: what should agent investigate exit with when it can't write the investigation record?

    1. PRECONDITION, with the store's error naming the folder (recommended): the store's folder isn't writable, the same kind of refusal the repo already gives for a bad --decisions folder; for a stopped run, the record is lost but the exit is non-zero, as D-3 asks
    2. A new exit code (say 95 RECORD_UNWRITABLE): a script can tell "couldn't save" apart from other preconditions, at the cost of one more code to document
    3. Keep the stopped run's 94 even when its save fails, and use 1 for the rest

    Reply here with a number or your own answer; shipmill takes this up on the tick after your reply.

  3. romamo commented on Oct 9, 2026

    @romamo
    Collaborator

    1 — exit PRECONDITION, with the store's error naming the folder

    (decision by @romamo, given in chat; posted by Claude on his behalf)

  4. shipmill-romamo commented on Oct 9, 2026

    @shipmill-romamo
    ContributorAuthor

    Triage: implement, with the answer above (option 1), recorded as D-5 in #59.

    Design:

    • InvestigationStore.save (sdk/src/cloudfall/investigation.py) wraps an OSError from the write in the store's own error, naming the investigations folder
    • agent_investigate (sdk/src/cloudfall/app.py) maps that error to PRECONDITION, with no traceback, on every path that saves: the normal end, the GeneratorExit (stopped) path, and any other save
    • A stopped run whose save fails exits PRECONDITION instead of 0; its record is lost, as the answer accepts

    A PR follows.

  5. removed
    needs-decisionA shipmill session asked a question here; waits for a reply
    on Oct 9, 2026
  6. shipmill-romamo commented on Oct 9, 2026

    @shipmill-romamo
    ContributorAuthor

    PR: #61. InvestigationStore.save raises InvestigationError (agent_investigations_unwritable, naming the folder) when it can't create the folder or write the record, and agent investigate exits 4 PRECONDITION with no traceback. On the stopped path, treaty would print a raised error as a traceback and exit 0, so the handler keeps the error and cloudfall.cli writes it to stderr as one JSON line and exits 4. Trade-off: that stopped run's record is lost, as D-5 accepts.

  7. added a commit that references this issue on Oct 9, 2026
  8. shipmill-romamo commented on Oct 9, 2026

    @shipmill-romamo
    ContributorAuthor

    Released in v0.6.0rc10.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions