Review round 3, on the round-2 primitive itself. One lesson covers all three findings: a rope write is only half of an edit, and "discard history" means whichever history the buffer actually has. P1 — the binding swallowed the edit. `set_generated_contents` returned `()`, so nothing reached `notify_buffer_edit_to_windows`. Two consequences, both reproduced by the reviewer. In the default build a window showing the buffer kept a `TextView` line index describing the PREVIOUS contents, and the next paint indexed the new rope with stale ranges — `assertion failed: end <= self.len()` in `src/rope.rs`. In the CRDT build `pending_crdt_ops` stayed empty, so replica mirrors never imported the owner's write and their optimistic edits were generated against content already replaced. The `delete`+`insert` pair this replaced had done that fan-out for free. Now applies ONE whole-buffer `Replace`, returns its `Edit`, and notifies from the binding. The doc comment states the obligation, because the next owner to adopt the primitive inherits it. P2 — "discard history" was false in CRDT mode. The v0.1 stacks are bypassed entirely there; the history lives in loro's `UndoManager`. `read_only` stops the replay but not the retention, which is the memory cost the contract claims to eliminate. `UndoManager` exposes no clear, but needs none: it records only what happens after it is constructed, the same property `CrdtState::from_bytes` already uses to keep the seed insert out of undo. `CrdtState::clear_undo_history` rebinds a fresh manager to the same doc. P2 — the docs described the pre-fix architecture. Q#TC6a said no Lua binding sets `read_only` and round-trip input is the only guard; the acceptance text still said `is_read_only() == false` while 16b had been flipped to true; `terminal.lua`'s comment repeated the obsolete claim. The architecture is layered and now says so: rope-level read-only protects the daemon copy, round-trip input protects the replica's optimistic mirror, and neither substitutes for the other. Q#TC6a keeps its analysis under a superseded-in-part box rather than being silently rewritten — its conclusion survives, two of its premises do not. New pins. acc16d paints the window after a SHRINKING generated write: stale offsets then point past the buffer end, so the failure is the reported crash rather than merely stale pixels. acc16e asserts the refresh is queued for mirrors, through the real copy-mode path; `crdt`-gated and therefore dark in CI, which is why 16d drives the binding rather than the terminal. Plus a CRDT unit test that ten renders leave the `UndoManager` with nothing recorded. Bites: dropping the notify panics acc16d at `rope.rs:145` and fails acc16e with `queued: []`; dropping the `UndoManager` rebind fails the new unit test on `can_undo`. Still open, and recorded in COHERENCE.md §14: the fan-out obligation makes `*compilation*`/listview adoption more than a one-line swap. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016gGQC6eqHJVbZJ5Hg7aLer |
||
|---|---|---|
| .. | ||
| api | ||
| commands | ||
| hooks | ||
| keymaps | ||
| menus | ||
| packages/repl | ||
| queries/latex | ||
| runtime | ||