You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ADR-0076 §12 defers everything in the Docs write
surface beyond replaceAllText and an append: deleteContentRange, arbitrary --index insertion, text and paragraph styling, tables, lists, headers and
footers, and named-range manipulation.
The Docs counterpart of #1613/#1623 (Sheets structural edits and deletion).
The cut is one line, not a list
Every deferred item requires this crate to own the Docs index model, which
§5 exists to avoid. That is the whole boundary:
Docs indices are UTF-16 code units; Rust strings are UTF-8. Any index
computed here is wrong for astral-plane characters in a way that corrupts
silently rather than failing — invisible in every ASCII test.
Inserting at a segment's endIndex is rejected, because the last
character is the segment terminator. That off-by-one is the most common
Docs API bug.
Today neither can happen: insertText is addressed with endOfSegmentLocation and the server locates the end, so no UTF-16
arithmetic exists anywhere in this crate. The first verb that takes an --index gives that up, and everything above comes back at once. Whoever
picks this up is paying that entry cost — it should be a deliberate decision,
not a side effect of adding a verb.
Questions to settle
Does deletion need its own gate operation? Almost certainly yes, and DriveOperation::DocsWrite's own doc comment says so where a delete verb's
author will read it: an operator who granted docs-write for "may replace
text" did not thereby consent to content removal. Same argument ADR-0075 §1
records for sheets-structure, and ADR-0073 §3 before it. A grant issued
today must not silently widen tomorrow.
How does --dry-run describe an effect that is not a text match?
ADR-0076 §7's occurrence count does not generalise, and ADR-0075 §6 had to
solve the same problem for dimension ranges.
Does one verb still equal one request? ADR-0076 §4 makes that a signature (batch_update takes one DocsRequest, not a Vec), which is
what keeps the batch-ordering hazard — where an insertion shifts every later
request's indices — structurally absent. A verb needing several requests
reopens both that and the log shape, and should say so explicitly.
Guards that will need revisiting
no_destructive_or_unleased_request_is_reachable (src/drive/docs/api.rs)
currently fails the build if deleteContentRange appears anywhere in the
write path. That is deliberate and should be narrowed consciously rather
than deleted — the guard is what makes "omni-dev cannot delete document
content" a property of the build rather than a claim in prose.
Summary
ADR-0076 §12 defers everything in the Docs write
surface beyond
replaceAllTextand an append:deleteContentRange, arbitrary--indexinsertion, text and paragraph styling, tables, lists, headers andfooters, and named-range manipulation.
The Docs counterpart of #1613/#1623 (Sheets structural edits and deletion).
The cut is one line, not a list
Every deferred item requires this crate to own the Docs index model, which
§5 exists to avoid. That is the whole boundary:
computed here is wrong for astral-plane characters in a way that corrupts
silently rather than failing — invisible in every ASCII test.
endIndexis rejected, because the lastcharacter is the segment terminator. That off-by-one is the most common
Docs API bug.
Today neither can happen:
insertTextis addressed withendOfSegmentLocationand the server locates the end, so no UTF-16arithmetic exists anywhere in this crate. The first verb that takes an
--indexgives that up, and everything above comes back at once. Whoeverpicks this up is paying that entry cost — it should be a deliberate decision,
not a side effect of adding a verb.
Questions to settle
DriveOperation::DocsWrite's own doc comment says so where a delete verb'sauthor will read it: an operator who granted
docs-writefor "may replacetext" did not thereby consent to content removal. Same argument ADR-0075 §1
records for
sheets-structure, and ADR-0073 §3 before it. A grant issuedtoday must not silently widen tomorrow.
deleteContentRangein v1 at all? feat(drive): structural sheet edits via spreadsheets.batchUpdate #1613 excluded deletion for Sheetsand feat(drive): deletion of sheets, rows and columns via batchUpdate #1623 tracks it separately; the same split may be right here. Note
--replace ""already removes text without any index arithmetic, whichcovers a real share of what deletion is wanted for.
--dry-rundescribe an effect that is not a text match?ADR-0076 §7's occurrence count does not generalise, and ADR-0075 §6 had to
solve the same problem for dimension ranges.
signature (
batch_updatetakes oneDocsRequest, not aVec), which iswhat keeps the batch-ordering hazard — where an insertion shifts every later
request's indices — structurally absent. A verb needing several requests
reopens both that and the log shape, and should say so explicitly.
Guards that will need revisiting
no_destructive_or_unleased_request_is_reachable(src/drive/docs/api.rs)currently fails the build if
deleteContentRangeappears anywhere in thewrite path. That is deliberate and should be narrowed consciously rather
than deleted — the guard is what makes "omni-dev cannot delete document
content" a property of the build rather than a claim in prose.
Refs #1615, #1639, #1613, #1623, ADR-0076 §4 §5 §12, ADR-0075 §1