Commit ffbab85
committed
feat(spec)!: close AriaProps against unknown keys, reclassify widget + five i18n shapes as no-door (#4001 批 16)
Fifteen strip sites measured per the #4852 remeasure; the counts held exactly
(widget 9/9, i18n 6/6, confirmed against the ledger gate's own AST counter).
Per-schema door measurement then split them one / fourteen.
Closed with strictObject:
ui/i18n.zod.ts AriaPropsSchema
The highest-fan-out single site the ui/ wave has closed — carried as `aria:` on
~30 shapes under six metadata-type roots (ListView, Page, PageComponent,
DashboardWidget, ChartConfig, Action, 20 SDUI component defs). Through the view
root, `aria: { label, describedBy }` parsed clean and came back `aria: {}`: the
accessible name existed in the source file and nowhere else. Those two spellings
are objectui's own ARIA_KEY_ALIASES, i.e. what stored view metadata carries.
Reclassified as no door, NOT tightened (14 sites):
ui/widget.zod.ts all six shapes / nine sites
ui/i18n.zod.ts I18nObject, PluralRule, NumberFormat, DateFormat, LocaleConfig
Measured three ways with positive AND negative controls in the same run: no
carrier key (nothing imports widget.zod but the barrel), unreachable in a
4766-node BFS from the 24 roots + defineStack, zero parse in all three repos
(cloud checked by code search against a proven-working index). A synthetic
carrier flips all of them, so the verdict is a fact about the graph.
Curation anchored on named sibling contracts, not edit distance: the two legacy
spellings on objectui's normalizer, and `ariaRole` on this shape's own
inconsistent prefix (two of three keys carry `aria`, `role` does not). The four
the distance fallback already reaches were measured first and left to it.
`live` and `ariaLabelledBy` get a prescription rather than a rename — finding 7
discipline. `live` is real and rendered by objectui's ListView alone, which
declares it via `AriaPropsSchema.extend({ live })`, so that surface keeps
accepting it and now inherits this error map; promoting it into the shared shape
would advertise aria-live on 29 renderers that do not implement it (#5058).
A `.strip()` was added to four files this batch does not otherwise touch:
animation, dnd (x2), keyboard, touch build their shapes as
`z.object({…}).merge(AriaPropsSchema.partial())`, and `.merge()` adopts the
incoming posture — closing AriaProps would have silently closed all five of those
no-door shapes with zod's generic message and no changeset. Pinned.
Ledger finding 20: the campaign's own BFS reported widget.zod.ts as REACHABLE.
Zod's `.describe()` returns a clone sharing the original `_zod.def`, so a bridge
firing on any ONE shared property under a shared name links unrelated shapes via
`name`/`label`. 2 keys of 20. The error is one-directional — it can only make a
batch tighten something dead (#4583). Corrected to whole-shape overlap in
ui/door-reachability.testkit.ts, pinned as a regression test, filed as #5056.
Instruments proven red before trusting green: six sabotages, one per assertion
class (walker, clone bridge, strictness, curation, finding-7 guidance,
merge-strip), each reverted.
Ledger: ui/ 118 strip of 198, authorable subtotal 82 — both recomputed from the
surviving rows, never decremented by this batch's count.
Refs #4001. Filed out of scope: #5055 (ADR-0049 for the 14 no-door sites),
#5056, #5058, #5059.1 parent c5e7bd9 commit ffbab85
11 files changed
Lines changed: 770 additions & 19 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
0 commit comments