Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/lint.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -3470,6 +3470,46 @@ jobs:
- name: Stall-guard budget invariant
run: pnpm check:stall-guard-budget

# The third member of the stall-guard family, and the only one that was
# never wired (#13246). `measure-stall-guard-headroom.mjs` re-derives the
# one term the budget gate above cannot read statically -- `p + s`, the
# job's prep plus the healthy run length -- by joining that gate's own
# sweep against GitHub's runner timestamps.
#
# ONLY THE `--self-test` LEG, and the asymmetry with the two steps above is
# deliberate: they run `--self-test && the gate`, this one must never
# append a bare invocation. The measurement path fetches
# `GET /actions/runs/{id}/jobs` and reads GITHUB_TOKEN/GH_TOKEN, so a bare
# run reds the farm on a token-less runner. "Consistency with the sibling"
# is the tidy-up that breaks this step.
#
# The `--self-test` half is a different animal, and conflating the two is
# exactly why this sat unrun: it takes no `--run`, so `fetchRunJobs` is
# unreachable from it. Measured with `net.Socket.connect`, `net.connect`,
# `dns.lookup` and `globalThis.fetch` all armed to throw, and with
# GITHUB_TOKEN/GH_TOKEN unset: 32 assertions passed, ~1.5s, no build. It
# drives the real `main()` over fixture payloads and fixture workflow trees
# in a temp dir, and asserts all three exit codes -- 0 covered, 1 a step
# that cannot deliver a verdict, 2 REFUSED -- so a tool that can only print
# "covered" cannot pass.
#
# Why it is worth a step rather than a note: #13121 gave the tool refusal
# branches (an unattributable observation refuses; an observation matching
# no guarded site is EXCLUDED and reported, never dropped), and every proof
# that those branches fire lives here. A refusal branch nobody exercises
# decays into decoration -- the same silence #13121 was filed about, one
# level up. The collision refusal in particular is unreachable from this
# tree, where all seven guarded steps carry distinct names, so only the
# synthetic `--root` fixtures can exercise it at all.
#
# WHAT REDDENS IT: its own script's code, and the guarded-site population
# this repo's workflows declare. Measured adversarially -- inverting the
# `attribute` NONE branch to attribute rather than exclude reds this step
# alone, naming the assertion. It reads `.github/workflows/**` plus temp
# fixtures; no network, no token, no build.
- name: Stall-guard headroom self-test (self-test half only, never the measurement)
run: pnpm check:stall-guard-headroom

# The dev-preflight gate's self-test — and deliberately only HALF of that
# gate (#8170, the second and only other member of #8110's split-gate
# family). Same neighbour as the step above for the same reason: both are
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -143,7 +143,8 @@
"check:spec-parsed-alias": "node scripts/check-spec-parsed-alias.mjs --self-test && node scripts/check-spec-parsed-alias.mjs",
"check:tenant-chokepoint": "node scripts/check-tenant-chokepoint.mjs --self-test && node scripts/check-tenant-chokepoint.mjs",
"check:stall-guard": "node scripts/run-with-stall-guard.mjs --self-test",
"check:stall-guard-budget": "node scripts/check-stall-guard-budget.mjs --self-test && node scripts/check-stall-guard-budget.mjs"
"check:stall-guard-budget": "node scripts/check-stall-guard-budget.mjs --self-test && node scripts/check-stall-guard-budget.mjs",
"check:stall-guard-headroom": "node scripts/measure-stall-guard-headroom.mjs --self-test"
},
"keywords": [
"objectstack",
Expand Down
19 changes: 15 additions & 4 deletions scripts/measure-stall-guard-headroom.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,10 +105,21 @@
* folded silently into the answer. Choosing the margin -- and deciding whether to
* spend it at all -- is a fleet-budget decision this tool has no standing to make.
*
* It is also NOT a CI gate and is deliberately not wired into any workflow: it
* needs the network and a token, and a check that cannot run offline has no
* business in the lint farm. `check-stall-guard-budget.mjs` is the gate; this is
* the instrument you reach for when that gate's headroom needs re-deriving.
* The MEASUREMENT path is NOT a CI gate and is deliberately not wired into any
* workflow: it needs the network and a token, and a check that cannot run
* offline has no business in the lint farm. `check-stall-guard-budget.mjs` is
* the gate; this is the instrument you reach for when that gate's headroom needs
* re-deriving.
*
* `--self-test` is the exception, and that distinction is load-bearing (#13246).
* The paragraph above was written of the TOOL and was read as covering the FLAG
* too, which left every assertion below unrun -- the #13121 refusal branches
* included, so the only proof they fire was itself never executed. The flag
* takes no `--run`, which makes `fetchRunJobs` unreachable from it: no socket,
* no token, only this repo's workflow directory and temp fixtures. It is wired
* as `check:stall-guard-headroom` and runs ONLY the flag -- never append a bare
* invocation to that script, however tidy the symmetry with its two siblings in
* the lint farm looks.
*
* ## Reading the exit code
*
Expand Down
Loading