Repository navigation
docs(types): the two i18n label vocabularies refuse each other, measured (objectui#9375) - #9719
Conversation
…red (objectui#9375) `BaseSchema`'s vocabulary prose said the INLINE locale map (`label` / `description`) and the KEYED bundle reference (`ariaLabel`) "each accept the other's shape vacuously", and the `label` docblock restated it one property over. True when objectui#4580 Q2-B wrote it; the installed pin has closed it. Measured on `BaseSchema` itself, both crossings and both faces: a keyed ref in `label` / `description` and an inline map in `ariaLabel` are each refused at `tsc` (TS2322) and at `safeParse` on the zod mirror, with each shape accepted in its own slot as the control. The prose now says what a wrong slot costs — a wrong ANSWER, not a silent acceptance — and points at the cross-vocabulary block of `inline-locale-declared-face-9092.test.ts`, which re-derives it every run. Comment-only: no declaration, accept set or requiredness moves. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UanLVj6xvbS6puBCewLr8L
|
changeset-claim-re-read
|
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
|
ACCEPT — card objectui#9375, reviewed by the ⛔ Nothing below is taken from the PR body. Each row was re-derived by this seat, and where this seat's instrument is a different one from the dev's, it says so rather than presenting corroboration as re-measurement. ① The load-bearing property: comment-onlyRe-derived on the API's own file list, ⛔ not on the dev's script:
⇒ objectui#9092's read-only fence on ② The mechanism the corrected prose asserts — corroborated, ⛔ NOT re-measuredThe docblock's new claim rests on the inline arm excluding both keyed names. Read at the producer,
③ The rot the card is actually about — confirmed at the rotten addressClaim E said the
⇒ dropping the number and naming the file and symbol is the repair, ⛔ not a cosmetic one. ⭐ This is the same class the board has spent the day on: a number in published prose is a claim with a shelf life. ④ The instrument the prose now points at exists
⑤ Gates — job conclusions, ⛔ not the aggregateAll 36 check runs on head
⑥ The changeset publishes verbatim — read as suchThe entry carries no figure that can rot: no counts, no line numbers, no in-flight PR claims, and its one temporal clause ("That was true when objectui#4580 Q2-B wrote it; the installed pin has since closed it") is stated in the past tense it belongs in. ⭐ This board has repaired four pending entries today for the opposite habit (objectui#9704, #9706, #9711, #9713); this one is written the right way round. Carried, ⛔ not done hereThe three items under the PR's own Acceptance notes are read and agreed: the Implemented-by: VERDICT: ACCEPT. Turning ready and enqueueing; card objectui#9375 closes on merge. Generated by Claude Code |
Fixes #9375
Clause-②: no
The vocabulary prose on
BaseSchemasaid the two i18n label shapes "each accept the other's shape vacuously". Measured against the tree, that is false in both directions — and thelabeldocblock one property over was saying the same thing in its own words, so both are corrected here. Comment-only: no declaration, accept set or requiredness moves, per objectui#9092's read-only fence onBaseSchema.1. The instrument first — does it discriminate?
The card rests on
packages/types/src/__tests__/inline-locale-declared-face-9092.test.ts(added by objectui#9364). Taken on its own word, a green run proves nothing: the file'stschalf is read only bytsc -p packages/types/tsconfig.test.json, and an@ts-expect-erroron a line that the compiler would never flag is itself an error, so the baseline zero had to be lit before it could be read.Three ablations, each proved to have reached the disk (marker counts before/after +
git hash-objectagainst the HEAD blob), each restored withgit checkout HEAD --andgit diff HEADproved empty, all under a trapped script:ariaLabel: LOCALE_MAPObjectGridSchema.label: KEYED_REF(159,83): error TS2322: Type '{ key: string; defaultValue: string; }' is not assignable to ...ariaLabel: KEYED_REF)(178,5): error TS2578: Unused '@ts-expect-error' directive.Baseline with all three restored:
tsc -p tsconfig.test.jsonexit 0,vitest10/10. The third row is the one that matters most: the instrument is not a slot that refuses every object — it distinguishes the two vocabularies.2. Then the same two crossings, measured on
BaseSchemaitselfThe instrument asserts the inline crossings on inheritors (
ObjectGridSchema,AppComponentSchema,PageNodeSchema.aria) and the keyed crossing on the flat slot. Since the docblock being corrected isBaseSchema's own, both crossings were re-measured directly onBaseSchema, in a throwaway probe that was deleted afterwards (worktree proved clean):tsc:label: KEYED,description: KEYEDandariaLabel: MAPeach fire an@ts-expect-error;label/description: MAPandariaLabel: KEYEDcompile as controls. Exit 0 with all five present.zod/base.zod.ts#BaseSchema):safeParseisfalsefor the same three crossings andtruefor the same two controls.Mechanism, read off the installed pin rather than assumed:
InlineLocaleMapSchemais typedRecord<string, string> & { key?: never; defaultValue?: never }, and the refusal message names the pattern^(?!(?:key|defaultValue)$)(default|[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*)$.3. What a wrong slot actually costs — also measured, not quoted
Against the installed pin, with controls:
resolveI18nLabel({ key: 'a.b', defaultValue: 'D' }, 'en')returns"a.b"— the key renders. Control:resolveI18nLabel({ en: 'Accounts', 'fr-FR': 'Comptes' }, 'en')returns"Accounts";resolveI18nLabel(42, 'en')returnsundefined.resolveKeyedI18nLabel({ en: 'Owner' })returnsundefined— the aria-label renders empty. Control:resolveKeyedI18nLabel({ key: 'a.b', defaultValue: 'D' })returns"D".So the residual hazard is a WRONG ANSWER, paid by metadata that reaches a resolver without passing either face — the normal case for server-driven JSON — and not the vacuous acceptance the prose claimed.
4. Sentences changed
A.
BaseSchema.ariaLabel, the sentence the card names.string | {object}, and each accepts the other's shape vacuously. Check which resolver owns a slot before writing an object into it; the ruling accepted this cost with exactly this naming + cross-referencing as the mitigation."string | {object}— but NEITHER SLOT ADMITS THE OTHER'S SHAPE. The installed pin types the inline arm withkey?: never; defaultValue?: neverand itsINLINE_LOCALE_KEYpattern excludes both names, so a keyed ref written intolabel/description, and an inline map written into this slot, are each REFUSED — attscon the declaration and atsafeParseon the zod mirror. The cross-vocabulary block of__tests__/inline-locale-declared-face-9092.test.tsre-derives that on every run, in both directions and with the accepting control beside each refusal; read it rather than this sentence." Followed by a new paragraph carrying the wrong-answer cost measured in section 3, and keeping the original advice ("check which resolver owns a slot") and the ruling's mitigation clause verbatim.B.
BaseSchema.label— the other half of the same claim, which the card did not name. This is the correction that would have been missed by fixing only the named sentence.keyanddefaultValue."key?: never; defaultValue?: neverand itsINLINE_LOCALE_KEYpattern excludes both names." Plus a pointer toariaLabelfor the full statement.C. The
NOT I18nLabelparagraph onariaLabel— marked as history rather than rewritten. PR #4593's three measurements were correct about the spelling the ruling withdrew, so they stay; what changed is that they no longer read as the current reading.I18nLabelis the spec's INLINE LOCALE MAP (string | Record<string, string>), so the shipped keyed fixture was accepted only vacuously..."I18nLabelof that release —string | Record<string, string>, a map with no name excluded from it: the shipped keyed fixture was accepted vacuously, ... The pin has since closed the vacuous half — see below. What survives is that the two vocabularies are structurally confusable to a READER — objectui#4167's exact hazard."D. Two spellings of the inline arm, which were the premise the refuted claim rested on. The file-level
KeyedI18nLabelvocabulary block and thelabeldocblock both spelled the spec's inline formstring | Record<string, string>flat — a spelling under which{ key, defaultValue }IS a member, which is exactly what made "accepted vacuously" readable as current. Both now carry the pin's exclusion (key?: never; defaultValue?: never). No other wording in those paragraphs moves.E. One line address removed. The
ariaLabeldocblock citedpackages/react/src/SchemaRenderer.tsx:111; the call is at line 126 onorigin/main. The quoted code is unchanged and still correct, so the citation now names the file and the symbol and drops the number — a number in published prose is a claim with a shelf life, andcheck:new-line-citationsreports on exactly this shape.5. Gates
Every exit code captured to disk before any pipe.
pnpm --filter @object-ui/types type-checktsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json, silentpnpm --filter @object-ui/types testTest Files 202 passed (202) · Tests 4698 passed (4698)pnpm --filter @object-ui/types builddist completeness: 1 package(s) complete (130 emitted files verified)node scripts/check-changeset-presence.mjs1 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)node scripts/check-changeset-claims.mjsnode scripts/check-new-cross-file-line-citations.mjs0 new citation(s)node scripts/check-control-bytes.mjsOK (scanned 7818 tracked text file(s))node scripts/check-installed-spec-pin-claims.mjsOKnode scripts/check-governed-queue-guard.mjs --test ...NOT GOVERNED — 2 path(s) checkednpx eslint packages/types/src/base.ts .changeset/9375-*.mdanywarnings on untouched linesWhole-repo
pnpm lintand the rest of the gate farm are left to CI.Published-bytes check, on the final commit: after building,
dist/base.d.tscarries the corrected sentence and no longer carries the old one — which is why the changeset is apatchrather than an empty declaration.6. Pending-changeset re-read (the
changeset-claim-re-readgate)The gate listed 11 pending changesets whose bodies name
packages/types/src/base.ts. It is report-only and judges name resolution, not meaning; the meaning question is answered here. Verdict: none of the 11 goes false, and one of them is independently corroborated by this PR's measurements. No pending body is edited.The decisive property, re-derived here on two instruments against merge-base
78a9c6744.base.ts, 0 are non-comment. Every+/-line matches^[+-] +\*.sha256[:16] = 1d8d2a4a9d1ed76f, 3202 bytes each. Lit control: renaming one declared key (ariaLabeltoariaLabelX) in the head copy and re-stripping gives122f6229754cf290, so the hash is capable of telling a declaration change apart from a comment change.KeyedI18nLabel(L22),BaseSchema.label(L91,label?: string | I18nLabel) andBaseSchema.ariaLabel(L465). Every other block is byte-identical, includingComponentInput,ComponentMeta,StyleProps,children,inputType,defaultValue,description, and thelabel?: nevermember ofComponentInputat L733 — a differentlabelfrom the one this PR edits.⇒ A pending claim can only go false here if it asserts something about the text of those three docblocks. Claims about members, retirement kits (
?: never+retirementTombstone()), mirrors, re-exports or parity are untouched by construction, and the block-level reading is what makes that a measurement rather than an argument.The one the gate's reader is right to single out:
.changeset/7088-hidden-jsdoc-single-hide-path.md. It is a claim about comment text in this very file, so the comment-only argument does not dispose of it. Read in full, its subject isBaseSchema.hidden's JSDoc and the siblingvisiblecomment (plus the schema-referencehiddenrow andSchemaRenderer.hiddenVisibleSynonymy.test.tsx, neither in this diff). Measured: thehidden,visible,visibleWhen,visibleOnandhiddenOnJSDoc blocks are byte-identical between merge-base and this branch, and no sentence of 7088's body nameslabel,ariaLabel,KeyedI18nLabel,I18nLabelor i18n at all (0 hits for that token set;base.tsresolves as the lit control). Its general sentence — "the JSDoc is the authority a later docs correction is measured against" — is not disputed by this change either: 7088 itself backs its JSDoc with a pin test, and this PR moves a JSDoc toward what an instrument re-derives, which is the same direction. Still true..changeset/zod-base-schema-mirror-parity-4605.md— the one this PR corroborates. It sayslabel/descriptiontake the spec's inline map andariaLabelthe keyed reference, that "each slot admits only its own vocabulary and both cross pairings are pinned as rejections", and thatresolveKeyedI18nLabel"returnsundefinedfor a locale map and would render an EMPTY aria-label". Both sentences were re-measured for this PR (section 2 and section 3) and both hold. Still true — and it is the pending body that already said what the docblock is only now catching up to.The other nine. Verified rather than inherited: each was scanned for any token of the changed docblocks' subject, with
base.tsas the lit control for the scanner. Two produced a hit and were read:5928-classname-style-props-renameuses "vocabulary" ofStyleProps' Tailwind scale (that block is byte-identical), andcomponentinput-reexport-4972uses it ofComponentInputControlType(likewise). The remaining seven —5905-componentinput-inputtype-tombstone,5905-componentinput-retire-constraint-keys,6067-component-meta-derive-from-canonical,7493-componentinput-retire-label-defaultvalue-advanced,component-meta-converge-and-deprecate-alias-5893,default-children-retired-5051,plugin-component-input-deprecate-5674— are about declarations, retirement kits and re-exports, and name none of the three changed blocks. All still true.Acceptance notes
Found and deliberately NOT done:
packages/types/src/objectql.tssays "neither resolver accepts the other's shape" — true of the two resolvers' signatures, misleading about runtime for the reason measured in section 3. The card names this sibling explicitly as a different claim; that file is also the surface of open PR objectui#9709, so it is left untouched. Noted, not filed — the card already records it.packages/{components,core,plugin-dashboard,react,types}/CHANGELOG.mdeach carry the old sentence in a released entry. Release records are history and are never rewritten. A whitespace-tolerant scan of the whole tree (the prose wraps near eighty columns, so a line-anchored matcher is blind to it) found no other LIVE copy:packages/types/src/app.tsand the instrument's own header were already corrected by objectui#9364.packages/types/src/base.tshas two other cross-file line citations of the same rotting shape (.../bridges/list-view.ts:180and:224, in thelabelanddescriptiondocblocks). Not verified and not touched — outside the vocabulary claim this card is about. Noted, not filed; the handler is whoever next edits those two docblocks, andcheck:new-line-citationsalready reports the class.🤖 Generated with Claude Code
https://claude.ai/code/session_01UanLVj6xvbS6puBCewLr8L
Generated by Claude Code