Skip to content

ci: a combined suite times out after the chat-focus runtime cases #995

Open

Description

@schlessera

Context

Found during #544 verification in draft #993 (main f2000d008a653deea4e6dade68348875a697260d plus scoped commit 9b36b7ed15bab355b4bec8ab7a2d5806e4ff8269). On Linux/non-root with Bun 1.3.14, a full local bun run test with the installed Chrome selected, keyless fixtures and the repository network guard passed all 16 scratch-link runtime cases and all seven mounted public chat decision focus cases, then printed:

(fail) (unnamed) [30000.47ms]
  ^ a beforeEach/afterEach hook timed out for this test.

The final local receipt (2026-10-04) was exit 1: 9,712 pass / 28 skip / that one unnamed hook timeout, 56,794 assertions, 9,741 tests across 618 files, 1,073.97 seconds. A paired control of the two runtime files alone passed 23 / 0 / 167 assertions in 106.86 seconds, and the sharded CI run of the same head passed. Neither control reproduces or explains the full-order occurrence. The log did not identify which await was blocked.

A possible shared cause is recorded but not established: #1043 traced a similar hang to oven-sh/bun#33828, a Bun 1.3.14 double close of extra-stdio fds that Playwright's Chrome launch exercises. That bug is fixed in Bun 1.4.0. The test-guard retention workaround from #1056 has since been removed: #1059 / #1195 moved CI to Bun 1.4.2, the suite requires Bun >=1.4.0 (The test suite requires Bun >=1.4.0, docs/process/testing.md:25-27), and the regression probe exercises guarded and native transports with no retention workaround (tests/extra-stdio-retention.test.ts:1-5). The earlier "disable retainExtraStdio" experiment therefore no longer exists to run.

The chat-focus fixture now records named phases, including its teardown (afterAll, packages/ui-react/tests/chat-focus-runtime.test.ts:89-95, via runtimeHookPhases at line 31), so a recurrence names the blocked stage instead of (unnamed).

Maintainer disposition (2026-10-07): there is no chat-focus failure in CI; an agent can run the discriminating full run; a clean full run on current main lets this close.

Scope

A bounded current-runtime termination audit:

  1. On current main, with a supported Bun (>=1.4.0; the CI pin is 1.4.2), frozen dependencies, real Chrome, keyless isolated roots and the network guard, run the full repository bun run test in its default order, once.
  2. If it exits cleanly with the chat-focus cleanup phase completing, post the receipt and close.
  3. If any hook timeout or non-termination occurs, record the phase diagnostics that name the blocked stage, the owned resources and child/process state still alive at that point, and the ordering of preceding runtime files. Then either file a scoped repair issue for the identified stage, or record the exact remaining reproduction conditions here.

Out of scope

No speculative app/server/browser lifecycle change, larger timeout, retries counted as repair evidence, skipped runtime coverage, real provider/network access, or a test on Bun 1.3.x (unsupported). Establishing whether the historical Bun 1.3.14 occurrence was caused by oven-sh/bun#33828 is not required and must not be claimed from a clean current run.

Acceptance criteria

  • One full bun run test on a named current-main SHA and supported Bun version is recorded with its exact command, Bun and Chrome versions, total pass/skip/fail counts, wall time and exit code.
  • Closing condition: that run exits 0 and the chat-focus cleanup phase completes. The closing comment states that this is consistent with, but does not prove, the Bun fd cause.
  • Otherwise: the comment names the blocked phase from the fixture's phase diagnostics, lists the resources and processes still owned at that point, and either links a newly filed scoped repair issue or states the precise conditions still needed to reproduce. The issue then stays open with needs: repro.
  • All seven chat-focus behavior assertions, the runtime fixtures and current deadlines are unchanged.

Verification

Use the repository test script with frozen dependencies, real Chrome, keyless roots and the existing network guard. Record sanitized executable and runtime identity only; provider values and deployment details do not belong here.

Contract impact

None. This is a verification audit. A later product change assesses its own contract impact after a cause is demonstrated.

2026-10-24: rewrote around a bounded current-runtime termination audit per the 2026-10-07 maintainer disposition; the Bun 1.3.14 retention-disable experiment is obsolete because the workaround was removed with the Bun 1.4.2 migration; refreshed the teardown citation; moved under the browser-verification epic. Earlier triage history is in the comments.

Activity

  1. added
    type: spikeTime-boxed investigation. The deliverable is a written decision, not code.
    area: ui-reactReact chat/files/voice components, stores, WebSocket transport.
    area: ciCI workflows, the gates they run, release scripts, packaging.
    needs: reproBlocked on a reproduction.
    on Oct 4, 2026
  2. added
    priority: p2Wanted, not scheduled. Pulled in when a milestone has room.
    on Oct 5, 2026
  3. schlessera commented on Oct 5, 2026

    @schlessera
    OwnerAuthor

    2026-10-05 triage at main 33af7e2972873286144dbcc93c232c904e3ced47: added priority: p2. This is a red local full-suite result: it is wanted, but no release is waiting on it. The attachment to #736 is verified and kept. The afterAll teardown anchor (packages/ui-react/tests/chat-focus-runtime.test.ts:82-88) still matches. needs: repro stays because no controlled failing run has located the blocked hook. No rerun was performed in this pass.

  4. schlessera commented on Oct 6, 2026

    @schlessera
    OwnerAuthor

    Possible shared cause, not proven: #1043 traced its hang to a Bun 1.3.14 bug, oven-sh/bun#33828, which is fixed in Bun 1.4.0. When a node:child_process child is spawned with an extra stdio pipe, collecting that Subprocess closes the extra fd a second time. Playwright launches Chrome this way. In #1043, a later collection in the same bun test process closed the pidfd and pipes of another child, so that child's exit was never observed.

    The same mechanism would explain this timeout. An earlier in-process Playwright launch (here scratch-links-runtime.test.ts) could leave a stale fd that later closes the pidfd of chat-focus's own Chrome, and browser.close() in afterAll would then wait for an exit it never sees.

    PR #1056 retains these subprocesses in the test guard on Bun older than 1.4.0. No run of this issue's combined suite has been made with that fix, so this issue stays open, and its needs: repro label still applies.

  5. schlessera commented on Oct 6, 2026

    @schlessera
    OwnerAuthor

    Triage 2026-10-07: local full-suite only; an agent can run the two discriminating runs listed in Scope. There is no chat-focus failure in CI. The (unnamed) 180000ms hook timeout in Depot dx4jt1b010 (10-04) was external-speech (#1043). Those timeouts stopped after #1056 merged (2026-10-06 06:09; the last was 10-06 00:10 on d36cca7c), which supports the Bun fd candidate cause. Next: one full run at current main (which includes #1056), and, if it fails, one with retainExtraStdio (scripts/test-network-guard.ts:24) disabled. Each takes about 18 minutes. A clean run on current main lets this close and fold into #1059. Replaced needs: repro with agent-ready (maintainer, 2026-10-07).

  6. added
    agent-readyContext and acceptance criteria are complete enough for an agent to take this unattended.
    and removed
    needs: reproBlocked on a reproduction.
    on Oct 6, 2026
  7. schlessera commented on Oct 24, 2026

    @schlessera
    OwnerAuthor

    Body history preserved from the pre-2026-10-24 specification. The body now specifies a bounded current-runtime termination audit; the experiment below is obsolete because the retainExtraStdio workaround was removed with the Bun 1.4.2 migration (#1059 / #1195).

    Final local receipt — 2026-10-04: the same combined run completes with exit 1, 9,712 pass / 28 skip / one unnamed hook timeout, 56,794 assertions, 9,741 tests across 618 files, 1,073.97 seconds. The timeout above is its sole failure. Current-head #993 Depot CI separately passes all 12 jobs, including all three unit shards (9,715 pass / 45 skip / zero failures), and the exact-head contract gate. Those sharded passes and the paired 23-case control do not explain the differently ordered full-process local cleanup occurrence. Retain needs: repro, preserve deadlines and keep this finding open independently of the scratch-link repair.

    2026-10-06 triage at main 825cd044: folded in the possible shared cause from the 2026-10-06 comment, which is not proven. #1043 traced its hang to oven-sh/bun#33828, a Bun 1.3.14 double close of extra stdio fds. That bug is fixed in Bun 1.4.0 (merge b3303995, contained in bun-v1.4.0). PR #1056 (9936c675) now keeps those subprocesses reachable in the test guard on Bun below 1.4.0. #1059 tracks moving the CI pins to 1.4.x. A discriminating reproduction would complete needs: repro:

    1. Rerun the recorded combined local bun run test ordering on Bun 1.3.14 at a main that includes 9936c675. A clean exit is consistent with the shared cause but does not prove it.
    2. Run the same ordering with the retainExtraStdio early return forced, so the workaround is disabled, and capture where afterAll (packages/ui-react/tests/chat-focus-runtime.test.ts:82-88) blocks. A browser.close() waiting on a Chrome child that is already <defunct> would attribute the hook timeout to the same mechanism.

    No such run was made in this pass. needs: repro stays.

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

    agent-readyContext and acceptance criteria are complete enough for an agent to take this unattended.area: ciCI workflows, the gates they run, release scripts, packaging.area: ui-reactReact chat/files/voice components, stores, WebSocket transport.priority: p2Wanted, not scheduled. Pulled in when a milestone has room.type: spikeTime-boxed investigation. The deliverable is a written decision, not code.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions