A paragraph's list references and the list definitions of the page model are differences the page writer now lowers. A definition new to the section becomes a native list node (jcid 0x60012) carrying the format string, list font, restart, bullet index and the definition's text formatting; a changed definition is rewritten in place; a definition another paragraph already owns is copied, since native list nodes belong to one paragraph; a dropped reference leaves the node unreferenced. Bullet definitions name their glyph and font and carry the cleared flag every native bullet node has. List nodes are allocated like other new objects and renamed to the model's identities in squash: a node written directly under a model identity had the null compact identity and failed OneNote's integrity check on open. The three-way merge carries definitions the local side added or changed, so a local bullet merges with a remote edit elsewhere. The model mutation driver toggles bullets, and its round-trip projection coalesces runs that differ only in attributes the writer leaves as stored, such as the language tag. corpus/list-edit is the native gate: a Rust-authored page with a bullet, two numbered paragraphs, a nested numbered child, a restart at three and plain paragraphs, cold-read by OneNote 2010 with the expected glyph and numbering text; tools/test_list_edit.py checks it without a VM. Assisted-by: claude-fable-5.1
clover caruso committed on 9/13/2026, 12:00:32 AMparentb6b6e90
24 files changedLine totals unavailable