Uh oh!
There was an error while loading. Please reload this page.
fix(tooling): check-error-code-casing — reach our default through an ||/?? fallback chain, and stop printing an unqualified clean sweep - #10760
Merged
Conversation
…, and qualify its verdict The four CODE_POSITION_PATTERNS all anchor the string literal immediately after the position token, so an intervening expression makes the literal invisible to the whole set. Two live wire-visible codes shipped through that gap while the gate printed an unqualified 'no lowercase error codes'. - fifth pattern reaching our default through an ||/?? chain, bounded so a match cannot leap into a neighbouring property's fallback; - KNOWN_LOWERCASE_CODES, shrink-only, carrying the two codes whose rename is owned by #10716 (services lane) — a stale entry fails; - the verdict now states what the run could not read (#10501 precedent). Part of #10658
os-zhuang
marked this pull request as ready for review
August 21, 2026 10:57
Uh oh!
There was an error while loading. Please reload this page.
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.
Closes#10658. Verified at
613fc4363b; baseorigin/main=8163a1c8e2.One file:
scripts/check-error-code-casing.mjs. No changeset — gate tooling, publishes nothing (skip-changeset).The defect, reproduced before anything changed
All four
CODE_POSITION_PATTERNSanchor the string literal immediately after the position token, so an intervening expression makes the literal invisible to the whole set — silently, and then the run prints a total that reads as complete.That tree has two, both inside the scanned set. Positive control, so the zero is read as a broken probe rather than a clean tree — the gate's own emission regex on both spellings:
Re-derived extent: 2, and it is still 2
Swept
packages/**.ts/.tsx(comments masked, the gate's own walk) with a deliberately broad probe —code:then any non-quote gap, then||/??, then a lower_snake literal:packages/plugins/plugin-auth/src/register-sso-provider.tsrequest_domain_verification_failedpackages/plugins/plugin-auth/src/register-sso-provider.tsverify_domain_failed2 hits in 4356 files — matches the card, so the known-list below is exactly two rows. The sibling shape
.code = <expr> || '<lower>'measures 0 occurrences; it is covered anyway (below), so the class is closed rather than the instance.origin/mainadvanced to78ac958552while this was in flight and touched 0 paths underpackages/, so the scanned population — and the extent — are unchanged.The landing hazard, and how it is resolved
Triage split the two wire-visible renames to #10716 (services lane), so this PR must not rename them — but a widened recognizer finds them on
mainand exits 1. Option 2 was checked, not assumed: #10716 is open and both codes are still live at 411/465 on the base, so it has not landed.Resolved by option 1, the
KNOWN_IMPORT_UNSAFEshape from #10665: a ⛔ SHRINK-ONLYKNOWN_LOWERCASE_CODEScarrying exactly those two rows, each naming the owning card. Keyed<file>::<literal>rather than by line, so a line shift cannot quietly invalidate an entry. Nothing new can join: a fresh finding is never absorbed by the list, and the author-facing remedy says so and refuses that route rather than offering it. When #10716 lands, each entry goes stale and the gate fails until the line is deleted — the list only ever shrinks. Both directions are pinned in--self-test.Where the line is drawn on vendor codes
The widened pattern still only ever captures a string literal, and a literal in our source is by construction ours. A vendor code passing through is a runtime value (
parsed?.code,err.code, a variable) — it has no literal for any pattern here to capture, before or after this change. So widening cannot start flagging a pass-through; it reaches only the default we author, which is exactly the operand ADR-0112 D1 governs (the code our failing request answers with). A vendor's spelling hard-coded as our default is a real violation, not a false positive.The second half of the line is the gap class, and it is what keeps a match inside one property's value. It admits an operand chain (identifiers, member/optional access, calls, indexes, further
||/??) and refuses, ; : { } =and every quote. The real false positive here is a neighbour's fallback —— and the comma is what stops it. Pinned as a reject case. The length bound is a runaway guard, also pinned.
Reject side, at tree scale
Differential sweep of the four base patterns vs. the five, per pattern, over the same 4356 files. The new pattern is additive — the other four are byte-identical to the base and unchanged in what they match:
Zero false positives repo-wide: the new pattern's only two raw matches are the two known rows.
check:dispatcher-error-vocabularyreports neither code on the base (a chain with one runtime limb reduces to nothing under #9568's all-or-nothing rule), so this shape was owned by no gate at all — which is the card.Both spellings pinned, as a pair
--self-testgrows 12 recognizer cases and 4 registry cases (17 -> 29, plus 4). The pair matters: the direct spelling of the same code is pinned beside the fallback spelling, because a recognizer that reached the new shape by breaking the old one would pass a self-test that only pinned the new one.Ablation
Prediction stated before running: reverting the widening reddens exactly 4 recognizer cases — the four expecting a hit through the fallback pattern — while the reject-side cases (expecting 0) and the registry cases stay green.
Mutation confirmed on disk before measuring: the two anchors
name: 'fallback',and itsre:line both went 1 -> 0, 151 bytes removed,git diff --statshowing 4 deletions. Observed, on the mutated tree:4 predicted, 4 observed, and the direct-spelling half stayed green — the pair did its job. The full scan independently flipped 0 -> 1 with 2 stale
KNOWN_LOWERCASE_CODESentries, which exercises the shrink-only limb from the other side. Restore leg proven too: anchors back to 1, tree clean againstHEAD, both runs green again. No build/distis involved —package.jsonruns this script from source — so there is no stale-artifact risk in either leg.The verdict shape: yes, it now says what it could not read
The card asks this to be weighed either way. Decided yes, on the #10501 precedent, because the reporting defect is the point of the card: an unqualified total renders a bounded read exactly like a complete one, and that is what shipped over a tree carrying two.
Two deliberate choices about what it counts:
adr0112-ok:comments present in the tree (20) — a comment that sits next to nothing suppresses nothing, and counting it would overstate the blindness.code:positions with no literal, but that number would be dishonest in this gate's mouth: most arecode: numberexit-code annotations and status fields, and the genuinely code-shaped remainder is delegated, not a hole —check:dispatcher-error-vocabularyowns constants, templates, ternaries and helper parameters ([finding]check:dispatcher-error-vocabularycannot see a lowercase thrown code —plugin-security's liveowd_widening_forbiddenwas never swept #9460/[finding]check:dispatcher-error-vocabularystill cannot see a code held in a local ternary —sys-metadata-repository's live 403NOT_CREATABLE/NOT_OVERRIDABLE#9568) and prints its own scope line. Printing a large uncovered-looking count for a population another gate covers would trade one misleading number for another. So the boundary is stated and its owner named.The qualifier prints on the failure path too: a partial finding list reads as complete for the same reason a partial total does.
Gates
node scripts/pm/dispatch-gates.mjswith no paths, at613fc4363b, clean tree — it derived the change set from the merge base as 1 path (a two-dotorigin/maindiff shows 5 files here, four of them sibling PRs that landed after this branch was cut). It named 3 families; the other three below were run because they were reasoned, not named:check:error-code-casingno unlisted lowercase error codes in 4356 scanned file(s)check:cross-package-test-inputsOK: 13 package(s) read outside themselves, all declaredcheck:ratchet-remedy-authority111 scripts swept; 7 mark ... 3 turn it down outright, 101 hand out no ratchet-expanding remedycheck:entry-guard125 scripts/ file(s) ... 83 export bindings, 73 of them inert on import (10 known-unsafe, SHRINK-ONLY)check:parse-guardcheck:nul-bytesOK (scanned 6234 text file(s) ... no raw ASCII control bytes)Two of those were run because a new shrink-only registry is exactly the shape they police, and both were verified directly rather than inferred from a green exit:
check:ratchet-remedy-authorityhand-classifies this very file asexcluded. A shrink-only registry whose remedy offers expansion would flip it tounmarked— a violation. Its ownclassify()run against this branch's source returnsexcluded, 0 live offers, 0 refused, 0 anchors, so the control entry stays correct and untouched.check:entry-guard— this file gains a second export (partitionKnown), and fix(scripts): burn 25 of the 35 KNOWN_IMPORT_UNSAFE entry-guard debts down #10704'sisEntrypointguard on it is untouched. It stays off theKNOWN_IMPORT_UNSAFESHRINK-ONLY ledger (0 occurrences), and importing it for its exports alone runs nothing, which is how the recognizer was proven against the real file.Out of scope, filed separately
The two renames are not addressed here — #10716 remains open and owns them. One follow-up filed for a documentation drift this change creates in the sibling gate's delegation map; see the report comment on #10658.
Generated by Claude Code
Generated by Claude Code