docs/plans/2026-04-09-slate-v2-schema-normalization-extensibility-completion-plan.md
Close the schema / normalization extensibility lane in
master-roadmap.md
and turn the corresponding open bucket in
release-file-review-ledger.md
from partial to closed-by-proof.
For this lane, "100% completion" means:
The repo already has real normalization work landed:
explicit trackingSo the lane is not open because there is no normalization model.
It is open because the current proof story is still too scattered and too thin at the primary owner:
partial summary rowDo not try to close this lane by reviving blanket legacy built-in normalization parity.
Do not invent a new schema package or normalization DSL.
Close the lane on the current model:
normalizeNode(...) as the real schema extension hookThat is the honest target. Anything broader is a different project.
slate-schema style abstractionshouldNormalize(...) as a narrow pass-level gatepackages/slate/test/normalization/**
inventory against the current default-vs-explicit splitDeleted inventory under packages/slate/test/normalization/** still resolves
into these clusters:
normalization.blocknormalization.editornormalization.inlinenormalization.textnormalization.voidThe plan must preserve that mapping instead of quietly drifting to a narrower story than the closure note already claims.
This lane is done when all of the following are true:
schema / normalization row in
true-slate-rc-proof-ledger.md
can flip from partial to closed without lying about blanket legacy
parityFiles:
Work:
Reason:
normalization-contract.ts the real ownerFiles:
Work:
normalization-contract.ts that maintainers can audit the lane there firstsnapshot-contract.ts as the general surface oracle for delegation and
editor-instance behavior, not the main owner of normalization breadthRequired test scenarios:
fallbackElement wrapping is proved directly in the normalization owner fileFiles:
Work:
withForcedLayout as the canonical root-layout examplenormalization-contract.tsfallbackElement when it needs wrapping instead of deletionRequired test scenarios:
fallbackElement and still
get the current scoped wrapping behaviorFiles:
Work:
Required guard scenarios:
fallbackElement wrapping preserves range refsFiles:
Work:
Reason:
Files:
Work:
normalization-contract.ts until it can honestly own the lanePrimary proof surfaces:
Required verification before declaring the lane closed:
yarn test:customyarn workspace slate-react exec tsx --test test/runtime.tsxyarn lint:typescriptpartialyarn exec mocha --require ./config/babel/register.cjs ./packages/slate/test/normalization-contract.tsyarn workspace slate-react exec tsx --test test/runtime.tsxyarn test:customyarn lint:typescript