Merge origin/main (v1.91.372.0, #3612 landed) into gsta158-quarantine; retarget to main

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-31 15:34:30 +00:00
commit 97487df18e
34 files changed
+721 -100

No files matched your search

+16 -3
View File
@@ -197,7 +197,15 @@ shards get duration-aware walls (`max(base, predicted × 3, files × 5s)`). The
legacy `--shards N --shard i` path keeps stable hash indices. Required CI uses
one duration-packed `--ci-plan`, 20 ordinary `--ci-run` shards plus a separate
exclusive-fixture shard, and a `--ci-verify` aggregate. CI shards still run on
independent machines without ordering unrelated jobs. The public
independent machines without ordering unrelated jobs. Two workflow-level
constants in `free-tests.yml` set that size for every event: `FREE_SUITE_RUNNER`
(`ubicloud-standard-2`) and `FREE_SUITE_SHARDS` (`'20'`), which `free-plan`
resolves into the shards' runner and shard count. A `workflow_dispatch` run may
override them with `free_runner` (`ubicloud-standard-2`, `-4` or `-8`) and
`free_shards` (1–40) for runner-sizing experiments only; its job summary says
so, and it is never cited as a PR or train Free Tests result. Each shard prints
`RESOURCES: peak_used_mib=… min_free_disk_mib=… samples=…` from a memory and
disk sample every 2 seconds, even when the suite fails. The public
`TREE_MUTATING` map now classifies exclusive host-state fixtures; its sole
entry is `test/bootstrap-retention.test.ts`, whose same-UID nondumpable actors
affect host-wide procfs permission checks. Locally, this file runs only after
@@ -1274,7 +1282,10 @@ re-run keeps the creation time, so it does not wait out the window again). A
head that is no longer the PR's head reports "superseded by <sha>" and plans
nothing. Selection, trials and verdict rules do not change. Version Gate is not
an input, so a stamp push waits only for its own Free Tests and always gets a
gate. Dispatches (`eval:bg`, the census) never wait.
gate. Dispatches (`eval:bg`, the census) never wait. Neither does a
`pr-summary` run (a repository whose policy declares a train): it plans no paid
slices, so `readiness` is skipped, the run ends with the screening summary, and
a red Free Tests shows on Free Tests alone.
**Verdict reuse (R2a restamp-only, R2 main moved; a gate edit).** A PR head
reuses the verdict of the newest executed gate of the same PR instead of
@@ -1511,7 +1522,9 @@ refresh to a maintainer.
- `free-durations-record.yml` (Mondays 04:00 UTC, before test-health, and on
dispatch) records the Linux seed on `ubicloud-standard-8` with
`scripts/ubicloud/setup-free-suite.sh` and the Windows seed through
`windows-free-tests.yml`'s `record_durations` path. When either recording adds
`windows-free-tests.yml`'s `record_durations` path. The recorder stays on
`ubicloud-standard-8` while the free-suite shards run on `FREE_SUITE_RUNNER`
(`ubicloud-standard-2`); both are Ubicloud standard runners. When either recording adds
or drops a test file, it force-updates the `bot/free-duration-seeds` branch,
opens or refreshes one seed PR whose body states the ratchet result, and
dispatches Free Tests, Windows Free Tests and Quality gate on it. Those
+9 -3
View File
@@ -85,7 +85,7 @@ the byte-pinned `/ship` renders in `test/fixtures/golden/`).
| `serial_patterns` | test-file globs the `lanes` check runs one process per file, apart from the unit files (default `**/*.serial.test.*`) |
| `sealed` | sealed or eval output that must never reach a public destination; read by the pre-push hook and `gstack-pregate sealed` (see [sealed output](#sealed)) |
| `price_file` | repo-relative path of the paid gate's call-plan data file (`GSTACK_EVAL_CALLS v1`); `gstack-eval-plan price-gate` prices from it and never executes anything ([docs/eval-calls.md](eval-calls.md)) |
| `stall_timeout_s` | seconds a test command may print nothing before its process group is killed and the check is `incomplete` (`PREGATE_STALLED`); default 300, `0` disables; `--stall-timeout` overrides (see [supervision](#supervision)) |
| `stall_timeout_s` | seconds a test command may print nothing before its process group is killed and the check is `incomplete` (`PREGATE_STALLED`); default 300, `0` disables; `--stall-timeout` overrides; the `--remote` gate is exempt (see [supervision](#supervision)) |
| `timeout_s` | seconds each runner process may take (the unit-file group, each serial file, each guard without its own `timeout_s`, and the remote gate's deadline) when `--timeout` is not passed; 1 to 3600, default 600. `gstack-ship-preflight` and the `finish` fallback run pregate without `--timeout`, so this is how a repo with long lanes sets theirs |
| `remote_gate` | the repo's remote test gate command; under 8 cores the local test tier becomes a `requires-remote` obligation naming it, and `--remote` runs it (see [remote gate](#remote-gate)) |
| `allowlist` | `[{ finding, paths?, pattern?, reason }]`: benign findings the `secrets` check accepts and names as allowlisted, by gstack-redact finding id or non-secret category, path globs and a pattern anchored at the finding; never `env.value` (see [allowlist](#allowlist)) |
@@ -411,7 +411,9 @@ test-tier command:
- is killed as **stalled** when its log does not grow for the stall timeout
(`--stall-timeout <s>`, else `stall_timeout_s`, else 300; `0` disables): the
check is `incomplete` with `PREGATE_STALLED` and names the last file
started; the next serial file still runs;
started; the next serial file still runs. The `--remote` gate is exempt: a
gate that waits on CI is quiet by design, so only its timeout bounds it, and
its heartbeats add `; last output: <the gate's last line>`;
- is killed as **timed out** when that runner process reaches its timeout
(`--timeout <s>`, else `timeout_s`, else 600; per runner process, so many
serial files that each fit still pass): the check is `incomplete`, its detail
@@ -452,7 +454,11 @@ the supervision above. Close the obligation one of two ways:
`PREGATE_REMOTE: tree=<tree> tests=<n> failed=<n> [spent=<usd>]`, reporting the
tree it actually tested. The obligation clears only when that tree is
`PREGATE_TREE`, `tests` > 0, `failed` = 0 and the gate exits 0; anything else
leaves it uncleared and the check `incomplete`. The cap defaults to
leaves it uncleared and the check `incomplete`. The gate runs until it exits
or reaches the timeout (`--timeout`, else `timeout_s`, else 600 s); the stall
timer does not apply, and each 60 s heartbeat names the gate's last output
line, so a gate that prints what it is waiting on (a CI run id and its
status) shows it. The cap defaults to
`$GSTACK_SPEND_CAP_USD`; there is no default spend. Spend prints as
`spent, reserved, unknown`: a gate that prints no `spent=` is `unknown`,
counted at the cap.
+16 -5
View File
@@ -473,7 +473,14 @@ ones, and the arm lost blockers. `bin/gstack-review-dispatch` closes both ends:
second line for the same field starts another: `Severity` raises its label,
`Blocks: yes` makes it CRITICAL and `Blocks: no` never lowers it; an inline
`Blocks: yes` is CRITICAL too, and with no finding above it is one. The native
adversarial voice's FIXABLE collects as CRITICAL (normalizer v2, GSTA-167). A phantom finding costs a fold; a lost one costs the gate.
adversarial voice's FIXABLE collects as CRITICAL (normalizer v2, GSTA-167). An unnumbered, unlabeled bullet with no file:line
under a paragraph finding whose Severity or Blocks line has not come yet is that finding's detail, so the field line after it
lands on the finding; a numbered item is its own finding.
A phantom finding costs a fold; a lost one costs the gate.
A reply with no finding counts as a review only with the clean marker its own brief asks for: `NO FINDINGS` alone on a
line for the specialists, the batched specialist, the targeted reader, the Red Team and fix-check, the `Recommendation:`
line for the outside voice, either for the native adversarial voice. Without one (a refusal, an empty reply, a reader
that never saw the diff) collect records `review: false`, prints `COLLECT_NOT_REVIEWED` and exits 1.
4. Lead judgment writes `judged.jsonl`; `judge` refuses a set that drops a merged
finding, lowers its severity, folds it into a less severe duplicate, or adds or
promotes one without a reason (`JUDGMENT_REJECTED`). A merged file missing any id
@@ -481,10 +488,14 @@ ones, and the arm lost blockers. `bin/gstack-review-dispatch` closes both ends:
5. `verify --ledger <f>` replays all of it from the run's ledger: rendered against
dispatched hashes per render (each render is one dispatch of its reader, so a
two-pass ledger checks pass-1 sends against pass-1 briefs; a later render prints as
`<reader>@2`), a collected output for every sent reader (`NOT_COLLECTED`
otherwise; a reader that failed is collected from its failure text, where any
label word becomes a finding the judge folds, and its coverage is logged
`unavailable` in the review-log row). A mismatched send re-sent
`<reader>@2`), a collected output that is a review for every sent reader (`NOT_COLLECTED`
otherwise, and the output row `NOT_REVIEWED`; the marker is checked again in the output file when it is unchanged, so an
older ledger meets the same rule; a non-review the same dispatch later replaced with a review, by re-sending the brief, is `VOIDED`
and counted in `voided=N`). The outside voice may fail without blocking: `collect --unavailable '<reason>'` records its failure text
as missing coverage (`COLLECT_UNAVAILABLE`); an empty reason or an output that holds findings is refused (exit 2), so a partial
answer is collected normally and loses nothing. Verify prints its brief and output `UNAVAILABLE` and `unavailable=N` on the
verdict line, and its coverage is logged `unavailable` in the review-log row; any other reader is refused (exit 2), because its
missing coverage leaves the review incomplete. A mismatched send re-sent
byte-exact before anything was collected is void and counted (`voided=N` on the
verdict line); one that produced an output stays `MISMATCH`. Then output hashes
against the merged lines they produced, and the judgment rerun against the
+13 -9
View File
@@ -2522,12 +2522,15 @@ same-titled section (title compared case-insensitively), the
````gstack-ship-receipt```` block is a section of its own so a receipt
rewrite replaces only the receipt, sections the file does not rewrite stay in
place, and new sections are appended after them. The text above the first
`## ` heading belongs to the file whenever the file has a `## ` section: the
current body's text there (the opening lines, and any lines between the receipt
and the first heading, or the whole body when it has no `## ` heading) is
replaced by the file's own text above its first heading, or dropped when the
file has none. A file with no `## ` section (a receipt-only or text-only post)
leaves that text alone. One stderr line names what was replaced, kept, added
`## ` heading belongs to the file when the file is a full post: a
receipt block above its first `## ` section, as /ship composes it. Then the current body's text there (the opening lines, and
any lines between the receipt and the first heading, or the whole body when it
has no `## ` heading) is replaced by the file's own text above its first
heading, or dropped when the file has none. A partial post (`## ` sections
with no receipt above them, such as a lane posting `## Screenshots`) and a
file with no `## ` section (a receipt-only or text-only post) leave that text alone, so a human
intro or a `Review-loop exception:` line under the receipt survives; only
opening lines the file brings of its own replace the PR's opening lines. One stderr line names what was replaced, kept, added
and dropped, a dropped piece with its first line, or with that line withheld
when the redaction scan flags it (`gstack-post: pr-body merged
by section: replaced What changed; kept ship receipt, Why, Approvals; added
@@ -3464,8 +3467,7 @@ the lane log, then rerun or split the selection. A tool missing from PATH is
<a id="pregate-stalled"></a>
### `PREGATE_STALLED`
**Meaning.** A test command the lanes check (or a guard, or the `--remote`
gate) launched wrote nothing to its log for the stall timeout (default 300 s,
**Meaning.** A test command the lanes check (or a guard) launched wrote nothing to its log for the stall timeout (default 300 s,
`stall_timeout_s` in the base branch's `.gstack/pregate.json` or the user-owned file, or
`--stall-timeout`). pregate killed its process group and names the last test
file started. The check is incomplete, never pass.
@@ -3474,7 +3476,9 @@ file started. The check is incomplete, never pass.
child, a server that never exits, a synchronous wait), fix it and rerun
`gstack-pregate --stage tests`. A test that is legitimately quiet for longer
needs a larger `--stall-timeout`; `0` disables the stall kill and leaves only
`--timeout`.
`--timeout`. The `--remote` gate never stalls: it is bounded by `--timeout`
(else `timeout_s`), so a gate that waits on CI needs a timeout long enough for
the CI run.
<a id="pregate-receipt-invalid"></a>
### `PREGATE_RECEIPT_INVALID`