From d6f4ea9f12141d84a7689f33054a35c6b2bafc04 Mon Sep 17 00:00:00 2001 From: garrytan Date: Thu, 15 Oct 2026 00:23:34 +0000 Subject: [PATCH 1/3] fix(pregate): test stage never hangs silently; small machines record the remote gate (Lane C, GBRA-95) C1 diagnosis (gbrain 92f0ea87, a core edit selecting 3,683 local files, 358 serial; Bun 1.4.2 and 1.4.3 identical): --timeout was applied per runner spawn (unit group plus one per serial file), so the check was unbounded, and spawnSync buffered all output until it returned: 360 s with 0 bytes on stdout and stderr. A backgrounded child holding stdout made spawnSync wait the full timeout and then report exit 0 (a silent wait, then green). Not the Bun 1.4.2 spawnSync hang. C2/C-b: test-tier commands (lanes runner, guards, the --remote gate) run via lib/pregate/supervise.ts: own process group (setsid), stdout/stderr appended to a log file (no pipes), async supervision; CheckDef.run may return a promise and runPregate/withFingerprint await it (a rejection is incomplete). Leftover group members are killed after exit; SIGINT/SIGTERM to pregate SIGKILLs running groups, writes no pregate.json, exits 130/143. Windows: taskkill /T /F (reparented or detached descendants can survive; documented). C3/C-a: --timeout bounds the whole check; groups past the deadline are not started. --stall-timeout (default stall_timeout_s, else 300; 0 disables) kills a group whose log stops growing and records PREGATE_STALLED naming the last file started. Live stderr: PREGATE_TEST per file (bun test adapter; any runner for one-file runs), PREGATE_HEARTBEAT after 60 s without progress, PREGATE: tests . --json stdout unchanged. C4/C-c: under 8 cores, a base-branch remote_gate or a non-local test_backend records the local tier as a requires-remote obligation with its command (pregate.json/remote_gate or test_backend/). --remote runs the declared remote_gate now (needs --allow-repo-commands, never --policy-from head) under --spend-cap/GSTACK_SPEND_CAP_USD; it clears only on PREGATE_REMOTE: tree= tests>0 failed=0 with exit 0, and reports spent/reserved/unknown. G1: new code PREGATE_STALLED has its result-codes row, troubleshooting anchor and the installer-form error line (CODE; url#anchor). Files (G2): lib/pregate/supervise.ts (new), lib/pregate/types.ts, lib/pregate/context.ts, lib/pregate/index.ts, lib/pregate/checks/lanes.ts, lib/pregate/checks/guards.ts, lib/pregate/config.ts, lib/headless-artifacts.ts, lib/result-codes.ts, bin/gstack-pregate, bin/gstack-doctor-components.sh (generated), docs/pregate.md, docs/troubleshooting.md, test/pregate-supervise.test.ts (new), test/pregate-remote.test.ts (new). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- bin/gstack-doctor-components.sh | 1 + bin/gstack-pregate | 59 +++++++-- docs/pregate.md | 76 ++++++++++- docs/troubleshooting.md | 15 +++ lib/headless-artifacts.ts | 4 +- lib/pregate/checks/guards.ts | 29 +++-- lib/pregate/checks/lanes.ts | 119 ++++++++++++++--- lib/pregate/config.ts | 22 +++- lib/pregate/context.ts | 32 ++++- lib/pregate/index.ts | 11 +- lib/pregate/supervise.ts | 182 ++++++++++++++++++++++++++ lib/pregate/types.ts | 14 +- lib/result-codes.ts | 5 + test/pregate-remote.test.ts | 148 +++++++++++++++++++++ test/pregate-supervise.test.ts | 222 ++++++++++++++++++++++++++++++++ 15 files changed, 879 insertions(+), 60 deletions(-) create mode 100644 lib/pregate/supervise.ts create mode 100644 test/pregate-remote.test.ts create mode 100644 test/pregate-supervise.test.ts diff --git a/bin/gstack-doctor-components.sh b/bin/gstack-doctor-components.sh index 181410d40..da3a86c6b 100644 --- a/bin/gstack-doctor-components.sh +++ b/bin/gstack-doctor-components.sh @@ -159,6 +159,7 @@ gstack_result_anchor() { PREGATE_NO_LANE) printf '%s' 'pregate-no-lane' ;; PREGATE_LANE_FAILED) printf '%s' 'pregate-lane-failed' ;; PREGATE_INCOMPLETE) printf '%s' 'pregate-incomplete' ;; + PREGATE_STALLED) printf '%s' 'pregate-stalled' ;; PREGATE_STALE) printf '%s' 'pregate-stale' ;; PREGATE_REMOTE_UNCLEARED) printf '%s' 'pregate-remote-uncleared' ;; ISSUE_UNREADABLE) printf '%s' 'issue-unreadable' ;; diff --git a/bin/gstack-pregate b/bin/gstack-pregate index 3f1272690..f377afa3a 100755 --- a/bin/gstack-pregate +++ b/bin/gstack-pregate @@ -4,7 +4,7 @@ * * gstack-pregate [run] [--stage preflight|tests|all] [--only ] [--base ] * [--allow-repo-commands] [--policy-from base|head] [--out ] - * [--timeout ] [--run ] [--explain] [--json] + * [--timeout ] [--stall-timeout ] [--remote --spend-cap ] [--run ] [--explain] [--json] * gstack-pregate verify [--out ] [--json] publication check: current tree, no fail/incomplete, obligations cleared * gstack-pregate clear --remote --run-url | --bundle-lane