@ansonlai/docx-redline-js 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,53 +7,51 @@ Use this page for ordinary `.docx` edits. For source changes or unusual Word str
7
7
  If your host provides a document-session wrapper:
8
8
 
9
9
  1. Inspect/search once with enough surrounding context to draft the change.
10
- 2. Apply using the returned revision-bound target handle. Send either the
11
- complete desired paragraph or exact replacements supported by that wrapper.
12
- 3. Treat only `ok: true` as complete. A failed handle must be refreshed by
13
- inspection; never reuse it against a changed document.
10
+ 2. Apply with the revision-bound handle and complete desired text or exact replacements.
11
+ 3. Treat only `ok: true` as complete; refresh failed handles before reuse.
14
12
 
15
13
  The repository's `examples/agent-session-wrapper.mjs` demonstrates this pattern.
16
14
  It is a development sample, not a package API.
17
15
 
18
16
  ## CLI fallback
19
17
 
20
- 1. Extract only the relevant clause or range:
18
+ 1. For a literal mechanical edit with known old and new text, try one-turn apply:
21
19
 
22
20
  ```bash
23
- docx-redline extract contract.docx --search "termination" --around 3
21
+ docx-redline apply contract.docx --find "thirty (30) days" --replace "sixty (60) days" --profile agent --output reviewed.docx
24
22
  ```
25
23
 
26
- Search is case-insensitive. Direct hits are capped; follow `selection.nextAfter` with `--after`, and cite `humanReference`, not `P42`.
24
+ The source must occur in one eligible paragraph. For text after a heading, add `--search "Section 4.1" --context-range 1:3`.
25
+ `--around 3` is symmetric; use it only when either side is eligible.
26
+
27
+ 2. For semantic drafting such as “make this provision mutual,” extract enough
28
+ context, then copy `exactText` with `paragraphId` or `fingerprint`:
29
+
30
+ ```bash
31
+ docx-redline extract contract.docx --search "termination" --around 3
32
+ ```
27
33
 
28
- 2. Copy `exactText` with `paragraphId` or `fingerprint`. Use a UTF-8 operations
29
- file or serializer-backed stdin, then apply once:
34
+ Search is case-insensitive; follow `selection.hint` and `selection.nextAfter`, and report `humanReference`. Apply once with a UTF-8 operations file or serializer-backed stdin:
30
35
 
31
36
  ```bash
32
37
  node emit-operations.mjs | docx-redline apply contract.docx --operations - --profile agent --compact --output reviewed.docx
33
38
  ```
34
39
 
35
- `emit-operations.mjs` should use `JSON.stringify`; do not interpolate legal
36
- text through shell quoting. `modified` is the complete desired accepted-view
37
- paragraph, not only the inserted words.
40
+ Use `JSON.stringify`, not shell interpolation. `modified` is the complete desired accepted-view paragraph.
38
41
 
39
42
  The `agent` profile preserves progressive execution and the ordinary revision policy while making incomplete work exit nonzero. Add `--atomic` deliberately; check `effectiveOptions`. Run `docx-redline apply --help` for redline, comment, and rejected-view restore shapes.
40
43
 
41
44
  ## Batch and result rules
42
45
 
43
- - Strong inspected targets are bound to the batch-start document. Independent
44
- edits do not need bottom-up sorting around earlier paragraph splits.
45
- - Consolidate multiple desired texts for the same source paragraph. Follow an
46
- explicit capture dependency for non-unique content created earlier in a batch.
46
+ - Strong inspected targets bind to the batch start; independent edits need no bottom-up sorting.
47
+ - Consolidate writes to one source; use captures for created-content dependencies.
47
48
  - Require `completion: true`, `written: true`, a non-null `outputPath`, and no
48
- per-operation error. The source is not overwritten unless `--in-place` is
49
- explicit.
49
+ per-operation error. For localized edits also require `change.committed: true`
50
+ and `change.verification.acceptedViewMatchesCompiledText: true`. The source is
51
+ not overwritten unless `--in-place` is explicit.
50
52
  - On failure, follow `error.recovery.action`. Never retry unchanged arguments.
