docs/solutions/best-practices/2026-05-09-lexical-list-utils-harvest-rows-need-path-ancestry-contracts.md
Lexical list utility tests look tempting to port as helper APIs:
$getListDepth, $getTopListNode, and $isLastItemInList.
That is the wrong target for Slate v2 unless Slate has accepted a public list helper API. The portable behavior is the tree fact those helpers expose.
refactor-existing but the source test is mostly helper
API shape.Write one compact package proof against Slate's public query primitives:
Path.levels gives the logical ancestor chain.Node.get lets the proof filter list and list-item paths.Node.has(editor, Path.next(path)) distinguishes terminal and non-terminal
sibling positions.The proof belongs in .tmp/slate-v2/packages/slate/test/query-contract.ts.
Slate's raw model does not need Lexical's list helper API to preserve the behavior. The durable contract is that public path and node queries can recover:
When harvesting list utility tests from another editor:
Path, Node, or Editor query contracts;