Skip to content

Harness driver waits for its child; adoption stops when nothing is pending; SDK calls time out - #9

Merged
navbytes merged 1 commit into
mainfrom
fix/hang-brief-followups
Sep 6, 2026
Merged

navbytes merged 1 commit into
mainfrom
fix/hang-brief-followups

Conversation

@navbytes

@navbytes navbytes commented Sep 6, 2026

Copy link
Copy Markdown
Owner

Follow-ups from the roost hang investigation, written up in docs/2026-09-06-roost-hang-report.md (answers docs/2026-09-06-roost-hang-brief.md). Short version: the 2026-09-04 wedges were the pty driver exiting on its --timeout with roost still running under the closed pty master; H1/H2/H3 on the plugin side were measured and cleared.

Changes

  • harness/pty-run.py never leaves its child behind. On timeout or --exit-when-done it SIGTERMs the child's process group, keeps draining for up to 3 s, SIGKILLs, reaps, and prints a timestamped stop line with the exit status. A pyte failure in the final snapshot no longer skips the capture files. (killpg on an exited, unreaped child raises EPERM on macOS, handled.)
  • Adoption stops when nothing is pending. adoptNativeForks returns { adopted, adoptables }; retryAdopt stops on a genuine zero as well as on success, so the sibling loop of every fork batch no longer polls three times for nothing. A pass that threw reports -1, so a transient session.list failure still retries.
  • 15 s timeout on SDK calls in the server half, the TUI entry point (session.list) and the transcript fetcher, via AbortSignal.timeout. A failed transcript fetch returns the deleted sentinel so the route retries instead of caching an empty transcript. src/tui/actions.ts is left untimed on purpose (session.prompt runs for a whole turn).
  • USAGE: /ctree subcommands queue behind a running turn; /tree opens from the local journal.

Verification

  • bun run typecheck clean; bun test 275 pass; bun run build clean.
  • python3 harness/pty-run.py --timeout 2 -- sh -c 'trap "" HUP; sleep 100' returns in ~2 s with the grandchild gone.
  • CTREE_E2E=1 bun test test/e2e: 16 pass.
  • Reviewed; the review's blocking finding (a failed pass stopping the retry loop) is fixed and covered by a unit test.

…nding; SDK calls time out

Follow-ups from docs/2026-09-06-roost-hang-report.md, which answers the roost
hang brief: the 2026-09-04 wedges were the pty driver exiting on its --timeout
with roost still alive under the closed pty master, not the plugin.

- harness/pty-run.py: on timeout or exit-when-done, SIGTERM the child's process
  group, keep draining for up to 3 s, SIGKILL, reap, and print a timestamped stop
  line with the exit status. A pyte failure in the final snapshot no longer skips
  the capture files. macOS reports killpg on an exited, unreaped child as EPERM.
- adoptNativeForks reports how many adoptable sessions a pass found; retryAdopt
  stops on a genuine zero as well as on success, so the sibling loop of a fork
  batch no longer polls three times for nothing. A pass that threw reports -1 so
  a transient session.list failure still retries.
- Every SDK call in the server half, the TUI entry point and the transcript
  fetcher carries a 15 s AbortSignal.timeout. A failed transcript fetch returns
  the "deleted" sentinel so the route retries instead of caching an empty one.
- USAGE: /ctree subcommands queue behind a running turn; /tree opens from the
  local journal.
@navbytes
navbytes merged commit c64fe07 into main Sep 6, 2026
1 check passed
@navbytes
navbytes deleted the fix/hang-brief-followups branch September 6, 2026 22:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant