Uh oh!
There was an error while loading. Please reload this page.
ci(lint): de-number the optional-error sink-contract step comment — the gate prints its own census - #12290
Merged
yinlianghui merged 1 commit intoAug 25, 2026
Conversation
The step's comment pinned a census of a moving tree in prose that nothing re-measures: "13 cases ... 36 sink types, 15 baselined". Every number was wrong, and the baselined figure had been wrong since the ledger paydown -- a reader trusting it believed there were fifteen outstanding sink repairs. The gate prints all three figures live on every run, so the comment does not need a copy. Drop the counts and keep the facts that do not drift: runs its own --self-test first, AST over packages/**, no spawns, ~3.5 s, and the no-`paths:`-filter rationale. Also drops "both narrowings", which had itself gone stale -- the gate now pins three and its self-test prints "all three narrowings". Part of #11551 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UjM2ia8Av1v5NqfqQEQmC6
yinlianghui
marked this pull request as ready for review
August 25, 2026 16:44
Uh oh!
There was an error while loading. Please reload this page.
yinlianghui
deleted the
claude/issue-11551-lint-yml-sink-contract-counts
branch
August 25, 2026 17:06
yinlianghui pushed a commit
that referenced
this pull request
Aug 25, 2026
…out its narrowing count :60 and :789 said "both"/"the two narrowings" while the file documents and pins three (Narrowing 1: as-cast, Narrowing 2: purity, Narrowing 3: unreadable member type, added by #11069) and its runtime string already prints "all three narrowings pinned as counts". Repointed both sentences to an integer-free spelling ("every narrowing below" / "the narrowings") so they cannot go stale again when a fourth narrowing arrives, matching the fix PR #12290 made for the sibling workflow-comment instance. :985 is left exactly as written — it is a correct past-tense statement about the state of the world before narrowing 3 existed (#11069's own history), not a present-tense claim. No behaviour, count, pin, or runtime string changed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#11551
.github/workflows/lint.yml's "Optional-errorsink contract" step carried a census of a moving tree pinned in prose that nothing re-measures:This drops the three counts and keeps the facts that do not drift.
The card's preferred option rests on a claim; I verified it directly
The card's option 1 ("drop the counts") rests on "the gate prints its live census on every run; the comment does not need a stale copy." That was the load-bearing assumption, so it was measured rather than inherited —
pnpm check:optional-error-sinkatbc5ab78d04, verbatim:The assumption holds, and precisely. All three numbers the comment restated are printed live on every run — the self-test case count (
19 case(s)), the sink-type population (41 sink type(s)) and the baselined total (1 baselined, shrink-only). Deleting them from the comment removes a stale copy, not the only copy. Option 1 is correct as stated; option 2 (point at the census line) is unnecessary, though the replacement text says where the live numbers come from.Re-measured on this base — and the card's own figures had already drifted again
The card's "reality" column was measured 2026-08-24. Re-measured at
bc5ab78d04:13 cases36 sink types15 baselined⭐ The baselined count moved 5 → 1 in the single day between filing and repair. The ledger's own history block records why: the maintainer's 2026-08-24 ruling on #10556 settled four of the five rows, leaving one recorded deliberate exception (
SettingsDiagnosticsLogger). Corroborated independently of the gate —scripts/optional-error-sink-contract.baseline.jsoncontains exactly one entry.That is the card's thesis demonstrating itself twice over. A repair that had merely corrected the three numbers would have shipped a comment that was already wrong about the sharpest of them on the day it landed.
The same is true of the file position: the card says "around line 1315" and the step now sits at 1723 — the file moved ~400 lines in one day, confirmed on this base.
A fourth stale count, inside the sentence being removed
both narrowingswas also wrong. The gate now pins three narrowings (as-cast, purity, and theUNREADABLEnarrowing added by #11069), and its self-test says so in the line quoted above: "all three narrowings pinned as counts". The replacement says "every narrowing pinned as a count" — removing the count rather than restating it, so this one cannot drift a fourth time.What is kept, deliberately
Per the filer, the parts that earn their place and do not drift: runs its own
--self-testfirst, both directions, AST overpackages/**, no spawns,~3.5 s, and the rationale for having nopaths:filter (a filter onpackages/**would go dormant on the PR that edits the baseline).~3.5 swas checked rather than assumed, since it is also a measured number:0.494sself-test +2.659sscan ≈ 3.15 s of node time at this commit. It has not drifted, which is the filer's point about it.On the "does this shape want a gate" question — not answered here
The card asks whether four workflow-comment-drift cards "want a gate rather than four separate repairs". Per the dispatch that is a triage question, so nothing is implemented for it. One measurement from this repair that bears on it, offered as input only: the three counts here were re-derivable mechanically — the gate prints all of them in a single stable line — so a gate for this instance would have been cheap. That is not obviously true of the sibling cards, whose claims are prose assertions about workflow behaviour (#9828's keying, #10894's fence scope, #10572's ordering contract) rather than integers a script already prints. A gate for "comments that restate a number a gate prints" would cover this card and plausibly none of the other three.
The three sibling cards are untouched here, as ruled.
Verification
Gate union derived at the final commit with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(gate list derived from the tree of 'objectstack-ai/objectstack' at commit bc5ab78d04; change set1 path(s) vs merge base 0b478e1ef). Editinglint.ymlpulls in workflow-shaped families ascripts/**diff would not, so the derived list was read rather than assumed: 18 families, all run, all green, exit codes captured before any pipe.check:agent-test-spelling✓ check-agent-test-spelling: 0 violations — 380 file(s) · 3867 bare -- token(s) …check:node-versioncheck-node-version: OK (34 setup-node step(s) across 28 workflows, all on Node 22).check:pnpm-acquisitioncheck-pnpm-acquisition: OK -- every job that runs pnpm acquires it first.check:pnpm-filter-targets✓ check:pnpm-filter-targets: 136/173 --filter occurrence(s) across 28 file(s) resolve …check:required-contexts✓ check-required-contexts: 6 required context name(s) pinned across 2 workflow(s) …check:shard-attestation✓ check-shard-attestation: 2 aggregate gate(s) count 3 declared leg(s) …check:type-check-coveragecheck-type-check-coverage: OK — 65/78 workspace packages type-checked …check:type-check-debtcheck-type-check-coverage --re-measure: OK — 32 ledger entr(ies) re-measured in 277.7s, 1843 raw tsc error(s) total, none above its recorded number.check:workflow-status-functionscheck-workflow-status-functions: OK (scanned 28 workflow file(s), 51 job(s) …)check-aggregator-roster.mjs✓ check-aggregator-roster: 3 aggregator(s) across 2 workflow(s); roster == needs: in both directions …check-required-contexts.mjs✓ check-required-contexts: 6 required context name(s) pinned across 2 workflow(s) …check-self-test-wired.mjs✓ check-self-test-wired: every one of the 134 script(s) CI runs that ship a --self-test has that self-test run by CI.check-self-test-workflow-commands.mjs✓ check-self-test-workflow-commands: no self-test CI runs prints a line the Actions runner would parse as a workflow command.check-shard-attestation.mjs✓ check-shard-attestation: 2 aggregate gate(s) count 3 declared leg(s) across 3 attesting job(s).check-step-collectors.mjs✓ check-step-collectors: 352 run: steps across 28 workflow(s) …check-whole-set-label-write.mjs✓ check-whole-set-label-write: 0 violations — 211 file(s) over 3 root(s) …check-drift-comment.mjs✓ check-drift-comment: 56 cases pass across 5 fixture diff(s).pm/ci-failure.mjs --self-testOK self-test: supersession keeps the newest per name and reports the drops …check:type-check-debtwas red on first run and is worth recording rather than hiding: it refused to run, it did not fail.--re-measurerequires the built dependency closure on disk and stops rather than "silently measure a DIFFERENT WORLD". Settled the waylint.ymlitself does —turbo run build --filter='./packages/*' --filter='./packages/*/*'(70 successful, 70 total) — then re-run to the green verdict quoted above. No narrowing is claimed anywhere in this table.Base freshness: the derivation reported "At least 1 commit(s) behind origin/main, but nothing this answer derives from changed across that range" — no
STALE TREEwarning, so no merge was needed to trust these numbers.git log HEAD..origin/main -- .github/workflows/lint.ymlis empty: PR #12266 also edits this file and is still queued, which is ordinary concurrency here and was not worked around. If it lands first and conflicts, the resolution is a merge oforigin/main, never a rebase or force-push.Changeset: none — a workflow comment publishes nothing.
skip-changesetapplied.Not restated as fact
The card's per-number attribution table (which PR moved which count) is the filer's account and was not re-derived here, so it is not repeated as established. The one attribution above — the 5 → 1 move — is read from the ledger file's own history block and its surviving entry, not from the card.
Generated by Claude Code