docs/plans/2026-04-13-slate-v2-add-proof-architecture-plan.md
Design the cleanest long-term proof and ledger shape for agent-driven
development across slate-v2.
The plan must optimize for:
The repo just proved both failure modes:
The current exact ledgers fixed the accounting side, but the proof side still has structural pressure:
slate-react runtime.tsx landfill proved the same problem on the
React side and has now been split into behavior-domain proof filesRepo learnings already point the right way:
Use this split:
Do not recover every legacy test file as a current source file. Do not keep growing giant omnibus proof files.
Keep the exact ledgers as the permanent archaeology layer:
Rules:
mapped-mixed is only for real split ownership:
mirrored, recovered, and/or explicit-skip subclaims inside one legacy fileexplicit-skip requires a contract reason, not “not used”needs-triage before a lane is called doneProof files should follow live behavior domains.
Good current examples:
Bad target shape:
snapshot-contract.ts that owns public surface, query helpers,
selection movement, normalization, structural transforms, ids, publishing,
and replacement semantics all at onceWhen a proof repeatedly restates the same low-level runtime shape, move that shape into a stable package surface.
That rule already paid off for renderer primitives and should keep paying off.
Agents should prove package primitives, not hand-copy their shape in five test files.
packages/slate/testKeep:
transaction-contract.tsnormalization-contract.tsoperations-contract.tstransforms-contract.tsrange-ref-contract.tsclipboard-contract.tstext-units-contract.tsextension-contract.tsheadless-contract.tsRefactor next:
Target split:
surface-contract.ts
Owns barrel exports, overrideable editor instance surface, static delegation,
children accessor, and public method availability.snapshot-contract.ts
Owns immutable snapshot publishing, versioning, id stability, replacement
semantics, and projection helpers.query-contract.ts
Owns read/query helpers that are not already better housed elsewhere:
above, before, after, positions, unhangRange, nodes, and related
read-time traversal behavior.Rule:
snapshot-contract.tspackages/slate-react/testThe one-shot runtime breakup already landed. Keep the same behavior-domain pressure on the remaining files so they do not become the next monsters.
Target:
surface-contract.tsx
package API, helper surface, and focused low-level editor-facing rowsprovider-hooks-contract.tsx
provider/editor lifecycle plus hook ownershipreact-editor-contract.tsx
ReactEditor mapping, focus, DOM path/point/range conversionsprimitives-contract.tsx
renderer and primitive ownershipeditable-behavior.tsx
mounted Editable / EditableBlocks behaviorprojections-and-selection-contract.tsx
projection store and ref localityapp-owned-customization.tsx
app-owned runtime customization laneslarge-doc-and-scroll.tsx
large-document and scroll behaviorRule:
test-utils.tspackages/slate-history/testCurrent split is acceptable.
Keep:
history-contract.tsintegrity-contract.tsAdd files only if one of those becomes bloated enough to hide gaps.
packages/slate-dom/testCurrent split is already good.
Keep:
bridge.tsclipboard-boundary.tsDo not drag old DOMEditor/Android-only legacy harnesses back into this package.
For each legacy row:
same-path-current
Use when the same relative current file still exists and still honestly owns
the behavior.mapped-recovered
Use when the behavior still matters and a current proof file owns it
directly.mapped-mixed
Use when the old file really split across packages or domains.explicit-skip
Use for:
Never recover these just to improve aesthetics.
These are the ADD rules to enforce:
Suggested thresholds:
500-700 LOC~40 logically different rowsThe exact numbers are not sacred. The category boundary is.
packages/slate/test/snapshot-contract.ts first.
This is the highest-value ADD cleanup because it is already doing too much.slate-react proof owners behavior-scoped after the runtime breakup.
If one of the new files starts mixing API shape, DOM mapping, and unrelated
runtime behavior again, split it before adding more rows.slate proof files own slate-dom or slate-react runtime
claims.snapshot-contract.ts and the remaining slate-react proof files stay out
of dumping-ground territorymapped-mixed as a lazy escape hatch.
Mitigation:
allow it only when one legacy file truly spans multiple current owner
surfaces.The cleanest ADD shape is not:
The cleanest ADD shape is:
That is the only setup that keeps both humans and agents out of bullshit.