Edits address places the same way reads do
The read layer names a place with `at: "8.01"`; the edit layer made the model
supply from_text/to_text -- exact document text, retyped -- to name a place it
already had a handle for. That is the highest-risk thing it does: a
fabrication or a whitespace drift silently scopes the wrong span, and the
model had no way to say "this clause" without reproducing it.
`scope: {kind: "at", at, follow?, depth?}` takes the same grammar as
library_read: a provision and everything under it, a page, or a clause plus
what it references. Nothing is retyped and the address is verifiable.
Layering: the address layer resolves, the op engine executes. Resolution
needs a skeleton and a page map; execution needs offsets, so the handler
resolves against the PINNED version's text and hands docxTextOps a
`{kind: "spans"}` scope. docxTextOps gains no structural dependency.
This only works because both layers project the DOCX with
extractDocxBodyText and there is no second extractor -- an offset resolved
for reading is valid for editing. That invariant is now load-bearing, which
is what makes deleting the mammoth fallback a prerequisite rather than
housekeeping. A resolved-empty scope throws instead of widening to the
document, and an `at` scope on an unextractable DOCX refuses.
Raw offsets are deliberately rejected as an edit scope: an edit names a
provision or a page, never a bare character position.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H9ToHYJVDxfeJcJwdzrP2H
| Repository | eliziff/Beaver |
|---|---|
| Author | Eli Ziff <eliasziff@gmail.com> |
| Authored | |
| Parents | f7035bc1 |
| Stats | 4 files changed , +181 , -8 |
| Part of | SourceDoc / DOCX engine: redlines, tracked changes, editing benchmark |
Capture this commit into my fork
Download a Markdown prompt that tells Claude how to port this
exact commit into your working tree. Run it via
claude -p < capture-commit-397b84f0.md
from inside the repo you want the change in.