Repository navigation
Commit 3a9b07f
test(spec): give the metadata-form reconciliation ledger a root coordinate and an ADR-0010 overlay skip (#19639)
Fixes #19329
Clause-②: no
Two instruments the top-level `zodOnly` direction (#19188) needs before
it can be wired at
all, both landing in the gate itself —
`packages/spec/src/system/metadata-form-zod-reconciliation.test.ts`.
Neither wires that
direction, and neither moves a verdict this gate reads today
(before/after comparison below).
## ① The ledger's root coordinate — spelling: an explicit sentinel,
`(root)`
`ROOT_PATH = '(root)'`, plus one function that knows both coordinate
spellings.
`resolveCoordinate(form, root, path)` returns the pair a coordinate
resolves to — the keys the
form offers there, and the schema node they are judged against — and the
「every ledger entry still resolves on both sides」 test now goes through
it. At the root that
pair is `topLevelFields(form)` against the type's own root schema; at
every other coordinate it
is the `nestedLists` entry's `offered` against `subSchemaAt(root,
path)`, i.e. the same two
values the test read before.
**Why a sentinel and not `''`** — the card left the spelling open, so
this is the decision and
its reasons:
1. `''` is **falsy**, and `path ? … : …` is the load-bearing spelling in
this very file
(`nestedLists`' own `prefix` test). Any reader written that way silently
reads the root
coordinate as "no path given" — the one confusion a coordinate must not
have.
2. An unfilled `path` then cannot masquerade as a deliberate root row.
Measured:
`resolveCoordinate(form, schema, '')` is `undefined`, so an empty `path`
fails the resolve
test loudly instead of quietly excusing a top-level key. Ablation A
below shows that pin go
red the moment `ROOT_PATH` becomes `''`.
3. The dotted algebra has no zero-segment element: `''.split('.')` is
`['']` — one empty
segment, not none — so `subSchemaAt(root, '')` walks a segment no schema
declares and
resolves to `undefined`. `''` would need a guard wherever a path is
walked; a sentinel needs
one at the single resolve step, and it is visible at the call site.
4. Parentheses cannot occur in a form's `field:` name, so the sentinel
cannot collide with a
real dotted path — asserted over the live registry (0 collisions across
all 17 forms),
not assumed.
5. It reads unambiguously in a failure label:
`object.(root).apiMethods`, not
`object..apiMethods`.
## ② The framework-field skip — derived from the ADR-0010 shape, applied
at the root only
`FRAMEWORK_FIELDS` mirrors the liveness gate's precedent
(`FRAMEWORK_FIELDS` in
`packages/spec/scripts/liveness/check-liveness.mts` — located by symbol;
read-only here, not
edited), and `offerableKeysAt(sub, path)` is where it applies.
**Derived, not hand-copied.** The seven `_`-prefixed keys are
`Object.keys(MetadataProtectionFields)` — the one exported raw shape
every metadata schema
spreads — so a key added to or dropped from the envelope moves this skip
in the same commit. A
second copy of the liveness gate's eight literal names would have been
the hand-copied-list
shape this whole file exists to abolish, and that `const` is
module-local to a `.mts` script,
so there is nothing to import from it either way: the shape is the
better source for both.
`protection` is the one name written out — the author-facing block the
loader translates INTO
that envelope, spliced under that name by each schema rather than
carried in a shape of its own
— and it is pinned against what it resolves to on every live type that
declares it: 13 of 17,
each `["docsUrl","lock","reason"]`, equal to `keysOf(ProtectionSchema)`.
**The skip stops at the root, deliberately**, and that is a measurement
rather than a
preference. The overlay is spread into nested shapes too (three times in
`view.zod.ts` alone),
and exactly one hand-written nested list resolves to a sub-schema
carrying all seven
`_`-prefixed keys: `object.fields`, whose `subset` entry is judged today
on how much of that
schema the quick-add grid does NOT cover. Skipping the overlay there
would move a number an
asserting leg reads. Pinned as a dark control over both a synthetic
probe and that live
instance; ablation B below shows it go red when the skip is applied at
every coordinate.
## The fence: before/after verdict comparison
Same command on both sides, exit code captured before any pipe, through
`scripts/pm/os-verify-lock.sh` (slot `issue-19329`):
```
pnpm --filter @objectstack/spec exec vitest run --project local --maxWorkers=2 \
--reporter=verbose src/system/metadata-form-zod-reconciliation.test.ts
```
| | unmodified `origin/main` (744a0a3) | this branch (7c1b59a) |
|:---|:---|:---|
| wrapper verdict | `VERDICT command-exit 0` | `VERDICT command-exit 0`
|
| test files | 1 passed (1) | 1 passed (1) |
| tests | **46 passed (46)** | **53 passed (53)** |
| non-pass marks | none | none |
| verdict-set sha256 |
`ad70459ed4c08edeaed52b8e8a7f9a64fa46a0b194c6a345f32407dbd547dcfd` |
`3b801fc825039fa32cb9d080a864993e2d2fc511fd46006247c65c981099ecfd` |
Exact set difference over the normalised verdict lines (status mark +
full test path, per-test
durations stripped), not a count:
- **Missing from after: 0.** All 46 `origin/main` verdicts are present
on the branch,
byte-identical, and all 46 still pass. No rename, no removal, no status
flip — so `formOnly`
and offered-but-retired keep asserting exactly what they assert today.
- **Added: 7**, all of them the new pins in one new `describe` block:
- the root coordinate resolves to the top-level pair, which no nested
path can
- the empty string is not the coordinate — an unfilled path fails loudly
instead
- no live form has a hand-written list at the sentinel, so it cannot be
shadowed
- the overlay set IS the ADR-0010 shape, not a second hand-copied list
- positive control: the overlay drops out of the offerable keys at the
root, and nothing
else does
- dark control: the skip does not reach a nested coordinate, live
instance included
- a top-level omission is recordable, and a row naming the overlay is
not
No existing verdict changed, so the fork the card reserved for that
outcome was not reached.
## Ablation — both pins can fail, and both legs restored
Through `scripts/ablation-replace.mjs` (anchor must hit; the write is
verified against the
disk; restore proven by blob equality with `HEAD` plus an empty `git
diff HEAD`), each wrapping
the same locked vitest run. No `dist` leg: the subject is reached by
relative `src` imports
inside its own package, so nothing resolves through `exports`.
| leg | mutation | on-disk evidence | result |
|:---|:---|:---|:---|
| A | `const ROOT_PATH = '(root)';` → `const ROOT_PATH = '';` | anchor 1
→ 0, blob `b72a5edfcd72` → `d138333efcbf` | **1 failed \| 52 passed** —
exactly 「the empty string is not the coordinate」 |
| B | `offerableKeysAt`'s `path === ROOT_PATH ? … : keys` → skip applied
unconditionally | anchor 1 → 0, blob `b72a5edfcd72` → `9ec64f2272af` |
**1 failed \| 52 passed** — exactly 「dark control: the skip does not
reach a nested coordinate」 |
Both legs: `ok restored: blob == HEAD (b72a5ed) and git diff HEAD
is empty`. Direction was
predicted before each run and matched (turn red, one named test each).
## Census, re-derived on this tree
1 parent ec2ede0 commit 3a9b07f
1 file changed
Lines changed: 291 additions & 16 deletions
Lines changed: 291 additions & 16 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
76 | 101 | | |
77 | 102 | | |
78 | 103 | | |
79 | 104 | | |
80 | 105 | | |
81 | 106 | | |
82 | 107 | | |
| 108 | + | |
83 | 109 | | |
| 110 | + | |
84 | 111 | | |
85 | 112 | | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
86 | 171 | | |
87 | 172 | | |
88 | 173 | | |
89 | | - | |
| 174 | + | |
| 175 | + | |
90 | 176 | | |
91 | 177 | | |
92 | 178 | | |
| |||
339 | 425 | | |
340 | 426 | | |
341 | 427 | | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
342 | 471 | | |
343 | 472 | | |
344 | 473 | | |
| |||
464 | 593 | | |
465 | 594 | | |
466 | 595 | | |
467 | | - | |
468 | | - | |
469 | | - | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
470 | 600 | | |
471 | | - | |
472 | | - | |
473 | | - | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
474 | 606 | | |
475 | 607 | | |
476 | | - | |
477 | | - | |
478 | | - | |
479 | | - | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
480 | 623 | | |
481 | | - | |
| 624 | + | |
482 | 625 | | |
483 | 626 | | |
484 | 627 | | |
485 | | - | |
| 628 | + | |
486 | 629 | | |
487 | 630 | | |
488 | 631 | | |
489 | 632 | | |
490 | | - | |
491 | | - | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
492 | 636 | | |
493 | | - | |
| 637 | + | |
494 | 638 | | |
495 | 639 | | |
496 | 640 | | |
| |||
690 | 834 | | |
691 | 835 | | |
692 | 836 | | |
| 837 | + | |
| 838 | + | |
| 839 | + | |
| 840 | + | |
| 841 | + | |
| 842 | + | |
| 843 | + | |
| 844 | + | |
| 845 | + | |
| 846 | + | |
| 847 | + | |
| 848 | + | |
| 849 | + | |
| 850 | + | |
| 851 | + | |
| 852 | + | |
| 853 | + | |
| 854 | + | |
| 855 | + | |
| 856 | + | |
| 857 | + | |
| 858 | + | |
| 859 | + | |
| 860 | + | |
| 861 | + | |
| 862 | + | |
| 863 | + | |
| 864 | + | |
| 865 | + | |
| 866 | + | |
| 867 | + | |
| 868 | + | |
| 869 | + | |
| 870 | + | |
| 871 | + | |
| 872 | + | |
| 873 | + | |
| 874 | + | |
| 875 | + | |
| 876 | + | |
| 877 | + | |
| 878 | + | |
| 879 | + | |
| 880 | + | |
| 881 | + | |
| 882 | + | |
| 883 | + | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
| 892 | + | |
| 893 | + | |
| 894 | + | |
| 895 | + | |
| 896 | + | |
| 897 | + | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
| 913 | + | |
| 914 | + | |
| 915 | + | |
| 916 | + | |
| 917 | + | |
| 918 | + | |
| 919 | + | |
| 920 | + | |
| 921 | + | |
| 922 | + | |
| 923 | + | |
| 924 | + | |
| 925 | + | |
| 926 | + | |
| 927 | + | |
| 928 | + | |
| 929 | + | |
| 930 | + | |
| 931 | + | |
| 932 | + | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
| 936 | + | |
| 937 | + | |
| 938 | + | |
| 939 | + | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
| 945 | + | |
| 946 | + | |
| 947 | + | |
| 948 | + | |
| 949 | + | |
| 950 | + | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
| 960 | + | |
| 961 | + | |
| 962 | + | |
| 963 | + | |
| 964 | + | |
| 965 | + | |
| 966 | + | |
| 967 | + | |
0 commit comments