Uh oh!
There was an error while loading. Please reload this page.
test(ci): pin the skip-changeset phantom — nothing wires it, and the page keeps denying it - #6274
Conversation
…e page keeps denying it The label object was re-minted in this repository (auto-created by being applied by name) and is now being read as a mechanism: a triage comment on #6243 instructed a PR to carry it, the developer refused, and the refusal was upheld on PR #6260. A test cannot see GitHub's label data, so it does not try. It pins the two halves that live in the tree: no read of the name under .github/ or scripts/ (option B landing without a decision), and the page keeping its denial plus the alternative to reach for instead. Also corrects a claim on that page that had become false: it reported a point-in-time labels-API reading from 2026-08-08 saying the label did not exist. It does. A reading nothing in the tree can keep true is replaced by the durable invariant, and the third assertion pins that it is not restored.
yinlianghui-tw
commented
Aug 25, 2026
PM review — ACCEPT. Both open questions ruled A, and the doc discovery is the real value of this PR.Reviewed by the ⭐ The discovery the card did not contain — verified independently before this reviewI ran both measurements myself rather than accepting the report: The page asserts the label does not exist; the API returns it today. That is exactly the combination the dev named as worst-available: the reader is told it does not exist, sees it in the picker, concludes the page is the stale side, and treats the phantom as the real mechanism. A point-in-time API reading aged into a falsehood — the same defect class as #6243's header, on the page whose job is to deny this exact phantom. Scope call (question 2) — A, keep the doc correction in this PRThe dev flagged the divergence instead of silently deciding, which is the right mechanics. On the substance: shipping a test that pins the page's denial of the label while leaving a sentence on that same page falsely asserting the label's nonexistence would land the file contradicting itself — the exact shape #6260 just fixed elsewhere. Same defect class, same file, zero collision (no open PR touches either file), reversible as one hunk. Folding it in was correct. ⭐ And it dissolves this card's old sequencing objection. My earlier comment argued the pin was worthless before the deletion. That was true of the pin as then described. What landed is different: the grep invariant plus the durable-phrasing pin is worth having now, because it stops the page from ever again carrying a point-in-time API reading that rots — deletion or no deletion. The grep invariant over the labels-API assertion (question 1's shape) — right, for the measured reasonZero occurrences of fetch/octokit/execSync in the suite today; a labels-API case would have been its only network call and only credential, and would red CI while the label object still exists. Pinning what the tree can see, and pinning that the page denies rather than describes, is the correct altitude. Both new cases confirmed collected by name (34 passed, was 32). Evidence qualityReverse verification run from the committed state with EXIT/INT/TERM traps so a cap-kill could not leave the tree mutated — that is a new safeguard tonight and worth copying. Mutations confirmed by counting anchored text, never editor exit status. The full-suite narrowing is declared and measured on three legs, including the one that matters: of 10 files matching The corrected count — label on seven closed PRs, not the one the card names — strengthens the premise and touched none of them. Correct restraint. ⛔ The two things that remain, neither of them this PR's
⛔ Not armed yet
Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Part of #4912
Part of, notFixes, deliberately.#4912 closes when both halves are done: thispin, and the deletion of the
skip-changesetlabel object. I could not perform thedeletion (evidence below), so a closing keyword here would silently close a card whose
administrative half is still owed.
What this changes
Two files, no runtime code:
scripts/__tests__/ci-cd-pipeline-doc.test.tscontent/docs/guide/ci-cd-pipeline.mdThe card got stronger while it sat — the predicted harm actually happened
#4912 predicted: "the next agent that greps for 'how do I declare this PR publishes nothing'
finds a label, applies it, and believes the declaration landed."
That occurred on 2026-08-25, hours before this PR. Verified rather than taken on trust:
invoked-as.mjs's "Nothing here enforces this yet" section is stale in both halves — the gate landed and the sweep completed, but the header still tells readers neither exists #6243 (claude[bot],2026-08-25T04:21:23Z) ends with a bareinstruction:
`skip-changeset`.ignoring it (report comment on
invoked-as.mjs's "Nothing here enforces this yet" section is stale in both halves — the gate landed and the sweep completed, but the header still tells readers neither exists #6243).So the label is no longer a latent phantom — it is actively being read as a mechanism by
agents, which is the harm the card described.
Premise re-measured on
origin/main@ef2a3bd8d— unchangedExactly one hit, the prose the card names. No changeset gate has a label-keyed skip path:
check-changeset-presence.mjs,check-changeset-fixed.mjsandcheck-changeset-no-major.mjscontain no read of any label. No workflow reads it either.
the label. It is on seven PRs, all closed: #4700, #4665, #4639, #4630, #4628, #4615, #4129.
⛔ I removed it from none of them — I opened none of them.
What the pin can and cannot observe
A label lives in GitHub's data, not in the tree. No test here can assert the label object is
gone, and this suite has no network call or credential anywhere in it — every other assertion
reads the filesystem. Reaching for the labels API to pin this would be the one test in the file
that can fail because of an outage.
label" is already true, stays true, and does not address the defect. That objection is why the
pin is not that. The two cases hold things a future commit could change without anyone
noticing:
never wires the phantom skip-changeset label into a workflow or a gate— walks.github/andscripts/and fails on any occurrence outside the test file that records thehistory. This is the guard against option B landing without a decision: a labelled bypass
on a changeset gate that deliberately has none, declined by
.github/WORKFLOWS.mddocuments 5 workflows that do not exist and omits 9 that do — including a changeset gate and askip-changesetlabel neither of which is real #3724 and again by the Askip-changesetlabel exists on this repo, but no workflow reads it — the repo's own test records that neither the workflow nor the label was ever real #4912ruling. The name is wired in the
objectstacksibling (lint.yml,pr-automation.yml,check-empty-changeset.mjs), which is how it reaches agents who then look for it here, socopying that wiring across is a live risk, not a theoretical one.
keeps the page denying skip-changeset rather than describing it—ci-cd-pipeline.mdis where a contributor looks up "how do I declare this PR publishes nothing", so the page is
what decides whether the next reader believes the label. Unlike the
size-check.ymlpinabove it, absence is the wrong assertion: the page must keep naming the label in order to
deny it. So the denial itself is pinned, along with the alternative to reach for instead — a
denial with no alternative sends the reader back to the label.
⭐ The page was asserting something false about this very phantom
Found while verifying, and it is the reason this PR is worth landing before the deletion
rather than after. The page carried:
That is false today. Measured via
get_labelonobjectstack-ai/objectui:The object exists, with exactly the auto-minted signature the card describes. So the worst
possible combination was in place: a contributor reads "the label does not exist", sees it in
the label picker, concludes the page is stale — and treats the label as the real mechanism.
A point-in-time API reading is not a fact this repository can keep true, and this one was
false within weeks. It is replaced with the durable invariant (nothing reads it; here is what to
do instead), and the third assertion pins that a point-in-time reading is not put back.
Verification
All on the final commit
1a1e7bc07(git rev-parse --short HEAD), clean tree. Exit codescaptured by redirect before any pipe (
cmd > out 2>&1; echo EXIT=$?); every line quoted isthe gate's own printed verdict, never a bare
$?.vitest run scripts/__tests__/ci-cd-pipeline-doc.test.ts --reporter=verboseTest Files 1 passed (1)·Tests 34 passed (34)type-check:scripts> tsc -p tsconfig.scripts.jsonlint:rootUNNARROWED✖ 28 problems (0 errors, 28 warnings)check:control-bytes✅ check-control-bytes: OK (scanned 5171 tracked text file(s); skipped 85 binary).check-doc-links.mjsLinks are valid across 15 scan roots.check-changeset-presence.mjs✅ No source of a released package changed in this range, so no changeset is owed.vitest run scripts/(the narrowed union)Test Files 77 passed (77)·Tests 2209 passed (2209)Both new cases confirmed COLLECTED BY NAME under
--reporter=verbose, not inferred from atotal:
lint:rootwas run unnarrowed. Its 28 warnings are all pre-existing@typescript-eslint/no-explicit-anyine2e/live/**,vitest.setup.base.tsand twoscripts/__tests__/vite-*files — zero in either file this PR touches (grep -c 'ci-cd-pipeline'over the lint output →0), and the same set PR #6260 reported.Reverse-verification — both pins fail when violated
Run from the committed state, each leg with a
trap … EXIT INT TERMrestore so a cap-killcould not leave the tree mutated. No build or
dist/is involved — vitest transforms thesetests from source, and the ablation exercised the byte-identical walker and normalizer.
.github/planted-ablation-probe.ymlreading the labelgrep -cin planted file →1, file exists →1[".github/planted-ablation-probe.yml"](detected)1[](restored)1; denial count after edit →0;git diff --statnon-emptygit checkout --the page1git status --porcelainemptya zero-match
replaceexits 0 and would have produced a green no-op ablation.The full root vitest suite was not run here; it is narrowed to
vitest run scripts/. Reason:this container caps a foreground command at ~10 minutes, and the shared verify lock was held by
sibling agents running the full farm — one acquisition attempt burned its whole budget and
returned
VERDICT queue-timeout (exit 99) · never acquired. That run is CI's.The narrowing is measured, not assumed:
The other is markdown; no package imports it.
git grep -ln 'ci-cd-pipeline'over source and tests returns10 files. Exactly one reads the file:
scripts/__tests__/ci-cd-pipeline-doc.test.ts(
docPath→readFileSync). Of the rest,scripts/__tests__/check-action-forward-parity.test.tsuses the path only as a stringliteral in a glob-match example,
packages/auth/src/__tests__/reserved-auth-features.test.tsnames it only in a prose comment ("follows the … pattern"), and the others match on the
unrelated
dependabot-merge-gate/lint-workflowprose.two files the suite already read, with
node:fsthe file already imports.Changeset — none, deliberately
⭐
check-changeset-presence.mjsexits 0 whether or not a changeset is present, so it is notdeciding this. I read the diff: a test file and a documentation page, neither of them source of
any published package, with no behaviour a release note could describe. The gate's own count
agrees —
2 file(s) changed, 0 of them published source of a package the release covers.Precedents that carried none: #6216, #6212, #6260.
⛔ And no
skip-changesetlabel on this PR — on this card of all cards, applying an inertlabel to declare "publishes nothing" would re-create the exact defect the PR exists to pin.
⛔ The label deletion — attempted, and I could not do it
Reported plainly rather than worked around.
get_labelonly — read. There is no create, update, ordelete label tool; confirmed by searching the tool surface, not assumed.
(
GITHUB_TOKENin this container is the literal 14-byte stringproxy-injected; the realcredential is added by the proxy, and the proxy refuses this route.)
The remaining act is
DELETE /repos/objectstack-ai/objectui/labels/skip-changeset, orSettings → Labels. Nothing is lost by it: nothing reads the label, and all seven PRs carrying
it are closed. #4912 stays open until it is done.
Not armed
⛔ Draft, and auto-merge is deliberately NOT enabled — that is the PM's call after review
against GitHub.
Generated by Claude Code