--in reaches the engine as a path prefix (docx2html/docx/find_api.mbt:481), whose own comment notes the match is safe "only because scanner ordinals are BRACKETED". A truncated scope therefore widens:
office replace FILE OUT.docx --text A --with B --in 'p[1'
matches p[1], p[10]…p[19], p[100]… — and replace mutates. Without --nth it acts on every in-scope candidate, and --expect N is computed over the widened set, so the assertion still passes while the wrong paragraphs change. office find widens the same way on the surface an agent reads before an irreversible edit.
office format refuses this via format_validate_scope; find and replace do not.
Not fixed in #523 on purpose. I wired that validator into both verbs there and review showed the cure was worse than the disease: it rejected body-relative paths the reader itself prints (a tolerated nested paragraph has the scan path p[1]/r[1]/p[1], pinned in office/cmd/office/cram/cli.t), rejected --in '' which previously meant "no scope", and shadowed the office.docx.para_id_* error family that both verbs document. That is a behavior change to two shipped verbs, and it belongs in its own PR with its own tests rather than riding along inside a deletion feature.
A fix needs a validator built from what the reader actually emits (run segments included, empty scope preserved) and ordered so the stable-identity refusals still speak first.
Related: --in given twice is not rejected on these two verbs either (format and delete-paragraph refuse it), so --in 'p[3]' --in 'p[30]' silently retargets.
🤖 Generated with Claude Code
https://claude.ai/code/session_011soWehbx5RSKVJoqBhFYEP
--inreaches the engine as a path prefix (docx2html/docx/find_api.mbt:481), whose own comment notes the match is safe "only because scanner ordinals are BRACKETED". A truncated scope therefore widens:matches
p[1],p[10]…p[19],p[100]… — andreplacemutates. Without--nthit acts on every in-scope candidate, and--expect Nis computed over the widened set, so the assertion still passes while the wrong paragraphs change.office findwidens the same way on the surface an agent reads before an irreversible edit.office formatrefuses this viaformat_validate_scope;findandreplacedo not.Not fixed in #523 on purpose. I wired that validator into both verbs there and review showed the cure was worse than the disease: it rejected body-relative paths the reader itself prints (a tolerated nested paragraph has the scan path
p[1]/r[1]/p[1], pinned inoffice/cmd/office/cram/cli.t), rejected--in ''which previously meant "no scope", and shadowed theoffice.docx.para_id_*error family that both verbs document. That is a behavior change to two shipped verbs, and it belongs in its own PR with its own tests rather than riding along inside a deletion feature.A fix needs a validator built from what the reader actually emits (run segments included, empty scope preserved) and ordered so the stable-identity refusals still speak first.
Related:
--ingiven twice is not rejected on these two verbs either (formatanddelete-paragraphrefuse it), so--in 'p[3]' --in 'p[30]'silently retargets.🤖 Generated with Claude Code
https://claude.ai/code/session_011soWehbx5RSKVJoqBhFYEP