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 }}
Repository navigation
Commit 775e079
Browse filesBrowse the repository at this point in the historyBrowse files
feat(types)!: refuse both content channels on the E3 residual (nine object views, detail-view, email, password) and repair the shorthand Omit erasure (objectui#9256) (#10897)
Part of #9256
Clause-②: yes
**Clause-② `yes`, as the claim declared:** twelve published arms stop
accepting an authored `children`, and two published TypeScript faces
stop erasing the members they inherit. Both narrow an accept set; a
contract review is owed before landing.
The E3 residual that the maintainer's ruling on objectui#8284 (comment
`5861449497`, Q2 A) moved onto this card: keys with a published arm
whose renderer reads **neither** content channel. It also carries the
ruling's execution parameter 3, the `InputShorthandSchema` /
`UiCalendarSchema` TypeScript `Omit` erasure. objectui#9256 stays open
for the rest of family D.
## What changed
- **Narrowed (12 keys):** `object-grid`, `object-form`, `object-kanban`,
`object-map`, `object-tree`, `object-view`, `object-gantt`,
`object-calendar`, `object-chart`, `detail-view`, `email`, `password`.
- TypeScript face: `body?: never` and `children?: never`, each with a
docblock naming what the node renders instead.
- zod mirror: `body` and `children` are two `retirementTombstone`
members fed ONE string from the new `neitherContentChannelGuidance`
builder in `zod/tombstone.zod.ts`. Both stay MEMBERS, so
`zod-mirror-parity`'s key sets stay equal.
- `body` was already refused on these arms (by `BaseSchema`,
objectui#6771), except on the `email` / `password` TypeScript face,
which the `Omit` erased. It is restated because `BaseSchema`'s refusal
names `children` as the remedy, and `children` is dead here too.
- **`Omit` erasure repaired:** `InputShorthandSchema` and
`UiCalendarSchema` now inherit through `OmitDeclared` (`form.ts`, not
exported). It is a key-remapping mapped type: it drops exactly the named
keys and keeps every other named member and the index signature.
- `ui:calendar` gains no refusal of its own. Its face now re-exposes
what `CalendarSchema` declares, so the published TypeScript face refuses
`body`, `children` and a `mode` outside the declared enum, which the
erased face accepted. Its mirror (a `.extend()` of that one) already
refused them.
- I measured the `ui:calendar` renderer anyway
(`renderers/form/calendar.tsx`, typed `CalendarSchema`). It reads
`defaultValue`, `mode` and `value`, and no channel.
- **Held (3 keys): `br`, `hr`, `img`.** See "Held, and the question it
leaves" below.
## Per-key measurement, taken on `origin/main` `0c50f1863` before any
edit
**Instrument.** The TypeScript compiler API, ⛔ not grep. It builds one
program per workspace package from that package's own `tsconfig.json`:
40 programs over 1573 source files, on a BUILT tree (turbo build 42/42
first), with `@object-ui/types` resolving to `packages/types/dist`. It
files every `.body` / `.children` read (property access, string element
access, object destructuring) under the declared type of its receiver.
- 547 channel reads were filed.
- **Lit controls fire:** `ButtonSchema` 1, `DivSchema` 1, `CardSchema`
1, `ContainerSchema` 1 (each `children`).
- **Receiver-reachability control:** the same program sees every
narrowed declaration as a receiver of the keys its renderer reads. The
zeros below are readings, not blindness.
| key | registration(s) claiming it | registration hop → reader, and the
type it reads the node as | `body` / `children` reads under that type |
receiver reads (reachability) | arm, TS face: before → after | arm, zod
face: before → after | disposition |
|---|---|---|---|---|---|---|---|
| `object-grid` | `plugin-grid:object-grid` (+ console `registerLazy` of
the same plugin) | `ObjectGridRenderer` (`any`) → `ObjectGrid` ·
`ObjectGridSchema` | 0 / 0 | 158 reads, 38 keys | body refused
(BaseSchema), children accepted → both refused | same → both refused by
name | narrowed |
| `object-form` | `plugin-form:object-form` | `ObjectFormRenderer`
(`any`) → `ObjectForm` · `ObjectFormSchema` | 0 / 0 | 200 / 44 | same |
same | narrowed |
| `object-kanban` | `plugin-kanban:object-kanban` (+ lazy) |
`ObjectKanbanRenderer` (`any`) → `ObjectKanban` · `ObjectKanbanSchema` |
0 / 0 | 67 / 13 | same | same | narrowed |
| `object-map` | `plugin-map:object-map` (+ lazy) | `ObjectMapRenderer`
(`any`) → `ObjectMap` · `ObjectMapSchema` | 0 / 0 | 30 / 16 | same |
same | narrowed |
| `object-tree` | `plugin-tree:object-tree` (+ lazy) |
`ObjectTreeRenderer` (`any`) → `ObjectTree` · `ObjectTreeSchema` | 0 / 0
| 13 / 8 | same | same | narrowed |
| `object-view` | `plugin-view:object-view` (and the `view` alias) |
`ObjectViewRenderer` (`any`) → `ObjectView` · `ObjectViewSchema` | 0 / 0
| 112 / 19 | same | same | narrowed |
| `object-gantt` | `plugin-gantt:object-gantt` (+ lazy) |
`ObjectGanttRenderer` (`any`) → `ObjectGantt` · `ObjectGanttSchema` | 0
/ 0 | 61 / 48 | same | same | narrowed |
| `object-calendar` | `plugin-calendar:object-calendar` (+ lazy) |
`ObjectCalendarRenderer` (`any`) → `ObjectCalendar` ·
`ObjectCalendarSchema` | 0 / 0 | 40 / 12 | same | same | narrowed |
| `object-chart` | `plugin-charts:object-chart` (+ lazy) |
`ObjectChartBlock` (`any`) → `ObjectChart` · `ObjectChartSchema` | 0 / 0
| 123 / 15 | same | same | narrowed |
| `detail-view` | `plugin-detail:detail-view` | `DetailViewRenderer`
(`any`) → `DetailView` · `DetailViewSchema` | 0 / 0 | 195 / 31 | same |
same | narrowed |
| `email` | `ui:email` (`field:email` stands down) | `any` wrapper
spreads the node into `InputRenderer` · `InputSchema` | 0 / 0 | 23 / 17
| BOTH accepted (erased `Omit`) → both refused | body refused, children
accepted → both refused by name | narrowed |
| `password` | `ui:password` (`field:password` stands down) | same as
`email` | 0 / 0 | 23 / 17 | same as `email` | same as `email` | narrowed
|
| `br` | `ui:br` | html-elements factory (`any`), void tag: passes
`undefined` as the child | reads neither (the one `schema?.children`
read is behind the void-tag guard) | n/a (`any`) | body refused,
children accepted (family arm) → unchanged | same → unchanged | **held**
|
| `hr` | `ui:hr` | same | same | n/a | same | same | **held** |
| `img` | `ui:img` | same | same | n/a | same | same | **held** |
The residual count stays 15: no key reads `children` today. 12 are
narrowed and 3 are held.
**`any`-typed receivers, attributed rather than assumed.**
- Every hop above is `any`-typed. Each hop body was read: none contains
a channel read.
- The any-typed reads in the eleven hosting files and packages were
attributed one by one:
- React `children` destructured off internal components' own props
(`SchemaRenderer` passes no node child as a React child);
- `document.body` and `err.body`;
- `TreeNode.children` on the record hierarchy `ObjectTree` builds;
- `FeedItem.body`;
- `record:alert`'s own `props.body`, which is another registration.
- The html factory's `schema?.children` read sits behind `isVoid ?
undefined : …`.
**Delegation hosts, checked for pass-through.** Every `SchemaRenderer`
call in the ten object/detail packages was traced. The node it renders
is built one of three ways:
- key by key — `ObjectForm` / `ModalForm` / `DrawerForm` / `TabbedForm`
/ `SplitForm` / `WizardForm` all build their `form` node that way, and
the `form` renderer DOES draw `children`, which is why this was checked;
- from a sub-key — `DetailView`'s `header` / `footer` / tab `content`,
`ObjectChart`'s drill-down table;
- or from a generated `object-*` node — `ObjectView` assembles
`object-kanban`, `object-calendar`, `object-gallery`, `object-timeline`,
`object-gantt`, `object-map`, `object-tree` and `object-chart` from
named keys, and every one of those reads neither channel (for gallery
and timeline: `packages/plugin-list` and `packages/plugin-timeline` hold
no node-channel read).
No host spreads its own node into a node that reads `children`.
**Generic traversers** (`validateChildren` in core, `sdui-parser`
`validateTree`, the metadata-admin preview canvases, the vscode
validator) walk children to validate or preview. They render nothing and
are node-agnostic, as for every row family D already holds.
**objectui#9910 cross-check.** None of the 12 narrowed registrations
declares a `children` slot input: a grep over their registration files
finds 0 hits, and the lit control is `html-elements.tsx` / `div.tsx`,
which do.
**Producers.** `pnpm census:body-dialect --keys` over the 15, plus
`ui:calendar` and `input`, with `div` / `card` / `page` / `button` / `p`
/ `h1` as lit controls in the same pass: 8981 files, 2744 candidate
nodes.
- **0** nodes author `children` on any of the 15.
- 1 node authors `body` on `ui:calendar`: it was the family-D TRIPWIRE
test line (test bucket), moved by this change.
- The controls read `div` 170 / `card` 183 / `page` 47 `children`.
- Producers derived: none. Nothing was migrated.
## The `Omit` repair — measured on the BUILT d.ts
A probe program under `packages/components` resolved `@object-ui/types`
to `packages/types/dist/index.d.ts` (`--traceResolution`). It carried 15
`@ts-expect-error` pins (the 10 object/detail `children`, `email`
`children`, `password` `body`, `email` `label: 42`, and the
`ui:calendar` `children` and `mode: 'default'`), a lit control (`const
n: number = 'x'`), and 12 channel-free controls.
- **On this branch:** exit 0 — every directive used, every control
compiles, the lit control fires.
- **On the base dist:** exit 2 with 15 × TS2578, and the lit control is
still used.
- The emitted `dist/form.d.ts` declares `OmitDeclared` locally and both
heritage clauses use it.
## Red on base, then green — one-shot, the restore proven by state
The predictions were written to a file BEFORE the mutation. The mutation
was `git checkout 0c50f18 -- THE-SEVEN-DECLARATION-FILES`, with every
test file at HEAD. It was proven by 7/7 blob hashes equal to BASE plus
anchor counts (`neitherContentChannel` 0, `OmitDeclared` 0). The run sat
under `trap … EXIT INT TERM` with absolute paths.
| reader | mutated (BASE arms) | restored (HEAD `14fd13c51`) |
|---|---|---|
| vitest, the new pin file | **RED** exit 1 — 73 failed / 90 passed;
exactly the predicted 12 × 5 `children` families + 12 `body`-message
rows + 1 nested row | **GREEN** 163 / 163 |
| `tsc -p packages/types/tsconfig.test.json` | **RED** exit 2 — 18 ×
TS2578 and 3 × TS2322 (the `Eq` pins) in the new file, plus 3 in
`zod-mirror-parity` naming the two re-collapsed pairs and the stale
`KnownDrift` row; 0 elsewhere | **GREEN** exit 0 |
| built-d.ts probe (types rebuilt; dist markers 0 → 29 / 6) | **RED**
exit 2, 15 × TS2578 | **GREEN** exit 0 |
The restore was proven by 7/7 blob hashes equal to HEAD, `git diff HEAD`
empty and `git status` clean, both after the restore and at the end.
⚠️ **The `body` rows on the ten object/detail arms are GREEN on base, by
design:** `BaseSchema` already refused `body` there. Only their MESSAGE
changes, and the message rows are the ones that turn red. `?: never` is
erased before vitest runs, so the TypeScript half is read by `tsc`
alone. The vitest run cannot see it.
## Serial constraints
- **Mapped at branch time (`0c50f1863`).** PRs objectui#10714, #10883
and #10884 were open then; all three have since merged, and PR
objectui#10875 was the base.
- `layout.ts` (TabItem) and `layout.zod.ts` (TabItemSchema): untouched,
because `br` / `hr` / `img` are held and neither file is edited.
- `content-channel-family-d-9256.test.ts`: the only edits are forced
ones, clear of PR objectui#10714's hunks, which sit in the ListItem and
Tabs sections:
- The file's own `ui:calendar` TRIPWIRE said "when the collapse is
repaired this line goes RED … turn it back into a `@ts-expect-error`
pair". The repair fired it.
- The pair moved to the new file. That file lost the tripwire line, its
`uiCalendarBody` array entry (32 → 31) and the now-unused
`UiCalendarSchema` type import.
- No pin was added there.
- `objectql.ts`: the insertion after `ObjectViewSchema`'s last member is
clear of PR objectui#10883's `NamedListView` docblock edit.
- `object-view-unmirrored-keys-7779.test.ts` (PR objectui#10884):
untouched.
- **Open PRs the branch-time map missed** (re-mapped by contract review
`5863631182`):
- PR objectui#10890 rewrote the same two `KnownDrift` header figures in
`zod-mirror-parity.test.ts` and landed first (`c30c8dd4c`). This branch
merged `main` at that commit (merge commit `31bb63bcb`, no rebase, no
force-push) and recounted the figures from the merged table; see "Merge
round" under Gates.
- PRs objectui#10888, #10889 and #10892 are textually disjoint, and all
three have since merged. `git merge-tree` of the merge head against
`main` at `6a7f24e92`, which carries all of them, reports no conflict.
- ⛔ `zod/index.zod.ts` and the `packages/cli` ratchet (objectui#10872)
are untouched.
## Collateral that the repair and narrowing made true or false — each
measured, none widened
- **`zod-mirror-parity.test.ts`:**
- The two `Omit` COLLAPSE rows (32 + 26 keys) leave
`MirroredUndeclared`. Its figures move from 4 / 60 to 2 / 2, and the
class note records the emptying.
- Restoring the named members NARROWED those faces: a collapsed face
accepted every key at `any`. So this is not the "declare the keys"
remedy that ledger refuses.
- The repaired shorthand face now carries `InputSchema`'s `onChange`
runtime slot. It enters `KnownDrift` as inherited drift: one entry, one
key. After the merge with PR objectui#10890 (which took
`ai.zod.ts#AIFormAssistSchema` out, one entry and two keys), the table
holds 49 entries / 88 keys, and both header sites say so.
- The union-arm non-vacuity leg had no multi-arm entry left in this
ledger. It now takes the same reader's arm-walking on `KnownDrift` and
re-arms here when a multi-arm entry lands.
- **`object-view-spec-parity.test.ts`:** `body` / `children` are
redeclared envelope keys on `object-view` now. They are triaged into
`SANCTIONED_LOCAL` as refusal-only surface, like `viewTabBar`, and the
declared-surface figure moves 24 → 26.
- **`CalendarSchema`'s texts on both faces said the TypeScript `Omit`
"collapses … and carries no member".** That became false; they are
corrected.
- **Two comments** that spelled the old plain-`Omit` heritage
(`index.ts`, `form-barrel-mirror-9406.test.ts`) are corrected.
- **`scripts/check-handler-key-read-sites.mjs`** caught my first
spelling. It was a computed spread (`...helper(…)`) that the gate cannot
resolve, so it stopped judging all eleven arms and its `detail-view`
`onTabChange` waiver read stale. The fix, the second commit, declares
both members explicitly. Now 49 / 49 reads are judged and 0 are left
unjudged.
## Held, and the question it leaves
`br` / `hr` / `img` read neither channel, but their only published arm
is `HtmlElementSchema`: ONE object over 38 tags, whose renderer draws
`children` for the other 35 (`p`, `h1`, …). Refusing the key on three
tags means splitting that family arm, or refining it per tag. Both
change a published contract's shape.
- The option the ruling adopted (option A in measurement `5859897857`)
reads: "leaving the three void tags to the tier because their arm is the
shared HtmlElementSchema family whose per-tag split was ruled out
(objectui#9067)".
- The parser tier already names them: the registration declares no
`children` slot on a void tag, so `validateTree` reports
`not-a-container`.
- A HELD control in the new pin file records the shared-arm fact, so the
hold is visible.
That the brief listed them among the keys to narrow is recorded as a
conflict in the report, ⛔ not resolved here by guessing.
## Gates (at HEAD `14fd13c51`, exit codes captured by
redirect-then-capture; heavy runs through the shared verify lock)
| gate | result |
|---|---|
| `@object-ui/types` build (tsc + vite + dist completeness) | exit 0 —
132 emitted files verified |
| `@object-ui/types` `type-check` (`tsc --noEmit` + examples +
`tsconfig.test.json`) | exit 0 |
| `pnpm exec vitest run packages/types/` (parity, node-slot, arm,
mirror, family-D and the new pins) | 259 files / 5670 tests, exit 0 |
| `pnpm exec vitest run scripts/` | 177 passed + 2 skipped of 179 files
/ 5317 tests, exit 0 |
| consumer type-check — every package naming a narrowed type (28
packages: the ten object plugins, app-shell, components, core, fields,
cli, react, runner, console, schema-catalog, vscode-extension …) | exit
0, 28 × `type-check: Done` |
| `pnpm --filter @object-ui/types lint` | 0 errors; 0 findings on any
added line (eslint JSON over the 13 touched files) |
| `check:control-bytes` · `check:new-line-citations` (0 new) ·
`changeset:check` · `check-changeset-presence` ·
`check:changeset-claims` · `check:pending-changeset-literals` | exit 0
each |
| `check:doc-types` · `check:doc-snippets` · `check:doc-examples` ·
`check:skill-examples` · `check:doc-fences` · `check:doc-example-ids`
(against the built types) | exit 0 each |
| `check:handler-key-reads` · `check:component-surface-parity` ·
`check:prompt-keys` · `check:registry-bare-names` · `check:spec-symbols`
· `check:readme-exports` · `pnpm check` (CLI self-check) | exit 0 each |
| governed guard `--test` over the 14 paths | NOT GOVERNED |
NOT MEASURED:
- `check:sdui-registration-pins` exits 2 without a console build. The
diff touches no registration and no `sideEffects` array. Left to CI.
- The 4-way `pnpm test` shards beyond `packages/types` and `scripts/`,
plus `test:dist` and E2E: left to CI.
### Merge round — head `31bb63bcb` (merges `main` at `c30c8dd4c`)
The one conflict was the two `KnownDrift` header figures in
`zod-mirror-parity.test.ts`. It was resolved by RECOUNTING the merged
table with the test's own AST reader, not by picking a side:
| tree | `KnownDrift` |
|---|---|
| base `0c50f1863` | 49 entries / 89 keys |
| PR objectui#10890 removes `ai.zod.ts#AIFormAssistSchema` | −1 entry /
−2 keys (48 / 87 on `c30c8dd4c`) |
| this branch adds `form.zod.ts#InputShorthandSchema` | +1 entry / +1
key (50 / 90 on `14fd13c51`) |
| merged `31bb63bcb` | **49 entries / 88 keys** |
The population bullet and the KNOWN_DRIFT restatement both read 49 / 88,
and the bullet keeps both histories in landing order. The other ledgers
read the same as before: `MirroredUndeclared` 2 / 2,
`UnmirroredDeclared` 12 / 84, `RuntimeOnlyDeclared` 3 / 7,
`WiderThanDeclared` 6 / 7. The merge head differs from `main` by exactly
this PR's 14 files.
| gate at `31bb63bcb` | result |
|---|---|
| `zod-mirror-parity` + `content-channel-e3-residual-9256` | 2 files /
200 tests, exit 0 |
| `@object-ui/types` build · `type-check` (incl. `tsconfig.test.json`) |
exit 0 · exit 0 |
| `pnpm exec vitest run packages/types/` (incl. PR objectui#10890's
`ai-zod-arms-10859` / `ai-node-faces-agree-10874` and the family-D file
PR objectui#10714 edited) | 261 files / 5696 tests, exit 0 |
| `pnpm exec vitest run scripts/` | 177 passed + 2 skipped of 179 files
/ 5322 tests, exit 0 |
| `check:control-bytes` · `check:new-line-citations` · `changeset:check`
· `check-changeset-presence` · `check:changeset-claims` ·
`check:pending-changeset-literals` · `check:handler-key-reads` | exit 0
each |
## Acceptance notes — out of scope, not fixed here
- **`input` reads neither channel as well.** `InputSchema`: 0 channel
reads, 17 keys read; the registration declares no `children` slot.
- It is this card's remaining family-D name, and it was not in this
claim.
- Its old hold-out ground ("a TS `Omit` carries nothing") is gone with
this repair: a tombstone on `InputSchema` now propagates on both faces.
- Carrier: the next objectui#9256 slice.
- **`PartialSchema`'s docblock in `index.ts`** says every generic
re-spelling of its `Omit` collapses for the same `keyof T` reason.
`OmitDeclared` is a generic spelling that does not: this PR measures it
on two faces.
- Carrier: the next objectui#9256 slice, which touches the same `Omit`
subject. objectui#6397, that alias's card, is closed.
- Noted, not filed.
- **The family-D test header** still records `InputSchema` as "family E,
frozen" and `DetailViewSchema` as unattributable. Both readings are
superseded by this change.
- Carrier: the next objectui#9256 slice.
- Noted, not edited: PR objectui#10714 held that file while this PR was
written. It has since merged, so the next slice edits the header freely.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01DuWo5bdP9SdVebamn99GGk)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: packages/types/src/__tests__/zod-mirror-parity.test.ts
+55-94Lines changed: 55 additions & 94 deletions
Original file line number
Diff line number
Diff line change
@@ -154,7 +154,12 @@
154
154
* a delta to this number; count the registry. Nothing asserts it against a written
155
155
* one, so this line is prose and can rot; the pin that cannot is the one
156
156
* comparing the two halves to each other.
157
-
* - **48 entries** in `KnownDrift`, **87 keys** across them — 49 / 89 until
157
+
* - **49 entries** in `KnownDrift`, **88 keys** across them — 48 / 87 until
158
+
* objectui#9256 repaired the `Omit` erasure on `form.zod.ts#InputShorthandSchema`:
159
+
* the face had declared nothing it inherited, so no key of it could drift, and it
160
+
* now carries `InputSchema`'s members, `onChange` included. ONE entry is new with
161
+
* one key, and it is `InputSchema`'s own runtime-slot drift inherited through the
162
+
* repaired heritage — not drift the change introduced. It was 49 / 89 until
158
163
* objectui#10874 settled the TypeScript face of the three `@object-ui/plugin-ai`
159
164
* declarations per key: `onApplySuggestion` / `onRejectSuggestion` became `?: never`
160
165
* (both faces now refuse them), so `ai.zod.ts#AIFormAssistSchema` measures clean and
@@ -674,7 +679,7 @@
674
679
*
675
680
* ## KNOWN_DRIFT is a ratchet, not a waiver
676
681
*
677
-
* 48 of the registered pairs carry TYPE drift TODAY (measured, not assumed). Each is
682
+
* 49 of the registered pairs carry TYPE drift TODAY (measured, not assumed). Each is
678
683
* pinned to its EXACT drifted key set, so the entry fails when new drift appears on
679
684
* that mirror AND when the recorded drift is fixed — a stale entry cannot rot
680
685
* quietly. Correcting them is not one change: the pairs below split into DISJOINT
@@ -2220,6 +2225,13 @@ interface KnownDrift {
2220
2225
'form.zod.ts#InputOTPSchema': 'onChange';
2221
2226
/** RUNTIME SLOT (objectui#6124): the `input` renderer calls `props.onChange(e.target.value)` after `SchemaRenderer`'s spread. */
2222
2227
'form.zod.ts#InputSchema': 'onChange';
2228
+
/**
2229
+
* Inherited drift: `InputSchema`'s runtime slot above, reaching this face since
2230
+
* objectui#9256 repaired its `Omit` heritage (it declared nothing it inherited
2231
+
* before, so nothing could drift). Both registrations spread their props into the
2232
+
* same `input` renderer, so the slot is the same slot.
2233
+
*/
2234
+
'form.zod.ts#InputShorthandSchema': 'onChange';
2223
2235
/** RUNTIME SLOT (objectui#6124): the `select` renderer calls `props.onChange(matchOptionValue(…))` after `SchemaRenderer`'s spread. (This pair LEFT the ledger with objectui#5927's widenings and re-enters on a different key for a different reason.) */
2224
2236
'form.zod.ts#SelectSchema': 'onChange';
2225
2237
/** RUNTIME SLOT (objectui#6124): the `textarea` renderer calls `props.onChange(e.target.value)` after `SchemaRenderer`'s spread. */
@@ -3651,7 +3663,7 @@ export const assertionWiderLedgerRecordsEveryKey: never = 0 as unknown as WiderL
3651
3663
* Exact MIRRORED-BUT-UNDECLARED key set per pair — the seed of the direction
3652
3664
* objectui#9711 opened, measured on the tree this ledger landed on.
3653
3665
*
3654
-
* `this ledger seeds **4 entries** carrying **60 keys**` — and ⛔ read that off the
3666
+
* `this ledger seeds **2 entries** carrying **2 keys**` — and ⛔ read that off the
3655
3667
* census at the bottom of this file, not off this sentence: both figures are pinned
3656
3668
* to this ledger's own AST by 'the fourth direction is enumerated and sized at test
3657
3669
* time', so an entry or an arm added here moves them or the file reddens.
@@ -3669,6 +3681,16 @@ export const assertionWiderLedgerRecordsEveryKey: never = 0 as unknown as WiderL
3669
3681
* one" remedy the next section refuses: no key was hand-declared, the twin and the
3670
3682
* mirror were put on one derivation, and the ruling named the mechanism.
3671
3683
*
3684
+
* ⭐ Then by two entries and 58 keys, when objectui#9256 executed parameter 3 of the
3685
+
* ruling on objectui#8284 (Q2 A): the `Omit` COLLAPSE rows — the `email` / `password`
3686
+
* and `ui:calendar` twins — left because their heritage clauses stopped collapsing
3687
+
* into `BaseSchema`'s index signature. ⚠️ That is NOT the "declare the keys" remedy
3688
+
* the next section refuses, and the direction is the reason: a collapsed face
3689
+
* accepted EVERY key at `any`, so restoring the named members NARROWED those faces
3690
+
* (`label: 42` and `body` stopped type-checking on `email`) rather than enlarging an
3691
+
* accept set. No key was hand-declared; the members are inherited from the very
3692
+
* declarations the mirrors `.omit()` / `.extend()`.
3693
+
*
3672
3694
* ## ⛔ What this ledger is NOT
3673
3695
*
3674
3696
* ⛔ It is NOT a worklist to be drained by DECLARING the keys it names. Declaring a
@@ -3699,17 +3721,17 @@ export const assertionWiderLedgerRecordsEveryKey: never = 0 as unknown as WiderL
3699
3721
* interface restates only the subset objectui's renderers read. The remedy axis
3700
3722
* is the same one objectstack#4115 opened when it made the keys flow in at all,
3701
3723
* and it is a spec-alignment decision, not a typo.
3702
-
* - **`Omit` COLLAPSE.** The declaration is `Omit< Base, K >` over an interface
3703
-
* that carries `BaseSchema`'s index signature, so `Exclude< keyof Base, K >`
3704
-
* resolves through `string` and the `Pick` collapses EVERY member into the index
3705
-
* signature. That face has never declared the keys its docblock describes —
3706
-
* measured, not assumed, and pinned independently of this file for the calendar
3707
-
* twin. The mirror propagates because zod `.extend()` carries the shape. ⭐ This
3708
-
* class is why the operator must not be "fixed" to read fewer keys: it is
3709
-
* reporting a real property of the published declaration, loudly, which is
3710
-
* precisely what a degenerate `DeclaredKeys< D >` should do. A vacuous reading
3711
-
* here over-reports and is caught; the naive `keyof D` spelling under-reports to
3712
-
* `never` and would never be caught at all.
3724
+
* - **`Omit` COLLAPSE — EMPTIED by objectui#9256.** The declaration was
3725
+
* `Omit< Base, K >` over an interface that carries `BaseSchema`'s index
3726
+
* signature, so `Exclude< keyof Base, K >` resolved through `string` and the
3727
+
* `Pick` collapsed EVERY member into the index signature; the mirror propagated
3728
+
* because zod `.extend()` carries the shape. Both instances (the `email` /
3729
+
* `password` and `ui:calendar` twins) were repaired on the DECLARATION side and
3730
+
* their rows deleted. ⭐ The class is still why the operator must not be "fixed"
3731
+
* to read fewer keys: it reported a real property of the published declaration,
3732
+
* loudly, which is precisely what a degenerate `DeclaredKeys< D >` should do. A
3733
+
* vacuous reading here over-reports and is caught; the naive `keyof D` spelling
3734
+
* under-reports to `never` and would never be caught at all.
3713
3735
*/
3714
3736
interfaceMirroredUndeclared{
3715
3737
// `app.zod.ts#AppComponentSchema` HAD a row here — 20 keys of SPEC-OWNED INFLOW
0 commit comments