7171 * and 37 / 53 until objectui#7344 swept the string / `z.any()` handler mirrors:
7272 * `DetailSchema` and `DetailViewSchema` entered (one `onBack` each) and
7373 * `CalendarViewSchema` grew by `onEventClick`.
74- * - **16 entries** in `UnmirroredDeclared`, **97 keys** across them. It read 17 / 98
74+ * - **15 entries** in `UnmirroredDeclared`, **96 keys** across them. It read 17 / 98
7575 * between objectui#6576, which SEEDED the new `ObjectDataTableSchema` pair with its
7676 * one measured key `drillDown` (a pair born ledgered, not growth on an existing
7777 * one), and objectui#7129, which RETIRED `DetailViewSectionSchema.hideEmpty` —
7878 * the ledger's first shrink by removing the DECLARATION rather than by mirroring
79- * it, and the entry's whole content, so the entry went too. ⚠️ It was
79+ * it, and the entry's whole content, so the entry went too. objectui#7623 took
80+ * that route a second time for `DashboardComponentSchema.title` (16 / 97 →
81+ * 15 / 96), again the entry's whole content — and the first time it reached the
82+ * SPEC-DERIVED half. ⚠️ It was
8083 * **121** when objectui#6058 seeded it; objectui#6152 moved 23 callback-shaped
8184 * keys to the ledger below by RECLASSIFICATION, not by fixing them, and
8285 * objectui#6639 MIRRORED `ObjectGridSchema.title` — one key actually repaired.
8386 * Anything citing "121" as the mirroring debt is citing a number that changed
84- * meaning — the comparable figure is 96 + 1 mirrored + 1 retired + 23
87+ * meaning — the comparable figure is 95 + 1 mirrored + 2 retired + 23
8588 * reclassified. The full statement is on that ledger.
8689 * - **7 entries** in `RuntimeOnlyDeclared`, **24 keys** across them. Six of the
87- * seven are a subset of the 16 pairs above; `TreeViewSchema` is NOT — it is
90+ * seven are a subset of the 15 pairs above; `TreeViewSchema` is NOT — it is
8891 * the first pair whose ONLY ledger entry is a runtime-only one
8992 * (objectui#6150 declared `onNodeClick` on an otherwise clean pair), so the
9093 * "no entry in either" population dropped by one to 141 — went to 142 when
91- * objectui#6576 added two pairs, one of them ledgered, and stands at **143**
92- * since objectui#7129 retired `DetailViewSectionSchema`'s only ledgered key.
94+ * objectui#6576 added two pairs, one of them ledgered, went to 143 when
95+ * objectui#7129 retired `DetailViewSectionSchema`'s only ledgered key, and
96+ * stands at **144** since objectui#7623 retired `DashboardComponentSchema`'s
97+ * only UNMIRRORED one (that pair keeps its `KnownDrift` entry — this
98+ * population counts entries in the two unmirrored ledgers).
9399 * - 160 − 40 = **120**, the "pairs with no entry" `LedgerMismatch` speaks of.
94100 *
95101 * ## Two ratchets, because the forward comparison has two halves
@@ -904,20 +910,25 @@ interface KnownDrift {
904910 * invites an author to write and the published validator has never heard of.
905911 *
906912 * ## ⚠️ READ THIS BEFORE QUOTING THE NUMBER — 121 became 98 by RECLASSIFICATION,
907- * ## then 97 by the first REPAIR
913+ * ## then 97 by the first REPAIR, then 96 by RETIREMENT
908914 *
909- * objectui#6058 seeded this ledger at **121 keys**. It records **97 **, and the two
915+ * objectui#6058 seeded this ledger at **121 keys**. It records **96 **, and the
910916 * movements are different facts. objectui#6152 measured the 23 callback-shaped
911917 * (`on*`) keys and ruled that mirroring is the wrong remedy for every one of them;
912918 * they moved, intact and still pinned, to `RuntimeOnlyDeclared` below — ⛔ nothing
913919 * was mirrored, no declaration was removed, nothing was waived by that move. Then
914920 * objectui#6639 MIRRORED `ObjectGridSchema.title` (census-directed maintainer
915921 * ruling 2026-08-29, declare branch) — one defect actually repaired, the ledger's
916- * first shrink by repair.
917- *
918- * So: **97 is the mirroring debt; 97 + 1 mirrored + 23 reclassified is what "121"
919- * used to mean.** A card that cites 121 as the size of the mirroring problem, or
920- * 98/97 as a shrink from it, is wrong in both directions. objectui#6141 is the
922+ * first shrink by repair. Then objectui#7129 and objectui#7623 each RETIRED a key by
923+ * deleting the DECLARATION (`DetailViewSectionSchema.hideEmpty`;
924+ * `DashboardComponentSchema.title`) — shrinks by removal, which is neither a repair
925+ * of the mirror nor a waiver: the key stops being offered to authors at all.
926+ *
927+ * So: **96 is the mirroring debt; 96 − 1 seeded + 1 mirrored + 2 retired + 23
928+ * reclassified is what "121" used to mean** (the seed is objectui#6576's
929+ * `ObjectDataTableSchema.drillDown`, which was never part of the 121). A card that
930+ * cites 121 as the size of the mirroring problem, or 98/97/96 as a shrink from it,
931+ * is wrong in both directions. objectui#6141 is the
921932 * standing example of what a silently moved count costs — it is why this paragraph
922933 * is in the ledger rather than in a commit message.
923934 *
@@ -945,18 +956,25 @@ interface KnownDrift {
945956 * explicit that forcing the 121 per-key decisions now would be wrong. Two splits
946957 * are recorded here so whoever works them off does not re-derive them:
947958 *
948- * - **SPEC-DERIVED (3 entries, 13 keys)** — `DashboardComponentSchema`,
949- * `DashboardWidgetSchema`, `ObjectViewSchema`. ⚠️ objectui#6705 invalidated the
950- * evidence for ONE of the three: `ObjectViewSchema` is no longer in
959+ * - **SPEC-DERIVED (2 entries, 12 keys)** — `DashboardWidgetSchema`,
960+ * `ObjectViewSchema`. It was 3 / 13 until objectui#7623 RETIRED
961+ * `DashboardComponentSchema.title` by deleting the DECLARATION — the
962+ * objectui#7129 route, reaching this half for the first time. That key was never
963+ * going to be answered by #2231 unification: the spec's strict `DashboardSchema`
964+ * refuses a root `title` outright, and objectui#7509 had already retired every
965+ * read of it, so the local declaration was offering a member the spec models
966+ * nowhere and no renderer consumed. ⚠️ objectui#6705 invalidated the
967+ * evidence for ONE of the two that remain: `ObjectViewSchema` is no longer in
951968 * `SPEC_DERIVED_PAIRS` below, because it never referenced a spec schema — it is
952969 * `BaseSchema.extend({…})` of local literals, and the pre-#6705 text scanner
953- * charged it a neighbouring private const's `Spec…` token. The split is left
954- * STANDING as written, counts and all: re-routing those keys from #2231's
970+ * charged it a neighbouring private const's `Spec…` token. That misclassification
971+ * is left STANDING as #6705 found it — neither the entry's classification nor its
972+ * key count moved for it: re-routing those keys from #2231's
955973 * unification question to a local mirror edit is a remedy decision on the
956974 * `UnmirroredDeclared` ledger, which #6705 was fenced out of. Whoever works
957975 * this split off must re-derive `ObjectViewSchema`'s side first.
958- * For the other two the reading is unchanged:
959- * their mirror takes its shape BY REFERENCE from `@objectstack/spec`. An
976+ * For `DashboardWidgetSchema` the reading is unchanged:
977+ * its mirror takes its shape BY REFERENCE from `@objectstack/spec`. An
960978 * unmirrored declared key there means the LOCAL declaration carries members the
961979 * spec schema does not model, which is objectui#2231's unification question and
962980 * NOT a local mirror edit. They are marked, not exempted: exempting them in the
@@ -970,10 +988,11 @@ interface KnownDrift {
970988 * (107 → 85; 84 since objectui#6639 mirrored `ObjectGridSchema.title`, 83 since
971989 * objectui#7129 retired one). The pair COUNTS did not move under the
972990 * reclassification — every affected pair kept keys here — so the split read 16
973- * entries / 97 keys after it. Two later changes moved the entry count itself:
991+ * entries / 97 keys after it. Three later changes moved the entry count itself:
974992 * objectui#6576 SEEDED `ObjectDataTableSchema` (a 17th entry, in neither half
975- * above), and objectui#7129 RETIRED an entry from the LOCAL half. The ledger now
976- * totals **16 entries / 97 keys** — 3 / 13 spec-derived, 12 / 83 local, plus the
993+ * above), objectui#7129 RETIRED an entry from the LOCAL half, and objectui#7623
994+ * RETIRED one from the SPEC-DERIVED half (13 → 12 keys there). The ledger now
995+ * totals **15 entries / 96 keys** — 2 / 12 spec-derived, 12 / 83 local, plus the
977996 * seeded pair.
978997 *
979998 * ## How this was measured, and the trap that makes the number hard to get
@@ -1008,14 +1027,17 @@ interface UnmirroredDeclared {
10081027 * heard of.
10091028 */
10101029 'complex.zod.ts#ChatbotSchema' : 'displayMode' | 'floatingConfig' | 'requestBody' ;
1030+ // `complex.zod.ts#DashboardComponentSchema` recorded `title` here (SPEC-DERIVED)
1031+ // until objectui#7623 RETIRED the declaration — the objectui#7129 route, not a
1032+ // mirror edit: the spec's strict `DashboardSchema` refuses a root `title` outright,
1033+ // and objectui#7509 had already retired every read of it. The pair keeps its
1034+ // `KnownDrift` entry above (three TYPE-drifted keys) and records nothing here.
10111035 /**
10121036 * SPEC-DERIVED → objectui#2231. The mirror takes its shape by reference from
1013- * `@objectstack/spec`, so `title` is a member the LOCAL declaration carries and the
1014- * spec schema does not model. Its three TYPE-drifted keys are in `KnownDrift` above
1015- * and route the same way.
1037+ * `@objectstack/spec`, so these are members the LOCAL declaration carries and the
1038+ * spec schema does not model. Its one TYPE-drifted key is in `KnownDrift` above and
1039+ * routes the same way.
10161040 */
1017- 'complex.zod.ts#DashboardComponentSchema' : 'title' ;
1018- /** SPEC-DERIVED → objectui#2231, same reading as `DashboardComponentSchema`. */
10191041 'complex.zod.ts#DashboardWidgetSchema' : 'pagination' | 'searchable' ;
10201042 /** LOCAL. Declared in `../data-display.ts`, absent from the mirror. */
10211043 'data-display.zod.ts#ChartSchema' : 'drillDown' ;
@@ -1399,14 +1421,16 @@ export const assertionDriftMatchesLedger: never = 0 as unknown as LedgerMismatch
13991421
14001422/**
14011423 * The SECOND half of the forward comparison: every pair's declared-but-unmirrored
1402- * key set equals what the two ledgers TOGETHER record for it — `never` for the 143
1403- * pairs with no entry in either (160 − 17 ). Six of `RuntimeOnlyDeclared`'s seven
1404- * pairs are a measured subset of `UnmirroredDeclared`'s 16 , so objectui#6152's
1424+ * key set equals what the two ledgers TOGETHER record for it — `never` for the 144
1425+ * pairs with no entry in either (160 − 16 ). Six of `RuntimeOnlyDeclared`'s seven
1426+ * pairs are a measured subset of `UnmirroredDeclared`'s 15 , so objectui#6152's
14051427 * reclassification left the clean population unchanged; objectui#6150 then added
1406- * `TreeViewSchema`, whose only entry is runtime-only, which is why the union is 17
1407- * pairs and not 16. (objectui#6576 took the union to 18; objectui#7129 brought it
1408- * back to 17 by retiring `DetailViewSectionSchema`'s only ledgered key, leaving
1409- * that pair with no entry in either half.)
1428+ * `TreeViewSchema`, whose only entry is runtime-only, which is why the union is 16
1429+ * pairs and not 15. (objectui#6576 took the union to 18; objectui#7129 brought it
1430+ * back to 17 by retiring `DetailViewSectionSchema`'s only ledgered key, and
1431+ * objectui#7623 to 16 by retiring `DashboardComponentSchema`'s — each leaving its
1432+ * pair with no entry in either half. ⚠️ That pair still carries a `KnownDrift`
1433+ * entry: "no entry in either" is about the two UNMIRRORED ledgers.)
14101434 *
14111435 * ⚠️ **The discriminating signal is the PER-PAIR set, not this file's exit code.**
14121436 * The exit code is a whole-file verdict, so it moves only while the rest of the
0 commit comments