diff --git a/CHANGELOG.md b/CHANGELOG.md index db5a7758b..487e88439 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,50 @@ # Changelog +## [1.91.105.0] - 2026-10-16 + +**The free suite stops needing its retry pass. +The health report tells the truth.** + +Six of 46 main runs last week needed the free suite's serial retry pass to go green. Five test files caused it, and three shared one cause: since git 2.29, every `git commit` starts a background `git maintenance run` that creates and deletes `.git/objects/maintenance.lock` after the commit has returned, so a test that lists, watches or deletes `.git` right afterwards sees a file that is there one moment and gone the next. Those fixtures now turn auto-maintenance off, and the free runner does it for every test child as a backstop. The other two flakes were a fixed-count poll and a smoke test that called live GitHub. `gstack-timeline-read` now refuses filters it cannot apply instead of returning everything. + +### The numbers that matter + +Measured with the repo's own reproducer (`scripts/ship-measure.ts free`, flaky retry off), before on 47d639a and after on this branch. Commands and per-file counts are in the PR body. + +| Measurement | Before | After | +|---|---|---| +| The five ledger files, 16-vCPU Ubicloud VM (`bun run test:ubicloud --diagnostic`) | 197/200 reruns clean | 600/600 | +| The three git fixtures under commit load, local runner env | 37/200 clean | 200/200 | +| Next-version smoke test, live GitHub calls | one `gh api` per open PR, one after another (27 PRs at 1.2 s: 32.6 s, past its 30 s limit) | none (runs in about 60 ms) | +| Weekly health: unseeded free test files | 164 (enforced check failing) | 0 | +| Weekly health: Windows wall population | dispatch recordings on main ("n/a (0 runs)" on Oct 12) | 78 successful PR runs, 9.2 min p50 (7 days to 2026-10-15) | + +The headline number is the first row: three of 200 clean-tree reruns failed before, none of 600 after. + +### What this means for you + +When the free suite goes red now, it is far more likely to be your change. Read the failure, not the retry ledger. + +### Itemized changes + +#### Fixed + +- **If you run `gstack-timeline-read --since` or `--branch` without a value,** you get exit 2 and `--since must be a relative time like "7 days ago" (got no value); accepted: ...` (or `--branch must be a branch name (got flag '--limit')`) instead of a crash. +- **If you pass `--since yesterday` or `--since "2 weeks"`,** you get exit 2 naming what it got, instead of your whole unfiltered history. Accepted forms: `7 days ago` (minute, hour, day, week, month), `7d` / `24h` / `2w`, and ISO dates `2026-10-01` or `2026-10-01T10:00:00Z`. +- **If you pass an argument `gstack-timeline-read` does not know,** it exits 2 with the usage line instead of ignoring it. `--help` prints the usage line. + +#### Changed + +- **If you read the weekly test-health report,** "Free-suite and Windows wall" now measures successful Windows runs on pull requests, says so (`windows-free-tests (successful PR runs) 9.2 min (78 runs)`), and prints `no successful PR runs in window` when there are none. It used to average the dispatch-only duration recordings on main. +- **If the health report says the duration seed is stale,** its fix line now names what the refresh needs (`UBICLOUD_API_KEY`, then `bun run test:ubicloud --record-durations`, which copies the seed back into your checkout) and tells contributors without the key to leave it to a maintainer. It no longer offers a CI recording, which does not exist. + +#### For contributors + +- The free runner appends `maintenance.auto=false` and `gc.auto=0` to every shard child's `GIT_CONFIG_*` pairs (`test/test-free-shards-git-maintenance.test.ts`). Fixtures that build their own git environment set the keys themselves; `docs/TESTING_INTERNALS.md#flake-ledger` has the rule and a recipe for reproducing a ledger entry from a CI run's `free-plan` artifact. +- The zombie publication-lock test synchronizes on a PID line its Python parent prints after `os.waitid(..., WNOWAIT)`, and the next-version smoke test runs the real CLI against a fake `gh` that logs and checks every call. +- `scripts/free-test-durations.json` is refreshed from a Ubicloud recording of this tree. +- No community contributions in this release. + ## [1.91.101.0] - 2026-10-13 **The field wave's residual gaps are closed.** v1.91.96.0 through v1.91.100.0 shipped the install-honesty and unattended-`/autoplan` wave (`docs/designs/GSTACK_FIELD_WAVE_2026_10_12.md`); running that release on a Capy machine left six gaps, each reproduced here with a test that failed first. diff --git a/TODOS.md b/TODOS.md index 9c7c45583..e8ab35a1b 100644 --- a/TODOS.md +++ b/TODOS.md @@ -88,9 +88,6 @@ Left open by the office-hours tier fix (#2801, #879, #1049, #1958, #1723, #1651 follows the carried `SESSION_TIER` through Phase 6 (first run gets the introduction, second run asks about the earlier assignment). No office-hours quality judge exists either. **Effort:** M. **Priority:** P2. -- **`gstack-timeline-read --since`/`--branch` without a value** — both still - read an unbound `$2` under `set -u` and crash with exit 1, the class #1723 - fixed for `--limit`. **Effort:** S. **Priority:** P3. ### P3: Oct 8 fix wave, safety hooks follow-ups (filed 2026-10-08) @@ -5394,3 +5391,65 @@ skills were told is fenced. Guard both writes. Effort S. **Priority:** P3. **Depends on:** none. + +### P1–P2: fix wave 2 follow-ups (filed 2026-10-15) + +From the free-suite health wave (flaky-pass fixes, #3154 seed refresh). Owner +Garry for each; revisit 2026-10-29 unless a date says otherwise. + +- **`gstack-next-version` fetches claimed slots one PR at a time** — + `GH_API_CONCURRENCY = 10` (bin/gstack-next-version:90), but its async workers + call `spawnSync`, so the per-PR `gh api` calls run serially: 8 stubbed PRs at + 0.5 s each took 4160 ms instead of about 500 ms (4108 ms on a rerun), and 27 + open PRs at about 1.2 s each pass the 30 s that callers allow, which is how the + old live smoke test failed. Every `/ship` slot allocation pays this. Fix: + async spawn with bounded overlap, verified by a delayed fake `gh`. Changing the + CLI selects 108 paid cases and 24 judges, so it ships as its own priced PR on + Garry's call. **Effort:** S. **Priority:** P1. +- **Standing Linux duration-seed recorder** — the seed refresh in this wave + keeps CEO-10 green for days, not weeks: main gains about 15 free test files a + day against a limit of 5 unseeded, so the weekly health run goes red again + until a recorder lands. Design: a scheduled `free-durations-record.yml` that + records on the standard runner and updates one seed PR before the Monday + health run, or the `free-plan` job consuming the latest recording artifact once + #3190 (owner of `free-tests.yml`) lands. Agree the design with the owner of + `free-tests.yml` before 2026-10-29. **Effort:** M. **Priority:** P1. +- **PR full-fallback and recorded spend (audit next step)** — 2026-10-15: + full-fallback 45.9% of PR runs, $73.52 recorded PR-lane spend per merged PR, + push-to-verdict p50 11.4 min (target 3–5 min). The pre-change spend baseline + was never recorded, so the 50% reduction verdict is unavailable + (docs/test-audit-2026-10.md, "Post-merge follow-up"). Next step, from the + audit's selection replay: touchfile mappings for `bin/`, `lib/`, `hosts/` and + `make-pdf/`, so a branch touching them stops selecting every case. Candidate + headline for the next wave. **Effort:** M. **Priority:** P1. +- **Free flaky-pass target follow-ups (2026-10-22 and 2026-10-29)** — read + main's `flake-ledger-*` artifacts (`bun run test:health --since-days 7`) and + check the free-suite flaky-pass rate is under 5% of main runs; a file still in + the ledger gets a named cause or a new entry here. **Effort:** S. **Priority:** P1. +- **`createQAFunctionalFixture` sets git auto-maintenance off itself** — its + repos inherit the free runner's backstop keys in CI, but a direct `bun test` + run still races `.git/objects/maintenance.lock` during observer setup. + The helper selects 22 paid cases, so this is a priced follow-up. + **Effort:** S. **Priority:** P2. +- **`test:ubicloud --diagnostic` cannot give clean counts for two ledger + shards** — `ship-measure free` reruns set a private `HOME` under `/tmp` and + `GSTACK_STATE_ROOT`, so `browse/test/path-validation.test.ts` (its upload + fixture builds an "outside" directory under `os.userInfo().homedir`, which + Bun takes from `HOME`) and `browse/test/pair-agent-tunnel-eval.test.ts` (its + denial log follows the inherited state root, not its fake `HOME`) fail 30/30 + in diagnostic mode while passing in the normal suite. Ledger shards that hold + them can never report `passed = n`. **Effort:** S. **Priority:** P2. +- **`test/plan-seed-submission.test.ts` reads its fake CLI's events after a + fixed 50 ms sleep** — "actual PTY launcher carries placeholder styling into + owned seed submission: xterm-256color" sends `/plan-eng-review\r`, sleeps + 50 ms and expects the `slash` event already in `events.jsonl`; under the + 16-worker duration recording on 2026-10-15 the event had not landed + (`['paste', 'enter', 'end_turn']`). Wait for the CLI's own write instead of a + timer (docs/TESTING_INTERNALS.md#flake-ledger). **Effort:** S. **Priority:** P2. +- **Split the free files the 2026-10-15 seed put over 60 s** — + `test/setup-install-registry.test.ts` (82 s), `test/host-renders-prune.test.ts` + (64 s) and `test/setup-codex-scope.test.ts` (60.4 s) are allowlisted with this + todo in `scripts/free-test-seed-allowlist.json`; `test/brain-sync.test.ts` + (57 s) and `test/setup-codex-scope-namespaces.test.ts` (57 s) are next. Split + each by describe block, rerun `bun run test:ubicloud --record-durations` and + delete the entries. **Effort:** S each. **Priority:** P2. diff --git a/VERSION b/VERSION index c658a42e6..852dfdc70 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.91.101.0 +1.91.105.0 diff --git a/agents-digest/gstack-AGENTS.md b/agents-digest/gstack-AGENTS.md index e4c2e7105..2e819d448 100644 --- a/agents-digest/gstack-AGENTS.md +++ b/agents-digest/gstack-AGENTS.md @@ -1,4 +1,4 @@ -# gstack digest v1.91.101.0 — regenerate/re-copy after upgrading gstack +# gstack digest v1.91.105.0 — regenerate/re-copy after upgrading gstack Behavioral rules from gstack (https://github.com/garrytan/gstack), compressed for agent hosts without a full skill install. The full skills add workflows, diff --git a/bin/gstack-timeline-read b/bin/gstack-timeline-read index e1edb9179..9a3133136 100755 --- a/bin/gstack-timeline-read +++ b/bin/gstack-timeline-read @@ -1,26 +1,78 @@ #!/usr/bin/env bash # gstack-timeline-read — read and format project timeline -# Usage: gstack-timeline-read [--since "7 days ago"] [--limit N] [--branch NAME] +# Usage: gstack-timeline-read [--since "7 days ago"|7d|YYYY-MM-DD] [--limit N] [--branch NAME] # # Session timeline: local-only, never sent anywhere. # Reads ~/.gstack/projects/$SLUG/timeline.jsonl, filters, formats. # Exit 0 silently if no timeline file exists or nothing matches. Missing bun # exits 127 and a failed read exits non-zero with its stderr (#2790). A missing -# or non-positive-integer --limit exits 2 before any read (#1723). +# or non-positive-integer --limit, a missing or unparseable --since, a missing +# --branch, or an unknown argument exits 2 before any read (#1723); --help +# prints the usage line and exits 0. set -euo pipefail +USAGE='Usage: gstack-timeline-read [--since "7 days ago"|7d|YYYY-MM-DD] [--limit N] [--branch NAME]' +SINCE_FORMS='accepted: " minute|hour|day|week|month[s] ago", "h|d|w", or an ISO date YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ' SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" eval "$("$SCRIPT_DIR/gstack-slug" 2>/dev/null)" . "$(dirname "$0")/gstack-state-root.sh" 2>/dev/null || { echo "$0: cannot resolve the gstack state root: $(dirname "$0")/gstack-state-root.sh is missing. fix: reinstall with ./setup or /gstack-upgrade (docs/state-root.md)" >&2; exit 1; } gstack_state_root_select GSTACK_HOME="$_gstack_sr_root" -SINCE="" +SINCE_MS=0 LIMIT=20 BRANCH="" +missing_value() { # remaining-arg-count next-arg -> why the flag has no usable value, or nothing + if [[ $1 -lt 2 ]]; then echo "got no value" + elif [[ -z "$2" ]]; then echo "got an empty value" + elif [[ "$2" == --* ]]; then echo "got flag '$2'" + fi + return 0 +} + +days_from_civil() { # year month day (UTC) -> days since 1970-01-01 + local y=$((10#$1)) m=$((10#$2)) d=$((10#$3)) + [[ $m -le 2 ]] && y=$((y - 1)) + local era=$((y / 400)) yoe doy mp + yoe=$((y - era * 400)); mp=$(((m + 9) % 12)); doy=$(((153 * mp + 2) / 5 + d - 1)) + echo $((era * 146097 + yoe * 365 + yoe / 4 - yoe / 100 + doy - 719468)) +} + +since_cutoff_ms() { # one --since value -> cutoff epoch ms, or nothing when unparseable + local now n unit seconds lower + now=$(date -u +%s) + lower=$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]') + if [[ "$lower" =~ ^([1-9][0-9]{0,5})[[:space:]]*(minute|hour|day|week|month)s?[[:space:]]+ago$ ]]; then + n=${BASH_REMATCH[1]}; unit=${BASH_REMATCH[2]} + elif [[ "$lower" =~ ^([1-9][0-9]{0,5})([hdw])$ ]]; then + n=${BASH_REMATCH[1]} + case ${BASH_REMATCH[2]} in h) unit=hour ;; d) unit=day ;; w) unit=week ;; esac + elif [[ "$1" =~ ^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])Z)?$ ]]; then + seconds=$(( $(days_from_civil "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}") * 86400 )) + [[ -n "${BASH_REMATCH[4]}" ]] && seconds=$((seconds + 10#${BASH_REMATCH[5]} * 3600 + 10#${BASH_REMATCH[6]} * 60 + 10#${BASH_REMATCH[7]})) + echo $((seconds * 1000)); return 0 + else + return 0 + fi + case $unit in minute) seconds=60 ;; hour) seconds=3600 ;; day) seconds=86400 ;; week) seconds=604800 ;; month) seconds=2592000 ;; esac + echo $(((now - n * seconds) * 1000)) +} + while [[ $# -gt 0 ]]; do case "$1" in - --since) SINCE="$2"; shift 2 ;; + --help|-h) echo "$USAGE"; exit 0 ;; + --since) + problem=$(missing_value $# "${2-}") + if [[ -n "$problem" ]]; then + echo "gstack-timeline-read: --since must be a relative time like \"7 days ago\" ($problem); $SINCE_FORMS" >&2 + exit 2 + fi + SINCE_MS=$(since_cutoff_ms "$2") + if [[ -z "$SINCE_MS" ]]; then + echo "gstack-timeline-read: --since must be a relative time like \"7 days ago\" (got '$2'); $SINCE_FORMS" >&2 + exit 2 + fi + shift 2 ;; --limit) if [[ $# -lt 2 ]]; then echo "gstack-timeline-read: --limit must be a positive integer (got no value); example: --limit 20" >&2 @@ -31,8 +83,17 @@ while [[ $# -gt 0 ]]; do exit 2 fi LIMIT="$2"; shift 2 ;; - --branch) BRANCH="$2"; shift 2 ;; - *) shift ;; + --branch) + problem=$(missing_value $# "${2-}") + if [[ -n "$problem" ]]; then + echo "gstack-timeline-read: --branch must be a branch name ($problem)" >&2 + exit 2 + fi + BRANCH="$2"; shift 2 ;; + *) + echo "gstack-timeline-read: unknown argument '$1'" >&2 + echo "$USAGE" >&2 + exit 2 ;; esac done @@ -47,23 +108,11 @@ command -v bun >/dev/null 2>&1 || { exit 127 } -cat "$TIMELINE_FILE" | GSTACK_TIMELINE_SINCE="$SINCE" GSTACK_TIMELINE_BRANCH="$BRANCH" GSTACK_TIMELINE_LIMIT="$LIMIT" bun -e " +cat "$TIMELINE_FILE" | GSTACK_TIMELINE_SINCE_MS="$SINCE_MS" GSTACK_TIMELINE_BRANCH="$BRANCH" GSTACK_TIMELINE_LIMIT="$LIMIT" bun -e " const lines = (await Bun.stdin.text()).trim().split('\n').filter(Boolean); -const since = process.env.GSTACK_TIMELINE_SINCE || ''; const branch = process.env.GSTACK_TIMELINE_BRANCH || ''; const limit = Number(process.env.GSTACK_TIMELINE_LIMIT); - -let sinceMs = 0; -if (since) { - // Parse relative time like '7 days ago' - const match = since.match(/(\d+)\s*(day|hour|minute|week|month)s?\s*ago/i); - if (match) { - const n = parseInt(match[1]); - const unit = match[2].toLowerCase(); - const ms = { minute: 60000, hour: 3600000, day: 86400000, week: 604800000, month: 2592000000 }; - sinceMs = Date.now() - n * (ms[unit] || 86400000); - } -} +const sinceMs = Number(process.env.GSTACK_TIMELINE_SINCE_MS); const entries = []; for (const line of lines) { diff --git a/browse/test/terminal-agent-publication-lock.test.ts b/browse/test/terminal-agent-publication-lock.test.ts index a745cf25d..0bbf5d801 100644 --- a/browse/test/terminal-agent-publication-lock.test.ts +++ b/browse/test/terminal-agent-publication-lock.test.ts @@ -6,7 +6,8 @@ import { spawnSync } from 'node:child_process'; import { acquireAgentStateLock, agentRecordPath, readAgentStartTime, writeAgentRecord, type AgentRecord } from '../src/terminal-agent-control'; const roots: string[] = []; -const children: ReturnType[] = []; +const children: Bun.Subprocess[] = []; +let unfinished: (() => Promise) | undefined; const directory = () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'publication-lock-')); roots.push(root); @@ -31,6 +32,8 @@ async function fixture(dead = true) { } afterEach(async () => { + if (unfinished) console.error((await unfinished()).message); + unfinished = undefined; for (const child of children.splice(0)) { if (child.exitCode === null) try { child.kill('SIGKILL'); } catch {} await child.exited; @@ -51,25 +54,36 @@ describe('owned terminal-agent publication lock recovery', () => { test.skipIf(process.platform !== 'linux')('a dead zombie with the exact recorded birth cannot retain its publication lock', async () => { const root = directory(); - const ready = path.join(root, 'zombie-pid'); const python = [ 'import os,time', 'pid=os.fork()', 'if pid==0: os._exit(0)', - `with open(${JSON.stringify(ready)},'w') as f: f.write(str(pid))`, + 'os.waitid(os.P_PID,pid,os.WEXITED|os.WNOWAIT)', + 'print(pid,flush=True)', 'time.sleep(30)', ].join('\n'); - const parent = Bun.spawn(['python3', '-c', python], { stdio: ['ignore', 'ignore', 'ignore'] }); + const parent = Bun.spawn(['python3', '-c', python], { stdio: ['ignore', 'pipe', 'pipe'] }); children.push(parent); - for (let n = 0; n < 300 && !fs.existsSync(ready); n++) await Bun.sleep(10); - expect(fs.existsSync(ready)).toBe(true); - const pid = Number(fs.readFileSync(ready, 'utf8')); - let state = ''; - for (let n = 0; n < 300; n++) { - state = fs.readFileSync(`/proc/${pid}/stat`, 'utf8').match(/^\d+ \(.*\) ([A-Z])/u)?.[1] || ''; - if (state === 'Z') break; - await Bun.sleep(10); + const failure = async (reason: string) => { + if (parent.exitCode === null) parent.kill('SIGKILL'); + const status = await parent.exited; + const stderr = await new Response(parent.stderr).text(); + return new Error(`${reason}; zombie parent exit status ${status}; stderr tail: ${stderr.slice(-500) || '(empty)'}`); + }; + unfinished = () => failure('zombie parent never reported its exited child'); + const reader = parent.stdout.getReader(); + let line = ''; + while (!line.includes('\n')) { + const chunk = await reader.read(); + if (chunk.done) throw await failure(`zombie parent closed stdout before a full PID line (got ${JSON.stringify(line)})`); + line += new TextDecoder().decode(chunk.value); } + reader.releaseLock(); + unfinished = undefined; + const reported = line.slice(0, line.indexOf('\n')); + if (!/^[1-9]\d*$/.test(reported)) throw await failure(`zombie parent reported a malformed PID ${JSON.stringify(reported)}`); + const pid = Number(reported); + const state = fs.readFileSync(`/proc/${pid}/stat`, 'utf8').match(/^\d+ \(.*\) ([A-Z])/u)?.[1] || ''; expect(state).toBe('Z'); expect(() => process.kill(pid, 0)).not.toThrow(); const record: AgentRecord = { pid, gen: 'zombie-generation', startedAt: Date.now(), diff --git a/docs/TESTING_INTERNALS.md b/docs/TESTING_INTERNALS.md index ea4f9e105..6bf03294b 100644 --- a/docs/TESTING_INTERNALS.md +++ b/docs/TESTING_INTERNALS.md @@ -1133,15 +1133,44 @@ Free-suite flake rules: daemon without `CI=true` launches Chromium sandboxed. - Handshakes with a runner wait for the runner's own observable effect (its progress line, a coalesced read count), not for a fixture side file or a timer. +- Fixtures that commit and then list, watch or remove a repository's `.git` + turn git auto-maintenance off themselves (`maintenance.auto=false` and + `gc.auto=0` in the repo config, or in the explicit git env they build). Since + git 2.29, `git commit` starts a detached `git maintenance run --auto` that + creates and deletes `.git/objects/maintenance.lock` after the commit has + returned; a listing counts it, a watcher's `lstat` misses it, and Bun's + `rmSync(..., { recursive: true, force: true })` returns without an error while + leaving the directory behind. `runFreeShard` appends the same two keys to + every shard child's `GIT_CONFIG_*` pairs as a backstop, so it covers fixtures + that inherit the environment, and `bun run scripts/ship-measure.ts free + --backend local` measures with that environment; a fixture with its own + replacement env never sees the backstop. + +To reproduce a ledger entry, take the shard's exact file list from the CI run's +`free-plan` artifact, then rerun it with the flaky retry off on a CI-mirrored VM: + +```bash +gh run download -R garrytan/gstack -n free-plan -D /tmp/free-plan +files=$(jq -r --argjson s '.shards[] | select(.shard == $s) | .files | join(",")' /tmp/free-plan/free-plan.json) +bun run test:ubicloud --diagnostic --files "$files" --reruns 30 +``` + +The ledger entry names the shard (`flake-ledger-`). Read the counts from +the run's `free-measurement.json` (`completed`, `passed`, `capHit`): with a +before-fix failure rate p, a fix needs at least 3/p clean completed reruns of +the same command, so zero failures would have under a 5% chance if nothing had +changed. Cut or unstarted reruns are incomplete, not passes. ### Free suite duration seed `scripts/free-test-durations.json` drives shard packing; files missing from it -pack at the seed's 99th percentile. Acceptable seeds come from +pack at the seed's 99th percentile. Acceptable seeds come only from `bun run test:ubicloud --record-durations` (each file timed in its own child on a -VM with the CI lane's environment) or a CI recording. A 4-core laptop or -small-sandbox recording is not acceptable: browser and display tests skip or slow -down there, so the seed misstates them. +VM with the CI lane's environment; it needs `UBICLOUD_API_KEY` and copies the +refreshed seed back into the checkout). A 4-core laptop or small-sandbox +recording is not acceptable: browser and display tests skip or slow down there, +so the seed misstates them. Contributors without `UBICLOUD_API_KEY` leave the +refresh to a maintainer. - `--ci-plan` warns in the job summary, with the refresh command, when more than 5 files are unseeded; it never fails a PR. `--ci-verify` lists shards that ran diff --git a/docs/test-audit-2026-10.md b/docs/test-audit-2026-10.md index 80e0d3445..f1a4ba51e 100644 --- a/docs/test-audit-2026-10.md +++ b/docs/test-audit-2026-10.md @@ -274,3 +274,34 @@ The 4 remaining shouting pins are enum or marker tokens (`PLAN MODE EXCEPTION ALWAYS RUN`, `[CRITICAL]`, `ALWAYS-ON` CLI output), not emphasis. Most remaining sentence pins sit in QA caller, detector-helper and workflow files that other work in flight owns. + +## Post-merge follow-up (2026-10-15) + +The "post-merge audit metrics" TODO, from a no-spend run of +`bun run test:health --since-days 7` (window 2026-10-08T22:14Z to +2026-10-15T22:14Z). The 2026-10-12 figures are the weekly health run in issue +#3154 (run 38234556073), kept as dated history. + +| Metric | 2026-10-12 | 2026-10-15 | Target | Verdict | +|---|---:|---:|---|---| +| PR full-fallback rate | 45.0% (58/129 runs) | 45.9% (39/85 runs) | none numeric; the replay above names the cause | open: branches touching `bin/`, `lib/`, `hosts/` or `make-pdf/` still select every case | +| Recorded PR-lane spend per merged PR | $75.09 (46 merged) | $73.52 (33 merged) | down at least 50% from the pre-change baseline | unavailable: baseline not recorded (below) | +| Cancelled slice-minutes per week | 1,939 (44 runs) | 1,545 (33 runs) | none numeric | reported | +| PR push-to-verdict | p50 12.0 min, p95 1,160.7 min (122 runs) | p50 11.4 min, p95 107.9 min (80 runs) | 3–5 minutes for typical PR checks (CONTRIBUTING.md) | missed | +| Free-suite flaky-pass rate | 13.0% (6/46 main runs) | 6.1% (2/33 main runs; `terminal-agent-publication-lock` 2/33, over the 5% per-file check) | under 5% of main runs | missed; fix wave 2 repairs the five ledger files | + +**Spend baseline.** The pre-change window was recomputed with the exported +`collectHealth` at `now = 2026-10-04T00:00Z`, seven days, through a client that +drops runs created and PRs merged after that instant (`listWorkflowRuns` has no +upper bound of its own). The window holds 12 merged PRs but no +`trial-outcomes-pr-*` artifacts and no paid-plan manifest with `prCoverage`: +the recorder that feeds this metric shipped with the audit, so the PR lanes +before it wrote nothing it can read (their other artifacts are retained until +2026-11-02 and later). Baseline not recorded; verdict unavailable. The P1 in +TODOS.md is opened on the absolute figures. + +**Census reliability (not yet due).** Due after the fourth scheduled census +after the audit merge (2026-10-26). Interim: periodic 2.00 expected failed +trials per run (6/538 over 3 runs; target at most 1.0), gate census 0.33 (1/308 +over 3 runs; target at most 0.5). The TODO keeps its due date; the census +repair stays with #3153 and #3200. diff --git a/package.json b/package.json index 25d95c6d1..440c2a6c6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gstack", - "version": "1.91.101", + "version": "1.91.105", "description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.", "license": "MIT", "type": "module", diff --git a/scripts/free-test-durations.json b/scripts/free-test-durations.json index 8f9c6cd90..5be4284f9 100644 --- a/scripts/free-test-durations.json +++ b/scripts/free-test-durations.json @@ -1,1061 +1,1225 @@ { "version": 1, - "recordedAt": "2026-10-04T19:16:06.359Z", + "recordedAt": "2026-10-15T23:37:39.698Z", "durations": { - "browse/test/activity.test.ts": 79, - "browse/test/adversarial-security.test.ts": 37, - "browse/test/batch.test.ts": 1702, - "browse/test/bridge-chromium-e2e.test.ts": 772, - "browse/test/browse-client.test.ts": 87, - "browse/test/browse-eval-wrapping.test.ts": 76, - "browse/test/browser-manager-custom-chromium.test.ts": 306, - "browse/test/browser-manager-unit.test.ts": 477, - "browse/test/browser-skill-commands.test.ts": 1200, - "browse/test/browser-skill-write.test.ts": 68, - "browse/test/browser-skills-e2e.test.ts": 86, - "browse/test/browser-skills-storage.test.ts": 44, - "browse/test/build-command-response.test.ts": 392, - "browse/test/build.test.ts": 109, + "browse/test/activity.test.ts": 55, + "browse/test/adversarial-security.test.ts": 47, + "browse/test/batch.test.ts": 1770, + "browse/test/bridge-chromium-e2e.test.ts": 728, + "browse/test/browse-client.test.ts": 102, + "browse/test/browse-eval-wrapping.test.ts": 72, + "browse/test/browser-manager-custom-chromium.test.ts": 313, + "browse/test/browser-manager-unit.test.ts": 435, + "browse/test/browser-skill-commands.test.ts": 1161, + "browse/test/browser-skill-write.test.ts": 76, + "browse/test/browser-skills-e2e.test.ts": 111, + "browse/test/browser-skills-storage.test.ts": 83, + "browse/test/build-command-response.test.ts": 354, + "browse/test/build.test.ts": 138, + "browse/test/bun-child-config.test.ts": 69, "browse/test/bun-polyfill.test.ts": 1281, - "browse/test/busy-daemon-iron-rule.test.ts": 15828, - "browse/test/busy-daemon-recovery.test.ts": 626, - "browse/test/cdp-allowlist.test.ts": 32, - "browse/test/cdp-e2e.test.ts": 567, - "browse/test/cdp-inspector-history-cap.test.ts": 29, - "browse/test/cdp-mutex.test.ts": 689, - "browse/test/cdp-session-cleanup.test.ts": 41, - "browse/test/chromium-profile-isolation.test.ts": 12612, - "browse/test/claude-bin.test.ts": 25, + "browse/test/busy-daemon-iron-rule.test.ts": 15837, + "browse/test/busy-daemon-recovery.test.ts": 609, + "browse/test/cdp-allowlist.test.ts": 19, + "browse/test/cdp-e2e.test.ts": 564, + "browse/test/cdp-inspector-history-cap.test.ts": 24, + "browse/test/cdp-mutex.test.ts": 673, + "browse/test/cdp-session-cleanup.test.ts": 34, + "browse/test/chromium-profile-isolation.test.ts": 13140, + "browse/test/claude-bin.test.ts": 13, + "browse/test/cli-chain-stdin.test.ts": 144, + "browse/test/cli-config-mismatch-message.test.ts": 84, "browse/test/cli-lock.test.ts": 25, - "browse/test/cli-loopback-no-proxy.test.ts": 101, - "browse/test/cli-setsid-daemonize.test.ts": 19, - "browse/test/cli-start-final-healthcheck.test.ts": 25, - "browse/test/cli-supervisor.test.ts": 34, - "browse/test/commands.test.ts": 31223, - "browse/test/compare-board.test.ts": 1013, - "browse/test/config.test.ts": 152, - "browse/test/content-security.test.ts": 777, - "browse/test/cookie-auth-verification.test.ts": 7544, - "browse/test/cookie-credential-deadline.test.ts": 350, - "browse/test/cookie-database.test.ts": 376, - "browse/test/cookie-fixture-delete-lease.test.ts": 58, - "browse/test/cookie-import-browser.test.ts": 115, - "browse/test/cookie-import-native-job.test.ts": 658, - "browse/test/cookie-import-native.test.ts": 3952, - "browse/test/cookie-import-node.test.ts": 337, - "browse/test/cookie-import-operation.test.ts": 1254, - "browse/test/cookie-import-reliability.test.ts": 1842, - "browse/test/cookie-import-transport.test.ts": 24, - "browse/test/cookie-picker-binding-browser.test.ts": 2309, - "browse/test/cookie-picker-binding.test.ts": 299, - "browse/test/cookie-picker-csrf-browser.test.ts": 569, - "browse/test/cookie-picker-routes.test.ts": 352, - "browse/test/cookie-picker-ui.test.ts": 10753, - "browse/test/daemon-log-hygiene.test.ts": 68, - "browse/test/daemon-mismatch-refuse.test.ts": 159, - "browse/test/data-platform.test.ts": 29, - "browse/test/dia-gui-readiness.test.ts": 650, - "browse/test/dia-launch-comparison.test.ts": 2802, - "browse/test/dia-macos-qualification.test.ts": 2944, - "browse/test/domain-skills-e2e.test.ts": 540, - "browse/test/domain-skills-storage.test.ts": 206, - "browse/test/dotenv-isolation.test.ts": 406, - "browse/test/dual-listener.test.ts": 397, + "browse/test/cli-loopback-no-proxy.test.ts": 80, + "browse/test/cli-setsid-daemonize.test.ts": 15, + "browse/test/cli-start-final-healthcheck.test.ts": 21, + "browse/test/cli-supervisor.test.ts": 31, + "browse/test/commands.test.ts": 31047, + "browse/test/compare-board.test.ts": 994, + "browse/test/config.test.ts": 130, + "browse/test/content-security.test.ts": 751, + "browse/test/cookie-auth-verification.test.ts": 7524, + "browse/test/cookie-credential-deadline.test.ts": 292, + "browse/test/cookie-database.test.ts": 411, + "browse/test/cookie-fixture-delete-lease.test.ts": 31, + "browse/test/cookie-import-browser.test.ts": 136, + "browse/test/cookie-import-native-job.test.ts": 517, + "browse/test/cookie-import-native.test.ts": 3623, + "browse/test/cookie-import-node.test.ts": 200, + "browse/test/cookie-import-operation.test.ts": 1110, + "browse/test/cookie-import-reliability.test.ts": 1661, + "browse/test/cookie-import-transport.test.ts": 32, + "browse/test/cookie-picker-binding-browser.test.ts": 2346, + "browse/test/cookie-picker-binding.test.ts": 255, + "browse/test/cookie-picker-csrf-browser.test.ts": 603, + "browse/test/cookie-picker-routes.test.ts": 294, + "browse/test/cookie-picker-ui.test.ts": 10759, + "browse/test/daemon-log-hygiene.test.ts": 44, + "browse/test/daemon-mismatch-refuse.test.ts": 174, + "browse/test/data-platform.test.ts": 80, + "browse/test/dia-gui-readiness.test.ts": 589, + "browse/test/dia-launch-comparison.test.ts": 2739, + "browse/test/dia-macos-qualification.test.ts": 2761, + "browse/test/domain-skills-e2e.test.ts": 493, + "browse/test/domain-skills-storage.test.ts": 208, + "browse/test/dotenv-isolation.test.ts": 378, + "browse/test/dual-listener.test.ts": 362, "browse/test/dx-polish.test.ts": 23, - "browse/test/error-handling.test.ts": 16, - "browse/test/extension-sender-auth.test.ts": 48, - "browse/test/extension-token.test.ts": 380, - "browse/test/file-drop.test.ts": 32, - "browse/test/file-permissions.test.ts": 38, - "browse/test/fill-change-event.test.ts": 1647, - "browse/test/find-browse.test.ts": 28, - "browse/test/findport.test.ts": 422, - "browse/test/from-file-path-validation.test.ts": 21, - "browse/test/gstack-config.test.ts": 1077, - "browse/test/gstack-update-check.test.ts": 3418, - "browse/test/handoff.test.ts": 8614, - "browse/test/headless-gpu-and-reap.test.ts": 785, - "browse/test/headless-launch-options.test.ts": 1836, - "browse/test/launch-signal-flags.test.ts": 15, - "browse/test/learnings-injection.test.ts": 86, - "browse/test/media-extract-unit.test.ts": 18, - "browse/test/memory-command.test.ts": 298, - "browse/test/memory-leak-reproducer.test.ts": 365, - "browse/test/navigation-guard.test.ts": 14581, - "browse/test/output-path-symlinks.test.ts": 68, - "browse/test/pair-agent-e2e.test.ts": 1923, - "browse/test/pair-agent-optin-gate.test.ts": 358, - "browse/test/pair-agent-tunnel-eval.test.ts": 7757, - "browse/test/path-validation.test.ts": 2020, - "browse/test/pdf-flags.test.ts": 51, - "browse/test/platform.test.ts": 28, - "browse/test/playwright-core-patch.test.ts": 34, - "browse/test/poisoned-bundle-probe.test.ts": 308, - "browse/test/process-liveness-windows.test.ts": 115, - "browse/test/proxy-config.test.ts": 28, - "browse/test/proxy-redact.test.ts": 14, - "browse/test/pty-inject-scan.test.ts": 642, - "browse/test/pty-session-lease.test.ts": 39, + "browse/test/error-handling.test.ts": 13, + "browse/test/extension-sender-auth.test.ts": 37, + "browse/test/extension-token.test.ts": 289, + "browse/test/file-drop.test.ts": 23, + "browse/test/file-permissions.test.ts": 27, + "browse/test/fill-change-event.test.ts": 1571, + "browse/test/find-browse.test.ts": 15, + "browse/test/findport.test.ts": 391, + "browse/test/from-file-path-validation.test.ts": 15, + "browse/test/gstack-config.test.ts": 1179, + "browse/test/gstack-update-check.test.ts": 3339, + "browse/test/handoff.test.ts": 8373, + "browse/test/headless-gpu-and-reap.test.ts": 1625, + "browse/test/headless-launch-options.test.ts": 1822, + "browse/test/launch-signal-flags.test.ts": 10, + "browse/test/learnings-injection.test.ts": 85, + "browse/test/media-extract-unit.test.ts": 13, + "browse/test/memory-command.test.ts": 294, + "browse/test/memory-leak-reproducer.test.ts": 359, + "browse/test/navigation-guard.test.ts": 6575, + "browse/test/output-path-symlinks.test.ts": 37, + "browse/test/pair-agent-e2e.test.ts": 1726, + "browse/test/pair-agent-optin-gate.test.ts": 353, + "browse/test/pair-agent-tunnel-eval.test.ts": 7806, + "browse/test/path-security-realpath.test.ts": 66, + "browse/test/path-validation.test.ts": 1862, + "browse/test/pdf-flags.test.ts": 24, + "browse/test/platform.test.ts": 19, + "browse/test/playwright-core-patch.test.ts": 31, + "browse/test/poisoned-bundle-probe.test.ts": 285, + "browse/test/process-liveness-windows.test.ts": 64, + "browse/test/proxy-config.test.ts": 22, + "browse/test/proxy-env-daemon.test.ts": 2817, + "browse/test/proxy-env.test.ts": 25, + "browse/test/proxy-redact.test.ts": 10, + "browse/test/pty-inject-scan.test.ts": 567, + "browse/test/pty-session-lease.test.ts": 25, "browse/test/rebrand-signed-bundle.test.ts": 18, - "browse/test/regression-pr1169-pdf-from-file-invalid-json.test.ts": 38, - "browse/test/restart-env.test.ts": 22, - "browse/test/sanitize.test.ts": 16, - "browse/test/screenshot-size-guard.test.ts": 261, - "browse/test/security-adversarial-fixes.test.ts": 18, + "browse/test/regression-pr1169-pdf-from-file-invalid-json.test.ts": 29, + "browse/test/restart-env.test.ts": 18, + "browse/test/runtime-root-server-bundle.test.ts": 30, + "browse/test/sanitize.test.ts": 12, + "browse/test/screenshot-size-guard.test.ts": 468, + "browse/test/security-adversarial-fixes.test.ts": 16, "browse/test/security-adversarial.test.ts": 18, - "browse/test/security-audit-r2.test.ts": 328, - "browse/test/security-bench.test.ts": 14, - "browse/test/security-classifier-download-cleanup.test.ts": 27, - "browse/test/security-classifier.test.ts": 26, - "browse/test/security-integration.test.ts": 23, - "browse/test/security-live-playwright.test.ts": 665, - "browse/test/security-sidecar-client.test.ts": 25, - "browse/test/security.test.ts": 23, - "browse/test/server-auth.test.ts": 394, - "browse/test/server-embedder-terminal-port.test.ts": 4056, - "browse/test/server-factory.test.ts": 1016, - "browse/test/server-flush-trackers.test.ts": 32, + "browse/test/security-audit-r2.test.ts": 318, + "browse/test/security-bench.test.ts": 11, + "browse/test/security-classifier-download-cleanup.test.ts": 41, + "browse/test/security-classifier.test.ts": 17, + "browse/test/security-integration.test.ts": 21, + "browse/test/security-live-playwright.test.ts": 631, + "browse/test/security-sidecar-client.test.ts": 50, + "browse/test/security.test.ts": 21, + "browse/test/server-auth.test.ts": 324, + "browse/test/server-embedder-terminal-port.test.ts": 4022, + "browse/test/server-factory.test.ts": 1068, + "browse/test/server-flush-trackers.test.ts": 11, "browse/test/server-launch-resolution.test.ts": 24, - "browse/test/server-lock-errors.test.ts": 23, - "browse/test/server-no-import-side-effects.test.ts": 566, - "browse/test/server-proxy-fail-fast.test.ts": 1378, - "browse/test/server-pty-lease-routes.test.ts": 297, - "browse/test/server-route-auth-blackbox.test.ts": 353, - "browse/test/server-route-dispatch-ratchet.test.ts": 309, - "browse/test/server-route-table.test.ts": 366, - "browse/test/server-sanitize-surrogates.test.ts": 335, - "browse/test/server-tmp-state-path.test.ts": 24, - "browse/test/session-cookie-store.test.ts": 44, - "browse/test/session-persist.test.ts": 680, - "browse/test/sidebar-tabs.test.ts": 347, - "browse/test/sidebar-ux.test.ts": 307, - "browse/test/sidepanel-patient-autoconnect.test.ts": 26, - "browse/test/sidepanel-reattach.test.ts": 19, - "browse/test/sidepanel-restart-dispose.test.ts": 20, - "browse/test/skill-token.test.ts": 29, - "browse/test/snapshot.test.ts": 7930, - "browse/test/socks-bridge.test.ts": 542, - "browse/test/sse-helpers.test.ts": 155, - "browse/test/sse-session-cookie.test.ts": 19, - "browse/test/state-ttl.test.ts": 17, - "browse/test/stealth-extended.test.ts": 10, - "browse/test/stealth-layer-c.test.ts": 15, - "browse/test/stealth-webdriver.test.ts": 1674, - "browse/test/stop-ack-before-shutdown.test.ts": 142, - "browse/test/stop-dead-daemon.test.ts": 225, - "browse/test/tab-each.test.ts": 38, - "browse/test/tab-guardrail.test.ts": 316, - "browse/test/tab-isolation.test.ts": 265, - "browse/test/tab-session-frame-detach.test.ts": 15, - "browse/test/telemetry-optout.test.ts": 89, - "browse/test/telemetry.test.ts": 34, - "browse/test/temp-dirs.test.ts": 60, - "browse/test/terminal-agent-detach-reattach.test.ts": 24, - "browse/test/terminal-agent-import.test.ts": 4388, - "browse/test/terminal-agent-integration.test.ts": 812, - "browse/test/terminal-agent-keepalive.test.ts": 17, - "browse/test/terminal-agent-lifecycle.test.ts": 4633, - "browse/test/terminal-agent-native-observation.test.ts": 21, - "browse/test/terminal-agent-owner-watchdog.test.ts": 119, - "browse/test/terminal-agent-pid-identity.test.ts": 32, - "browse/test/terminal-agent-port-range.test.ts": 33, - "browse/test/terminal-agent-publication-lock.test.ts": 1571, - "browse/test/terminal-agent-ring-buffer-runtime.test.ts": 39, - "browse/test/terminal-agent-session-routing.test.ts": 18, - "browse/test/terminal-agent-watchdog.test.ts": 17, - "browse/test/terminal-agent.test.ts": 283, - "browse/test/terminal-pty-lifecycle.test.ts": 12, - "browse/test/token-registry.test.ts": 31, - "browse/test/tunnel-gate-unit.test.ts": 275, - "browse/test/tunnel-revoke-cli.test.ts": 1086, - "browse/test/url-validation.test.ts": 114, - "browse/test/watch.test.ts": 320, - "browse/test/watchdog.test.ts": 2372, - "browse/test/welcome-page.test.ts": 20, - "browse/test/windows-spawn-hide.test.ts": 31, - "browse/test/xprotect-heal.test.ts": 763, - "browse/test/xvfb.test.ts": 16850, - "browser-skills/hackernews-frontpage/script.test.ts": 19, - "design/test/approval.test.ts": 51, - "design/test/auth.test.ts": 17, + "browse/test/server-lock-errors.test.ts": 25, + "browse/test/server-no-import-side-effects.test.ts": 602, + "browse/test/server-proxy-fail-fast.test.ts": 1356, + "browse/test/server-pty-lease-routes.test.ts": 347, + "browse/test/server-route-auth-blackbox.test.ts": 407, + "browse/test/server-route-dispatch-ratchet.test.ts": 260, + "browse/test/server-route-table.test.ts": 361, + "browse/test/server-sanitize-surrogates.test.ts": 290, + "browse/test/server-tmp-state-path.test.ts": 11, + "browse/test/session-cookie-store.test.ts": 46, + "browse/test/session-persist.test.ts": 778, + "browse/test/sidebar-tabs.test.ts": 309, + "browse/test/sidebar-ux.test.ts": 320, + "browse/test/sidepanel-font-size.test.ts": 25, + "browse/test/sidepanel-patient-autoconnect.test.ts": 12, + "browse/test/sidepanel-reattach.test.ts": 14, + "browse/test/sidepanel-restart-dispose.test.ts": 14, + "browse/test/skill-token.test.ts": 19, + "browse/test/snapshot.test.ts": 8022, + "browse/test/socks-bridge.test.ts": 469, + "browse/test/sse-helpers.test.ts": 156, + "browse/test/sse-session-cookie.test.ts": 18, + "browse/test/state-ttl.test.ts": 11, + "browse/test/stealth-extended.test.ts": 11, + "browse/test/stealth-layer-c.test.ts": 11, + "browse/test/stealth-webdriver.test.ts": 1556, + "browse/test/stop-ack-before-shutdown.test.ts": 130, + "browse/test/stop-dead-daemon.test.ts": 233, + "browse/test/tab-each.test.ts": 34, + "browse/test/tab-guardrail.test.ts": 294, + "browse/test/tab-isolation.test.ts": 272, + "browse/test/tab-session-frame-detach.test.ts": 9, + "browse/test/telemetry-optout.test.ts": 22, + "browse/test/telemetry.test.ts": 22, + "browse/test/temp-dirs.test.ts": 44, + "browse/test/terminal-agent-detach-reattach.test.ts": 15, + "browse/test/terminal-agent-import.test.ts": 4392, + "browse/test/terminal-agent-integration.test.ts": 738, + "browse/test/terminal-agent-keepalive.test.ts": 12, + "browse/test/terminal-agent-lifecycle.test.ts": 4754, + "browse/test/terminal-agent-native-observation.test.ts": 19, + "browse/test/terminal-agent-owner-watchdog.test.ts": 113, + "browse/test/terminal-agent-pid-identity.test.ts": 27, + "browse/test/terminal-agent-port-range.test.ts": 30, + "browse/test/terminal-agent-publication-lock.test.ts": 1647, + "browse/test/terminal-agent-ring-buffer-runtime.test.ts": 49, + "browse/test/terminal-agent-session-routing.test.ts": 23, + "browse/test/terminal-agent-watchdog.test.ts": 18, + "browse/test/terminal-agent.test.ts": 291, + "browse/test/terminal-pty-lifecycle.test.ts": 11, + "browse/test/token-registry.test.ts": 22, + "browse/test/tunnel-gate-unit.test.ts": 259, + "browse/test/tunnel-revoke-cli.test.ts": 937, + "browse/test/url-validation.test.ts": 75, + "browse/test/watch.test.ts": 297, + "browse/test/watchdog.test.ts": 2991, + "browse/test/welcome-page.test.ts": 14, + "browse/test/windows-spawn-hide.test.ts": 25, + "browse/test/xprotect-heal.test.ts": 761, + "browse/test/xvfb.test.ts": 16287, + "browser-skills/hackernews-frontpage/script.test.ts": 14, + "design/test/approval.test.ts": 35, + "design/test/auth.test.ts": 27, "design/test/brief.test.ts": 12, - "design/test/cli-persistence.test.ts": 6855, - "design/test/cli-version.test.ts": 38, - "design/test/daemon-discovery.test.ts": 11745, - "design/test/daemon.test.ts": 157, - "design/test/feedback-roundtrip-daemon.test.ts": 404, - "design/test/feedback-roundtrip.test.ts": 2871, - "design/test/gallery.test.ts": 19, - "design/test/image-args.test.ts": 40, - "design/test/image-gen-pairing.test.ts": 14, - "design/test/models.test.ts": 51, - "design/test/persist.test.ts": 53, + "design/test/cli-persistence.test.ts": 6612, + "design/test/cli-version.test.ts": 31, + "design/test/daemon-discovery.test.ts": 11317, + "design/test/daemon.test.ts": 154, + "design/test/feedback-roundtrip-daemon.test.ts": 339, + "design/test/feedback-roundtrip.test.ts": 3020, + "design/test/gallery.test.ts": 16, + "design/test/image-args.test.ts": 52, + "design/test/image-gen-pairing.test.ts": 49, + "design/test/models.test.ts": 197, + "design/test/persist.test.ts": 43, "design/test/receipted-fetch.test.ts": 25, - "design/test/serve.test.ts": 178, - "design/test/variants-briefs.test.ts": 3675, - "design/test/variants-retry-after.test.ts": 8224, - "ios-qa/daemon/test/allowlist.test.ts": 19, - "ios-qa/daemon/test/audit.test.ts": 20, - "ios-qa/daemon/test/auth-mint.test.ts": 25, - "ios-qa/daemon/test/cli-mint.test.ts": 212, - "ios-qa/daemon/test/daemon-integration.test.ts": 388, - "ios-qa/daemon/test/proxy-classify.test.ts": 29, - "ios-qa/daemon/test/proxy-transport.test.ts": 1817, - "ios-qa/daemon/test/session-tokens.test.ts": 16, - "ios-qa/daemon/test/single-instance.test.ts": 18, - "ios-qa/daemon/test/tailscale-localapi.test.ts": 30, - "ios-qa/daemon/test/tunnel-bootstrap.test.ts": 405, - "ios-qa/scripts/gen-accessors.test.ts": 54, - "make-pdf/test/asideClient.test.ts": 20, - "make-pdf/test/cli-args.test.ts": 14, - "make-pdf/test/cli-exit-codes.test.ts": 353, - "make-pdf/test/diagram-prepass.test.ts": 69, - "make-pdf/test/e2e/ci-prereqs.test.ts": 24, - "make-pdf/test/e2e/combined-gate.test.ts": 869, - "make-pdf/test/e2e/diagram-gate.test.ts": 2774, - "make-pdf/test/e2e/emoji-gate.test.ts": 975, - "make-pdf/test/e2e/format-gate.test.ts": 5010, - "make-pdf/test/e2e/landscape-gate.test.ts": 3557, - "make-pdf/test/e2e/toc-gate.test.ts": 6090, - "make-pdf/test/image-policy.test.ts": 11, + "design/test/serve.test.ts": 173, + "design/test/variants-briefs.test.ts": 3634, + "design/test/variants-retry-after.test.ts": 8211, + "ios-qa/daemon/test/allowlist.test.ts": 17, + "ios-qa/daemon/test/audit.test.ts": 30, + "ios-qa/daemon/test/auth-mint.test.ts": 24, + "ios-qa/daemon/test/cli-mint.test.ts": 217, + "ios-qa/daemon/test/daemon-integration.test.ts": 3846, + "ios-qa/daemon/test/proxy-classify.test.ts": 20, + "ios-qa/daemon/test/proxy-transport.test.ts": 1747, + "ios-qa/daemon/test/session-tokens.test.ts": 14, + "ios-qa/daemon/test/single-instance.test.ts": 15, + "ios-qa/daemon/test/tailscale-localapi.test.ts": 46, + "ios-qa/daemon/test/tunnel-bootstrap.test.ts": 407, + "ios-qa/scripts/gen-accessors.test.ts": 51, + "make-pdf/test/asideClient.test.ts": 19, + "make-pdf/test/cli-args.test.ts": 10, + "make-pdf/test/cli-exit-codes.test.ts": 305, + "make-pdf/test/diagram-prepass.test.ts": 65, + "make-pdf/test/e2e/ci-prereqs.test.ts": 23, + "make-pdf/test/e2e/combined-gate.test.ts": 802, + "make-pdf/test/e2e/diagram-gate.test.ts": 2550, + "make-pdf/test/e2e/emoji-gate.test.ts": 845, + "make-pdf/test/e2e/format-gate.test.ts": 4652, + "make-pdf/test/e2e/landscape-gate.test.ts": 3129, + "make-pdf/test/e2e/toc-gate.test.ts": 5807, + "make-pdf/test/image-policy.test.ts": 13, "make-pdf/test/pdftotext.test.ts": 34, "make-pdf/test/render-offline-sanitize.test.ts": 27, - "make-pdf/test/render.test.ts": 42, - "make-pdf/test/setup-smoke.test.ts": 144, - "make-pdf/test/toc-anchors.test.ts": 29, - "make-pdf/test/toc-pages.test.ts": 39, - "test/agent-sdk-runner.test.ts": 8240, - "test/agents-digest.test.ts": 23, - "test/analytics.test.ts": 20, - "test/anthropic-preflight.test.ts": 12, - "test/archaeology-lint.test.ts": 1549, - "test/arm-benchmark-selftest.test.ts": 346, - "test/arm-setup-smoke-workflow.test.ts": 24, - "test/artifacts-allowlist-decisions.test.ts": 16, - "test/artifacts-init-migration.test.ts": 301, - "test/aside-driver.test.ts": 212, - "test/aside-probe-shell.test.ts": 9611, - "test/aside-render.test.ts": 10146, - "test/audit-compliance.test.ts": 25, - "test/auq-error-fallback-hook.test.ts": 165, - "test/auq-format-always-loaded.test.ts": 38, - "test/auq-mode-capture.test.ts": 123, - "test/auq-native-capture.test.ts": 2618, - "test/auq-parallel.test.ts": 12753, - "test/auto-decide-fixture.test.ts": 3039, - "test/autoplan-amend-input.test.ts": 1241, - "test/autoplan-artifact-recorder.test.ts": 5811, - "test/autoplan-artifact-windows-argv.test.ts": 88, - "test/autoplan-dual-voice-evidence.test.ts": 1237, - "test/autoplan-dual-voice-fixture.test.ts": 2799, - "test/autoplan-edit-digests-al.test.ts": 234, - "test/autoplan-init.test.ts": 802, - "test/autoplan-method-read-audit.test.ts": 245, - "test/autoplan-methodology-names.test.ts": 871, - "test/autoplan-obligations.test.ts": 2547, - "test/autoplan-owned-state.test.ts": 1551, - "test/autoplan-pending-artifact.test.ts": 911, - "test/autoplan-pending-question.test.ts": 4243, - "test/autoplan-phase-handoff.test.ts": 184, - "test/autoplan-phase-observer.test.ts": 112, - "test/autoplan-phase-order.test.ts": 67, - "test/autoplan-preconfigured-onboarding-ar.test.ts": 765, - "test/autoplan-public-narration.test.ts": 46, - "test/autoplan-publication-generation.test.ts": 32, - "test/autoplan-publication-guard.test.ts": 2028, - "test/autoplan-publication-hook.test.ts": 6492, - "test/autoplan-review-discovery.test.ts": 10172, - "test/autoplan-snapshot.test.ts": 1850, - "test/benchmark-cli.test.ts": 544, - "test/benchmark-runner.test.ts": 31, - "test/bin-context-windows-slug.test.ts": 1639, - "test/bin-windows-bun-import-paths.test.ts": 820, - "test/binding-template-drift.test.ts": 44, - "test/bootstrap-retention-shard.test.ts": 2379, - "test/bootstrap-retention.test.ts": 12525, - "test/bootstrap-session-lifecycle.test.ts": 5099, - "test/brain-cache-roundtrip.test.ts": 68, - "test/brain-cache-spec.test.ts": 22, - "test/brain-preflight.test.ts": 29, - "test/brain-sync-windows-paths.test.ts": 14, - "test/brain-sync.test.ts": 26459, - "test/branch-slug-hygiene.test.ts": 466, - "test/build-gbrain-env.test.ts": 76, - "test/build-script-shell-compat.test.ts": 15, - "test/builder-profile.test.ts": 3493, - "test/bun-subprocess-fd-lifetime.test.ts": 57, - "test/bun-version-drift.test.ts": 19, - "test/cache-concurrent-refresh.test.ts": 80, - "test/carve-guard-completeness.test.ts": 26, - "test/carve-guards-negative.test.ts": 27, - "test/carve-plan-fixture.test.ts": 572, - "test/carve-section-ordering.test.ts": 54, - "test/carve-section-sharding.test.ts": 1521, - "test/catalog-budget.test.ts": 40, - "test/catalog-mode-full.test.ts": 1152, - "test/catalog-trim.test.ts": 44, - "test/ceo-barless-submit.test.ts": 111, - "test/ceo-count-ad-v2.test.ts": 113, - "test/ceo-expansion-auq.test.ts": 106, - "test/ceo-expansion-pacing-native.test.ts": 58, - "test/ceo-finding-fixture.test.ts": 890, - "test/ceo-hold-posture-review.test.ts": 138, - "test/ceo-mode-expansion-disposition.test.ts": 73, - "test/ceo-mode-handoff.test.ts": 109, - "test/ceo-mode-labels-native.test.ts": 71, - "test/ceo-mode-option.test.ts": 1633, + "make-pdf/test/render.test.ts": 38, + "make-pdf/test/setup-smoke.test.ts": 91, + "make-pdf/test/toc-anchors.test.ts": 28, + "make-pdf/test/toc-pages.test.ts": 31, + "test/agent-sdk-runner.test.ts": 8223, + "test/agents-digest.test.ts": 14, + "test/analytics.test.ts": 15, + "test/anthropic-preflight.test.ts": 11, + "test/archaeology-lint.test.ts": 1732, + "test/arm-benchmark-selftest.test.ts": 453, + "test/arm-setup-smoke-workflow.test.ts": 47, + "test/artifacts-allowlist-decisions.test.ts": 14, + "test/artifacts-init-migration.test.ts": 251, + "test/aside-driver.test.ts": 171, + "test/aside-probe-shell.test.ts": 9587, + "test/aside-render.test.ts": 10296, + "test/audit-compliance.test.ts": 23, + "test/auq-error-fallback-hook.test.ts": 151, + "test/auq-format-always-loaded.test.ts": 33, + "test/auq-mode-capture.test.ts": 116, + "test/auq-native-capture.test.ts": 2233, + "test/auq-parallel.test.ts": 12909, + "test/auq-substance-panel.test.ts": 84, + "test/auto-decide-fixture.test.ts": 3010, + "test/autoplan-admission.test.ts": 855, + "test/autoplan-amend-input.test.ts": 1061, + "test/autoplan-answer-invalidation.test.ts": 6231, + "test/autoplan-artifact-recorder.test.ts": 5572, + "test/autoplan-artifact-windows-argv.test.ts": 130, + "test/autoplan-bounded-journal.test.ts": 416, + "test/autoplan-capy-e2e.test.ts": 7074, + "test/autoplan-compaction-copies.test.ts": 115, + "test/autoplan-driver.test.ts": 2946, + "test/autoplan-dual-voice-evidence.test.ts": 1624, + "test/autoplan-dual-voice-fixture.test.ts": 3902, + "test/autoplan-edit-digests-al.test.ts": 377, + "test/autoplan-gate-judgment.test.ts": 8263, + "test/autoplan-guard-log.test.ts": 79, + "test/autoplan-guard-reasons.test.ts": 13, + "test/autoplan-init.test.ts": 1158, + "test/autoplan-long-session-observer.test.ts": 204, + "test/autoplan-method-read-audit.test.ts": 522, + "test/autoplan-methodology-names.test.ts": 1204, + "test/autoplan-obligations.test.ts": 2380, + "test/autoplan-owned-read.test.ts": 2354, + "test/autoplan-owned-state.test.ts": 1541, + "test/autoplan-pending-artifact.test.ts": 979, + "test/autoplan-pending-question.test.ts": 4282, + "test/autoplan-phase-handoff.test.ts": 112, + "test/autoplan-phase-observer.test.ts": 99, + "test/autoplan-phase-order.test.ts": 65, + "test/autoplan-preconfigured-onboarding-ar.test.ts": 746, + "test/autoplan-public-narration.test.ts": 41, + "test/autoplan-publication-generation.test.ts": 23, + "test/autoplan-publication-guard.test.ts": 1777, + "test/autoplan-publication-hook.test.ts": 2534, + "test/autoplan-publication-payload.test.ts": 2270, + "test/autoplan-record.test.ts": 2073, + "test/autoplan-residuals.test.ts": 1917, + "test/autoplan-review-discovery.test.ts": 10592, + "test/autoplan-revise.test.ts": 6976, + "test/autoplan-run-concurrency.test.ts": 1551, + "test/autoplan-run-recovery.test.ts": 4885, + "test/autoplan-schema-canary-compare.test.ts": 20, + "test/autoplan-scope.test.ts": 664, + "test/autoplan-snapshot.test.ts": 2140, + "test/autoplan-timing.test.ts": 337, + "test/benchmark-cli.test.ts": 529, + "test/benchmark-provider-adapters.test.ts": 60, + "test/benchmark-runner.test.ts": 23, + "test/bin-context-windows-slug.test.ts": 2361, + "test/bin-windows-bun-import-paths.test.ts": 843, + "test/binary-version-probe.test.ts": 125, + "test/binding-template-drift.test.ts": 51, + "test/bootstrap-retention-shard.test.ts": 2455, + "test/bootstrap-retention.test.ts": 12736, + "test/bootstrap-session-lifecycle.test.ts": 5093, + "test/brain-cache-roundtrip.test.ts": 113, + "test/brain-cache-spec.test.ts": 21, + "test/brain-preflight.test.ts": 32, + "test/brain-sync-removals.test.ts": 8936, + "test/brain-sync-windows-paths.test.ts": 11, + "test/brain-sync.test.ts": 57159, + "test/branch-slug-hygiene.test.ts": 758, + "test/build-cso-nonfatal.test.ts": 46, + "test/build-cso-result-record.test.ts": 745, + "test/build-gbrain-env.test.ts": 58, + "test/build-script-shell-compat.test.ts": 13, + "test/builder-profile.test.ts": 3729, + "test/bun-subprocess-fd-lifetime.test.ts": 64, + "test/bun-version-drift.test.ts": 646, + "test/cache-concurrent-refresh.test.ts": 54, + "test/capy-skill-wrapper.test.ts": 4065, + "test/carve-guard-completeness.test.ts": 13, + "test/carve-guards-negative.test.ts": 18, + "test/carve-plan-fixture.test.ts": 380, + "test/carve-section-ordering.test.ts": 40, + "test/carve-section-sharding.test.ts": 1438, + "test/catalog-budget.test.ts": 44, + "test/catalog-mode-full.test.ts": 962, + "test/catalog-trim.test.ts": 43, + "test/census-red-docs.test.ts": 40, + "test/ceo-barless-submit.test.ts": 87, + "test/ceo-count-ad-v2.test.ts": 33, + "test/ceo-expansion-auq.test.ts": 84, + "test/ceo-expansion-pacing-native.test.ts": 81, + "test/ceo-finding-fixture.test.ts": 773, + "test/ceo-hold-posture-review.test.ts": 109, + "test/ceo-mode-expansion-disposition.test.ts": 66, + "test/ceo-mode-handoff-hook.test.ts": 53, + "test/ceo-mode-handoff.test.ts": 70, + "test/ceo-mode-labels-native.test.ts": 44, + "test/ceo-mode-option.test.ts": 1653, "test/ceo-mode-pending-submit.test.ts": 53, - "test/ceo-mode-posture-native.test.ts": 52, - "test/ceo-mode-preference-al.test.ts": 1809, - "test/ceo-mode-prerequisite.test.ts": 1092, - "test/ceo-mode-routing-fixture.test.ts": 863, - "test/ceo-plan-mode-fixture.test.ts": 833, - "test/ceo-posture-packet.test.ts": 305, - "test/ceo-section-loading-fixture.test.ts": 329, - "test/ceo-split-collection.test.ts": 551, - "test/ceo-split-question-policy.test.ts": 487, - "test/ceo-stale-fill-decision.test.ts": 88, - "test/ceo-workflow-clarity.test.ts": 43, - "test/changed-files-union.test.ts": 377, - "test/chromium-sandbox-ci.test.ts": 159, - "test/ci-eval-cache.test.ts": 26, - "test/ci-image-cli-pin.test.ts": 39, - "test/ci-image-tag-binding.test.ts": 18, - "test/ci-native-evidence.test.ts": 653, - "test/ci-paid-coordination.test.ts": 5397, - "test/claude-code-migration.test.ts": 82, - "test/claude-code-runner.test.ts": 3023, - "test/claude-code-skill.test.ts": 1395, - "test/claude-code-windows-job.test.ts": 49, - "test/claude-md-size.test.ts": 18, - "test/claude-overlay-models.test.ts": 37, - "test/claude-overlay-setup-default.test.ts": 28091, - "test/claude-overlay-setup-installs.test.ts": 40548, - "test/claude-overlay-setup-lifecycle.test.ts": 44959, - "test/claude-provider-keychain.test.ts": 88, - "test/code-intelligence-cli.test.ts": 719, - "test/code-intelligence.test.ts": 4382, - "test/codex-boundary-evidence.test.ts": 12, - "test/codex-carve-fixture.test.ts": 781, - "test/codex-ci-access.test.ts": 239, - "test/codex-eval-recording.test.ts": 311, - "test/codex-generation-model.test.ts": 129, - "test/codex-hardening.test.ts": 10053, - "test/codex-invocation-sites.test.ts": 320, - "test/codex-model-probe.test.ts": 2328, - "test/codex-resume-flag-semantics.test.ts": 14, - "test/codex-session-lifecycle.test.ts": 12051, - "test/codex-skill-isolation.test.ts": 144, - "test/codex-under-codex-detection.test.ts": 36, - "test/codex-web-search-flag.test.ts": 252, - "test/conductor-env-shim.test.ts": 13, - "test/context-bill.test.ts": 93, - "test/context-budget-ratchet.test.ts": 103, - "test/context-identity.test.ts": 6836, - "test/context-remaining-work-provenance.test.ts": 14, - "test/context-save-hardening.test.ts": 377, - "test/cookie-workflow-judge-input.test.ts": 631, - "test/cookie-workflow-manual-review.test.ts": 75, - "test/coverage-audit-evidence.test.ts": 184, - "test/coverage-audit.test.ts": 1000, - "test/cso-bounded-file.test.ts": 26, - "test/cso-cache.test.ts": 279, - "test/cso-cli-lifecycle.test.ts": 5236, - "test/cso-cli-recheck.test.ts": 18369, - "test/cso-cli.test.ts": 30585, - "test/cso-contracts.test.ts": 261, - "test/cso-distribution.test.ts": 2283, - "test/cso-docker-integration.test.ts": 55, - "test/cso-docker-mounts.test.ts": 36, - "test/cso-docker-policy.test.ts": 28, - "test/cso-eval.test.ts": 2551, - "test/cso-git-hardening.test.ts": 595, - "test/cso-history.test.ts": 14, - "test/cso-image-provisioning.test.ts": 303, - "test/cso-launcher-generation.test.ts": 1741, - "test/cso-lease-identity.test.ts": 499, - "test/cso-macos-launcher.test.ts": 18, - "test/cso-node-lifecycle-integration.test.ts": 38, - "test/cso-ntfs-fixture.test.ts": 114, - "test/cso-postgresql-policy.test.ts": 26, - "test/cso-preparation-adversarial.test.ts": 108, - "test/cso-preparation-container.test.ts": 177, - "test/cso-preparation-executor.test.ts": 831, - "test/cso-preparation.test.ts": 138, - "test/cso-preserved.test.ts": 21, - "test/cso-public-ghcr.test.ts": 65, - "test/cso-python-runner-shadow.test.ts": 2469, - "test/cso-rails-verification.test.ts": 38, - "test/cso-registry-socket.test.ts": 2017, - "test/cso-runtime-promotion.test.ts": 34, - "test/cso-scanner-cli.test.ts": 7513, - "test/cso-scanner-docker-integration.test.ts": 37, - "test/cso-scanner-executor.test.ts": 140, - "test/cso-scanner-release.test.ts": 59, - "test/cso-scanners.test.ts": 63, - "test/cso-snapshot-disappearance-race.test.ts": 145, - "test/cso-snapshot-identity.test.ts": 460, - "test/cso-snapshot-state.test.ts": 3425, - "test/cso-spec-taxonomy-alignment.test.ts": 15, - "test/cso-stack-cold-integration.test.ts": 33, - "test/cso-verification-cleanup.test.ts": 1081, - "test/cso-verifier.test.ts": 22, - "test/cso-watchdog.test.ts": 7564, - "test/cso-windows-build-contract.test.ts": 22, - "test/cso-windows-launcher.test.ts": 22, - "test/cso-witness.test.ts": 1000, - "test/declared-annotation.test.ts": 20, - "test/dependency-security.test.ts": 59, - "test/deps-smoke.test.ts": 60, - "test/design-approval-flow.test.ts": 6295, - "test/design-board-reload.test.ts": 23, - "test/design-catalog.test.ts": 30, - "test/design-checklist-sync.test.ts": 717, - "test/design-completion-handoff-scored.test.ts": 38, - "test/design-consultation-command-contract.test.ts": 297, - "test/design-consultation-contract.test.ts": 28, - "test/design-daemon-windows-identity.test.ts": 51, - "test/design-detect-contract.test.ts": 108, - "test/design-detector-source-fixture.test.ts": 6955, - "test/design-doc-data-guard.test.ts": 16, - "test/design-flag-utils.test.ts": 31, - "test/design-html-section-completion.test.ts": 2867, - "test/design-md.test.ts": 543, - "test/design-printed-paths.test.ts": 91, - "test/design-research-fixture.test.ts": 18, - "test/design-setup-probe.test.ts": 11049, - "test/dev-setup-render-isolation.test.ts": 109, - "test/devex-finding-fixture.test.ts": 865, - "test/devex-peer-comparison-calibration.test.ts": 383, - "test/diagram-render-drift.test.ts": 313, - "test/diff-scope.test.ts": 2220, - "test/disabled-dated-record-at.test.ts": 76, - "test/disabled-plan-review-evidence.test.ts": 1172, - "test/discover-section-templates.test.ts": 21, - "test/distill-apply.test.ts": 1309, - "test/distill-free-text.test.ts": 1382, - "test/docs-config-keys.test.ts": 109, - "test/docsync-atomic-writes.test.ts": 1892, - "test/docsync-authority.test.ts": 413, - "test/docsync-child-marker.test.ts": 25, - "test/docsync-command-grammar.test.ts": 274, - "test/docsync-fault-interface.test.ts": 29390, - "test/docsync-lifecycle-interface.test.ts": 117, - "test/docsync-nested-writes.test.ts": 435, - "test/docsync-report-interface.test.ts": 395, - "test/document-skills-redaction.test.ts": 35, - "test/dom-dump-hygiene.test.ts": 718, - "test/dx-selected-navigation-ap.test.ts": 74, - "test/e2e-harness-audit.test.ts": 23, - "test/e2e-shard-reuse.test.ts": 2106, - "test/e2e-tier-alignment.test.ts": 121, - "test/egress-lib.test.ts": 376, - "test/egress-receipt-wiring.test.ts": 187, - "test/egress-receipt.test.ts": 5398, - "test/empty-find-fallthrough.test.ts": 267, - "test/eng-batching-current-ledger.test.ts": 241, + "test/ceo-mode-posture-native.test.ts": 41, + "test/ceo-mode-preference-al.test.ts": 1850, + "test/ceo-mode-prerequisite.test.ts": 1067, + "test/ceo-mode-routing-fixture.test.ts": 788, + "test/ceo-plan-mode-fixture.test.ts": 778, + "test/ceo-posture-packet.test.ts": 299, + "test/ceo-section-loading-fixture.test.ts": 339, + "test/ceo-split-collection.test.ts": 482, + "test/ceo-split-question-policy.test.ts": 398, + "test/ceo-stale-fill-decision.test.ts": 81, + "test/ceo-workflow-clarity.test.ts": 25, + "test/changed-files-union.test.ts": 378, + "test/chromium-sandbox-ci.test.ts": 232, + "test/ci-eval-cache.test.ts": 265, + "test/ci-image-cli-pin.test.ts": 25, + "test/ci-image-tag-binding.test.ts": 50, + "test/ci-native-evidence.test.ts": 776, + "test/ci-paid-coordination.test.ts": 6577, + "test/claude-code-migration.test.ts": 174, + "test/claude-code-runner.test.ts": 3074, + "test/claude-code-skill.test.ts": 1475, + "test/claude-code-windows-job.test.ts": 36, + "test/claude-md-size.test.ts": 11, + "test/claude-overlay-models.test.ts": 25, + "test/claude-overlay-setup-default.test.ts": 34320, + "test/claude-overlay-setup-installs.test.ts": 47031, + "test/claude-overlay-setup-lifecycle.test.ts": 55022, + "test/claude-producer-stream.test.ts": 3536, + "test/claude-provider-keychain.test.ts": 170, + "test/code-intelligence-cli.test.ts": 650, + "test/code-intelligence.test.ts": 4299, + "test/codex-boundary-evidence.test.ts": 13, + "test/codex-carve-fixture.test.ts": 762, + "test/codex-ci-access.test.ts": 212, + "test/codex-effort.test.ts": 1568, + "test/codex-eval-recording.test.ts": 306, + "test/codex-generation-model.test.ts": 114, + "test/codex-hardening.test.ts": 10279, + "test/codex-invocation-sites.test.ts": 322, + "test/codex-model-probe.test.ts": 5510, + "test/codex-multiblock.test.ts": 11, + "test/codex-probe-cache.test.ts": 12496, + "test/codex-probe-subcommands.test.ts": 5105, + "test/codex-resume-flag-semantics.test.ts": 13, + "test/codex-session-lifecycle.test.ts": 12014, + "test/codex-skill-isolation.test.ts": 141, + "test/codex-under-codex-detection.test.ts": 25, + "test/codex-web-search-flag.test.ts": 445, + "test/conductor-env-shim.test.ts": 9, + "test/context-bill.test.ts": 83, + "test/context-budget-ratchet.test.ts": 111, + "test/context-identity.test.ts": 25573, + "test/context-remaining-work-provenance.test.ts": 15, + "test/context-save-hardening.test.ts": 422, + "test/cookie-workflow-judge-input.test.ts": 744, + "test/cookie-workflow-manual-review.test.ts": 132, + "test/copilot-windows-bash.test.ts": 11, + "test/cost-known.test.ts": 87, + "test/coverage-audit-evidence.test.ts": 176, + "test/coverage-audit.test.ts": 1280, + "test/cso-bounded-file.test.ts": 29, + "test/cso-cache.test.ts": 314, + "test/cso-cli-lifecycle.test.ts": 5069, + "test/cso-cli-recheck.test.ts": 17629, + "test/cso-cli.test.ts": 29819, + "test/cso-contracts.test.ts": 242, + "test/cso-distribution.test.ts": 3183, + "test/cso-docker-integration.test.ts": 28, + "test/cso-docker-mounts.test.ts": 43, + "test/cso-docker-policy.test.ts": 25, + "test/cso-docker-socket-realpath.test.ts": 29, + "test/cso-eval.test.ts": 7658, + "test/cso-file-ceiling.test.ts": 31627, + "test/cso-git-global-config.test.ts": 27, + "test/cso-git-hardening.test.ts": 329, + "test/cso-history.test.ts": 13, + "test/cso-image-provisioning.test.ts": 283, + "test/cso-launcher-generation.test.ts": 1631, + "test/cso-lease-identity.test.ts": 491, + "test/cso-macos-launcher.test.ts": 21, + "test/cso-native-evidence.test.ts": 92, + "test/cso-node-lifecycle-integration.test.ts": 39, + "test/cso-ntfs-fixture.test.ts": 111, + "test/cso-postgresql-policy.test.ts": 25, + "test/cso-preparation-adversarial.test.ts": 137, + "test/cso-preparation-container.test.ts": 83, + "test/cso-preparation-executor.test.ts": 690, + "test/cso-preparation-java.test.ts": 28, + "test/cso-preparation.test.ts": 72, + "test/cso-preserved.test.ts": 15, + "test/cso-public-ghcr.test.ts": 30, + "test/cso-python-runner-shadow.test.ts": 2634, + "test/cso-rails-verification.test.ts": 31, + "test/cso-registry-socket.test.ts": 1812, + "test/cso-requalification.test.ts": 3194, + "test/cso-runtime-promotion.test.ts": 146, + "test/cso-scanner-cli.test.ts": 7588, + "test/cso-scanner-docker-integration.test.ts": 36, + "test/cso-scanner-executor.test.ts": 128, + "test/cso-scanner-release.test.ts": 131, + "test/cso-scanners.test.ts": 81, + "test/cso-snapshot-disappearance-race.test.ts": 189, + "test/cso-snapshot-identity.test.ts": 443, + "test/cso-snapshot-state.test.ts": 3612, + "test/cso-spec-taxonomy-alignment.test.ts": 13, + "test/cso-stack-cold-integration.test.ts": 29, + "test/cso-staging-run.test.ts": 82, + "test/cso-verification-cleanup.test.ts": 1072, + "test/cso-verifier.test.ts": 108, + "test/cso-watchdog.test.ts": 8237, + "test/cso-windows-build-contract.test.ts": 16, + "test/cso-windows-docker.test.ts": 20, + "test/cso-windows-launcher.test.ts": 23, + "test/cso-witness.test.ts": 948, + "test/declared-annotation.test.ts": 16, + "test/defensive-review-framing.test.ts": 14, + "test/dependency-security.test.ts": 53, + "test/deps-smoke.test.ts": 52, + "test/design-approval-flow.test.ts": 6434, + "test/design-board-reload.test.ts": 22, + "test/design-catalog.test.ts": 29, + "test/design-checklist-sync.test.ts": 818, + "test/design-completion-handoff-scored.test.ts": 44, + "test/design-consultation-command-contract.test.ts": 305, + "test/design-consultation-contract.test.ts": 27, + "test/design-daemon-windows-identity.test.ts": 42, + "test/design-detect-contract.test.ts": 141, + "test/design-detector-source-fixture.test.ts": 5985, + "test/design-doc-data-guard.test.ts": 13, + "test/design-flag-utils.test.ts": 27, + "test/design-html-section-completion.test.ts": 2953, + "test/design-md.test.ts": 548, + "test/design-printed-paths.test.ts": 84, + "test/design-research-fixture.test.ts": 22, + "test/design-setup-probe.test.ts": 11343, + "test/detector-corpora.test.ts": 381, + "test/detector-corpus-auto-decide-preserved.test.ts": 42, + "test/detector-corpus-plan-ceo-section-loading.test.ts": 47, + "test/detector-corpus-plan-design-review-plan-mode.test.ts": 274, + "test/detector-corpus-plan-eng-multi-finding-batching.test.ts": 255, + "test/detector-corpus-shared-libs-plan-callers.test.ts": 23, + "test/detector-corpus-ship-docsync-late-result.test.ts": 48, + "test/dev-setup-render-isolation.test.ts": 159, + "test/devex-finding-fixture.test.ts": 1112, + "test/devex-peer-comparison-calibration.test.ts": 322, + "test/diagram-render-drift.test.ts": 311, + "test/diff-scope.test.ts": 1961, + "test/disabled-dated-record-at.test.ts": 129, + "test/disabled-plan-review-evidence.test.ts": 1340, + "test/discover-section-templates.test.ts": 14, + "test/dispatch-rules.test.ts": 34, + "test/distill-apply.test.ts": 1018, + "test/distill-free-text.test.ts": 1009, + "test/docs-config-keys.test.ts": 161, + "test/docsync-atomic-writes.test.ts": 1577, + "test/docsync-authority.test.ts": 546, + "test/docsync-child-marker.test.ts": 21, + "test/docsync-command-grammar.test.ts": 263, + "test/docsync-fault-interface.test.ts": 27316, + "test/docsync-lifecycle-interface.test.ts": 138, + "test/docsync-nested-writes.test.ts": 729, + "test/docsync-report-interface.test.ts": 376, + "test/doctor-components.test.ts": 20, + "test/document-skills-redaction.test.ts": 18, + "test/dom-dump-hygiene.test.ts": 759, + "test/dx-selected-navigation-ap.test.ts": 102, + "test/e2e-harness-audit.test.ts": 20, + "test/e2e-shard-reuse.test.ts": 2335, + "test/e2e-tier-alignment.test.ts": 136, + "test/egress-lib.test.ts": 302, + "test/egress-receipt-wiring.test.ts": 193, + "test/egress-receipt.test.ts": 5416, + "test/empty-find-fallthrough.test.ts": 250, + "test/eng-batching-current-ledger.test.ts": 235, "test/eng-batching-native-replay.test.ts": 62, - "test/eng-batching-saved-ledger.test.ts": 594, - "test/eng-count-question-policy.test.ts": 39, - "test/eng-devex-s-count.test.ts": 52, - "test/eng-finding-retry-budget.test.ts": 558, - "test/eng-first-review.test.ts": 231, - "test/eng-published-navigation.test.ts": 66, - "test/eng-resolution-block-position.test.ts": 250, - "test/eng-review-routing.test.ts": 27, - "test/eng-scope-entry-ap.test.ts": 76, - "test/eng-seeded-completion-ai.test.ts": 12154, - "test/eng-seeded-coverage.test.ts": 1489, - "test/eng-semantic-terminal.test.ts": 127, - "test/eng-test-plan-edit-approval.test.ts": 1021, - "test/env-host-fence-conformance.test.ts": 5625, - "test/eval-budgets-policy.test.ts": 45, - "test/eval-cli-family.test.ts": 1325, - "test/eval-detach-timeout-floor.test.ts": 1040, - "test/eval-flake-rank.test.ts": 211, - "test/eval-input-cache.test.ts": 67, - "test/eval-kinds.test.ts": 43, - "test/eval-list-cli.test.ts": 202, - "test/eval-model.test.ts": 11, - "test/evals-pr-lane-workflow.test.ts": 16, - "test/evals-workflow-wiring.test.ts": 216, - "test/evidence.test.ts": 7519, - "test/exit-propagation.test.ts": 350, - "test/explain-level-config.test.ts": 356, - "test/extension-pty-inject-invariant.test.ts": 17, - "test/external-host-carve.test.ts": 2013, - "test/flake-ledger.test.ts": 36, - "test/founder-resources-optout.test.ts": 123, - "test/free-fixtures.test.ts": 982, - "test/free-home-guard.test.ts": 82, - "test/free-seed-ratchet.test.ts": 87, - "test/free-tests-workflow-wiring.test.ts": 27, - "test/freeze-owned-lifecycle.test.ts": 3045, - "test/frontend-scope.test.ts": 1198, - "test/fs-atomic.test.ts": 26, - "test/fs-utils.test.ts": 227, - "test/gate-secret-scan.test.ts": 588, - "test/gate-tail-lint.test.ts": 1573, - "test/gbrain-cycle-completed.test.ts": 39, - "test/gbrain-detect-install.test.ts": 691, - "test/gbrain-detect-shape.test.ts": 443, - "test/gbrain-detection-override.test.ts": 928, - "test/gbrain-dream-stage.test.ts": 255, - "test/gbrain-exec-invariant.test.ts": 18, - "test/gbrain-guards.test.ts": 28, - "test/gbrain-init-voyage-code-3.test.ts": 164, - "test/gbrain-lib-validate-varname.test.ts": 59, - "test/gbrain-lib-verify.test.ts": 143, - "test/gbrain-local-status.test.ts": 3852, - "test/gbrain-prune-gone-worktrees.test.ts": 291, - "test/gbrain-read-capability.test.ts": 2074, - "test/gbrain-refresh-install-render.test.ts": 15, - "test/gbrain-repo-policy-client.test.ts": 822, - "test/gbrain-repo-policy.test.ts": 1369, - "test/gbrain-source-gitignore.test.ts": 25, - "test/gbrain-source-worktree-advance.test.ts": 664, - "test/gbrain-sources-parse.test.ts": 21, - "test/gbrain-sources.test.ts": 120, - "test/gbrain-spawn-windows-shell.test.ts": 22, - "test/gbrain-structured-busy.test.ts": 2231, - "test/gbrain-supabase-provision.test.ts": 142, - "test/gbrain-sync-skip.test.ts": 10653, - "test/gbrain-sync-voyage-code-3-integration.test.ts": 19, - "test/gen-skill-docs-checks.test.ts": 10271, - "test/gen-skill-docs-idempotency.test.ts": 2368, - "test/gen-skill-docs-import-purity.test.ts": 39, - "test/gen-skill-docs-out-dir.test.ts": 2089, - "test/gen-skill-docs-prune-stale.test.ts": 648, - "test/gen-skill-docs.test.ts": 5322, - "test/generated-docs-fences.test.ts": 199, - "test/generator-eexist.test.ts": 304, - "test/git-ref-fixture-tripwire.test.ts": 104, - "test/global-discover.test.ts": 267, + "test/eng-batching-saved-ledger.test.ts": 591, + "test/eng-count-question-policy.test.ts": 31, + "test/eng-devex-s-count.test.ts": 42, + "test/eng-finding-retry-budget.test.ts": 468, + "test/eng-first-review.test.ts": 245, + "test/eng-published-navigation.test.ts": 71, + "test/eng-resolution-block-position.test.ts": 244, + "test/eng-review-routing.test.ts": 24, + "test/eng-scope-entry-ap.test.ts": 78, + "test/eng-seeded-completion-ai.test.ts": 12134, + "test/eng-seeded-coverage.test.ts": 1388, + "test/eng-semantic-terminal.test.ts": 74, + "test/eng-test-plan-edit-approval.test.ts": 993, + "test/env-host-fence-conformance.test.ts": 7384, + "test/env-host-runtime-assets.test.ts": 1475, + "test/eval-budgets-policy.test.ts": 54, + "test/eval-cli-family.test.ts": 1519, + "test/eval-detach-timeout-floor.test.ts": 1187, + "test/eval-flake-rank.test.ts": 214, + "test/eval-history.test.ts": 1863, + "test/eval-input-cache.test.ts": 73, + "test/eval-kinds.test.ts": 48, + "test/eval-list-cli.test.ts": 198, + "test/eval-model.test.ts": 9, + "test/eval-sweep-workflow.test.ts": 14, + "test/evals-pr-lane-workflow.test.ts": 14, + "test/evals-tracking-issue.test.ts": 225, + "test/evals-workflow-wiring.test.ts": 254, + "test/evidence-bundle-portability.test.ts": 4205, + "test/evidence.test.ts": 13605, + "test/exit-propagation.test.ts": 336, + "test/explain-level-config.test.ts": 588, + "test/extension-pty-inject-invariant.test.ts": 20, + "test/external-host-carve.test.ts": 2237, + "test/flake-ledger.test.ts": 37, + "test/founder-resources-optout.test.ts": 149, + "test/free-fixtures.test.ts": 1206, + "test/free-home-guard.test.ts": 174, + "test/free-seed-ratchet.test.ts": 63, + "test/free-tests-workflow-wiring.test.ts": 24, + "test/freeze-owned-lifecycle.test.ts": 2992, + "test/frontend-scope.test.ts": 1093, + "test/fs-atomic.test.ts": 35, + "test/fs-utils.test.ts": 250, + "test/gate-diff-cli.test.ts": 3008, + "test/gate-diff.test.ts": 48, + "test/gate-integrity-templates.test.ts": 46, + "test/gate-list.test.ts": 243, + "test/gate-secret-scan.test.ts": 549, + "test/gate-tail-lint.test.ts": 1555, + "test/gbrain-cycle-completed.test.ts": 43, + "test/gbrain-detect-install.test.ts": 634, + "test/gbrain-detect-shape.test.ts": 428, + "test/gbrain-detection-override.test.ts": 1061, + "test/gbrain-dream-stage.test.ts": 266, + "test/gbrain-exec-invariant.test.ts": 13, + "test/gbrain-guards.test.ts": 22, + "test/gbrain-init-voyage-code-3.test.ts": 167, + "test/gbrain-lib-validate-varname.test.ts": 50, + "test/gbrain-lib-verify.test.ts": 161, + "test/gbrain-local-status.test.ts": 3925, + "test/gbrain-prune-gone-worktrees.test.ts": 270, + "test/gbrain-read-capability.test.ts": 1624, + "test/gbrain-refresh-install-render.test.ts": 10, + "test/gbrain-repo-policy-client.test.ts": 881, + "test/gbrain-repo-policy.test.ts": 1487, + "test/gbrain-source-gitignore.test.ts": 26, + "test/gbrain-source-worktree-advance.test.ts": 768, + "test/gbrain-sources-parse.test.ts": 18, + "test/gbrain-sources.test.ts": 110, + "test/gbrain-spawn-windows-shell.test.ts": 19, + "test/gbrain-structured-busy.test.ts": 1751, + "test/gbrain-supabase-provision.test.ts": 134, + "test/gbrain-sync-skip.test.ts": 10695, + "test/gbrain-sync-voyage-code-3-integration.test.ts": 14, + "test/gen-skill-docs-checks.test.ts": 11679, + "test/gen-skill-docs-idempotency.test.ts": 2729, + "test/gen-skill-docs-import-purity.test.ts": 38, + "test/gen-skill-docs-out-dir.test.ts": 2511, + "test/gen-skill-docs-prune-stale.test.ts": 713, + "test/gen-skill-docs.test.ts": 6678, + "test/generated-bash-placeholders.test.ts": 623, + "test/generated-docs-fences.test.ts": 203, + "test/generator-eexist.test.ts": 352, + "test/git-ref-fixture-tripwire.test.ts": 103, + "test/gitattributes-eol.test.ts": 874, + "test/global-discover.test.ts": 722, + "test/greptile-early-cli.test.ts": 249, + "test/greptile-early.test.ts": 25, "test/gstack-analytics-avg-duration.test.ts": 214, - "test/gstack-artifacts-init.test.ts": 6071, - "test/gstack-artifacts-url.test.ts": 120, - "test/gstack-brain-context-load.test.ts": 1067, + "test/gstack-artifacts-init.test.ts": 6656, + "test/gstack-artifacts-url.test.ts": 123, + "test/gstack-brain-context-load.test.ts": 899, + "test/gstack-browser-ensure.test.ts": 3315, + "test/gstack-capy-install.test.ts": 5793, "test/gstack-ci-gate.test.ts": 25, - "test/gstack-codex-session-import.test.ts": 651, - "test/gstack-config-browse-extension-id.test.ts": 299, - "test/gstack-config-cross-project.test.ts": 197, - "test/gstack-config-defaults.test.ts": 4668, - "test/gstack-config-gbrain-refresh.test.ts": 167, - "test/gstack-config-key-locale.test.ts": 136, - "test/gstack-config-memorable-key.test.ts": 388, - "test/gstack-config-redact-keys.test.ts": 187, - "test/gstack-config-transcript-scope.test.ts": 2581, - "test/gstack-context-recovery.test.ts": 113, - "test/gstack-decision-bins.test.ts": 5622, - "test/gstack-decision-semantic.test.ts": 39, - "test/gstack-decision.test.ts": 86, - "test/gstack-design-claim.test.ts": 673, - "test/gstack-design-detect-plugins.test.ts": 375, - "test/gstack-design-detect.test.ts": 16142, - "test/gstack-design-doc-find.test.ts": 346, - "test/gstack-detach.test.ts": 23780, - "test/gstack-developer-profile.test.ts": 11773, - "test/gstack-docs-candidate.test.ts": 526, - "test/gstack-egress-cli.test.ts": 585, - "test/gstack-gbrain-detect-mcp-mode.test.ts": 926, - "test/gstack-gbrain-mcp-verify.test.ts": 1242, - "test/gstack-gbrain-source-wireup.test.ts": 2711, - "test/gstack-gbrain-sync-transcript-mode.test.ts": 2500, - "test/gstack-gbrain-sync.test.ts": 1905, - "test/gstack-home-module-scope.test.ts": 71, - "test/gstack-learnings-search.test.ts": 1661, - "test/gstack-memorable.test.ts": 8823, - "test/gstack-memory-helpers.test.ts": 11132, - "test/gstack-memory-ingest.test.ts": 13878, - "test/gstack-next-version.test.ts": 1637, - "test/gstack-paths.test.ts": 949, - "test/gstack-question-log.test.ts": 2540, - "test/gstack-question-preference.test.ts": 7386, - "test/gstack-redact-cli.test.ts": 3399, - "test/gstack-render-cli.test.ts": 470, - "test/gstack-repo-mode.test.ts": 1212, - "test/gstack-retro-metrics.test.ts": 723, - "test/gstack-safe-git.test.ts": 999, - "test/gstack-schema-pack.test.ts": 13, - "test/gstack-session-kind.test.ts": 58, - "test/gstack-settings-hook-schema-aware.test.ts": 5595, - "test/gstack-settings-hook-symlink.test.ts": 1366, - "test/gstack-skill-start.test.ts": 6635, - "test/gstack-slug-cwd-walk-up.test.ts": 856, - "test/gstack-slug-get.test.ts": 414, - "test/gstack-slug-parity.test.ts": 4012, - "test/gstack-slug-sanitize.test.ts": 141, - "test/gstack-state-root-override.test.ts": 478, - "test/gstack-team-init-hook-schema.test.ts": 110, - "test/gstack-upgrade-fresh-shell.test.ts": 4110, - "test/gstack-upgrade-migration-v1_17_0_0.test.ts": 62, - "test/gstack-upgrade-migration-v1_37_0_0.test.ts": 94, - "test/gstack-upgrade-migration-v1_40_0_0.test.ts": 156, - "test/gstack-upgrade-migration-v1_78_0_0.test.ts": 38, - "test/gstack-upgrade-migration-v1_91_19_0.test.ts": 147, - "test/gstack-version-bump.test.ts": 1836, - "test/harness-version.test.ts": 100, - "test/health-capture.test.ts": 139, - "test/health-eval-fixture.test.ts": 178, - "test/helpers-unit.test.ts": 37, - "test/helpers/budget-override.test.ts": 16, - "test/helpers/capture-parity-baseline.test.ts": 143, + "test/gstack-codex-session-import.test.ts": 660, + "test/gstack-config-browse-extension-id.test.ts": 362, + "test/gstack-config-cross-project.test.ts": 215, + "test/gstack-config-defaults.test.ts": 5994, + "test/gstack-config-gbrain-refresh.test.ts": 130, + "test/gstack-config-key-locale.test.ts": 138, + "test/gstack-config-memorable-key.test.ts": 401, + "test/gstack-config-redact-keys.test.ts": 295, + "test/gstack-config-transcript-scope.test.ts": 2475, + "test/gstack-context-recovery.test.ts": 105, + "test/gstack-decision-bins.test.ts": 6121, + "test/gstack-decision-semantic.test.ts": 37, + "test/gstack-decision.test.ts": 24, + "test/gstack-design-claim.test.ts": 754, + "test/gstack-design-detect-plugins.test.ts": 354, + "test/gstack-design-detect.test.ts": 16090, + "test/gstack-design-doc-find.test.ts": 404, + "test/gstack-detach.test.ts": 23805, + "test/gstack-developer-profile.test.ts": 14209, + "test/gstack-docs-candidate.test.ts": 937, + "test/gstack-doctor.test.ts": 23299, + "test/gstack-egress-cli.test.ts": 551, + "test/gstack-gbrain-detect-mcp-mode.test.ts": 938, + "test/gstack-gbrain-mcp-verify.test.ts": 1240, + "test/gstack-gbrain-source-wireup.test.ts": 2974, + "test/gstack-gbrain-sync-transcript-mode.test.ts": 2471, + "test/gstack-gbrain-sync.test.ts": 1938, + "test/gstack-home-module-scope.test.ts": 67, + "test/gstack-launch-probe.test.ts": 110, + "test/gstack-learnings-search.test.ts": 1856, + "test/gstack-lease.test.ts": 948, + "test/gstack-memorable.test.ts": 8619, + "test/gstack-memory-helpers.test.ts": 11103, + "test/gstack-memory-ingest.test.ts": 13647, + "test/gstack-next-version.test.ts": 1469, + "test/gstack-paths.test.ts": 944, + "test/gstack-post-cli.test.ts": 460, + "test/gstack-post.test.ts": 26, + "test/gstack-question-log.test.ts": 2744, + "test/gstack-question-preference.test.ts": 9361, + "test/gstack-redact-cli.test.ts": 3346, + "test/gstack-regen.test.ts": 2152, + "test/gstack-render-cli.test.ts": 412, + "test/gstack-repo-mode.test.ts": 1410, + "test/gstack-restamp-queue.test.ts": 9472, + "test/gstack-retro-metrics.test.ts": 726, + "test/gstack-safe-git.test.ts": 1131, + "test/gstack-schema-pack.test.ts": 11, + "test/gstack-session-kind.test.ts": 154, + "test/gstack-settings-hook-schema-aware.test.ts": 5276, + "test/gstack-settings-hook-symlink.test.ts": 1339, + "test/gstack-ship-policy.test.ts": 1340, + "test/gstack-ship-receipt.test.ts": 1634, + "test/gstack-skill-start.test.ts": 21654, + "test/gstack-slug-cwd-walk-up.test.ts": 904, + "test/gstack-slug-get.test.ts": 500, + "test/gstack-slug-parity.test.ts": 4728, + "test/gstack-slug-sanitize.test.ts": 171, + "test/gstack-state-root-override.test.ts": 571, + "test/gstack-team-init-hook-schema.test.ts": 163, + "test/gstack-upgrade-bin.test.ts": 6020, + "test/gstack-upgrade-fresh-shell.test.ts": 5524, + "test/gstack-upgrade-migration-v1_17_0_0.test.ts": 49, + "test/gstack-upgrade-migration-v1_37_0_0.test.ts": 117, + "test/gstack-upgrade-migration-v1_40_0_0.test.ts": 188, + "test/gstack-upgrade-migration-v1_78_0_0.test.ts": 45, + "test/gstack-upgrade-migration-v1_91_19_0.test.ts": 157, + "test/gstack-version-bump.test.ts": 1759, + "test/gstack-wtree-windows-paths.test.ts": 186, + "test/harness-version.test.ts": 115, + "test/headless-artifacts.test.ts": 751, + "test/health-capture.test.ts": 207, + "test/health-eval-fixture.test.ts": 279, + "test/helpers-unit.test.ts": 39, + "test/helpers/budget-override.test.ts": 18, + "test/helpers/capture-parity-baseline.test.ts": 166, "test/helpers/claude-pty-runner.auq.unit.test.ts": 52, - "test/helpers/claude-pty-runner.boundaries.unit.test.ts": 56, - "test/helpers/claude-pty-runner.classify.unit.test.ts": 41, - "test/helpers/claude-pty-runner.launch.unit.test.ts": 282, - "test/helpers/claude-pty-runner.plan-native.unit.test.ts": 41, - "test/helpers/claude-pty-runner.runners.unit.test.ts": 272, - "test/helpers/claude-pty-runner.scope-gate-floor.unit.test.ts": 43, - "test/helpers/claude-pty-runner.screen.unit.test.ts": 44, - "test/helpers/e2e-gate.unit.test.ts": 90, - "test/helpers/eval-store.test.ts": 254, - "test/helpers/hermetic-env.test.ts": 1014, - "test/helpers/observability.test.ts": 57, - "test/helpers/providers/gemini.test.ts": 22, + "test/helpers/claude-pty-runner.boundaries.unit.test.ts": 70, + "test/helpers/claude-pty-runner.classify.unit.test.ts": 61, + "test/helpers/claude-pty-runner.launch.unit.test.ts": 302, + "test/helpers/claude-pty-runner.plan-native.unit.test.ts": 48, + "test/helpers/claude-pty-runner.runners.unit.test.ts": 284, + "test/helpers/claude-pty-runner.scope-gate-floor.unit.test.ts": 45, + "test/helpers/claude-pty-runner.screen.unit.test.ts": 67, + "test/helpers/e2e-gate.unit.test.ts": 18, + "test/helpers/eval-store.test.ts": 316, + "test/helpers/hermetic-env.test.ts": 1223, + "test/helpers/observability.test.ts": 81, + "test/helpers/providers/gemini.test.ts": 39, "test/helpers/resolve-repo-path.test.ts": 17, - "test/helpers/run-bin.test.ts": 22, - "test/helpers/session-runner.test.ts": 95, - "test/helpers/sync-command-capture.test.ts": 1069, - "test/heredoc-pipe-deadlock.test.ts": 127, - "test/hermetic-skill-runtime.test.ts": 2120, - "test/hermetic-skills-seeding.test.ts": 133, - "test/hermetic-wiring.test.ts": 147, - "test/hook-log.test.ts": 260, - "test/hook-scripts.test.ts": 16635, + "test/helpers/run-bin.test.ts": 24, + "test/helpers/session-runner.test.ts": 100, + "test/helpers/sync-command-capture.test.ts": 1050, + "test/heredoc-pipe-deadlock.test.ts": 128, + "test/hermetic-skill-runtime.test.ts": 2480, + "test/hermetic-skills-seeding.test.ts": 154, + "test/hermetic-wiring.test.ts": 174, + "test/honesty-kernel.test.ts": 42, + "test/hook-log.test.ts": 231, + "test/hook-scripts.test.ts": 26541, "test/hooks-windows-paths.test.ts": 132, - "test/host-config.test.ts": 1529, - "test/host-conformance.test.ts": 70830, - "test/hostile-path-writers.test.ts": 2026, - "test/impeccable-fixtures.test.ts": 20, - "test/install-fixture.test.ts": 901, - "test/instruction-facts.test.ts": 51, - "test/investigate-freeze-path.test.ts": 3645, - "test/ios-debug-bridge-release-guard.test.ts": 16, - "test/ios-qa-daemon-cli.test.ts": 22, - "test/ios-qa-regen.test.ts": 231, - "test/ios-qa-stateserver-hardening.test.ts": 15, - "test/ios-qa-swift-build.test.ts": 20, - "test/ios-qa.test.ts": 327, - "test/is-conductor.test.ts": 11, - "test/jargon-list.test.ts": 29, - "test/jsonl-merge.test.ts": 286, - "test/jsonl-store.test.ts": 20, - "test/judge-calibration.test.ts": 49, - "test/land-and-deploy-ci-gate.test.ts": 2944, - "test/land-and-deploy-flow.test.ts": 555, - "test/land-and-deploy-postfail.test.ts": 36, - "test/learnings-callers-unavailable.test.ts": 1224, - "test/learnings-injection.test.ts": 15, - "test/learnings.test.ts": 4579, - "test/llm-judge-abort.test.ts": 28, - "test/llm-judge-frontier.test.ts": 96, - "test/llm-judge-stream.test.ts": 35, - "test/llms-txt-shape.test.ts": 28, - "test/maintenance-cli-args.test.ts": 195, - "test/memorable-user-prompt-hook.test.ts": 11526, - "test/memory-cache-injection.test.ts": 298, - "test/memory-ingest-include-gitignored.test.ts": 60, - "test/memory-ingest-landing.test.ts": 2005, - "test/memory-ingest-sources.test.ts": 1063, - "test/memory-ingest-timeout.test.ts": 24, - "test/memory-pipeline.test.ts": 584, - "test/migration-checkpoint-ownership.test.ts": 124, - "test/migrations-v1.27.0.0.test.ts": 714, - "test/migrations-v1.65.0.0.test.ts": 214, - "test/mktemp-portability.test.ts": 76, - "test/model-overlays.test.ts": 24, - "test/module-size-ratchet.test.ts": 104, - "test/native-auto-decide-pty.test.ts": 10141, - "test/native-auto-decide.test.ts": 279, - "test/no-quoted-tilde-assignments.test.ts": 37, - "test/no-stale-gstack-brain-refs.test.ts": 347, - "test/no-suicide-exit.test.ts": 101, - "test/office-hours-attempt.test.ts": 39397, - "test/office-hours-budget.test.ts": 38, - "test/office-hours-completion.test.ts": 213, - "test/office-hours-open-question-form.test.ts": 19, - "test/office-hours-phase4-caller.test.ts": 36, - "test/office-hours-review.test.ts": 450, - "test/office-hours-writeback-env.test.ts": 456, - "test/office-posture-recording.test.ts": 52, + "test/host-config.test.ts": 2652, + "test/host-conformance.test.ts": 88220, + "test/host-renders-prune.test.ts": 63454, + "test/host-renders.test.ts": 23899, + "test/hostile-path-writers.test.ts": 2246, + "test/impeccable-fixtures.test.ts": 15, + "test/install-fixture.test.ts": 1045, + "test/install-verdict.test.ts": 106, + "test/instruction-facts.test.ts": 58, + "test/investigate-freeze-path.test.ts": 5436, + "test/investigate-recipes.test.ts": 125, + "test/ios-debug-bridge-release-guard.test.ts": 11, + "test/ios-qa-daemon-cli.test.ts": 23, + "test/ios-qa-regen.test.ts": 278, + "test/ios-qa-stateserver-hardening.test.ts": 14, + "test/ios-qa-swift-build.test.ts": 17, + "test/ios-qa.test.ts": 205, + "test/is-conductor.test.ts": 9, + "test/jargon-list.test.ts": 13, + "test/jsonl-merge.test.ts": 320, + "test/jsonl-store.test.ts": 16, + "test/judge-calibration.test.ts": 55, + "test/judge-panel-median.test.ts": 49, + "test/land-and-deploy-ci-gate.test.ts": 3185, + "test/land-and-deploy-command-trigger.test.ts": 13, + "test/land-and-deploy-flow.test.ts": 699, + "test/land-and-deploy-postfail.test.ts": 16, + "test/lane-coordination.test.ts": 1877, + "test/learnings-callers-unavailable.test.ts": 1442, + "test/learnings-injection.test.ts": 14, + "test/learnings.test.ts": 5210, + "test/llm-judge-abort.test.ts": 26, + "test/llm-judge-frontier.test.ts": 110, + "test/llm-judge-stream.test.ts": 37, + "test/llms-txt-shape.test.ts": 34, + "test/maintenance-cli-args.test.ts": 154, + "test/memorable-user-prompt-hook.test.ts": 11317, + "test/memory-cache-injection.test.ts": 300, + "test/memory-ingest-include-gitignored.test.ts": 56, + "test/memory-ingest-landing.test.ts": 1641, + "test/memory-ingest-sources.test.ts": 2647, + "test/memory-ingest-timeout.test.ts": 25, + "test/memory-pipeline.test.ts": 712, + "test/migration-checkpoint-ownership.test.ts": 132, + "test/migrations-v1.27.0.0.test.ts": 825, + "test/migrations-v1.65.0.0.test.ts": 233, + "test/mktemp-portability.test.ts": 80, + "test/model-catalog-isolation.test.ts": 65, + "test/model-overlays.test.ts": 20, + "test/model-policy-cli.test.ts": 3238, + "test/model-policy-freshness.test.ts": 176, + "test/model-policy-workflow.test.ts": 238, + "test/model-policy.test.ts": 63, + "test/model-role-invocation.test.ts": 34715, + "test/module-size-ratchet.test.ts": 183, + "test/native-auto-decide-pty.test.ts": 10065, + "test/native-auto-decide.test.ts": 323, + "test/no-quoted-tilde-assignments.test.ts": 31, + "test/no-stale-gstack-brain-refs.test.ts": 354, + "test/no-suicide-exit.test.ts": 98, + "test/office-hours-attempt.test.ts": 39337, + "test/office-hours-budget.test.ts": 35, + "test/office-hours-completion.test.ts": 140, + "test/office-hours-open-question-form.test.ts": 30, + "test/office-hours-phase4-caller.test.ts": 38, + "test/office-hours-review.test.ts": 1017, + "test/office-hours-writeback-env.test.ts": 471, + "test/office-posture-recording.test.ts": 53, "test/onboarding-moved-literals.test.ts": 41, "test/one-way-doors.test.ts": 11, - "test/open-gstack-browser-liveness.test.ts": 16, - "test/openclaw-native-skills.test.ts": 20, - "test/osv-config-wiring.test.ts": 15, - "test/osv-ignore-expiry.test.ts": 15, - "test/outside-review-result.test.ts": 171, + "test/open-gstack-browser-liveness.test.ts": 13, + "test/openclaw-native-skills.test.ts": 13, + "test/osv-config-wiring.test.ts": 32, + "test/osv-ignore-expiry.test.ts": 10, + "test/outside-consent.test.ts": 1004, + "test/outside-review-result.test.ts": 789, + "test/outside-review-severity.test.ts": 81, + "test/outside-review-unparsed-severity.test.ts": 145, + "test/outside-runner-contract.test.ts": 734, + "test/outside-send-boundary.test.ts": 349, "test/outside-voice-evidence.test.ts": 50, - "test/outside-voice-failure-policy.test.ts": 119, - "test/outside-voice-fixture.test.ts": 210, - "test/outside-voice-invocation.test.ts": 7327, - "test/outside-voice-preflight.test.ts": 389, - "test/outside-voice-provenance.test.ts": 823, - "test/outside-voice-receipt.test.ts": 336, - "test/outside-voice-routing.test.ts": 876, - "test/overlay-lifecycle.test.ts": 318, - "test/overlay-measurement.test.ts": 323, - "test/overlay-recording-order.test.ts": 30, - "test/overlay-sdk-cancel-eof.test.ts": 124, - "test/paid-free-boundary.test.ts": 1765, - "test/paid-orphan-tripwire.test.ts": 73, - "test/paid-overlay-scheduling.test.ts": 396, - "test/paid-pr-profile.test.ts": 1220, - "test/paid-report-census.test.ts": 51, - "test/paid-report-fail-open.test.ts": 910, - "test/paid-retry-supervision.test.ts": 1259, - "test/paid-run-manifest.test.ts": 1471, - "test/paid-selection-propagation.test.ts": 42, - "test/paid-shard-settlement.test.ts": 1264, - "test/paid-shards.test.ts": 2468, - "test/paid-slice-deadline.test.ts": 1539, - "test/pair-agent-token-hygiene.test.ts": 17, - "test/parity-baseline-integrity.test.ts": 22, - "test/parity-sectioned.test.ts": 18, - "test/parity-suite.test.ts": 100, - "test/pending-question-completion.test.ts": 122, - "test/periodic-exclude-policy.test.ts": 83, - "test/plan-count-artifacts.test.ts": 32, + "test/outside-voice-failure-policy.test.ts": 150, + "test/outside-voice-fixture.test.ts": 205, + "test/outside-voice-invocation.test.ts": 8911, + "test/outside-voice-preflight.test.ts": 371, + "test/outside-voice-provenance.test.ts": 1109, + "test/outside-voice-receipt.test.ts": 419, + "test/outside-voice-routing.test.ts": 1202, + "test/overlay-lifecycle.test.ts": 314, + "test/overlay-measurement.test.ts": 272, + "test/overlay-recording-order.test.ts": 26, + "test/overlay-sdk-cancel-eof.test.ts": 118, + "test/owner-brief-contributor-banned.test.ts": 469, + "test/paid-free-boundary.test.ts": 2404, + "test/paid-orphan-tripwire.test.ts": 88, + "test/paid-overlay-scheduling.test.ts": 521, + "test/paid-pr-profile.test.ts": 1441, + "test/paid-report-census.test.ts": 188, + "test/paid-report-fail-open.test.ts": 1328, + "test/paid-retry-supervision.test.ts": 1123, + "test/paid-run-manifest.test.ts": 1635, + "test/paid-selection-propagation.test.ts": 61, + "test/paid-shard-settlement.test.ts": 1269, + "test/paid-shards.test.ts": 5942, + "test/paid-slice-deadline.test.ts": 1542, + "test/pair-agent-token-hygiene.test.ts": 12, + "test/parity-baseline-integrity.test.ts": 19, + "test/parity-sectioned.test.ts": 16, + "test/parity-suite.test.ts": 98, + "test/path-spelling.test.ts": 345, + "test/pending-question-completion.test.ts": 108, + "test/periodic-exclude-policy.test.ts": 86, + "test/plan-ceo-floor-interactive-boundary.test.ts": 1207, + "test/plan-count-artifacts.test.ts": 35, "test/plan-count-checkbox.test.ts": 15261, - "test/plan-count-clipped-elision.test.ts": 57, - "test/plan-count-collection-completion.test.ts": 29806, - "test/plan-count-completion.test.ts": 13868, - "test/plan-count-cropped-wrap.test.ts": 81, - "test/plan-count-cross-cwd-ancestry.test.ts": 120, - "test/plan-count-design-ui-recovery.test.ts": 15671, - "test/plan-count-dx-handoff.test.ts": 79, - "test/plan-count-empty-review.test.ts": 1530, - "test/plan-count-file-permission.test.ts": 44605, - "test/plan-count-fixture.test.ts": 14980, - "test/plan-count-history.test.ts": 746, - "test/plan-count-long-edit.test.ts": 42, - "test/plan-count-native-input.test.ts": 11561, - "test/plan-count-owned-permission.test.ts": 11419, - "test/plan-count-pending-exit.test.ts": 310, - "test/plan-count-prerequisite.test.ts": 48, - "test/plan-count-preview-footer.test.ts": 3463, - "test/plan-count-session-cwd.test.ts": 85, - "test/plan-count-timeout.test.ts": 9578, - "test/plan-count-transcript.test.ts": 128, - "test/plan-count-truncated-border.test.ts": 71, - "test/plan-count-truncated-question.test.ts": 38, - "test/plan-create-combined-permission.test.ts": 139, - "test/plan-create-permission.test.ts": 77, - "test/plan-create-prepublication.test.ts": 127, - "test/plan-design-floor-fixture.test.ts": 290, - "test/plan-design-sdk-fixture.test.ts": 494, - "test/plan-design-with-ui-fixture.test.ts": 1484, - "test/plan-edit-cropped-permission.test.ts": 110, - "test/plan-eng-resume.test.ts": 15, - "test/plan-floor-dx-actor.test.ts": 82, - "test/plan-floor-permission.test.ts": 1718, - "test/plan-floor-review.test.ts": 59, - "test/plan-floor-target.test.ts": 12498, - "test/plan-format-kind-note.test.ts": 16, - "test/plan-mode-evidence.test.ts": 635, - "test/plan-pending-question-pty.test.ts": 449, - "test/plan-review-board-feedback.test.ts": 4791, - "test/plan-review-calibration.test.ts": 395, - "test/plan-review-cases.test.ts": 1166, - "test/plan-review-decisions.test.ts": 280, - "test/plan-review-report-recording.test.ts": 5427, - "test/plan-scope-selection.test.ts": 2877, - "test/plan-seed-submission.test.ts": 54088, - "test/plan-skill-question-events.test.ts": 2623, - "test/plan-skill-question-hook-scope.test.ts": 4070, - "test/plan-skill-questions.test.ts": 16275, - "test/plan-skill-read-permission.test.ts": 47, - "test/plan-skill-webfetch-permission.test.ts": 1300, - "test/plan-tune-cathedral.test.ts": 830, - "test/plan-tune-gates.test.ts": 1096, - "test/plan-tune.test.ts": 1244, - "test/platform-qualification-workflow.test.ts": 15, - "test/post-rename-doc-regen.test.ts": 28, - "test/pr-dependencies.test.ts": 1624, - "test/pr-direct-cases.test.ts": 1778, - "test/pr-shared-input-selection.test.ts": 632, - "test/pr-title-rewrite.test.ts": 90, - "test/pr-title-sync-workflow-safety.test.ts": 15, - "test/preamble-compose.test.ts": 20, - "test/preamble-first-task-scaffold.test.ts": 758, - "test/prompt-audit-manifest.test.ts": 226, - "test/provider-model-defaults.test.ts": 268, - "test/pty-askuserquestion-single-line.test.ts": 35, + "test/plan-count-clipped-elision.test.ts": 54, + "test/plan-count-collection-completion.test.ts": 30092, + "test/plan-count-completion.test.ts": 13883, + "test/plan-count-cropped-wrap.test.ts": 79, + "test/plan-count-cross-cwd-ancestry.test.ts": 119, + "test/plan-count-design-ui-recovery.test.ts": 15722, + "test/plan-count-dx-handoff.test.ts": 77, + "test/plan-count-empty-review.test.ts": 1507, + "test/plan-count-file-permission.test.ts": 44625, + "test/plan-count-fixture.test.ts": 14941, + "test/plan-count-history.test.ts": 694, + "test/plan-count-long-edit.test.ts": 37, + "test/plan-count-native-input.test.ts": 11526, + "test/plan-count-owned-permission.test.ts": 11302, + "test/plan-count-pending-exit.test.ts": 228, + "test/plan-count-prerequisite.test.ts": 42, + "test/plan-count-preview-footer.test.ts": 3451, + "test/plan-count-session-cwd.test.ts": 66, + "test/plan-count-timeout.test.ts": 9435, + "test/plan-count-transcript.test.ts": 57, + "test/plan-count-truncated-border.test.ts": 39, + "test/plan-count-truncated-question.test.ts": 36, + "test/plan-create-combined-permission.test.ts": 92, + "test/plan-create-permission.test.ts": 55, + "test/plan-create-prepublication.test.ts": 91, + "test/plan-design-floor-fixture.test.ts": 227, + "test/plan-design-sdk-fixture.test.ts": 424, + "test/plan-design-with-ui-fixture.test.ts": 1433, + "test/plan-edit-cropped-permission.test.ts": 100, + "test/plan-eng-resume.test.ts": 13, + "test/plan-floor-dx-actor.test.ts": 74, + "test/plan-floor-edit-wrap.test.ts": 50, + "test/plan-floor-permission.test.ts": 1548, + "test/plan-floor-review.test.ts": 34, + "test/plan-floor-target.test.ts": 12502, + "test/plan-format-approach-prompt.test.ts": 9, + "test/plan-format-kind-note.test.ts": 14, + "test/plan-mode-evidence.test.ts": 720, + "test/plan-pending-question-pty.test.ts": 417, + "test/plan-reality.test.ts": 325, + "test/plan-review-board-feedback.test.ts": 4268, + "test/plan-review-calibration.test.ts": 331, + "test/plan-review-cases.test.ts": 1020, + "test/plan-review-decisions.test.ts": 277, + "test/plan-review-report-recording.test.ts": 5394, + "test/plan-scope-selection.test.ts": 2729, + "test/plan-seed-submission.test.ts": 54219, + "test/plan-skill-question-events.test.ts": 2175, + "test/plan-skill-question-hook-scope.test.ts": 3003, + "test/plan-skill-questions.test.ts": 15836, + "test/plan-skill-read-permission.test.ts": 42, + "test/plan-skill-webfetch-permission.test.ts": 1164, + "test/plan-tune-cathedral.test.ts": 609, + "test/plan-tune-gates.test.ts": 1102, + "test/plan-tune.test.ts": 1274, + "test/platform-qualification-workflow.test.ts": 10, + "test/post-rename-doc-regen.test.ts": 21, + "test/pr-dependencies.test.ts": 2026, + "test/pr-direct-cases.test.ts": 2049, + "test/pr-shared-input-selection.test.ts": 737, + "test/pr-title-rewrite.test.ts": 118, + "test/pr-title-sync-workflow-safety.test.ts": 11, + "test/preamble-compose.test.ts": 17, + "test/preamble-first-task-scaffold.test.ts": 760, + "test/pregate-guards.test.ts": 4463, + "test/pregate-invalidation.test.ts": 3533, + "test/pregate-regate.test.ts": 9630, + "test/pregate-selection.test.ts": 6068, + "test/pricing-eval-plan.test.ts": 1121, + "test/prompt-audit-manifest.test.ts": 315, + "test/prosons-neutral-posture.test.ts": 13, + "test/provider-model-defaults.test.ts": 284, + "test/pty-askuserquestion-single-line.test.ts": 32, "test/pty-numbered-option-indent-native.test.ts": 43, - "test/pty-option-selection.test.ts": 606, - "test/pty-output-wake.test.ts": 10216, - "test/pty-screen-session.test.ts": 8854, - "test/pty-screen-supervision.test.ts": 10449, - "test/pty-screen-unicode-ap.test.ts": 123, - "test/pty-screen.test.ts": 99, - "test/pty-skill-seeding-wiring.test.ts": 533, - "test/pty-trust-dialog.test.ts": 3098, - "test/pty-upgrade-isolation.test.ts": 744, - "test/pty-workspace-trust.test.ts": 367, - "test/qa-browser-deadline-evidence.test.ts": 3517, - "test/qa-browser-preservation.test.ts": 1293, - "test/qa-bugs-fixture.test.ts": 24, - "test/qa-caller-authority.test.ts": 67, - "test/qa-caller-freshness-order.test.ts": 36, - "test/qa-caller-report-observer.test.ts": 146, - "test/qa-checkpoint-evidence.test.ts": 89, - "test/qa-deadline-publication-observer.test.ts": 249, - "test/qa-deadline-selection.test.ts": 37, - "test/qa-deadline.test.ts": 19608, - "test/qa-evidence-producer.test.ts": 8176, - "test/qa-evidence-selection.test.ts": 65, - "test/qa-evidence.test.ts": 9951, - "test/qa-exploratory-callers.test.ts": 10604, - "test/qa-fix-loop-fixture.test.ts": 2062, - "test/qa-functional-evidence.test.ts": 4913, - "test/qa-functional-fixture.test.ts": 958, - "test/qa-functional-observer-atomic.test.ts": 266, - "test/qa-functional-observer.test.ts": 961, - "test/qa-functional-prompt.test.ts": 798, - "test/qa-health-rubric.test.ts": 13, - "test/qa-lazy-sections.test.ts": 7697, - "test/qa-only-browser-probe.test.ts": 753, - "test/qa-only-capability.test.ts": 1533, - "test/qa-only-cleanup.test.ts": 7534, - "test/qa-only-fixture.test.ts": 10977, - "test/qa-probe-gates.test.ts": 47, - "test/qa-supervision-selection.test.ts": 33, - "test/question-log-hook.test.ts": 1349, - "test/question-preference-hook.test.ts": 2606, - "test/question-tuning-registry-path.test.ts": 19, - "test/recover-receipts.test.ts": 291, - "test/redact-audit-log.test.ts": 38, - "test/redact-context-exemptions.test.ts": 37, - "test/redact-doc-resolver.test.ts": 12, + "test/pty-option-selection.test.ts": 593, + "test/pty-output-wake.test.ts": 10731, + "test/pty-screen-session.test.ts": 8883, + "test/pty-screen-supervision.test.ts": 10487, + "test/pty-screen-unicode-ap.test.ts": 114, + "test/pty-screen.test.ts": 101, + "test/pty-skill-seeding-wiring.test.ts": 471, + "test/pty-trust-dialog.test.ts": 3058, + "test/pty-upgrade-isolation.test.ts": 765, + "test/pty-workspace-trust.test.ts": 366, + "test/published-text.test.ts": 22, + "test/qa-browser-deadline-evidence.test.ts": 3875, + "test/qa-browser-preservation.test.ts": 1496, + "test/qa-bugs-fixture.test.ts": 16, + "test/qa-caller-authority.test.ts": 75, + "test/qa-caller-freshness-order.test.ts": 42, + "test/qa-caller-report-observer.test.ts": 125, + "test/qa-checkpoint-evidence.test.ts": 75, + "test/qa-deadline-publication-observer.test.ts": 267, + "test/qa-deadline-selection.test.ts": 41, + "test/qa-deadline.test.ts": 19474, + "test/qa-evidence-producer.test.ts": 8730, + "test/qa-evidence-selection.test.ts": 63, + "test/qa-evidence.test.ts": 10210, + "test/qa-exploratory-callers.test.ts": 13918, + "test/qa-fix-loop-fixture.test.ts": 2035, + "test/qa-functional-evidence.test.ts": 4595, + "test/qa-functional-fixture.test.ts": 946, + "test/qa-functional-observer-atomic.test.ts": 450, + "test/qa-functional-observer.test.ts": 1037, + "test/qa-functional-prompt.test.ts": 901, + "test/qa-health-rubric.test.ts": 14, + "test/qa-lazy-sections.test.ts": 9380, + "test/qa-only-browser-probe.test.ts": 759, + "test/qa-only-capability.test.ts": 1581, + "test/qa-only-cleanup.test.ts": 7810, + "test/qa-only-fixture.test.ts": 11208, + "test/qa-probe-gates.test.ts": 49, + "test/qa-report-fields.test.ts": 12, + "test/qa-supervision-selection.test.ts": 32, + "test/question-log-hook.test.ts": 1479, + "test/question-preference-hook.test.ts": 2613, + "test/question-tuning-registry-path.test.ts": 13, + "test/recover-receipts.test.ts": 177, + "test/redact-audit-log.test.ts": 50, + "test/redact-context-exemptions.test.ts": 33, + "test/redact-doc-resolver.test.ts": 21, "test/redact-dotenv-filename-false-positive.test.ts": 14, "test/redact-engine-autoredact.test.ts": 15, - "test/redact-engine.test.ts": 55, - "test/redact-parcel-id-false-positive.test.ts": 15, - "test/redact-pattern-lint.test.ts": 32, - "test/redact-prepush-hook.test.ts": 2270, - "test/redact-prepush-rebase-force-push.test.ts": 723, - "test/redact-prepush-scan-range.test.ts": 1204, - "test/redact-prepush-target.test.ts": 7510, - "test/redact-span-binding.test.ts": 44, - "test/redact-unicode-offsets.test.ts": 77, - "test/regression-1539-review-self-verify.test.ts": 18, - "test/regression-1611-gbrain-sync-resume.test.ts": 32, - "test/regression-1624-retro-stale-base.test.ts": 18, - "test/regression-2922-memory-ingest-sources.test.ts": 512, - "test/regression-dot-leading-slug.test.ts": 114, - "test/regression-issue2091-bsd-mktemp.test.ts": 167, - "test/regression-pr1169-build-app-sed.test.ts": 53, - "test/regression-pr1169-mktemp-fallbacks.test.ts": 45, - "test/regression-transcript-frontmatter-fence.test.ts": 26, - "test/regression-transcript-slug-collision.test.ts": 25, - "test/relink-disabled-router.test.ts": 752, - "test/relink.test.ts": 8534, - "test/remote-identity-vectors.test.ts": 588, - "test/render-sections-provenance.test.ts": 273, - "test/replay-pr-selection.test.ts": 611, - "test/resolver-ask-user-format.test.ts": 26, - "test/resolvers-gbrain-put-rewrite.test.ts": 24, - "test/resolvers-gbrain-save-results.test.ts": 14, - "test/retired-commands.test.ts": 26, - "test/review-army-budget.test.ts": 1749, - "test/review-consensus-lifecycle.test.ts": 34, - "test/review-count-markdown.test.ts": 96, - "test/review-entry-and-design-clarity-au.test.ts": 65, - "test/review-enum-lifecycle.test.ts": 28, - "test/review-finalization-budget.test.ts": 2584, - "test/review-log.test.ts": 1663, - "test/review-n-plus-one-contract.test.ts": 600, - "test/review-quality-provenance.test.ts": 38, - "test/review-start-evidence.test.ts": 14218, - "test/review-workflow-clarity.test.ts": 34, - "test/review-workflow-fixture.test.ts": 28, - "test/router-disabled-skills.test.ts": 521, - "test/routing-probe.test.ts": 27, - "test/run-in-background-guidance.test.ts": 562, - "test/run-shard-child.test.ts": 1243, - "test/safety-rule-registry.test.ts": 32, - "test/salience-allowlist.test.ts": 28, - "test/sandbox-doctor-shell.test.ts": 16, - "test/schema-version-migration.test.ts": 56, - "test/secret-sink-harness.test.ts": 48, - "test/section-capture-native-tools.test.ts": 3733, - "test/section-manifest-consistency.test.ts": 25, - "test/security-dashboard-fallback.test.ts": 1341, - "test/session-runner-browse-errors.test.ts": 677, - "test/session-runner-groupkill.test.ts": 4084, - "test/session-runner-startup-grace.test.ts": 13152, - "test/session-runner-stream-lifecycle.test.ts": 269, - "test/session-runner-timeout.test.ts": 3029, - "test/session-runner-tools.test.ts": 5249, - "test/session-update-autostash.test.ts": 5025, - "test/session-update-stages.test.ts": 2567, - "test/setup-alias-name-uniqueness.test.ts": 1347, - "test/setup-browser-hint.test.ts": 43, - "test/setup-bun-cmd-and-pipe-bugs.test.ts": 28, - "test/setup-claude-code-migration.test.ts": 10453, - "test/setup-claude-skill-assets.test.ts": 857, - "test/setup-cleanup-orphans.test.ts": 192, - "test/setup-codesign-restore.test.ts": 337, - "test/setup-codesign.test.ts": 25, - "test/setup-codex-design-pdf-runtime.test.ts": 131, - "test/setup-codex-model.test.ts": 17, - "test/setup-codex-scope-migrations.test.ts": 26060, - "test/setup-codex-scope-namespaces.test.ts": 43086, - "test/setup-codex-scope-review-boundaries.test.ts": 38312, - "test/setup-codex-scope.test.ts": 47656, - "test/setup-conductor-auq-hook.test.ts": 17398, - "test/setup-conductor-worktree.test.ts": 36, - "test/setup-cso-windows-probe.test.ts": 50, - "test/setup-deploy-key-presence.test.ts": 19, - "test/setup-emoji-font.test.ts": 62, - "test/setup-gbrain-bin-invocation-paths.test.ts": 16, - "test/setup-gbrain-fixture.test.ts": 2472, - "test/setup-gbrain-path4-caller.test.ts": 2591, - "test/setup-gbrain-path4-structure.test.ts": 16, - "test/setup-gbrain-remote-caller.test.ts": 8660, - "test/setup-help.test.ts": 57, + "test/redact-engine.test.ts": 86, + "test/redact-parcel-id-false-positive.test.ts": 16, + "test/redact-pattern-lint.test.ts": 20, + "test/redact-prepush-emails.test.ts": 15524, + "test/redact-prepush-hook.test.ts": 3820, + "test/redact-prepush-rebase-force-push.test.ts": 721, + "test/redact-prepush-scan-range.test.ts": 1346, + "test/redact-prepush-target.test.ts": 9300, + "test/redact-span-binding.test.ts": 38, + "test/redact-unicode-offsets.test.ts": 67, + "test/regression-1539-review-self-verify.test.ts": 14, + "test/regression-1611-gbrain-sync-resume.test.ts": 30, + "test/regression-1624-retro-stale-base.test.ts": 12, + "test/regression-1834-retro-recommendations.test.ts": 10, + "test/regression-2922-memory-ingest-sources.test.ts": 605, + "test/regression-dot-leading-slug.test.ts": 99, + "test/regression-issue2091-bsd-mktemp.test.ts": 178, + "test/regression-issue3024-zsh-sourced-helpers.test.ts": 1239, + "test/regression-pr1169-build-app-sed.test.ts": 63, + "test/regression-pr1169-mktemp-fallbacks.test.ts": 37, + "test/regression-transcript-frontmatter-fence.test.ts": 28, + "test/regression-transcript-slug-collision.test.ts": 51, + "test/relink-disabled-router.test.ts": 859, + "test/relink.test.ts": 10148, + "test/remote-identity-vectors.test.ts": 671, + "test/render-sections-provenance.test.ts": 332, + "test/replay-pr-selection.test.ts": 712, + "test/resolver-ask-user-format.test.ts": 25, + "test/resolvers-gbrain-put-rewrite.test.ts": 33, + "test/resolvers-gbrain-save-results.test.ts": 15, + "test/restamp-command-boundary.test.ts": 4040, + "test/retired-commands.test.ts": 34, + "test/review-army-budget.test.ts": 1652, + "test/review-base-refresh.test.ts": 140, + "test/review-checklists.test.ts": 21, + "test/review-consensus-lifecycle.test.ts": 30, + "test/review-count-markdown.test.ts": 97, + "test/review-entry-and-design-clarity-au.test.ts": 90, + "test/review-enum-lifecycle.test.ts": 27, + "test/review-finalization-budget.test.ts": 2568, + "test/review-log-findings.test.ts": 5932, + "test/review-log.test.ts": 3338, + "test/review-n-plus-one-contract.test.ts": 689, + "test/review-quality-provenance.test.ts": 37, + "test/review-start-evidence.test.ts": 22686, + "test/review-workflow-clarity.test.ts": 58, + "test/review-workflow-fixture.test.ts": 31, + "test/router-disabled-skills.test.ts": 692, + "test/routing-probe.test.ts": 23, + "test/run-in-background-guidance.test.ts": 2088, + "test/run-shard-child.test.ts": 1252, + "test/runtime-pins.test.ts": 72, + "test/runtime-root-assets.test.ts": 1849, + "test/safety-rule-registry.test.ts": 33, + "test/salience-allowlist.test.ts": 23, + "test/sandbox-doctor-shell.test.ts": 14, + "test/schema-version-migration.test.ts": 52, + "test/sealed-guard.test.ts": 2229, + "test/secret-sink-harness.test.ts": 51, + "test/section-capture-native-tools.test.ts": 3876, + "test/section-manifest-consistency.test.ts": 20, + "test/security-dashboard-fallback.test.ts": 1473, + "test/session-runner-browse-errors.test.ts": 784, + "test/session-runner-groupkill.test.ts": 4125, + "test/session-runner-startup-grace.test.ts": 13091, + "test/session-runner-stream-lifecycle.test.ts": 265, + "test/session-runner-timeout.test.ts": 3026, + "test/session-runner-tools.test.ts": 5279, + "test/session-update-autostash.test.ts": 5169, + "test/session-update-hook-hold.test.ts": 3156, + "test/session-update-stages.test.ts": 4257, + "test/setup-alias-name-uniqueness.test.ts": 1642, + "test/setup-browser-hint.test.ts": 41, + "test/setup-bun-cmd-and-pipe-bugs.test.ts": 33, + "test/setup-bun-floor.test.ts": 196, + "test/setup-claude-code-migration.test.ts": 16522, + "test/setup-claude-skill-assets.test.ts": 1133, + "test/setup-cleanup-orphans.test.ts": 161, + "test/setup-codesign-restore.test.ts": 381, + "test/setup-codesign.test.ts": 21, + "test/setup-codex-design-pdf-runtime.test.ts": 167, + "test/setup-codex-model.test.ts": 34, + "test/setup-codex-scope-migrations.test.ts": 34163, + "test/setup-codex-scope-namespaces.test.ts": 56588, + "test/setup-codex-scope-review-boundaries.test.ts": 51854, + "test/setup-codex-scope.test.ts": 60385, + "test/setup-conductor-auq-hook.test.ts": 22213, + "test/setup-conductor-worktree.test.ts": 35, + "test/setup-crlf-repair.test.ts": 244, + "test/setup-cso-degrade.test.ts": 179, + "test/setup-cso-windows-probe.test.ts": 45, + "test/setup-deploy-key-presence.test.ts": 16, + "test/setup-deploy-not-deployed.test.ts": 10, + "test/setup-deploy-vercel-trigger.test.ts": 11, + "test/setup-emoji-font.test.ts": 59, + "test/setup-gbrain-bin-invocation-paths.test.ts": 12, + "test/setup-gbrain-fixture.test.ts": 2363, + "test/setup-gbrain-path4-caller.test.ts": 2659, + "test/setup-gbrain-path4-structure.test.ts": 15, + "test/setup-gbrain-remote-caller.test.ts": 8779, + "test/setup-gbrain-windows-mcp.test.ts": 67, + "test/setup-help.test.ts": 62, "test/setup-hook-canonical-paths.test.ts": 22, - "test/setup-install-registry.test.ts": 57854, - "test/setup-kiro-native.test.ts": 595, - "test/setup-link-ownership.test.ts": 700, - "test/setup-needs-build.test.ts": 185, - "test/setup-plan-tune-hooks-noninteractive.test.ts": 336, - "test/setup-playwright-best-effort.test.ts": 16814, - "test/setup-playwright-platform.test.ts": 5260, - "test/setup-prune-stale-generated.test.ts": 152, - "test/setup-runtime-lib-command.test.ts": 12166, - "test/setup-sections-linking.test.ts": 24, - "test/setup-skill-copies.test.ts": 340, - "test/setup-staged-copy.test.ts": 50, - "test/setup-timeline-hook-gate.test.ts": 198, - "test/setup-windows-fallback.test.ts": 43, - "test/setup-windows-rerun-refresh.test.ts": 137, - "test/shard-cli-parity.test.ts": 92, - "test/shard-engine-equivalence.test.ts": 3103, - "test/shard-engine.test.ts": 3685, - "test/shared-libs-cancellation.test.ts": 102, - "test/shared-libs-checker-interface-evidence.test.ts": 40661, - "test/shared-libs-evidence.test.ts": 23, - "test/shared-libs-fixture.test.ts": 8027, - "test/shared-libs-plan-actor.test.ts": 83, - "test/shared-libs-rendering.test.ts": 997, - "test/shared-libs-revalidation-prompt.test.ts": 10006, - "test/shared-libs-review-start-evidence.test.ts": 2475, - "test/shared-libs-snapshot-check.test.ts": 26813, - "test/shared-libs-source-reads.test.ts": 1318, - "test/shared-libs-stage-actor.test.ts": 106924, + "test/setup-hook-syntax-gate.test.ts": 8637, + "test/setup-install-registry.test.ts": 82095, + "test/setup-kiro-native.test.ts": 677, + "test/setup-link-ownership.test.ts": 738, + "test/setup-needs-build.test.ts": 290, + "test/setup-plan-tune-hooks-noninteractive.test.ts": 499, + "test/setup-playwright-best-effort.test.ts": 17826, + "test/setup-playwright-platform.test.ts": 5145, + "test/setup-prune-stale-generated.test.ts": 154, + "test/setup-ps1.test.ts": 86, + "test/setup-runtime-lib-command.test.ts": 13993, + "test/setup-runtime-root-guard.test.ts": 16555, + "test/setup-sections-linking.test.ts": 13, + "test/setup-skill-copies.test.ts": 390, + "test/setup-staged-copy.test.ts": 51, + "test/setup-timeline-hook-gate.test.ts": 339, + "test/setup-windows-fallback.test.ts": 52, + "test/setup-windows-launch-hint.test.ts": 255, + "test/setup-windows-rerun-refresh.test.ts": 235, + "test/shard-cli-parity.test.ts": 109, + "test/shard-engine-equivalence.test.ts": 3108, + "test/shard-engine.test.ts": 3680, + "test/shared-libs-cancellation.test.ts": 107, + "test/shared-libs-checker-interface-evidence.test.ts": 55245, + "test/shared-libs-evidence.test.ts": 21, + "test/shared-libs-fixture.test.ts": 8454, + "test/shared-libs-plan-actor.test.ts": 112, + "test/shared-libs-rendering.test.ts": 1261, + "test/shared-libs-revalidation-prompt.test.ts": 14020, + "test/shared-libs-review-start-evidence.test.ts": 3967, + "test/shared-libs-snapshot-check.test.ts": 34383, + "test/shared-libs-source-reads.test.ts": 1425, + "test/shared-libs-stage-actor.test.ts": 121031, "test/ship-apple-gate.test.ts": 18, - "test/ship-control-flow.test.ts": 297, - "test/ship-coverage-audit-af.test.ts": 56, - "test/ship-document-release-dispatch.test.ts": 4124, - "test/ship-hook-actor.test.ts": 1960, - "test/ship-hook-refresh.test.ts": 2208, - "test/ship-hook-windows-paths.test.ts": 300, - "test/ship-plan-completion-invariants.test.ts": 956, - "test/ship-pr-liveness-policy.test.ts": 17, - "test/ship-publication-gates.test.ts": 187, - "test/ship-reentry-gates.test.ts": 24, - "test/ship-review-loop.test.ts": 20, - "test/ship-section-fixture.test.ts": 391, - "test/ship-skip-actor.test.ts": 28529, - "test/ship-skip-requeue.test.ts": 34, - "test/ship-skip-selection.test.ts": 697, - "test/ship-template-redaction.test.ts": 21, - "test/ship-test-detection-markers.test.ts": 144, - "test/ship-triage-labels.test.ts": 17, - "test/ship-version-sync.test.ts": 508, - "test/ship-workflow-clarity.test.ts": 40, + "test/ship-control-flow.test.ts": 237, + "test/ship-coverage-audit-af.test.ts": 57, + "test/ship-document-release-dispatch.test.ts": 4850, + "test/ship-greptile-early.test.ts": 14, + "test/ship-greptile-pr-check.test.ts": 78, + "test/ship-hook-actor.test.ts": 2099, + "test/ship-hook-refresh.test.ts": 2830, + "test/ship-hook-windows-paths.test.ts": 370, + "test/ship-issue-intent.test.ts": 707, + "test/ship-measure-bar.test.ts": 66, + "test/ship-measure-loop-skill.test.ts": 13, + "test/ship-measure-seeded-fixture.test.ts": 1254, + "test/ship-measure-sweep.test.ts": 621, + "test/ship-measure.test.ts": 2141, + "test/ship-plan-completion-invariants.test.ts": 1363, + "test/ship-pr-liveness-policy.test.ts": 14, + "test/ship-publication-gates.test.ts": 680, + "test/ship-reentry-gates.test.ts": 25, + "test/ship-review-loop.test.ts": 22, + "test/ship-section-fixture.test.ts": 364, + "test/ship-skip-actor.test.ts": 33403, + "test/ship-skip-requeue.test.ts": 33, + "test/ship-skip-selection.test.ts": 840, + "test/ship-template-redaction.test.ts": 18, + "test/ship-test-detection-markers.test.ts": 170, + "test/ship-triage-labels.test.ts": 13, + "test/ship-version-sync.test.ts": 650, + "test/ship-workflow-clarity.test.ts": 52, "test/shortcut-debt-ledger.test.ts": 20, - "test/skill-browse-state-extraction.test.ts": 32, - "test/skill-budget-regression.test.ts": 37, - "test/skill-census.test.ts": 34, - "test/skill-ceo-section-ordering.test.ts": 1979, - "test/skill-check-driver.test.ts": 106, - "test/skill-collision-sentinel.test.ts": 18, - "test/skill-coverage-floor.test.ts": 53, - "test/skill-cross-model-recommendation-emit.test.ts": 33, - "test/skill-fixture.test.ts": 50, - "test/skill-parser.test.ts": 27, - "test/skill-positional-literals.test.ts": 1051, - "test/skill-preflight-budget.test.ts": 17, - "test/skill-size-budget.test.ts": 428, - "test/skill-validation.test.ts": 961, - "test/skillify-host-paths.test.ts": 859, - "test/slop-diff-cli.test.ts": 346, - "test/sol-skill-fixture.test.ts": 697, - "test/spawnsync-timeout-tripwire.test.ts": 170, - "test/spec-quality-gate-secret-sink.test.ts": 1394, - "test/spec-template-invariants.test.ts": 23, - "test/state-root-config-merge.test.ts": 680, - "test/state-root-one-variable.test.ts": 4178, - "test/state-root-parity.test.ts": 143, - "test/state-root-ratchet.test.ts": 301, - "test/state-root-resolver-failure.test.ts": 36, - "test/static-no-legacy-writes.test.ts": 1068, - "test/strict-output-capture.test.ts": 85, - "test/strict-output-formats.test.ts": 984, - "test/strict-output-settlement.test.ts": 4276, - "test/strict-output.test.ts": 20, - "test/sync-gbrain-cycle-freshness.test.ts": 63, - "test/sync-gbrain-readiness-fixture.test.ts": 166, - "test/sync-gbrain-source-probe.test.ts": 529, - "test/takes-fence-fallback.test.ts": 15, - "test/tasks-section-jq.test.ts": 25, - "test/taste-engine.test.ts": 939, - "test/team-mode.test.ts": 1461, - "test/telemetry-repo-strip.test.ts": 30, - "test/telemetry.test.ts": 6614, - "test/template-context-parity.test.ts": 17, - "test/terse-build.test.ts": 23, - "test/test-free-shards-capture.test.ts": 1277, - "test/test-free-shards-sandbox-knobs.test.ts": 108, - "test/test-free-shards-settlement-lifecycle.test.ts": 46457, - "test/test-free-shards-settlement-ownership.test.ts": 38118, - "test/test-free-shards.test.ts": 9781, - "test/test-health-report.test.ts": 214, - "test/test-health-workflow.test.ts": 16, - "test/test-of-test-ratchet.test.ts": 164, - "test/test-pr-profile.test.ts": 33, - "test/test-value-bar.test.ts": 88, - "test/testing-internals-anchors.test.ts": 739, - "test/third-party-actions-recording.test.ts": 103, - "test/third-party-actions.test.ts": 267, - "test/timeline-stop-hook.test.ts": 1019, - "test/timeline.test.ts": 1816, - "test/touchfiles-facade.test.ts": 27, - "test/touchfiles-map-diff.test.ts": 171, - "test/touchfiles.test.ts": 1048, - "test/tracker-guard-wiring.test.ts": 53, - "test/tracker-guard.test.ts": 168, - "test/transcript-consent.test.ts": 908, - "test/transcript-gate-values.test.ts": 1348, - "test/transcript-scope-brain-sync.test.ts": 3974, - "test/transcript-scope-ingest.test.ts": 753, - "test/troubleshooting-anchors.test.ts": 18, - "test/typecheck-test-ratchet.test.ts": 42, - "test/ubicloud-runner.test.ts": 67, - "test/uninstall-windows-copies.test.ts": 1925, - "test/uninstall.test.ts": 5711, - "test/update-check-crash-sentinel.test.ts": 551, - "test/upgrade-migration-v1.test.ts": 50, - "test/upgrade-setup-recovery.test.ts": 81, - "test/upgrade-template-pins.test.ts": 15, - "test/user-render-out-dir-install.test.ts": 130, - "test/user-slug-fallback.test.ts": 558, - "test/v0-dormancy.test.ts": 31, - "test/verify-gate.test.ts": 1934, - "test/version-source.test.ts": 42, - "test/windows-free-selection-autoplan-guard.test.ts": 29, - "test/windows-native-workflows.test.ts": 213, - "test/workflow-action-pins.test.ts": 22, - "test/workflow-boundaries-fixture.test.ts": 2585, - "test/workflow-concurrency.test.ts": 18, - "test/workflow-excerpt.test.ts": 115, - "test/workflow-judge-cache.test.ts": 2105, - "test/workflow-judge-input.test.ts": 54, - "test/worktree-isolated-shapes.test.ts": 36, - "test/worktree.test.ts": 684, - "test/writing-style-resolver.test.ts": 26 + "test/sideways-review.test.ts": 13, + "test/skill-browse-state-extraction.test.ts": 27, + "test/skill-budget-regression.test.ts": 39, + "test/skill-census.test.ts": 27, + "test/skill-ceo-section-ordering.test.ts": 2191, + "test/skill-check-driver.test.ts": 112, + "test/skill-collision-sentinel.test.ts": 19, + "test/skill-coverage-floor.test.ts": 70, + "test/skill-cross-model-recommendation-emit.test.ts": 31, + "test/skill-fixture.test.ts": 51, + "test/skill-parser.test.ts": 33, + "test/skill-positional-literals.test.ts": 1195, + "test/skill-preflight-budget.test.ts": 16, + "test/skill-size-budget.test.ts": 473, + "test/skill-validation.test.ts": 1125, + "test/skillify-host-paths.test.ts": 1013, + "test/slop-diff-cli.test.ts": 342, + "test/sol-skill-fixture.test.ts": 811, + "test/spawned-consent-rule.test.ts": 21, + "test/spawnsync-timeout-tripwire.test.ts": 183, + "test/spec-quality-gate-secret-sink.test.ts": 1706, + "test/spec-template-invariants.test.ts": 27, + "test/spend-ledger.test.ts": 118, + "test/stamp-templates.test.ts": 491, + "test/state-root-config-merge.test.ts": 937, + "test/state-root-one-variable.test.ts": 4563, + "test/state-root-parity.test.ts": 199, + "test/state-root-ratchet.test.ts": 316, + "test/state-root-resolver-failure.test.ts": 33, + "test/static-no-legacy-writes.test.ts": 1085, + "test/strict-output-capture.test.ts": 88, + "test/strict-output-formats.test.ts": 832, + "test/strict-output-settlement.test.ts": 4340, + "test/strict-output.test.ts": 19, + "test/sync-gbrain-code-scope.test.ts": 119, + "test/sync-gbrain-cycle-freshness.test.ts": 86, + "test/sync-gbrain-readiness-fixture.test.ts": 129, + "test/sync-gbrain-source-probe.test.ts": 525, + "test/takes-fence-fallback.test.ts": 17, + "test/tasks-section-jq.test.ts": 24, + "test/taste-engine.test.ts": 869, + "test/team-init-hook-shell-neutral.test.ts": 120, + "test/team-mode.test.ts": 2060, + "test/telemetry-repo-strip.test.ts": 33, + "test/telemetry.test.ts": 7450, + "test/template-context-parity.test.ts": 13, + "test/terse-build.test.ts": 18, + "test/test-free-shards-capture.test.ts": 1244, + "test/test-free-shards-git-maintenance.test.ts": 155, + "test/test-free-shards-sandbox-knobs.test.ts": 119, + "test/test-free-shards-settlement-lifecycle.test.ts": 45902, + "test/test-free-shards-settlement-ownership.test.ts": 37525, + "test/test-free-shards.test.ts": 9838, + "test/test-health-report.test.ts": 264, + "test/test-health-workflow.test.ts": 12, + "test/test-of-test-ratchet.test.ts": 172, + "test/test-pr-profile.test.ts": 40, + "test/test-value-bar.test.ts": 103, + "test/testing-internals-anchors.test.ts": 708, + "test/third-party-actions-recording.test.ts": 111, + "test/third-party-actions.test.ts": 264, + "test/timeline-stop-hook-slug.test.ts": 4374, + "test/timeline-stop-hook.test.ts": 564, + "test/timeline.test.ts": 11905, + "test/touchfiles-facade.test.ts": 21, + "test/touchfiles-map-diff.test.ts": 167, + "test/touchfiles.test.ts": 1114, + "test/tracker-guard-wiring.test.ts": 48, + "test/tracker-guard.test.ts": 160, + "test/transcript-consent.test.ts": 985, + "test/transcript-gate-values.test.ts": 1393, + "test/transcript-scope-brain-sync.test.ts": 4558, + "test/transcript-scope-ingest.test.ts": 783, + "test/tree-receipt-stamp-sensitive.test.ts": 10129, + "test/trial-cause.test.ts": 979, + "test/troubleshooting-anchors.test.ts": 1314, + "test/troubleshooting-windows-recovery.test.ts": 13, + "test/typecheck-test-ratchet.test.ts": 34, + "test/ubicloud-runner.test.ts": 2556, + "test/uninstall-windows-copies.test.ts": 1819, + "test/uninstall.test.ts": 5563, + "test/update-check-crash-sentinel.test.ts": 633, + "test/upgrade-migration-v1.test.ts": 46, + "test/upgrade-setup-recovery.test.ts": 380, + "test/upgrade-template-pins.test.ts": 10, + "test/user-render-out-dir-install.test.ts": 172, + "test/user-slug-fallback.test.ts": 677, + "test/v0-dormancy.test.ts": 32, + "test/verify-gate.test.ts": 2066, + "test/version-source.test.ts": 12, + "test/voice-directive.test.ts": 32, + "test/windows-free-selection-autoplan-guard.test.ts": 26, + "test/windows-native-workflows.test.ts": 238, + "test/workflow-action-pins.test.ts": 18, + "test/workflow-boundaries-fixture.test.ts": 2830, + "test/workflow-concurrency.test.ts": 15, + "test/workflow-excerpt.test.ts": 112, + "test/workflow-judge-cache.test.ts": 2117, + "test/workflow-judge-input.test.ts": 51, + "test/workflow-required-steps.test.ts": 24, + "test/worktree-isolated-shapes.test.ts": 30, + "test/worktree.test.ts": 608, + "test/writing-style-resolver.test.ts": 18 } } diff --git a/scripts/free-test-seed-allowlist.json b/scripts/free-test-seed-allowlist.json index 92bf700bb..1b4c032ea 100644 --- a/scripts/free-test-seed-allowlist.json +++ b/scripts/free-test-seed-allowlist.json @@ -1,6 +1,9 @@ { "entries": [ {"file": "test/host-conformance.test.ts", "reason": "real ./setup per host and layout; the time is setup's own skill-linking loop, not fixture copies (shared fixture landed in W6c)"}, - {"file": "test/shared-libs-stage-actor.test.ts", "reason": "re-runs the paid shared-libs runner body against git fixture repos per test; owned by the paid-harness value-bar review"} + {"file": "test/shared-libs-stage-actor.test.ts", "reason": "re-runs the paid shared-libs runner body against git fixture repos per test; owned by the paid-harness value-bar review"}, + {"file": "test/setup-install-registry.test.ts", "reason": "82s in the 2026-10-15 recording (58s on 2026-10-04): 11 cases each run the real ./setup, gstack-relink, gstack-config and gstack-uninstall against throwaway checkouts", "todo": "split by describe block so the packer can balance it, then rerun bun run test:ubicloud --record-durations (TODOS.md, fix wave 2 follow-ups)"}, + {"file": "test/host-renders-prune.test.ts", "reason": "64s in the 2026-10-15 recording (unseeded before): every case runs a real ./setup or the gstack-upgrade migration over host render dirs", "todo": "split by describe block so the packer can balance it, then rerun bun run test:ubicloud --record-durations (TODOS.md, fix wave 2 follow-ups)"}, + {"file": "test/setup-codex-scope.test.ts", "reason": "60.4s in the 2026-10-15 recording (48s on 2026-10-04): Codex install scope through the real ./setup", "todo": "split by describe block so the packer can balance it, then rerun bun run test:ubicloud --record-durations (TODOS.md, fix wave 2 follow-ups)"} ] } diff --git a/scripts/test-free-shards.ts b/scripts/test-free-shards.ts index e009f7be6..8b53a9f20 100755 --- a/scripts/test-free-shards.ts +++ b/scripts/test-free-shards.ts @@ -1490,6 +1490,24 @@ function logFreeRecovery(log: (line: string) => void, outcome: FreeShardOutcome, } } +/** + * Backstop for fixtures that commit and then list, watch or remove `.git`: + * git's detached auto-maintenance child creates and deletes + * `.git/objects/maintenance.lock` after `git commit` has returned. Appends + * `maintenance.auto=false` and `gc.auto=0` after any inherited GIT_CONFIG_* + * pairs; a malformed inherited count is left untouched so git still rejects it. + */ +export function disableGitAutoMaintenance(env: NodeJS.ProcessEnv): void { + const inherited = (env.GIT_CONFIG_COUNT ?? '').trim(); + if (inherited !== '' && !/^\d+$/.test(inherited)) return; + const count = inherited === '' ? 0 : Number(inherited); + env[`GIT_CONFIG_KEY_${count}`] = 'maintenance.auto'; + env[`GIT_CONFIG_VALUE_${count}`] = 'false'; + env[`GIT_CONFIG_KEY_${count + 1}`] = 'gc.auto'; + env[`GIT_CONFIG_VALUE_${count + 1}`] = '0'; + env.GIT_CONFIG_COUNT = String(count + 2); +} + /** One line per shard, printed after the run: `[test:free] shard i/N: M files, XXs, pass|fail|timed-out`. */ function shardEpilogue(outcome: FreeShardOutcome, totalShards: number): string { return `[test:free] shard ${outcome.shard}/${totalShards}: ${outcome.files.length} files, ` @@ -1559,6 +1577,7 @@ export async function runFreeShard( // shards and prior daemons replace each other's state; override inherited state. env.BROWSE_STATE_FILE = path.join(stateDir, '.gstack', 'browse.json'); env.GSTACK_FREE_SHARD_ID = randomUUID(); + disableGitAutoMaintenance(env); const home = options.homeGuard ? options.homeGuard(files, env, stateDir) : guardFreeHome(files, env); const startedAt = Date.now(); diff --git a/scripts/test-health-report.ts b/scripts/test-health-report.ts index 28a775a02..e4dc5da46 100644 --- a/scripts/test-health-report.ts +++ b/scripts/test-health-report.ts @@ -138,7 +138,7 @@ export function flakeCheck(window: FlakeWindow | Error): Check { export function unseededCheck(root: string): Check { const base = { id: 'unseeded-free-files', title: 'Free test files missing from the duration seed (CEO-10)', - fix: 'Refresh the seed: `bun run test:ubicloud --record-durations` (or a CI recording; a 4-core laptop recording is not acceptable), then commit scripts/free-test-durations.json (docs/TESTING_INTERNALS.md#free-suite-duration-seed).' }; + fix: 'Refresh the seed with UBICLOUD_API_KEY set: `bun run test:ubicloud --record-durations` times every free file on a CI-mirrored VM and copies scripts/free-test-durations.json back into this checkout; commit it (docs/TESTING_INTERNALS.md#free-suite-duration-seed). Without UBICLOUD_API_KEY, leave the refresh to a maintainer: a 4-core laptop or sandbox recording skips or slows browser and display tests, so it is not accepted.' }; const durations = loadFreeTestDurations(root); if (!durations) return { ...base, status: 'unavailable', detail: 'unavailable: scripts/free-test-durations.json is missing or unreadable; next: refresh the seed' }; const unseeded = unseededFreeFiles(collectFreeTestFiles(root), durations); @@ -243,12 +243,13 @@ export function collectHealth(inputs: HealthInputs): HealthReport { detail: window.files.slice(0, 15).map(file => `${file.file}: ${file.flakyRuns}/${window.runs} runs (${pct(file.rate)})${file.failing ? ' FAIL > 5%' : ''}`) }; })); - metrics.push(metric('free-wall', 'Free-suite and Windows wall', 'p50 of run_started_at to updated_at for successful main runs of free-tests.yml and windows-free-tests.yml', () => { - const wall = (workflow: string) => { - const walls = listWorkflowRuns(client, repo, workflow, { since, branch: 'main' }).filter(run => run.conclusion === 'success').map(run => span(run.startedAt, run.updatedAt)!); - return `${minutes(percentile(walls, 0.5))} (${walls.length} runs)`; - }; - return { value: `free-tests ${wall('free-tests.yml')}; windows-free-tests ${wall('windows-free-tests.yml')}` }; + metrics.push(metric('free-wall', 'Free-suite and Windows wall', 'p50 of run_started_at to updated_at for successful main runs of free-tests.yml and successful pull_request runs of windows-free-tests.yml (its workflow_dispatch duration recordings excluded)', () => { + const walls = (workflow: string, filter: { branch?: string; event?: string }) => + listWorkflowRuns(client, repo, workflow, { since, ...filter }).filter(run => run.conclusion === 'success').map(run => span(run.startedAt, run.updatedAt)!); + const free = walls('free-tests.yml', { branch: 'main' }); + const windows = walls('windows-free-tests.yml', { event: 'pull_request' }); + const windowsValue = windows.length ? `${minutes(percentile(windows, 0.5))} (${windows.length} runs)` : 'no successful PR runs in window'; + return { value: `free-tests ${minutes(percentile(free, 0.5))} (${free.length} runs); windows-free-tests (successful PR runs) ${windowsValue}` }; })); metrics.push(metric('free-serial', 'Free-suite serial time', 'sum of scripts/free-test-durations.json (the committed seed)', () => { diff --git a/test/free-seed-ratchet.test.ts b/test/free-seed-ratchet.test.ts index b53c4627f..31950be21 100644 --- a/test/free-seed-ratchet.test.ts +++ b/test/free-seed-ratchet.test.ts @@ -95,6 +95,7 @@ describe('seed ceiling and shrink-only allowlist', () => { }); test('the committed seed holds the ceiling and the allowlist only shrinks', () => { + expect(SEED_ALLOWLIST_FILE).toBe('scripts/free-test-seed-allowlist.json'); const seed = JSON.parse(fs.readFileSync(path.join(ROOT, FREE_TEST_DURATIONS_FILE), 'utf8')) as { durations: Record }; const allowlist = parseSeedAllowlist(fs.readFileSync(path.join(ROOT, SEED_ALLOWLIST_FILE), 'utf8')); const explicitBase = process.env.GSTACK_FREE_SEED_BASE; diff --git a/test/gstack-docs-candidate.test.ts b/test/gstack-docs-candidate.test.ts index 276d06b6c..2d1c8d59a 100644 --- a/test/gstack-docs-candidate.test.ts +++ b/test/gstack-docs-candidate.test.ts @@ -21,6 +21,7 @@ function repo() { fs.mkdirSync(path.join(dir, 'handbook'), { recursive: true }); git(root, 'init', '-q', '-b', 'main', dir); git(dir, 'config', 'user.email', 't@t'); git(dir, 'config', 'user.name', 't'); git(dir, 'config', 'commit.gpgsign', 'false'); + git(dir, 'config', 'maintenance.auto', 'false'); git(dir, 'config', 'gc.auto', '0'); fs.writeFileSync(path.join(dir, 'app.ts'), 'export const a = 1;\n'); fs.writeFileSync(path.join(dir, 'handbook', 'guide.md'), '# Guide\n'); git(dir, 'add', '.'); git(dir, 'commit', '-qm', 'base'); @@ -38,7 +39,7 @@ describe('gstack-docs-candidate', () => { test('snapshot records base, HEAD, index, NUL-safe path lists and content hashes without touching the repository', () => { const { dir, record } = repo(); const gitDir = path.join(dir, '.git'); - const before = fs.readdirSync(gitDir, { recursive: true }).length; + const before = fs.readdirSync(gitDir, { recursive: true }) as string[]; const indexBefore = fs.readFileSync(path.join(gitDir, 'index')); const result = run(dir, 'snapshot', '--out', record, '--audit-id', 'a1', '--mode', 'edit', '--base', 'main', '--docs', 'handbook'); expect(result.status, result.stderr).toBe(0); @@ -51,7 +52,9 @@ describe('gstack-docs-candidate', () => { expect(saved.hashes['app.ts']).toBe(git(dir, 'hash-object', 'app.ts')); expect(saved.index).toHaveLength(2); expect(fs.statSync(record).mode & 0o777).toBe(0o600); - expect(fs.readdirSync(gitDir, { recursive: true }).length).toBe(before); + const after = fs.readdirSync(gitDir, { recursive: true }) as string[]; + const changed = [...before.filter(entry => !after.includes(entry)).map(entry => `-${entry}`), ...after.filter(entry => !before.includes(entry)).map(entry => `+${entry}`)]; + expect(after.length, `.git entries changed during snapshot: ${changed.join(', ') || '(same names)'}`).toBe(before.length); expect(fs.readFileSync(path.join(gitDir, 'index')).equals(indexBefore)).toBe(true); }); diff --git a/test/gstack-next-version.test.ts b/test/gstack-next-version.test.ts index 9c8901318..83993db72 100644 --- a/test/gstack-next-version.test.ts +++ b/test/gstack-next-version.test.ts @@ -932,35 +932,90 @@ describe("width pinned on failed base read (3-digit repos)", () => { describe("integration (smoke)", () => { const SMOKE_SCRIPT = join(import.meta.dir, "..", "bin", "gstack-next-version"); - // Bumps timeout to 30s — the test spawns a real `bun run` subprocess that - // does a `gh pr list` against the live GitHub API to inspect claimed slots. - // Network latency makes 5s tight on developer machines. + const FAKE_OWNER = "fixture-owner"; + const CLAIM = { pr: 41, branch: "fixture/claim", version: "1.6.4.0", url: "https://github.com/fixture-owner/repo/pull/41" }; + // A named fake `gh` first on PATH answers every call the CLI makes in this + // checkout and logs each argv; anything else exits 2 so a fixture gap cannot + // silently change the path. The live GitHub API is never called. + function fakeGh(dir: string): { calls: () => string[][]; glabCalls: () => string } { + const log = join(dir, "gh-calls.log"); + const glabLog = join(dir, "glab-calls.log"); + const prList = JSON.stringify([{ number: CLAIM.pr, headRefName: CLAIM.branch, headRepositoryOwner: { login: FAKE_OWNER }, url: CLAIM.url, isDraft: false }]); + const content = Buffer.from(`${CLAIM.version}\n`).toString("base64"); + writeFileSync(join(dir, "gh"), [ + "#!/bin/sh", + `printf '%s\\037' "$@" >> '${log}'; printf '\\n' >> '${log}'`, + 'case "$*" in', + ' "auth status") exit 0 ;;', + ' "pr view --json number -q .number") exit 1 ;;', + ` "pr list --state open --base main --limit 200 --json number,headRefName,headRepositoryOwner,url,isDraft") printf '%s\\n' '${prList}'; exit 0 ;;`, + ` "repo view --json owner -q .owner.login") echo '${FAKE_OWNER}'; exit 0 ;;`, + ` "api repos/{owner}/{repo}/contents/VERSION?ref=${encodeURIComponent(CLAIM.branch)} -q .content") echo '${content}'; exit 0 ;;`, + "esac", + `echo "FAKE_GH_UNHANDLED $*" >> '${log}'`, + 'echo "FAKE_GH_UNHANDLED $*" >&2', + "exit 2", + "", + ].join("\n"), { mode: 0o755 }); + writeFileSync(join(dir, "glab"), `#!/bin/sh\necho "$*" >> '${glabLog}'\nexit 1\n`, { mode: 0o755 }); + return { + calls: () => readFileSync(log, "utf8").trimEnd().split("\n").map((line) => line.split("\x1f").filter(Boolean)), + glabCalls: () => { try { return readFileSync(glabLog, "utf8"); } catch { return ""; } }, + }; + } + test("CLI runs against real repo and emits parseable JSON", async () => { - const proc = Bun.spawnSync([ - "bun", - "run", - "./bin/gstack-next-version", - "--base", - "main", - "--bump", - "patch", - "--current-version", - "1.6.3.0", - "--workspace-root", - "null", // skip sibling scan in CI - ], { timeout: 30_000 }); - const out = new TextDecoder().decode(proc.stdout); - const parsed = JSON.parse(out); - expect(parsed).toHaveProperty("version"); - expect(parseVersion(parsed.version)).not.toBeNull(); - expect(parsed).toHaveProperty("bump", "patch"); - expect(parsed).toHaveProperty("host"); - expect(["github", "gitlab", "unknown"]).toContain(parsed.host); - expect(parsed).toHaveProperty("claimed"); - expect(Array.isArray(parsed.claimed)).toBe(true); - expect(parsed).toHaveProperty("siblings"); - expect(parsed.siblings).toEqual([]); // --workspace-root null disabled scanning - expect(parsed).toHaveProperty("version_path", "VERSION"); // default when no config + no flag + const stubDir = mkdtempSync(join(tmpdir(), "nextver-smoke-gh-")); + try { + const gh = fakeGh(stubDir); + const proc = Bun.spawnSync([ + "bun", + "run", + "./bin/gstack-next-version", + "--base", + "main", + "--bump", + "patch", + "--current-version", + "1.6.3.0", + "--workspace-root", + "null", // skip sibling scan in CI + ], { timeout: 30_000, env: { ...process.env, PATH: `${stubDir}:${process.env.PATH ?? ""}` } }); + const stderr = new TextDecoder().decode(proc.stderr); + expect(proc.exitCode, stderr).toBe(0); + const out = new TextDecoder().decode(proc.stdout); + const parsed = JSON.parse(out); + expect(parsed).toHaveProperty("version"); + expect(parseVersion(parsed.version)).not.toBeNull(); + expect(parsed).toHaveProperty("bump", "patch"); + expect(parsed).toHaveProperty("host"); + expect(["github", "gitlab", "unknown"]).toContain(parsed.host); + expect(parsed).toHaveProperty("claimed"); + expect(Array.isArray(parsed.claimed)).toBe(true); + expect(parsed).toHaveProperty("siblings"); + expect(parsed.siblings).toEqual([]); // --workspace-root null disabled scanning + expect(parsed).toHaveProperty("version_path", "VERSION"); // default when no config + no flag + + const remote = execFileSync("git", ["remote", "get-url", "origin"], { cwd: join(import.meta.dir, ".."), encoding: "utf8", timeout: 10_000 }).trim(); + expect(gh.calls()).toEqual([ + ...(remote.includes("github.com") ? [] : [["auth", "status"]]), + ["pr", "view", "--json", "number", "-q", ".number"], + ["pr", "list", "--state", "open", "--base", "main", "--limit", "200", "--json", "number,headRefName,headRepositoryOwner,url,isDraft"], + ["repo", "view", "--json", "owner", "-q", ".owner.login"], + ["api", `repos/{owner}/{repo}/contents/VERSION?ref=${encodeURIComponent(CLAIM.branch)}`, "-q", ".content"], + ]); + expect(gh.calls().flat().join(" ")).not.toContain("FAKE_GH_UNHANDLED"); + expect(stderr).not.toContain("FAKE_GH_UNHANDLED"); + expect(gh.glabCalls()).toBe(""); + expect(parsed.host).toBe("github"); + expect(parsed.offline).toBe(false); + expect(parsed.fallback).toBeNull(); + expect(parsed.warnings).toEqual([]); + expect(parsed.claimed).toEqual([CLAIM]); // the canned PR's owner matches the canned repo owner + expect(parsed.version).toBe("1.6.5.0"); // the canned claim on 1.6.4.0 is skipped + } finally { + rmSync(stubDir, { recursive: true, force: true }); + } }, 30_000); // Headroom over the 4-5s wall time of the spawned process under load test("CLI runs with --version-path and surfaces it in JSON output", async () => { diff --git a/test/plan-design-sdk-fixture.test.ts b/test/plan-design-sdk-fixture.test.ts index 04f18c4e3..0f53d5ed5 100644 --- a/test/plan-design-sdk-fixture.test.ts +++ b/test/plan-design-sdk-fixture.test.ts @@ -18,6 +18,7 @@ async function exercise(mode: 'success' | 'max-turns' | 'first-timeout' | 'secon const scratch = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'legacy-design-free-'))); const home = path.join(scratch, 'home'); fs.mkdirSync(home); const env = { PATH: process.env.PATH ?? '', HOME: home, GIT_CONFIG_NOSYSTEM: '1', + GIT_CONFIG_COUNT: '2', GIT_CONFIG_KEY_0: 'maintenance.auto', GIT_CONFIG_VALUE_0: 'false', GIT_CONFIG_KEY_1: 'gc.auto', GIT_CONFIG_VALUE_1: '0', GIT_CONFIG_GLOBAL: process.platform === 'win32' ? 'NUL' : '/dev/null', ...(process.env.SystemRoot ? { SystemRoot: process.env.SystemRoot } : {}) }; const callbacks: Array<{ name: string; fn: () => Promise; timeout: number }> = []; @@ -25,6 +26,8 @@ async function exercise(mode: 'success' | 'max-turns' | 'first-timeout' | 'secon const recordBudgets: number[] = []; let launched = false, sdkSignal: AbortSignal | undefined; let inputVerified = false, saved = '', resultError: unknown; + const removals: string[] = []; + const survivors = () => `surviving fixture dirs: ${dirs.filter(dir => fs.existsSync(dir)).join(', ') || '(none)'}; removals: ${removals.join('; ') || '(none)'}`; const owned = (p: string) => { const full = path.resolve(p); expect(full.startsWith(scratch + path.sep)).toBe(true); @@ -43,13 +46,17 @@ async function exercise(mode: 'success' | 'max-turns' | 'first-timeout' | 'secon }, copyFileSync(a: string, b: string) { owned(b); fs.copyFileSync(a, b); }, cpSync(a: string, b: string, opts: any) { owned(b); fs.cpSync(a, b, opts); }, - rmSync(p: string, opts: any) { owned(p); fs.rmSync(p, opts); }, + rmSync(p: string, opts: any) { + owned(p); + try { fs.rmSync(p, opts); } catch (error) { removals.push(`${p}: ${error}`); throw error; } + if (fs.existsSync(p)) removals.push(`${p}: rmSync returned but the path survived`); + }, }; const args = { ROOT, fs: localFs, path, os: { tmpdir: () => scratch }, expect, CAPTURE_MS, CAPTURE_LONG_MS, OFFICE_HOURS_BUN_GRACE_MS, resolveEvalModel, runId: 'free-legacy-design', evalCollector: { addTest(entry: any) { - expect(dirs.every(dir => !fs.existsSync(dir))).toBe(true); + expect(dirs.every(dir => !fs.existsSync(dir)), survivors()).toBe(true); rows.push(entry); } }, runRecordedOfficeHoursAttempt: (options: Parameters[0]) => { @@ -134,7 +141,7 @@ async function exercise(mode: 'success' | 'max-turns' | 'first-timeout' | 'secon expect(callbacks).toHaveLength(1); expect(callbacks[0]!.timeout).toBe(CAPTURE_LONG_MS); try { await callbacks[0]!.fn(); } catch (error) { resultError = error; } expect(inputVerified).toBe(true); expect(dirs).toHaveLength(1); - expect(dirs.every(dir => !fs.existsSync(dir))).toBe(true); + expect(dirs.every(dir => !fs.existsSync(dir)), survivors()).toBe(true); expect(recordBudgets).toEqual([CAPTURE_LONG_MS - OFFICE_HOURS_BUN_GRACE_MS]); expect(sdkSignal?.aborted).toBe(true); return { resultError, rows, saved }; diff --git a/test/test-free-shards-git-maintenance.test.ts b/test/test-free-shards-git-maintenance.test.ts new file mode 100644 index 000000000..3eb4e9bc3 --- /dev/null +++ b/test/test-free-shards-git-maintenance.test.ts @@ -0,0 +1,106 @@ +/** + * The free runner's git auto-maintenance backstop: every shard child gets + * maintenance.auto=false and gc.auto=0 appended to its inherited GIT_CONFIG_* + * pairs, so a fixture commit cannot leave a detached `git maintenance run` + * creating and deleting .git/objects/maintenance.lock under a later listing, + * watch or removal. Fixtures that build their own git env set the keys + * themselves (docs/TESTING_INTERNALS.md#flake-ledger). + */ +import { afterEach, describe, expect, test } from 'bun:test'; +import * as fs from 'node:fs'; +import * as os from 'node:os'; +import * as path from 'node:path'; +import { spawnSync } from 'node:child_process'; +import { disableGitAutoMaintenance, runFreeShard } from '../scripts/test-free-shards'; + +const roots: string[] = []; +afterEach(() => { for (const root of roots.splice(0)) fs.rmSync(root, { recursive: true, force: true }); }); +const scratch = () => { + const root = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'free-git-maintenance-'))); + roots.push(root); + return root; +}; +const gitConfigEnv = (env: NodeJS.ProcessEnv) => Object.fromEntries(Object.entries(env).filter(([key]) => key.startsWith('GIT_CONFIG_')).sort()); +const cleanGitEnv = (home: string): NodeJS.ProcessEnv => ({ + PATH: process.env.PATH ?? '', HOME: home, GIT_CONFIG_NOSYSTEM: '1', GIT_CONFIG_GLOBAL: path.join(home, 'no-global-gitconfig'), + ...(process.env.SystemRoot ? { SystemRoot: process.env.SystemRoot } : {}), +}); + +/** The GIT_CONFIG_* entries the real runFreeShard child received. */ +async function childGitConfig(env: NodeJS.ProcessEnv | undefined): Promise { + const out = path.join(scratch(), 'child-env.json'); + const probe = `require('fs').writeFileSync(${JSON.stringify(out)}, JSON.stringify(Object.fromEntries(Object.entries(process.env).filter(([k]) => k.startsWith('GIT_CONFIG_')))));` + + `console.log('Ran 1 tests across 1 files. [1.00ms]');`; + const outcome = await runFreeShard(['probe'], 1, 1, { env, quiet: true, log: () => {}, + commandFor: () => ({ command: process.execPath, args: ['-e', probe] }) }); + expect(outcome.status).toBe('passed'); + return gitConfigEnv(JSON.parse(fs.readFileSync(out, 'utf8'))); +} + +const OFF = { maintenance: ['maintenance.auto', 'false'], gc: ['gc.auto', '0'] } as const; +const appended = (start: number) => ({ + [`GIT_CONFIG_KEY_${start}`]: OFF.maintenance[0], [`GIT_CONFIG_VALUE_${start}`]: OFF.maintenance[1], + [`GIT_CONFIG_KEY_${start + 1}`]: OFF.gc[0], [`GIT_CONFIG_VALUE_${start + 1}`]: OFF.gc[1], +}); + +describe('free runner: git auto-maintenance off for every shard child', () => { + test('absent and zero inherited GIT_CONFIG_COUNT both start the pairs at index 0', async () => { + const home = scratch(); + expect(await childGitConfig(cleanGitEnv(home))).toEqual(gitConfigEnv({ ...cleanGitEnv(home), GIT_CONFIG_COUNT: '2', ...appended(0) })); + expect(await childGitConfig({ ...cleanGitEnv(home), GIT_CONFIG_COUNT: '0' })) + .toEqual(gitConfigEnv({ ...cleanGitEnv(home), GIT_CONFIG_COUNT: '2', ...appended(0) })); + }); + + test('a nonzero inherited count keeps its pairs and appends after them', async () => { + const env = { ...cleanGitEnv(scratch()), GIT_CONFIG_COUNT: '1', GIT_CONFIG_KEY_0: 'user.name', GIT_CONFIG_VALUE_0: 'Fixture' }; + expect(await childGitConfig(env)).toEqual(gitConfigEnv({ ...env, GIT_CONFIG_COUNT: '3', ...appended(1) })); + }); + + test('an explicit options.env and the default process.env are both covered, and neither caller object changes', async () => { + const env = { ...cleanGitEnv(scratch()), GIT_CONFIG_COUNT: '1', GIT_CONFIG_KEY_0: 'core.autocrlf', GIT_CONFIG_VALUE_0: 'false' }; + const envBefore = structuredClone(env); + const processBefore = gitConfigEnv(process.env); + await childGitConfig(env); + expect(env).toEqual(envBefore); + const inherited = Number(process.env.GIT_CONFIG_COUNT || '0'); + expect(await childGitConfig(undefined)).toEqual({ ...processBefore, GIT_CONFIG_COUNT: String(inherited + 2), ...appended(inherited) }); + expect(gitConfigEnv(process.env)).toEqual(processBefore); + }); + + test('a malformed inherited count is passed through untouched and git still rejects it', async () => { + const env = { ...cleanGitEnv(scratch()), GIT_CONFIG_COUNT: 'abc', GIT_CONFIG_KEY_0: 'user.name', GIT_CONFIG_VALUE_0: 'Fixture' }; + const child = await childGitConfig(env); + expect(child).toEqual(gitConfigEnv(env)); + const result = spawnSync('git', ['config', '--get', 'user.name'], { env: { ...env, ...child }, encoding: 'utf8', timeout: 10_000 }); + expect(result.status, result.stderr).not.toBe(0); + expect(result.stderr).toContain('GIT_CONFIG_COUNT'); + }); + + test('a traced commit in the runner child env starts no git maintenance run; the default env does', async () => { + const root = scratch(); + const base = cleanGitEnv(root); + const traced = (env: NodeJS.ProcessEnv, name: string) => { + const repo = path.join(root, name); + const git = (...args: string[]) => { + const result = spawnSync('git', args, { cwd: repo, env: { ...env, GIT_TRACE: '1' }, encoding: 'utf8', timeout: 10_000 }); + expect(result.status, result.stderr).toBe(0); + return result.stderr; + }; + fs.mkdirSync(repo); + git('init', '-q', '-b', 'main'); + git('config', 'user.email', 't@t'); git('config', 'user.name', 't'); git('config', 'commit.gpgsign', 'false'); + fs.writeFileSync(path.join(repo, 'a.txt'), 'a\n'); + git('add', 'a.txt'); + return git('commit', '-qm', 'traced').split('\n').filter(line => /maintenance run|gc --auto/.test(line)); + }; + expect(traced(base, 'defaults').length, 'control: the default env must show the auto-maintenance child').toBeGreaterThan(0); + const runnerEnv = { ...base, ...(await childGitConfig(base)) }; + expect(traced(runnerEnv, 'runner')).toEqual([]); + }); + + test('disableGitAutoMaintenance mutates only the env it is given', () => { + const env: NodeJS.ProcessEnv = { GIT_CONFIG_COUNT: ' 2 ', GIT_CONFIG_KEY_0: 'a.b', GIT_CONFIG_VALUE_0: '1', GIT_CONFIG_KEY_1: 'c.d', GIT_CONFIG_VALUE_1: '2' }; + disableGitAutoMaintenance(env); + expect(env).toEqual({ GIT_CONFIG_KEY_0: 'a.b', GIT_CONFIG_VALUE_0: '1', GIT_CONFIG_KEY_1: 'c.d', GIT_CONFIG_VALUE_1: '2', GIT_CONFIG_COUNT: '4', ...appended(2) }); + }); +}); diff --git a/test/test-health-report.test.ts b/test/test-health-report.test.ts index 98a5a3f3c..75970cef3 100644 --- a/test/test-health-report.test.ts +++ b/test/test-health-report.test.ts @@ -149,6 +149,10 @@ describe('enforced checks and the tracking issue (DX-9)', () => { const failing = unseededCheck(freeRoot(2, 6)); expect(failing).toMatchObject({ status: 'fail', detail: expect.stringContaining('stale seed: 6 unseeded file(s) > 5') }); expect(failing.fix).toContain('bun run test:ubicloud --record-durations'); + expect(failing.fix).toContain('UBICLOUD_API_KEY'); + expect(failing.fix).toContain('copies scripts/free-test-durations.json back into this checkout'); + expect(failing.fix).toContain('leave the refresh to a maintainer'); + expect(failing.fix).not.toContain('CI recording'); expect(unseededCheck(freeRoot(2, 5))).toMatchObject({ status: 'pass', detail: expect.stringContaining('5 unseeded file(s) (limit 5)') }); }); @@ -162,7 +166,8 @@ describe('enforced checks and the tracking issue (DX-9)', () => { }); describe('collectHealth over recorded fixture data', () => { - function fixture() { + function fixture(windowsRuns: unknown[] = [run(70, { event: 'pull_request', head_branch: 'feature' }), + run(71, { event: 'workflow_dispatch', run_started_at: day(2), updated_at: day(1) })]) { const prTrials = formatTrialOutcomes([trialRecord('gate-a', 'passed', { tier: 'gate', lane: 'gate/pr', cost_usd: 2.5 }), trialRecord('gate-b', 'passed', { tier: 'gate', lane: 'gate/pr', execution: 'reused', cost_usd: 0 })]); const census = formatTrialOutcomes([ @@ -184,7 +189,7 @@ describe('collectHealth over recorded fixture data', () => { [/workflows\/free-tests\.yml\/runs/, () => ({ workflow_runs: [run(60), run(61, { conclusion: 'failure' })] })], [/runs\/60\/artifacts/, () => ({ artifacts: [{ id: 61, name: 'flake-ledger-2', size_in_bytes: 10 }] })], [/runs\/61\/artifacts/, () => ({ artifacts: [] })], - [/workflows\/windows-free-tests\.yml\/runs/, () => ({ workflow_runs: [run(70)] })], + [/workflows\/windows-free-tests\.yml\/runs/, () => ({ workflow_runs: windowsRuns })], ], { 11: { 'manifest.json': JSON.stringify({ prCoverage: { mode: 'full-fallback' } }) }, 12: { 'trial-outcomes.jsonl': prTrials }, @@ -207,7 +212,7 @@ describe('collectHealth over recorded fixture data', () => { expect(value('census-redispatch').value).toBe('0 of 1 census(es) re-dispatched; longest paid slice job 20.0 min'); expect(value('quarantine-evidence').value).toContain('insufficient evidence (not the same as healthy)'); expect(value('free-flaky-pass-rate').value).toStartWith('50.0% (1/2 main runs'); - expect(value('free-wall').value).toBe('free-tests 0.0 min (1 runs); windows-free-tests 0.0 min (1 runs)'); + expect(value('free-wall').value).toBe('free-tests 0.0 min (1 runs); windows-free-tests (successful PR runs) 0.0 min (1 runs)'); expect(value('free-serial').value).toBe('3 s over 3 files'); for (const entry of report.metrics.filter(entry => entry.id !== 'net-complexity')) { expect(entry.rule.length).toBeGreaterThan(10); @@ -218,6 +223,18 @@ describe('collectHealth over recorded fixture data', () => { expect(formatHealth(report)).toContain('rule: share of evals.yml pull_request runs'); }); + test('the Windows wall counts only successful pull_request runs and says so when there are none', () => { + const wall = (windowsRuns: unknown[]) => collectHealth({ client: fixture(windowsRuns), repo: 'o/r', now: NOW, sinceDays: 7, cacheDir: tmp('health-cache-'), root: freeRoot(3, 0) }) + .metrics.find(entry => entry.id === 'free-wall')!; + const pr = (id: number, minutes: number, extra: Record = {}) => run(id, { event: 'pull_request', head_branch: `pr-${id}`, + run_started_at: day(1), updated_at: new Date(Date.parse(day(1)) + minutes * 60_000).toISOString(), ...extra }); + expect(wall([pr(70, 6), pr(71, 7), pr(74, 8), pr(72, 30, { conclusion: 'failure' }), run(73, { event: 'workflow_dispatch', run_started_at: day(3), updated_at: day(1) })]).value) + .toBe('free-tests 0.0 min (1 runs); windows-free-tests (successful PR runs) 7.0 min (3 runs)'); + expect(wall([run(73, { event: 'workflow_dispatch', run_started_at: day(3), updated_at: day(1) })]).value) + .toBe('free-tests 0.0 min (1 runs); windows-free-tests (successful PR runs) no successful PR runs in window'); + expect(wall([]).rule).toContain('workflow_dispatch duration recordings excluded'); + }); + test('a rate-limited API degrades every remote metric to a named unavailable reason, never 0, and keeps the issue open', () => { const client = fakeClient([[/./, () => { throw new Error('gh api failed: HTTP 403: API rate limit exceeded for installation ID 1'); }]]); const report = collectHealth({ client, repo: 'o/r', now: NOW, sinceDays: 7, cacheDir: tmp('health-cache-'), root: freeRoot(3, 0) }); diff --git a/test/timeline.test.ts b/test/timeline.test.ts index eb4303cc4..d08c058a6 100644 --- a/test/timeline.test.ts +++ b/test/timeline.test.ts @@ -222,4 +222,64 @@ describe('gstack-timeline-read', () => { }); } } + + // --since/--branch used to read an unbound $2 (exit 1), and an unparseable + // --since silently returned unfiltered history. + const badFilters: Array<[string, string[], string]> = [ + ['--since missing value', ['--since'], '--since must be a relative time like "7 days ago" (got no value)'], + ['--since empty value', ['--since', ''], '--since must be a relative time like "7 days ago" (got an empty value)'], + ['--since followed by a flag', ['--since', '--limit', '5'], "(got flag '--limit')"], + ['--since yesterday', ['--since', 'yesterday'], "--since must be a relative time like \"7 days ago\" (got 'yesterday')"], + ['--since 2 weeks', ['--since', '2 weeks'], "(got '2 weeks')"], + ['--since 7days', ['--since', '7days'], "(got '7days')"], + ['--since impossible month', ['--since', '2026-13-01'], "(got '2026-13-01')"], + ['--since unanchored', ['--since', 'about 7 days ago, roughly'], "(got 'about 7 days ago, roughly')"], + ['--branch missing value', ['--branch'], '--branch must be a branch name (got no value)'], + ['--branch empty value', ['--branch', ''], '--branch must be a branch name (got an empty value)'], + ['--branch followed by a flag', ['--branch', '--limit', '5'], "--branch must be a branch name (got flag '--limit')"], + ['unknown flag', ['--bogus'], "unknown argument '--bogus'"], + ['stray argument', ['stray'], "unknown argument 'stray'"], + ]; + for (const history of ['empty', 'populated'] as const) { + for (const [label, args, message] of badFilters) { + test(`${label} exits 2 before any read on ${history} history`, () => { + if (history === 'populated') { + runLog(JSON.stringify({ skill: 'review', event: 'completed', branch: 'main', ts: '2026-03-28T10:00:00Z' })); + } + const result = runReadStatus(args); + expect(result.status, result.stderr).toBe(2); + expect(result.stdout).toBe(''); + expect(result.stderr).toContain(message); + if (label.startsWith('--since')) expect(result.stderr).toContain('accepted: " minute|hour|day|week|month[s] ago", "h|d|w", or an ISO date'); + if (label === 'unknown flag' || label === 'stray argument') expect(result.stderr).toContain('Usage: gstack-timeline-read'); + }); + } + + test(`--help prints the usage line and exits 0 on ${history} history`, () => { + if (history === 'populated') { + runLog(JSON.stringify({ skill: 'review', event: 'completed', branch: 'main', ts: '2026-03-28T10:00:00Z' })); + } + const result = runReadStatus(['--help']); + expect(result.status).toBe(0); + expect(result.stdout.trim()).toBe('Usage: gstack-timeline-read [--since "7 days ago"|7d|YYYY-MM-DD] [--limit N] [--branch NAME]'); + }); + + const yesterday = new Date(Date.now() - 86_400_000).toISOString().slice(0, 10); + for (const since of ['7 days ago', '3 Hours ago', '7d', '24h', '1w', yesterday, `${yesterday}T00:00:00Z`]) { + test(`--since '${since}' keeps recent events and drops old ones on ${history} history`, () => { + if (history === 'populated') { + runLog(JSON.stringify({ skill: 'review', event: 'completed', branch: 'main', ts: '2020-01-01T10:00:00Z' })); + runLog(JSON.stringify({ skill: 'ship', event: 'completed', branch: 'main', ts: new Date(Date.now() - 3_600_000).toISOString() })); + } + const result = runReadStatus(['--since', since]); + expect(result.status, result.stderr).toBe(0); + expect(result.stderr).toBe(''); + if (history === 'empty') expect(result.stdout).toBe(''); + else { + expect(result.stdout).toContain('/ship completed'); + expect(result.stdout).not.toContain('/review completed'); + } + }); + } + } });