@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.
- package/AGENTS.md +19 -8
- package/CHANGELOG.md +43 -0
- package/README.md +57 -18
- package/dist/docx-redline-js.esm.js +29 -1
- package/dist/docx-redline-js.esm.js.map +2 -2
- package/dist/docx-redline-js.esm.min.js +66 -66
- package/dist/docx-redline-js.esm.min.js.map +3 -3
- package/docs/AGENT_FAST_START.md +22 -24
- package/docs/AGENT_KNOWLEDGE_BASE.md +33 -16
- package/docs/SKILL_AUTHORING.md +61 -22
- package/docs/releases/0.7.0.md +199 -0
- package/docs/schemas/document-operations.schema.json +13 -0
- package/docs/validation-reports/2026-09-14-localized-patching-rollout.md +90 -0
- package/index.d.ts +2 -0
- package/node/cli-help.js +30 -3
- package/node/cli.js +259 -34
- package/package.json +5 -1
- package/services/batch-operation-orchestrator.js +25 -16
- package/services/document-inspection.js +30 -0
- package/services/document-operation-applier.js +68 -9
- package/services/document-operation-contract.js +56 -5
- package/services/localized-replacement-compiler.js +304 -0
- package/services/operation-batch-compiler.js +33 -1
- package/services/operation-preflight.js +10 -6
- package/services/standalone-operation-runner.d.ts +55 -3
package/docs/AGENT_FAST_START.md
CHANGED
|
@@ -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
|
|
11
|
-
|
|
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.
|
|
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
|
|
21
|
+
docx-redline apply contract.docx --find "thirty (30) days" --replace "sixty (60) days" --profile agent --output reviewed.docx
|
|
24
22
|
```
|
|
25
23
|
|
|
26
|
-
|
|
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
|
-
|
|
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
|
-
`
|
|
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
|
|
44
|
-
|
|
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.
|
|
49
|
-
|
|
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
|
|
52
|
-
|
|
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.
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
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
|
-
|
|
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
|
-
|
|
497
|
-
per-operation error.
|
|
498
|
-
|
|
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.
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
530
|
+
# 7. Batch operations with ops.json
|
|
519
531
|
docx-redline apply contract.docx --operations operations.json --output reviewed.docx
|
|
520
532
|
|
|
521
|
-
#
|
|
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.
|
|
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
|
package/docs/SKILL_AUTHORING.md
CHANGED
|
@@ -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
|
|
17
|
-
typical shell skill should require
|
|
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
|
|
21
|
-
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
|
-
|
|
84
|
-
|
|
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 "
|
|
116
|
+
docx-redline extract input.docx --search "termination" --around 3
|
|
88
117
|
```
|
|
89
118
|
|
|
90
|
-
Use `selection.nextAfter` with `--after` when truncated.
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
-
|
|
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