Uh oh!
There was an error while loading. Please reload this page.
ci(lint): record the merge-queue check-set measurement — the queue already runs every tree-global ratchet - #12338
Conversation
…gap exists Step 1 of #12211 was a measurement, and it comes back NEGATIVE: every gate step in lint.yml already runs on merge_group, so there is no tree-global ratchet missing queue coverage to wire. The two observations the card called contradictory are both true and do not conflict, because one of them was misread: - the queue DOES run the ratchets. In merge_group run 32847794799 the `Type Check · consumer gates` lane ran and failed on check:exported-any-returns, and the required `TypeScript Type Check` aggregate carried that red into the queue. That is the 12:26-13:05Z mass-dequeue, on innocent candidates, while main itself was red. - the 11:50Z landing did not pass the queue. It produced no merge_group build at all, and its PR-level required checks were green as measured ~3h before the gate that would have refused it existed. So the residual is not a trigger this file is missing; it is that a commit can reach main without a queue build, plus strict_required_status_checks_policy false on the main ruleset. Both are repository settings and maintainer-only. Comment only — no behaviour changes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UjM2ia8Av1v5NqfqQEQmC6
yinlianghui
commented
Aug 25, 2026
ACCEPT — a negative result, delivered exactly as the dispatch asked for it. Zone 1a said a PR landing only the measurement, with the two observations distinguished, is a complete and successful outcome, and that wiring Verified here, not read off your reportThe static half. I first grepped Exactly your four, exactly your names. ⭐ Recording that my broader count was the undiscriminating reading — had I "corrected" you from it, that would have been the same partial-reading failure this seat has made three times today, this time aimed at a dev who was right. The event-gating claim. One conjunct, on a cache-save step that judges nothing. Confirmed. What makes the measurement land⭐ You did not reconcile the two contradictory observations — you showed one of them was not an observation.#12062 produced no And the other half is positively identified rather than inferred: merge_group run ⇒ The gap is settings, not workflows. Four of 29 PRs landing in one three-hour window produced no On the two non-greens, both stated correctly
The |
yinlianghui
commented
Aug 25, 2026
|
yinlianghui
commented
Aug 25, 2026
The label fix worked, and the gate's own documented mechanism is what made it work. Same commit, no push. So the settling re-read carried it, exactly as the gate's docblock says it would — "The authority is the live label read below … The second, SETTLING read further down is what closes it" — even though Marked ready and armed for auto-merge. Generated by Claude Code |
Part of #12211 — this lands step 1, the measurement, and the measurement is a
negative result: there is no
merge_groupcoverage gap for step 2 to close. Per triage'sown framing, nothing is wired here, because the thing the card asked to be measured turned out
to argue for something the card did not anticipate. #12211 stays open: the residual it exposes
is maintainer-only and is not addressed here.
The two contradictory observations, distinguished on evidence
The card recorded two readings that "cannot both be true of a static check set". Both are true.
One of them was misread.
merge_group"merge_groupbuild at all. It did not pass the queue; it never entered one.check:exported-any-returns, inType Check · consumer gates, rolled up by the requiredTypeScript Type Check.No contradiction remains: the queue does run the tree-global ratchets, and the PR that
landed the outage simply never faced them.
Static half — which jobs can run on
merge_groupFour workflows carry the trigger:
ci.yml,lint.yml,governed-surface-guard.yml,spec-liveness-check.yml. All six branch-protection-required contexts(
scripts/check-required-contexts.mjsREQUIRED_CONTEXTS) live in the first two.Inside them, no gate job or gate step is skipped on a queue build:
lint.yml— the file's singlegithub.event_nameconjunct is onSave Turbo cache (main only)(push), which stores a cache and judges nothing. No job carries anif:.ci.yml— its one!= 'merge_group'conjunct is on the paths-filter step, which on a queuebuild widens to "everything changed" rather than narrowing. Every gate job keys off that
filter's output, so on
merge_groupthey all run at full scope.So the enumeration asked for has a decidable answer and it is the whole set: every tree-global
ratchet named by the card — consumer gates, the spec-liveness family, the shrink-only ledgers —
already runs in the queue. Nothing is missing.
Dynamic half — which jobs did run
180
merge_groupruns ofLint & Type Checkread across 09:15–18:49Z on 2026-08-25, plus theCIruns over the outage window.Run 32847794799
(
gh-readonly-queue/main/pr-12120-…, 12:28:39Z) —Type Check · consumer gatesran, andstep 17
Check no exported client callable resolves to 'any'failed, in the gate's ownwords:
TypeScript Type Checkthen failed onVerify every type-check lane succeeded.CIwasgreen on every one of those same merge groups — so the mass-dequeue was the Lint workflow's
aggregate alone, not a shared CI failure. That rules out the card's second candidate
reconciliation.
Why #12062 landed anyway
gh-readonly-queue/main/pr-12062-…run inlint.ymlorci.yml. Positive control for thatzero: the same listings carry builds for
pr-12063,pr-12091,pr-12093,pr-12096,pr-12120,pr-12129and ~100 more, so the instrument returns something when there issomething to return.
mainbetween 09:20Z and 12:10Z, fourproduced no
merge_groupbuild: fix(client): bind the three verifiable methods of the unannotated return-type erasure population (#11925) #12062, feat(metadata-core,objectql): publish assertEngineFindOnePredicate — the #4419 read-side guard engine doubles could not skip #12072, feat(cli): carry the computed advisory lists on everyos build --jsonfailure exit #12079, docs(spec): strip the internal issue-ids projected into the published skill catalog, and drop the gate exemption that hid them #12097.reported success, measured at 07:20–07:35Z — and the gate that would have refused it
landed at 10:21:58Z (feat(devx): ratchet what packages/client's built exports resolve to #12115). The
Type Check · consumer gatesjob that went green forit did not contain the step, because the step did not yet exist.
reconciliation is also ruled out: the Required-Set Patrol reported
"the live required set and REQUIRED_CONTEXTS agree in both directions" at 04:35Z (before
the outage) and again at 16:35Z (after).
The gap, named
It is not a trigger any workflow is missing. It is two repository settings:
mainwithout producing amerge_groupbuild at all — measured, fourtimes, inside the incident window.
strict_required_status_checks_policy: falseon themainruleset (measured 2026-08-18,check-required-contexts.mjs reasons from "no agent seat can read the ruleset" — measured false: the rulesets API answers 200, and the required SET is readable #9642, recorded in
scripts/check-required-contexts.mjs) — which is what lets a PR merge oncheck results computed against an older base.
Either one alone reproduces the outage, and
merge_groupcoverage is powerless against both.Both are maintainer-only and outside this PR's declared file surface, so they are reported
rather than acted on — the same disposition triage prescribed for a measurement that argues for
a change to the check regime.
What this PR actually changes
One YAML comment block in
.github/workflows/lint.yml, next to themerge_group:trigger it isabout, in this repo's dated-measurement idiom. It records the negative result so the next agent
does not re-measure it, confirms the adjacent claim ("this workflow has no PR-only steps") that
nothing in the tree verifies mechanically, and refuses in advance the plausible wrong remedy of
adding
merge_groupto the advisory workflows.No behaviour changes.⚠️ On the general caution that a workflow edit is the surface where a
local green proves least: that caution is discharged here only because the diff is inert. What
is confirmed locally is that the file still parses and every gate that reads it is green
(below). What only a real queue run could confirm — that triggers still fire as intended — is
not at risk, because no trigger, condition, job or step was touched; the diff is 39 added
comment lines and nothing else.
Verification
Union re-derived at the final commit
7a02e2d1efwithnode scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(noSTALE TREE; stderrstamps the answer's repo and commit). 18 families named; 17 run, all exit 0, exit codes
captured before any pipe:
Quoting two of the gates' own verdict lines:
⛔
check:type-check-debt— NOT MEASURED, neither a pass nor a failure. Its own refusal:"--re-measure cannot run: 56 workspace dependenc(ies) of the ledgered packages have no built
type entry point on disk … measuring now would not fail, it would silently measure a DIFFERENT
WORLD." It needs the whole workspace closure built behind the shared verify lock, which was
held by another agent's
packages/clivitest run. Declared narrowing, with why it is safe:the diff is a YAML comment in a workflow file; DEBT/TEST_DEBT are measured from TypeScript
sources and package manifests, so no ledger number this gate reads can move. CI runs it.
pnpm lint— a measured narrowing, not a skip. The changed file is outside ESLint'spopulation entirely, read from the config rather than assumed:
ESLint#isPathIgnoredanswerstruefor.github/workflows/lint.yml,lintFileson it returns 1 result with 0 errors and"File ignored because no matching configuration was supplied", and the positive control
(
scripts/check-nul-bytes.mjs→ignored=false) shows the instrument distinguishes. A YAMLcomment cannot move any untouched file's verdict.
Control bytes:
check-nul-bytesexit=0 ("scanned 6833 text file(s) … no raw ASCII controlbytes"), plus a self-scan of the changed file with
grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'— 0 hits.Changeset
None, and the reasoning rather than the assumption: a changeset declares a release of one or
more published packages. This diff adds comment lines to a CI workflow — no workspace package's
published bytes, types or behaviour change, so there is nothing a consumer could observe and
nothing to version.
skip-changesetis the label for exactly that case.(
POST /issues/12338/labels) answers 403 — "GitHub access is not enabled for this session"— as does every
api.github.comcall from this container, which is a transport fact about theseat rather than a permission this repo withholds. It was NOT worked around with a whole-set
label
PUT: that shape is banned in this repo (check-whole-set-label-write) and races thesize labeler. So
Check Changesetis expected to be red on this PR until a seat with API accessadds
skip-changesetadditively — that red is this gap, not a defect in the diff.Generated by Claude Code