51
- - `retryPlan.base: "original"` means correct and replay the complete batch.
52
- `base: "output"` means keep committed progressive work and retry only the
53
- reported failed or unattempted indexes.
54
- - Never accept/reject revisions or remove comments without user authorization.
55
- `slice-cross-author` is the history-preserving option for a surgical edit
56
- inside another reviewer's pending insertion.
53
+ - `retryPlan.base: "original"` means replay the batch; `"output"` means retain committed work and retry reported indexes.
54
+ - Never accept/reject revisions or remove comments without user authorization. `slice-cross-author` preserves history for edits inside foreign insertions.
57
55
 
58
56
  Advanced operations and recovery: [Agent Knowledge Base](AGENT_KNOWLEDGE_BASE.md); canonical contract: [document-operations.schema.json](schemas/document-operations.schema.json)
59
57
  Wrapper design: [README](../README.md#example-agent-session-wrapper-development-only)
@@ -482,20 +482,26 @@ Use this for everything by default. `apply` is fast, progressive, and self-valid
482
482
 
483
483
  The short route for a document-editing request is:
484
484
 
485
- 1. Run one focused `extract` for the clauses or range being edited. Search is a
486
- case-insensitive substring match; add `--around 3` when surrounding drafting
487
- context is needed. Copy `exactText` plus `paragraphId` or `fingerprint`.
488
- 2. Build the final operations from the operation table above. Use one operation
485
+ 1. For an exact mechanical change with known old and new literals, use localized
486
+ `--find`/`--replace`. Omit the target for global fail-closed resolution, or
487
+ scope a visible heading with `--search` and a directional range such as
488
+ `--context-range 1:3`. Repeated anchor matches are unioned; one eligible patch
489
+ paragraph is still required. `--occurrence` selects only within that paragraph.
490
+ 2. For semantic drafting, run one focused `extract`. Add `--around 3` when
491
+ surrounding context on either side is needed, then copy `exactText` plus
492
+ `paragraphId` or `fingerprint`.
493
+ 3. Build the final operations from the operation table above. Use one operation
489
494
  per target paragraph, and consolidate multiple changes to that paragraph.
490
- 3. Run `apply` once per stable batch. Strong inspected targets are bound against
495
+ 4. Run `apply` once per stable batch. Strong inspected targets are bound against
491
496
  the batch-start document, so independent operations do not need manual
492
497
  bottom-up sorting around structural edits. Consolidate multiple complete
493
498
  desired states for the same source. A unique exact reference to paragraph
494
499
  text created elsewhere in the batch is scheduled automatically; use explicit
495
500
  captures/selectors for non-unique or advanced created-content dependencies.
496
- 4. Walk every result and require `completion: true`, `written: true`, and no
497
- per-operation error.
498
- 5. Run a focused `extract` on changed clauses only when placement or list/table
501
+ 5. Walk every result and require `completion: true`, `written: true`, and no
502
+ per-operation error. For localized patches also require committed `change`
503
+ evidence and positive accepted-view verification.
504
+ 6. Run a focused `extract` on changed clauses only when placement or list/table
499
505
  structure needs confirmation.
500
506
 
501
507
  Do not probe operation behavior with disposable apply commands or read a vendor
@@ -503,22 +509,28 @@ bundle before this route. If `apply` returns an error, use the recovery matrix
503
509
  below and make one cause-specific correction.
504
510
 
505
511
  ```bash
506
- # 1. Focused contextual discovery
512
+ # 1. Globally unique mechanical edit in one call
513
+ docx-redline apply contract.docx --find "thirty (30) days" --replace "sixty (60) days" --profile agent --output reviewed.docx
514
+
515
+ # 2. Mechanical edit strictly within three paragraphs after a visible heading
516
+ docx-redline apply contract.docx --search "Section 4.1" --context-range 1:3 --find "thirty (30) days" --replace "sixty (60) days" --profile agent --output reviewed.docx
517
+
518
+ # 3. Focused contextual discovery for semantic drafting
507
519
  docx-redline extract contract.docx --search "termination" --around 3
508
520
 
509
- # 2. Inline one-liner edit (fastest for 1–2 edits; no JSON file needed)
521
+ # 4. Inline complete-paragraph edit
510
522
  docx-redline apply contract.docx --target "Original clause" --modified "New clause" --output reviewed.docx
511
523
 
512
- # 3. Direct edit without tracked changes (clean text, no revision clutter)
524
+ # 5. Direct edit without tracked changes (clean text, no revision clutter)
513
525
  docx-redline apply contract.docx --target "Typo fix" --modified "Fixed typo" --no-redlines --output clean.docx
514
526
 
515
- # 4. Cross-author edit inside another reviewer's pending insertion
527
+ # 6. Cross-author edit inside another reviewer's pending insertion
516
528
  docx-redline apply contract.docx --target "Pending clause text" --modified "Updated clause text" --existing-revisions slice-cross-author --output reviewed.docx
517
529
 
518
- # 5. Batch operations with ops.json
530
+ # 7. Batch operations with ops.json
519
531
  docx-redline apply contract.docx --operations operations.json --output reviewed.docx
520
532
 
521
- # 6. Serializer-backed stdin with compact stdout
533
+ # 8. Serializer-backed stdin with compact stdout
522
534
  node emit-operations.mjs | docx-redline apply contract.docx --operations - --profile agent --compact --output reviewed.docx
523
535
  ```
524
536
 
@@ -575,12 +587,17 @@ normalize or reconstruct `exactText`. Operation files follow
575
587
  Paragraph indexes are 1-based. Inspection filters are `--index 12`,
576
588
  `--range 10:30`, `--indexes 2,5,8`, `--search text`, `--revised`, `--table`,
577
589
  `--body`, `--non-empty`, and `--view accepted|rejected|current`. Search is
578
- case-insensitive. Add `--around N` (`--context N` or `-C N`) to a search;
590
+ case-insensitive. When a search returns 0 matches in the active view but matches
591
+ exist in the alternate view (such as searching for a deleted clause to restore),
592
+ `selection.hint` provides immediate guidance to re-run with `--view rejected`.
593
+ Add `--around N` (`--context N` or `-C N`) to a search;
579
594
  context records are labeled separately and do not consume the direct-hit
580
595
  `--limit`. Continue a bounded result with `--after <paragraph-index>`. Ordinary
581
596
  unscoped CLI inspection defaults to 20 direct records and a 48 KiB soft budget;
582
597
  `--all` deliberately opts out. A malformed filter or unknown option is an error
583
- rather than an unfiltered fallback.
598
+ rather than an unfiltered fallback. CLI help commands (`apply --help`,
599
+ `extract --help`, `--help`) report canonical GitHub repository URLs in their
600
+ `documentation` array.
584
601
 
585
602
  Mutating commands use `--author`, operation-level authors, then
586
603
  `DOCX_REDLINE_AUTHOR`, falling back visibly to `AI Redliner`; review-resolution
@@ -4,6 +4,31 @@ Use this page when creating or updating an agent skill, MCP server, or custom
4
4
  harness for `@ansonlai/docx-redline-js`. Ordinary document-editing agents should
5
5
  load [Agent Fast Start](AGENT_FAST_START.md), not this design contract.
6
6
 
7
+ > [!WARNING]
8
+ > Before 1.0, every skill or harness must identify and pin its exact tested
9
+ > library release and required CLI contract/capabilities. Treat any different
10
+ > release or contract as unverified until compatibility tests pass.
11
+
12
+ For example, an integration authored for the current contract-8 release should
13
+ record a compatibility declaration equivalent to:
14
+
15
+ ```json
16
+ {
17
+ "testedLibraryRelease": "0.7.0",
18
+ "requiredCliContractVersion": 8,
19
+ "requiredCapabilities": [
20
+ "command-help-v1",
21
+ "recovery-envelope-v1",
22
+ "localized-replacements-v1",
23
+ "speculative-search-apply-v1",
24
+ "localized-change-summary-v1"
25
+ ]
26
+ }
27
+ ```
28
+
29
+ The package pin anchors the release; runtime negotiation proves the executable
30
+ exposes the required contract. A new release cannot inherit an old claim.
31
+
7
32
  ## Runtime negotiation
8
33
 
9
34
  Run this before the first document operation when the skill vendors or invokes
@@ -13,14 +38,11 @@ the CLI:
13
38
  docx-redline version
14
39
  ```
15
40
 
16
- Require contract version 7 and only the capabilities the integration uses. A
17
- typical shell skill should require `command-help-v1`, `inspection-context-v1`,
18
- `bounded-inspection-v1`, `human-document-references-v1`,
41
+ Require contract version 8 (the currently declared contract) and only the
42
+ capabilities the integration uses. A typical shell skill should require
19
43
  `agent-safety-profile-v2`, `deduplicated-cli-receipts`, and
20
- `recovery-envelope-v1`. Require `operations-stdin` or `compact-cli-json-v1` only
21
- when the host uses those features. Fail closed with an upgrade instruction when
22
- a required capability is absent. Never inspect `dist/`, minified source, or ZIP
23
- parts to compensate for a stale runtime.
44
+ `recovery-envelope-v1`. Require other capabilities only when used. Fail closed
45
+ when one is absent; never inspect bundles or ZIP parts as a fallback.
24
46
 
25
47
  ## Safety invariants
26
48
 
@@ -52,14 +74,6 @@ Choose and document these separately from safety invariants:
52
74
  | Reviewer identity | flag, operation author, environment, or fallback | `AI Redliner` is a valid visible fallback. `DOCX_REDLINE_AUTHOR` is an optional harness preference, not a guard. |
53
75
  | Output naming | derived sibling or explicit destination | Keep source immutability unless in-place mutation is deliberately authorized. |
54
76
 
55
- Examples of valid profile composition:
56
-
57
- ```bash
58
- docx-redline apply input.docx --operations operations.json --profile agent --output reviewed.docx
59
- docx-redline apply input.docx --operations operations.json --profile agent --atomic --output reviewed.docx
60
- docx-redline apply input.docx --operations operations.json --profile agent --existing-revisions slice-cross-author --output reviewed.docx
61
- ```
62
-
63
77
  Check `effectiveOptions` rather than assuming the resolved transaction,
64
78
  revision, author, or redline policy.
65
79
 
@@ -80,16 +94,34 @@ return the full structured result rather than recreating the CLI serializer.
80
94
 
81
95
  ## Ordinary generated workflow
82
96
 
83
- The first executable document-editing example in a generated skill should be a
84
- focused contextual extraction:
97
+ For an exact mechanical edit whose existing and replacement literals are known,
98
+ the first executable example should use the one-turn fast path:
99
+
100
+ ```bash
101
+ docx-redline apply input.docx --find "thirty (30) days" --replace "sixty (60) days" --profile agent --output reviewed.docx
102
+ ```
103
+
104
+ If the literal is not globally unique, scope it with a meaningful visible
105
+ anchor. A heading followed by a multi-paragraph provision should use a
106
+ directional window such as `--search "Section 4.1" --context-range 1:3`;
107
+ `--around 3` is symmetric and should be used only when either side is eligible.
108
+ Require the returned localized `change` evidence, including `committed: true`
109
+ and `verification.acceptedViewMatchesCompiledText: true`.
110
+
111
+ Semantic requests such as “make this provision mutual” still begin with focused
112
+ contextual extraction because the agent must identify and draft the complete
113
+ legal change:
85
114
 
86
115
  ```bash
87
- docx-redline extract input.docx --search "force majeure" --around 3
116
+ docx-redline extract input.docx --search "termination" --around 3
88
117
  ```
89
118
 
90
- Use `selection.nextAfter` with `--after` when truncated. Apply once per stable
91
- batch. Run `docx-redline apply --help` for canonical redline, whole-paragraph
92
- comment, and rejected-view restore shapes; the operation schema remains
119
+ Use `selection.nextAfter` with `--after` when truncated. When a search for
120
+ deleted or restorable content yields 0 matches in accepted view, follow
121
+ `selection.hint` and re-run with `--view rejected`. Apply once per stable batch.
122
+ Run `docx-redline apply --help` for canonical redline, whole-paragraph comment,
123
+ and rejected-view restore shapes; CLI help documentation fields return canonical
124
+ GitHub URLs. The operation schema remains
93
125
  [document-operations.schema.json](schemas/document-operations.schema.json).
94
126
 
95
127
  ## Recovery contract
@@ -116,8 +148,15 @@ an exact machine target with a human-facing reference.
116
148
 
117
149
  ## Generation checklist
118
150
 
151
+ - The exact tested library release is recorded and pinned; floating installs
152
+ are rejected while the library remains before 1.0.
153
+ - The required CLI contract version and minimum capability set are declared,
154
+ checked at runtime, and updated only after compatibility tests pass.
119
155
  - Runtime version and required capabilities are checked once.
120
- - The first ordinary edit command is focused `extract --search ... --around`.
156
+ - Literal edits use localized replacements and one-turn speculative apply;
157
+ semantic drafting starts with focused extraction.
158
+ - Successful localized edits require committed, post-mutation `change`
159
+ verification before completion is reported.
121
160
  - Safety invariants are not mixed with transaction or revision-policy choices.
122
161
  - Operations-file and stdin examples use structured serialization.
123
162
  - The four-field recovery contract precedes any diagnostic commentary.
@@ -0,0 +1,199 @@
1
+ ## @ansonlai/docx-redline-js v0.7.0
2
+
3
+ Version 0.7.0 targets the remaining latency in AI-driven document editing: tool
4
+ turns and generated paragraph text. It adds exact localized replacements,
5
+ fail-closed one-turn apply, directional provision scoping, and compact verified
6
+ change evidence while retaining the existing OOXML mutation pipeline.
7
+
8
+ The engine remains OOXML-only and host-independent. This release adds no runtime
9
+ dependency and does not require Microsoft Word, Office automation, COM, or a
10
+ proprietary document API. Existing reconciliation, tracked-change generation,
11
+ package validation, rollback, comment preservation, and Accept/Reject semantics
12
+ remain authoritative.
13
+
14
+ ---
15
+
16
+ ### Breaking Changes & Migration
17
+
18
+ - **CLI contract version 8:** Wrappers using the new fast path should require
19
+ `localized-replacements-v1`, `speculative-search-apply-v1`, and
20
+ `localized-change-summary-v1`. Negotiate only the capabilities actually used.
21
+ - **Pre-1.0 integration pinning:** Skills, MCP servers, and harnesses should pin
22
+ the exact `0.7.0` package release they tested and declare contract 8 plus their
23
+ minimum capability set. Treat another release or contract as unverified until
24
+ compatibility tests pass.
25
+ - **No operation-shape removal:** Existing operations with complete `modified`
26
+ content continue to work. Localized replacements and `change` results are
27
+ additive; consumers ignoring unknown result fields remain compatible.
28
+
29
+ ---
30
+
31
+ ### 1. Localized Exact Replacements
32
+
33
+ A text operation can now provide exact replacement instructions instead of
34
+ reproducing the complete paragraph:
35
+
36
+ ```json
37
+ {
38
+ "type": "redline",
39
+ "target": { "paragraphId": "1A2B3C4D" },
40
+ "replacements": [
41
+ {
42
+ "find": "thirty (30) days",
43
+ "replace": "sixty (60) days"
44
+ }
45
+ ]
46
+ }
47
+ ```
48
+
49
+ The compiler resolves the source paragraph against the immutable batch-start
50
+ accepted view, applies non-overlapping patches simultaneously, synthesizes the
51
+ complete desired text, and passes it through the ordinary reconciliation,
52
+ validation, receipt, and rollback pipeline.
53
+
54
+ V1 is deliberately narrow:
55
+
56
+ - one accepted-view paragraph;
57
+ - exact, case-sensitive source matching;
58
+ - optional positive, 1-based `occurrence` within that paragraph;
59
+ - an empty `replace` may delete a span;
60
+ - ambiguous, missing, no-op, overlapping, or conflicting patches fail before
61
+ mutation; and
62
+ - captures, rejected-view mutation, created-content dependencies, and
63
+ cross-paragraph patches remain outside localized-replacement v1.
64
+
65
+ ### 2. One-Turn Speculative Apply
66
+
67
+ Globally unique literal edits no longer require preliminary extraction:
68
+
69
+ ```bash
70
+ docx-redline apply contract.docx --find "thirty (30) days" --replace "sixty (60) days" --profile agent --output reviewed.docx
71
+ ```
72
+
73
+ For a heading followed by a multi-paragraph provision, use a visible text anchor
74
+ and directional paragraph scope:
75
+
76
+ ```bash
77
+ docx-redline apply contract.docx --search "Section 4.1" --context-range 1:3 --find "thirty (30) days" --replace "sixty (60) days" --profile agent --output reviewed.docx
78
+ ```
79
+
80
+ `1:3` means strictly the next three physical paragraphs, excluding the heading
81
+ and preceding paragraphs. Other supported forms include `0:0`, `0:3`,
82
+ `-3:-1`, and `-3:3`; offsets are inclusive, bounded to `-20..20`, and clamped at
83
+ document boundaries. `--around 3` is shorthand for `-3:3`.
84
+
85
+ Every matching search anchor contributes a window. The library unions and
86
+ deduplicates those windows, then requires exactly one eligible paragraph to
87
+ contain the exact `find` literal. Thus a visible section number may appear both
88
+ as a heading and in cross-references without the anchor itself deciding what is
89
+ edited. `--occurrence` may disambiguate only inside the uniquely selected
90
+ paragraph; it never chooses between paragraphs.
91
+
92
+ ### 3. Refusal Without Output Damage
93
+
94
+ Speculation remains conservative:
95
+
96
+ - no contextual anchor returns `TARGET_NOT_FOUND`;
97
+ - no exact patch source returns `PATCH_SOURCE_NOT_FOUND`;
98
+ - multiple eligible paragraphs return `AMBIGUOUS_TARGET`;
99
+ - multiple source spans within one paragraph return
100
+ `AMBIGUOUS_PATCH_SOURCE`; and
101
+ - invalid ranges and mixed targeting forms return a request error.
102
+
103
+ These failures include machine recovery metadata and bounded candidates. They
104
+ occur before output writing, so an existing destination is not truncated or
105
+ overwritten. The source remains immutable unless `--in-place` is explicit.
106
+
107
+ ### 4. Explicit Post-Mutation Change Evidence
108
+
109
+ Successful localized operations return a compact evidence object:
110
+
111
+ ```json
112
+ {
113
+ "change": {
114
+ "kind": "localized_replacement",
115
+ "committed": true,
116
+ "finalDisposition": "applied",
117
+ "target": {
118
+ "paragraphId": "1A2B3C4D",
119
+ "humanReference": "Section 4.1 — Termination"
120
+ },
121
+ "context": {
122
+ "search": "Section 4.1",
123
+ "range": "1:3",
124
+ "anchorMatchCount": 2
125
+ },
126
+ "replacements": [
127
+ {
128
+ "find": "thirty (30) days",
129
+ "replace": "sixty (60) days",
130
+ "beforeExcerpt": "...thirty (30) days...",
131
+ "afterExcerpt": "...sixty (60) days..."
132
+ }
133
+ ],
134
+ "verification": {
135
+ "acceptedViewMatchesCompiledText": true
136
+ }
137
+ }
138
+ }
139
+ ```
140
+
141
+ Evidence is derived from the resolved source and actual post-mutation accepted
142
+ view rather than simply echoing the request. Excerpts are deterministically
143
+ bounded to 120 characters. Agent completion additionally requires committed,
144
+ applied evidence and positive accepted-view verification. Atomic rollback marks
145
+ previously attempted evidence `committed: false` and `rolled_back`.
146
+
147
+ ### 5. Agent Guidance and Development Wrapper
148
+
149
+ - Agent Fast Start, the repository launch card, Skill Authoring Contract,
150
+ README, CLI help, and the advanced knowledge base now distinguish exact
151
+ mechanical edits from semantic drafting.
152
+ - Literal names, dates, numbers, defined terms, and isolated phrase changes can
153
+ use localized one-turn apply. Semantic requests such as “make this provision
154
+ mutual” still begin with focused extraction and drafting.
155
+ - The skill-authoring contract warns pre-1.0 integrations to pin the exact
156
+ package release and required CLI contract/capabilities.
157
+ - `examples/agent-session-wrapper.mjs` remains a development-only illustration,
158
+ not a package export or alternate mutation engine.
159
+
160
+ ---
161
+
162
+ ### Performance Results
163
+
164
+ The controlled `npm run benchmark:localized` comparison uses the same runtime
165
+ for both paths, with 3 warmups and 11 measured iterations per case:
166
+
167
+ - tool turns fell from 2 to 1 (**50% reduction**);
168
+ - generated request bytes fell **65.06%–79.39%**;
169
+ - the deterministic request-token proxy fell **64.77%–78.98%**; and
170
+ - median native engine/I/O time ranged from **0.58% slower to 5.41% faster**,
171
+ confirming that the intended savings are primarily outside the OOXML engine.
172
+
173
+ The token proxy is `ceil(UTF-8 request bytes / 4)`, not a provider tokenizer or
174
+ billed-token measurement. Provider reasoning, streaming, network, and full
175
+ Claude/OpenCode wall time were not estimated. See the
176
+ [localized rollout audit](../validation-reports/2026-09-14-localized-patching-rollout.md).
177
+
178
+ ### Verification
179
+
180
+ - `npm test`: **113 passed, 0 failed**
181
+ - `npm run check:types`: declarations verified for **123 runtime exports**
182
+ - `npm run test:isolation`: dependency and Word-API isolation passed
183
+ - Focused CLI/compiler/test/benchmark lint: passed
184
+ - Package dry run: compiler and published guidance included; development-only
185
+ benchmark and wrapper excluded
186
+
187
+ ---
188
+
189
+ ### Installation
190
+
191
+ ```bash
192
+ npm install @ansonlai/docx-redline-js@0.7.0
193
+ ```
194
+
195
+ CDN (ESM):
196
+
197
+ ```html
198
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@ansonlai/docx-redline-js@0.7.0/dist/docx-redline-js.esm.min.js"></script>
199
+ ```
@@ -38,6 +38,16 @@
38
38
  },
39
39
  "additionalProperties": false
40
40
  },
41
+ "localizedReplacement": {
42
+ "type": "object",
43
+ "required": ["find", "replace"],
44
+ "properties": {
45
+ "find": { "type": "string", "minLength": 1 },
46
+ "replace": { "type": "string" },
47
+ "occurrence": { "type": "integer", "minimum": 1 }
48
+ },
49
+ "additionalProperties": false
50
+ },
41
51
  "target": {
42
52
  "oneOf": [
43
53
  { "type": "string", "minLength": 1 },
@@ -99,6 +109,9 @@
99
109
  },
100
110
  "additionalProperties": false
101
111
  },
112
+ {
113
+ "allOf": [ { "$ref": "#/$defs/base" }, { "type": "object", "required": ["replacements"], "properties": { "type": { "enum": ["redline", "replace"] }, "replacements": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/localizedReplacement" } } } } ]
114
+ },
102
115
  {
103
116
  "allOf": [ { "$ref": "#/$defs/base" }, { "type": "object", "required": ["modified"], "properties": { "type": { "enum": ["redline", "replace", "format", "list-change", "table-reconciliation", "insert"] }, "modified": { "type": "string" }, "structuredContent": { "type": "boolean" }, "targetEnd": { "$ref": "#/$defs/target" }, "targetEndRef": { "type": ["integer", "string", "null"] }, "anchor": { "$ref": "#/$defs/rejectedTextInsertionAnchor" } } } ]
104
117
  },
@@ -0,0 +1,90 @@
1
+ # Localized Patching and Turn-Reduction Rollout Audit
2
+
3
+ **Date:** 2026-09-14
4
+ **Scope:** WP-05 correctness matrix and controlled workflow benchmark for CLI
5
+ contract 8
6
+
7
+ ## Outcome
8
+
9
+ The contract-8 literal fast path removes one of two tool turns and reduces the
10
+ generated mutation request by roughly two-thirds to four-fifths in the measured
11
+ cases. Native DOCX execution remains essentially the same speed: median changes
12
+ ranged from 0.58% slower to 5.41% faster. This is the intended result—the
13
+ feature attacks agent turn and output-generation latency without replacing the
14
+ OOXML reconciliation or validation pipeline.
15
+
16
+ All successful candidates produced the expected accepted-view text, positive
17
+ localized change verification, and a byte-identical source document. Refused
18
+ speculation remained non-writing in the automated suite.
19
+
20
+ ## Controlled comparison
21
+
22
+ Run:
23
+
24
+ ```bash
25
+ npm run benchmark:localized
26
+ ```
27
+
28
+ The benchmark uses `tests/fixtures/sample_doc_test.docx`, 3 warmups, and 11
29
+ measured iterations per workflow. Both paths run on the same current source
30
+ tree to isolate workflow shape from runtime or machine drift:
31
+
32
+ - **0.6.2-style baseline:** focused `extract`, followed by a canonical
33
+ full-paragraph operation.
34
+ - **Contract-8 candidate:** targetless localized `apply`, either globally or
35
+ within a directional heading scope.
36
+
37
+ | Case | Tool turns | Request bytes | Token proxy | Median local ms | p95 local ms |
38
+ |---|---:|---:|---:|---:|---:|
39
+ | Short punctuation, baseline → candidate | 2 → 1 | 244 → 79 | 61 → 20 | 55.34 → 53.37 | 83.89 → 62.11 |
40
+ | Long provision, baseline → candidate | 2 → 1 | 352 → 123 | 88 → 31 | 58.02 → 54.88 | 70.04 → 59.44 |
41
+ | Directional heading, baseline → candidate | 2 → 1 | 626 → 129 | 157 → 33 | 56.46 → 56.79 | 77.35 → 63.92 |
42
+
43
+ Observed reductions:
44
+
45
+ - Tool turns: **50%** in every case.
46
+ - Generated request bytes: **65.06%–79.39%**.
47
+ - Deterministic token proxy: **64.77%–78.98%**.
48
+ - Median local engine/I/O time: **-0.58%–5.41%** (effectively neutral).
49
+ - p95 local engine/I/O time: **15.13%–25.96% lower** in this run; timing is
50
+ observational and not a correctness gate.
51
+
52
+ The directional candidate returned 20 more response bytes than its two-turn
53
+ baseline because its one response includes explicit location and before/after
54
+ verification. That small cost is intentional: it removes the verification turn
55
+ while making the applied change auditable.
56
+
57
+ ## Measurement boundary
58
+
59
+ `generatedTokenProxy` is `ceil(UTF-8 request bytes / 4)`. It is a deterministic
60
+ comparison aid, not a provider tokenizer or billed-token count. Local timing
61
+ uses `performance.now()` and includes DOCX reads, inspection, mutation,
62
+ validation, and output writing.
63
+
64
+ The benchmark does **not** measure model reasoning, token streaming, tool
65
+ transport, network latency, or end-to-end Claude/OpenCode wall time. Those
66
+ components require external harness transcript instrumentation and must not be
67
+ inferred from native timing. The JSON artifact is written to
68
+ `tmp/benchmarks/localized-turn-reduction-latest.json`.
69
+
70
+ ## Correctness coverage
71
+
72
+ The expanded suites cover:
73
+
74
+ - simultaneous localized replacements, ambiguity, deletion, no-op and overlap
75
+ rejection, unsupported v1 shapes, summary ordering, excerpt bounds, and
76
+ atomic rollback disposition;
77
+ - global speculative success; `0:0`, `0:3`, `1:3`, `-3:-1`, and `-3:3`
78
+ directional windows; boundary clamping; repeated-anchor window deduplication;
79
+ missing anchors and patch sources; multi-paragraph and same-paragraph
80
+ ambiguity; occurrence scoping; stale IDs; protected outputs; response bounds;
81
+ and agent-profile exit behavior.
82
+
83
+ ## Verification
84
+
85
+ - `npm test`: 113 suites passed, 0 failed with the expanded assertions.
86
+ - `npm run check:types`: 123 runtime exports have declarations.
87
+ - `npm run test:isolation`: dependency and Word-API isolation passed.
88
+ - Focused ESLint for the localized compiler, CLI, benchmark, and tests passed.
89
+ - `npm pack --dry-run --json`: 154 entries; the compiler and this report are
90
+ included, while the fixture-dependent benchmark script is excluded.
package/index.d.ts CHANGED
@@ -23,6 +23,8 @@ export type {
23
23
  DocumentOperationBatchResult,
24
24
  HighlightDocumentOperation,
25
25
  InsertionAffinity,
26
+ LocalizedReplacement,
27
+ LocalizedReplacementChange,
26
28
  OperationConflict,
27
29
  OperationDependencyPlan,
28
30
  OperationPreflightItemResult,