mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-15 01:15:29 +02:00
feat: two-phase session timeout — silent APIs die at the startup grace, named
The single spawn-armed timer charged API queue latency to the work budget: the recurring '0 turns / $0.00 / x3 attempts' failure with four budget-bump receipts (180->300s, 240->360s, 300->420s, 90->300s). Split: startup phase (no NDJSON byte yet) kills EARLY at min(grace, timeout) with the distinct exitReason 'timeout_startup' — an availability verdict, not transcript archaeology — and the work phase arms on the first byte for the REMAINING budget, so total wall never exceeds the timeout (tier envelopes are margin-free: tests pass timeout: CAPTURE_MS and bun-budget the same tier). Local grace 90s (observed queue latency 60-90s), CI floor 300s (TODOS-filed; shared runners queue harder), both pinned by the new grace tests with fake -claude shims covering the late-first-byte and silent-API paths. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
0c0077100a
commit
59acf5759e
@@ -59,7 +59,10 @@ describe('session-runner timeout kills the whole process group', () => {
|
||||
});
|
||||
const wall = Date.now() - started;
|
||||
|
||||
expect(result.exitReason).toBe('timeout');
|
||||
// The shim never prints NDJSON, so the two-phase timer kills it in the
|
||||
// STARTUP phase (grace = min(default, timeout) = 3s here) — the
|
||||
// distinct reason is the point: no byte ever arrived.
|
||||
expect(result.exitReason).toBe('timeout_startup');
|
||||
// The old bug's signature was the drain blocking long past the budget
|
||||
// (600s -> 1400s). Generous 10x bound: timeout 3s + the 5s stderr
|
||||
// grace race must return promptly once the group is dead.
|
||||
|
||||
Reference in New Issue
Block a user