Skip to content

Add a regression test for the two-tier stalled-output timeout in the CLI-subprocess driver #5196

Description

@JSONbored

Context

packages/gittensory-engine/src/miner/cli-subprocess-driver.ts's createCliSubprocessCodingAgentDriver currently wires only a single flat timeoutMs with no first-output liveness signal. A separate candidate in this same batch ('Add a two-tier stalled-output fast-fail timeout to the miner's CLI-subprocess coding-agent driver') adds an optional firstOutputTimeoutMs, mirroring src/selfhost/ai.ts's firstOutputTimer/resolveClaudeFirstOutputTimeoutMs pattern - a pattern that exists there because a naive single-timeout design caused a real production outage (#4994/#5053) against the identical claude/codex binaries. Once that lands, the new stall-detection path has no dedicated regression coverage of its own.

Dependencies

Depends on the two-tier stalled-output timeout candidate in this same batch ('Add a two-tier stalled-output fast-fail timeout to the miner's CLI-subprocess coding-agent driver') landing first - do not start until firstOutputTimeoutMs exists on CliSubprocessDriverOptions and the subprocess is actually killed and reported distinctly on stall in packages/gittensory-engine/src/miner/cli-subprocess-driver.ts.

Requirements

  1. Using the existing injected-spawn fake pattern already used for this driver's tests, add a case where the subprocess produces zero stdout past firstOutputTimeoutMs: assert it is killed early and the returned error is a distinct 'stalled' shape, not the generic full-timeout error.
  2. Add a case where the subprocess is slow but produces at least one byte of stdout before firstOutputTimeoutMs elapses: assert it is NOT killed by the first-output timer and proceeds to its normal completion/timeout path.
  3. Add a case where the subprocess produces some initial output (clearing the first-output timer) but never exits before the full timeoutMs elapses: assert the pre-existing full-timeout behavior is preserved unchanged - this is the regression guard that the new feature didn't alter the old path.
  4. Name the test cases/describe blocks so they clearly map to the ORB production-outage scenarios (fix(review): claude-code subscription-CLI hangs/times out repeatedly (4,030 Sentry events, ongoing) #4994/fix(selfhost): claude-code fast-fail timeout false-positives on --output-format json (buffered, non-streaming) #5053) this pattern exists to prevent, for future maintainers' benefit.
  5. Do not modify attempt/governor control-flow or any code outside the CLI-subprocess driver and its own test file - this PR is test-only, layered on top of the already-merged timeout feature.

Deliverables / Acceptance Criteria

Test Coverage Requirements

This PR must ship with full test coverage for every changed line and branch - the repo's Codecov patch gate requires 99%+ coverage and the house standard is to aim for 100%, including both sides of every conditional/nullish-coalescing branch introduced. Add: (1) unit tests covering both the stall-detected and stall-avoided success/failure paths described above, (2) an invariant test for 'a subprocess that has already produced at least one byte of stdout is never killed by the first-output timer' (the other side of the stall-detection conditional), and (3) this test suite IS the regression test for the #4994/#5053 outage class - ensure the case names make that traceability explicit.

Expected Outcome

The two-tier timeout behavior is locked in by a dedicated regression suite, so a future refactor of the CLI-subprocess driver cannot silently reintroduce the exact stalled-output outage class that already happened once in production.

Links & Resources

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:featureGittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.help wantedExtra attention is needed

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions