fix(ci-carry): a per_file remainder file that skips here too is not owed (GST-1314) (#3985)

* fix(ci-carry): a per_file remainder file that skips here too is not owed (GST-1314); anchor per_file paths, --no-env-file, declare gstack's per_file runner

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* chore: name the changelog fragment after the branch

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(evidence): a truncated per_file log never counts a remainder file not owed (GST-1314)

Review-Finding: p1b/outside-voice#1 reader=outside-voice
Review-Finding: p1b/red-team#3 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(changelog): GST-1314 fragment names the truncated-log refusal

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(pregate): a per_file log cut at 2 MB still refuses (GST-1314)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
Garry Tanandcapy-ai[bot] authored and GitHub committed 2026-11-04 08:14:07 +00:00
1 parent c1ace7483b
commit 068087f33c
6 files changed
+108 -30

No files matched your search

+19 -11
View File
@@ -775,20 +775,28 @@ once:
them here. A /ship lane or guard whose inventory names one carries the
covered files and runs only the skipped ones here, through the runner its
`ship_lanes_from` entry declares as `per_file` (a command with `{files}`,
such as `"per_file": "bun test --timeout=30000 {files}"`, the same form as the
tests stage's `runner`). That run is recorded under `<label>.skipped`, the
`LANE:` line adds `skipped_here=<n> file(s) tests_ran_here=<n>`, and the CI row
is written only after four checks pass. In order, they are the remainder's
exit (`skipped_failed`), its test count above zero (`skipped_zero_run`), every
carried run again (`run_changed`), and the working tree once more
such as `"per_file": "bun --no-env-file test --timeout=30000 {files}"`, the
same form as the tests stage's `runner`). It runs one file at a time, each path
anchored with `./` because Bun reads a bare relative path as a substring
filter. Those runs are recorded under `<label>.skipped`, the `LANE:` line adds
`skipped_here=<n> file(s) tests_ran_here=<n>`, and the CI row is written only
after four checks pass. In order, they are each file's exit
(`skipped_failed`), each file's test count above zero (`skipped_zero_run`),
every carried run again (`run_changed`), and the working tree once more
(`tree_changed`, for an edit made during those checks). An edit made while the
remainder itself runs leaves its ledger row without a tree, so it shows as
`skipped_zero_run`. Any of these refusals runs the whole lane here. An entry with no `per_file` refuses as
`skipped_zero_run`. One exception to the count check (GST-1314): a file whose
Bun summary registered tests and skipped every one of them here too, the way
an env-gated or tool-gated file skips by design, is not owed. The CI row lists
it under `skipped_here.not_owed` and the `LANE:` line adds
`not_owed_here=<n>`. A file that registers no test here still refuses, and so
does a file whose log hit the 2 MB cap, since a cut log's last summary may not
be the run's. Any of these refusals runs the whole lane here. An entry with no `per_file` refuses as
`inventory_skipped`, naming the files, and the lane runs here whole. A partly
skipped file ran tests and stays covered. gstack's own Free Tests writer does
not emit the list yet: it starts in the same follow-up pull request that
declares `per_file` for gstack's `bun run test` lane, so gstack's carry does not
change until both switch on together. A `tree.json`
skipped file ran tests and stays covered. gstack's `bun run test` lane
declares `per_file`, and its Free Tests writer starts emitting the list in a
follow-up pull request, so the runner is in place on the base before any run
lists a skipped file. A `tree.json`
without the key (older writers, other repos) is read as before, with every
listed file counted as run; add the list to your writer to close that gap.
The remote gate's clearance does not use it: that gate runs on a Linux runner