You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
finding(types): BaseSchema under-declares visible (predicate string) and ariaLabel (I18nLabel) — the renderer supports both, five test fixtures now cast past the gap #4581
Filed by the PM from PR #4578's accepted report (open question 1, ruled: file rather than fix there).
@object-ui/types' BaseSchema declares visible?: boolean, but the renderer evaluates a predicate STRING via evaluateCondition (and visibleWhen?: string exists alongside); and it declares ariaLabel?: string, while AriaPropsSchema is string | I18nLabel and SchemaRenderer itself calls resolveKeyedI18nLabel on it. Once schema is honestly typed (PR #4578), these gaps surface: five existing test fixtures exercising exactly those documented capabilities needed as unknown as BaseSchema casts, each carrying a comment naming this gap (react aria/expressions suites, components html-anchor-links).
The producer-side fix: widen BaseSchema.visible to boolean | string and .ariaLabel to string | I18nLabel in packages/types, then drop the five casts. Deliberately NOT done in #4548 — widening a shared base type is its own card with its own blast radius, and packages/types was #4564's in-flight surface at the time.
Observation-class for triage (the casts are commented, nothing silent). Refs #4548, PR #4578, #4580 (the SchemaNode dual-declaration sibling — a reconciliation there may absorb this).
CLAIM — session session_017Qqyix2QcnpUC9XeYVDzx3. Absorbed into #4580's seat (branch claude/issue-4580-one-schemanode) per the ruling recorded there: the BaseSchema.visible / ariaLabel widening and the five cast-drops ride the SchemaNode reconciliation, since they share the producer file and the repo-wide canary.
Census correction from the seat (PR #4593 — visible landed, ariaLabel did not).
This card records "five existing test fixtures ... each carrying a comment naming this gap". On disk there are sixas BaseSchema / as unknown as BaseSchema casts, in three classes, and one carries such a comment:
1. disabled is the same defect as visible, with the same evidence, and is not in this card's text.SchemaRenderer.tsx:466 evaluates it through the same evaluateCondition ((condition: string | boolean | undefined, context?) => boolean), and a disabledOn?: string sibling exists for the same reason — identical to the visible / visibleWhen / visibleOn shape this card argues from. I did not widen it, because the card names only visible and ariaLabel and an unruled widening of a shared base type is its own blast radius. It is one line in packages/types/src/base.ts plus two cast-drops whenever it is ruled.
2. html-anchor-links.test.tsx is named here but is not this gap. Its cast exists because a Record< string, unknown > is spread into a BaseSchema position — unrelated to visible / ariaLabel, and it will still be there after this card closes.
And the ariaLabel half is blocked on a vocabulary question, not on effort. The card says widen to string | I18nLabel, but @object-ui/types' I18nLabel is the spec's inline locale map (string | Record< string, string >) while SchemaRenderer.tsx:111 resolves the key with resolveKeyedI18nLabel, whose input is the keyed form { key, defaultValue?, params? }. Measured: under string | I18nLabel the shipped fixture is accepted for the wrong reason (as a locale map with "locales" named key/defaultValue), the same label carrying params is rejected, and a genuine { en: 'Owner' } type-checks while rendering an empty aria-label. Verbatim probe results in PR #4593's body; the sibling label/description slots are attached to #4163.
CLAIM (remainder) — session session_017Qqyix2QcnpUC9XeYVDzx3, branch claude/issue-4581-label-vocabulary. The visible half landed via PR #4593 (3d9769a31); this seat executes the rest under the vocabulary rulings recorded on #4580 (comment 5284007579):
Q2-B:ariaLabel declares the KEYED form the renderer actually resolves, and the shape gets a name — KeyedI18nLabel exported from @object-ui/types — retiring the three inline copies (react/utils/i18n.ts, layout/NavigationRenderer.tsx, app-shell/utils/index.ts). My original string | I18nLabel spelling is withdrawn as measured-wrong (see PR fix(types): BaseSchema.visible accepts the predicate string the renderer evaluates (#4581) #4593's probe evidence).
Q3-A:disabled widens to boolean | string (same evidence shape as visible), dropping the two remaining family casts plus the ariaLabel cast.
Q1-B (premise-gated): the two list-view.ts sites (:180/:224) resolve inline I18nLabel maps at the bridge via the spec's own resolveI18nLabel — BaseSchema.label/.description stay string. Premise to verify first: the bridge context knows the locale and re-translates on locale change; measured otherwise = STOP and report.
⚠️ Constraints: check PR #4208's pending diff (the rc.6 train, blocked on #4165) before touching packages/layout or app-shell/utils — an overlapping inline-copy retirement waits for the train. app-shell is also #4024's in-flight package (SettingsView surface — different file; touch only utils/index.ts's type spelling or leave it). This closes #4581 and clears #4580's blocker; #4580 re-dispatches separately with Q4-B.
PM step-7 复核: ACCEPT — and Fixes #4581 is correct. PR #4603 ships Q2-B and Q3-A exactly as ruled, and the Q1-B STOP is the ruling working: the premise was measured false on all four legs (plain class method cannot call a hook; BridgeContext declares no locale; context assigned once with updateContext() at zero callers, so no re-translation channel; SpecBridge has zero in-repo production consumers), with the spec's own resolver doc (#6761) cited as naming exactly the freeze the stop condition feared. The train-overlap check done as a CONTENT measurement rather than trusting the stale file list — and reporting that the card's stated reason for react/utils was wrong while its conclusion was right — is the standard. The toggle finding is the best kind of fallout handling: the sweep (not a test) caught it, the first test was discovered VACUOUS (SchemaRenderer's own resolved aria-label shadows the renderer's attribute) and rewritten to invoke the registered renderer directly, and both wrong predictions stand in headers with corrections appended. .d.ts measured per package including the zod order-only files proven multiset-identical — checked rather than waved away.
OQ2 ruled: A — the app-shell patch entry STAYS as shipped. Rule-following beats seat judgment, the fixed group bumps together regardless, and an amend cycle costs more than a redundant line. #4605 (zod mirror now three properties narrower than the TS declarations) noted as observation-class, correctly graded on measured consequence.
OQ1 (where inline maps resolve, given the bridge provably cannot) is ruled on #4580 — it revises my own Q1-B and carries a real veto window.
Activity
yinlianghui commentedon Aug 13, 2026
CLAIM — session
session_017Qqyix2QcnpUC9XeYVDzx3. Absorbed into #4580's seat (branchclaude/issue-4580-one-schemanode) per the ruling recorded there: theBaseSchema.visible/ariaLabelwidening and the five cast-drops ride the SchemaNode reconciliation, since they share the producer file and the repo-wide canary.Generated by Claude Code
Generated by Claude Code
yinlianghui commentedon Aug 13, 2026
Census correction from the seat (PR #4593 —
visiblelanded,ariaLabeldid not).This card records "five existing test fixtures ... each carrying a comment naming this gap". On disk there are six
as BaseSchema/as unknown as BaseSchemacasts, in three classes, and one carries such a comment:react/__tests__/SchemaRenderer.expressions.test.tsx:52,:61visible: '${…}'react/__tests__/SchemaRenderer.expressions.test.tsx:132,:141disabled: '${…}'disabled, not named by this cardreact/__tests__/SchemaRenderer.aria.test.tsx:59ariaLabel: { key, defaultValue }components/__tests__/html-anchor-links.test.tsx:33{ type: 'a', ...schema }Record< string, unknown >spreadTwo consequences worth recording on the card:
1.
disabledis the same defect asvisible, with the same evidence, and is not in this card's text.SchemaRenderer.tsx:466evaluates it through the sameevaluateCondition((condition: string | boolean | undefined, context?) => boolean), and adisabledOn?: stringsibling exists for the same reason — identical to thevisible/visibleWhen/visibleOnshape this card argues from. I did not widen it, because the card names onlyvisibleandariaLabeland an unruled widening of a shared base type is its own blast radius. It is one line inpackages/types/src/base.tsplus two cast-drops whenever it is ruled.2.
html-anchor-links.test.tsxis named here but is not this gap. Its cast exists because aRecord< string, unknown >is spread into aBaseSchemaposition — unrelated tovisible/ariaLabel, and it will still be there after this card closes.And the
ariaLabelhalf is blocked on a vocabulary question, not on effort. The card says widen tostring | I18nLabel, but@object-ui/types'I18nLabelis the spec's inline locale map (string | Record< string, string >) whileSchemaRenderer.tsx:111resolves the key withresolveKeyedI18nLabel, whose input is the keyed form{ key, defaultValue?, params? }. Measured: understring | I18nLabelthe shipped fixture is accepted for the wrong reason (as a locale map with "locales" namedkey/defaultValue), the same label carryingparamsis rejected, and a genuine{ en: 'Owner' }type-checks while rendering an emptyaria-label. Verbatim probe results in PR #4593's body; the siblinglabel/descriptionslots are attached to #4163.Generated by Claude Code
Generated by Claude Code
yinlianghui commentedon Aug 13, 2026
CLAIM (remainder) — session
session_017Qqyix2QcnpUC9XeYVDzx3, branchclaude/issue-4581-label-vocabulary. Thevisiblehalf landed via PR #4593 (3d9769a31); this seat executes the rest under the vocabulary rulings recorded on #4580 (comment 5284007579):ariaLabeldeclares the KEYED form the renderer actually resolves, and the shape gets a name —KeyedI18nLabelexported from@object-ui/types— retiring the three inline copies (react/utils/i18n.ts, layout/NavigationRenderer.tsx, app-shell/utils/index.ts). My originalstring | I18nLabelspelling is withdrawn as measured-wrong (see PR fix(types): BaseSchema.visible accepts the predicate string the renderer evaluates (#4581) #4593's probe evidence).disabledwidens toboolean | string(same evidence shape asvisible), dropping the two remaining family casts plus the ariaLabel cast.list-view.tssites (:180/:224) resolve inlineI18nLabelmaps at the bridge via the spec's ownresolveI18nLabel—BaseSchema.label/.descriptionstaystring. Premise to verify first: the bridge context knows the locale and re-translates on locale change; measured otherwise = STOP and report.packages/layoutorapp-shell/utils— an overlapping inline-copy retirement waits for the train.app-shellis also #4024's in-flight package (SettingsView surface — different file; touch onlyutils/index.ts's type spelling or leave it). This closes #4581 and clears #4580's blocker; #4580 re-dispatches separately with Q4-B.Generated by Claude Code
Generated by Claude Code
fix(components): the toggle renderer resolves its keyed ariaLabel ins…
yinlianghui commentedon Aug 13, 2026
PM step-7 复核: ACCEPT — and
Fixes #4581is correct. PR #4603 ships Q2-B and Q3-A exactly as ruled, and the Q1-B STOP is the ruling working: the premise was measured false on all four legs (plain class method cannot call a hook;BridgeContextdeclares no locale; context assigned once withupdateContext()at zero callers, so no re-translation channel; SpecBridge has zero in-repo production consumers), with the spec's own resolver doc (#6761) cited as naming exactly the freeze the stop condition feared. The train-overlap check done as a CONTENT measurement rather than trusting the stale file list — and reporting that the card's stated reason for react/utils was wrong while its conclusion was right — is the standard. The toggle finding is the best kind of fallout handling: the sweep (not a test) caught it, the first test was discovered VACUOUS (SchemaRenderer's own resolved aria-label shadows the renderer's attribute) and rewritten to invoke the registered renderer directly, and both wrong predictions stand in headers with corrections appended..d.tsmeasured per package including the zod order-only files proven multiset-identical — checked rather than waved away.OQ2 ruled: A — the app-shell patch entry STAYS as shipped. Rule-following beats seat judgment, the fixed group bumps together regardless, and an amend cycle costs more than a redundant line. #4605 (zod mirror now three properties narrower than the TS declarations) noted as observation-class, correctly graded on measured consequence.
OQ1 (where inline maps resolve, given the bridge provably cannot) is ruled on #4580 — it revises my own Q1-B and carries a real veto window.
Flipping ready and arming auto-merge now.
Generated by Claude Code
Generated by Claude Code
fix(types): BaseSchema.visible accepts the predicate string the rende…
fix(types): ariaLabel declares the keyed vocabulary, disabled accepts…