@ansonlai/docx-redline-js 0.5.4 → 0.6.1

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.
Files changed (55) hide show
  1. package/AGENTS.md +82 -697
  2. package/ARCHITECTURE.md +13 -1
  3. package/CHANGELOG.md +8 -0
  4. package/README.md +177 -45
  5. package/core/paragraph-targeting.js +14 -2
  6. package/dist/docx-redline-js.esm.js +184 -51
  7. package/dist/docx-redline-js.esm.js.map +3 -3
  8. package/dist/docx-redline-js.esm.min.js +77 -77
  9. package/dist/docx-redline-js.esm.min.js.map +4 -4
  10. package/docs/AGENT_FAST_START.md +59 -0
  11. package/docs/AGENT_KNOWLEDGE_BASE.md +878 -0
  12. package/docs/SKILL_AUTHORING.md +126 -0
  13. package/docs/TESTING.md +35 -1
  14. package/docs/schemas/document-operations.schema.json +5 -1
  15. package/docs/validation-reports/2026-09-12-agent-cli-discovery-baseline.md +56 -0
  16. package/docs/validation-reports/2026-09-12-agent-protocol-rollout.md +86 -0
  17. package/docs/validation-reports/2026-09-13-agent-cli-efficiency-rollout.md +86 -0
  18. package/engine/oxml-engine.js +80 -13
  19. package/engine/run-builders.js +5 -15
  20. package/index.d.ts +28 -3
  21. package/node/cli-help.js +209 -0
  22. package/node/cli.js +323 -65
  23. package/node/docx-document.js +120 -69
  24. package/node/index.d.ts +6 -2
  25. package/package.json +15 -3
  26. package/scripts/generate-cross-author-slicing-fixtures.ps1 +25 -25
  27. package/services/batch-operation-orchestrator.js +215 -120
  28. package/services/document-inspection.js +89 -11
  29. package/services/document-operation-applier.js +52 -34
  30. package/services/document-operation-contract.js +10 -6
  31. package/services/document-operation-mutations.js +51 -5
  32. package/services/document-operation-session.js +4 -0
  33. package/services/error-recovery.js +174 -0
  34. package/services/operation-batch-compiler.js +394 -0
  35. package/services/operation-preflight.js +91 -72
  36. package/services/standalone-operation-runner.d.ts +17 -1
  37. package/docs/plans/2026-09-05-structural-revisions-and-fidelity-oracles.md +0 -1669
  38. package/docs/plans/2026-09-08-cross-author-revision-slicing.md +0 -1399
  39. package/docs/plans/completed/2026-03-01-release-0.1.4-design.md +0 -33
  40. package/docs/plans/completed/2026-03-01-release-0.1.4.md +0 -110
  41. package/docs/plans/completed/2026-05-31-architectural changes.md +0 -593
  42. package/docs/plans/completed/2026-08-02-reliability-improvements.md +0 -1155
  43. package/docs/plans/completed/2026-08-30-reliability-testing-improvements.md +0 -488
  44. package/docs/plans/completed/2026-09-01-performance-and-complexity-reduction.md +0 -669
  45. package/docs/plans/completed/2026-09-03-agent-friendly-document-workflows.md +0 -427
  46. package/docs/plans/completed/2026-09-04-comment-anchor-and-cli-reliability.md +0 -519
  47. package/docs/plans/completed/PERFORMANCE-CONSOLIDATION.md +0 -69
  48. package/docs/plans/completed/structural-revision-capability-matrix.md +0 -115
  49. package/docs/test-comparison-dashboard.html +0 -4338
  50. package/docs/validation-reports/2026-08-30-phase-1-word-visual-preflight.md +0 -22
  51. package/docs/validation-reports/2026-08-30-phase-2-word-visual-preflight.md +0 -24
  52. package/docs/validation-reports/2026-08-30-phase-3-coverage.md +0 -73
  53. package/docs/validation-reports/2026-09-02-multilevel-bullets-visual-review.md +0 -82
  54. package/docs/validation-reports/2026-09-02-multimodal-visual-samples.md +0 -114
  55. package/docs/validation-reports/2026-09-02-visual-failures-preflight.md +0 -79
package/ARCHITECTURE.md CHANGED
@@ -69,7 +69,13 @@ No Word add-in entrypoints or host-specific integration layers are part of this
69
69
 
70
70
  ## Entry Points
71
71
 
72
- - `index.js` (Root exports containing the reconciliation logic)
72
+ - `index.js`: primary host-independent exports for OOXML reconciliation.
73
+ - `services/standalone-operation-runner.js`: stable complete-document XML
74
+ operations, exported as `@ansonlai/docx-redline-js/standalone-runner`.
75
+ - `node/index.js`: Node-only complete-DOCX buffer facade, exported as
76
+ `@ansonlai/docx-redline-js/node`.
77
+ - `bin/docx-redline.js`: CLI launcher; command implementation lives in
78
+ `node/cli.js` and shared operation behavior lives in `services/`.
73
79
 
74
80
  ## Module Responsibilities
75
81
 
@@ -334,6 +340,12 @@ still be re-exported from `index.js`.
334
340
  - Operation-level authors override the batch author. Runtime results expose
335
341
  `authorUsed`, `authorsUsed`, `operationType`, `resolvedBy`, and resolved target
336
342
  metadata so integrations can audit what the engine actually selected.
343
+ - Target fingerprints are revision-view scoped. Inspection returns a
344
+ `revisionView` beside every paragraph and computes its fingerprint from the
345
+ same text/view pair. Restore normalization defaults omitted target and range
346
+ endpoint views to `rejected`; all other operations default to `accepted`.
347
+ Explicit views remain authoritative, and cross-view text/fingerprint mistakes
348
+ return an actionable mismatch hint rather than silently weakening targeting.
337
349
  - A normalized target match does not become an edit coordinate system for a
338
350
  text-bearing mutation. Mutation uses canonical accepted-view source text, and `resolvedTarget.targetTextMatch`
339
351
  records `exact`, `space_equivalent`, or `normalized` selection plus bounded
package/CHANGELOG.md CHANGED
@@ -9,9 +9,17 @@
9
9
  - **Exact mismatch diagnostics**: `PATCH_ROUNDTRIP_MISMATCH` now includes the expected and actual code points at the first mismatch. Document-operation results also report bounded `targetTextMatch` diagnostics when target selection used equivalent whitespace.
10
10
  - **Baseline-delta validation (WP09c)**: Restoration, operation, and package validation now compare issue multisets against the source. Unchanged legacy defects remain visible without blocking safe work, while any added occurrence or mutation-envelope error fails closed with `GENERATED_OOXML_INVALID` before an operation is reported as applied.
11
11
  - **Revision identity sanitation (WP09d)**: New paragraph/list builders inherit effective `pPr`/`rPr` formatting without cloning historical revision descendants. Operation-level whole-document validation catches duplicate revision IDs and rolls back the operation savepoint before committing its receipt.
12
+ - **View-consistent restore targeting**: `restore` targets now default to the rejected view, where a wholly deleted paragraph's source text exists. Rejected-view inspection now computes fingerprints from rejected-view text and reports the view beside each paragraph. Explicit cross-view text or fingerprint mistakes retain strict refusal while returning an actionable view hint.
12
13
 
13
14
  ### New Features
14
15
 
16
+ - **Self-describing and bounded agent discovery (WP-00–WP-02)**: CLI contract version 6 adds command-specific JSON help, canonical redline/comment/restore examples, case-insensitive contextual search with `--around`/`--context`/`-C`, direct-hit pagination through `--limit` and `--after`, and deliberate `--all` opt-out. Unscoped inspection is capped at 20 direct records and a 48 KiB soft budget without truncating any returned `exactText`; extraction now distinguishes matches from context and prioritizes human-facing provision/heading references over machine paragraph ordinals.
17
+ - **Composable agent safety and compact output (WP-03–WP-04)**: CLI contract version 7 replaces the atomic-coupled agent profile capability with `agent-safety-profile-v2`. `--profile agent` now enforces complete-success exits while preserving progressive execution and the ordinary revision policy; `--atomic` and `--existing-revisions` compose explicitly. Compact CLI JSON keeps receipts only in the authoritative top-level array, omits exact-match diagnostics, summarizes successful equivalent-whitespace matches, and supports one-line `--compact` output without changing Node or standalone-runner results.
18
+ - **Packaged skill-authoring contract (WP-05)**: `docs/SKILL_AUTHORING.md` separates automation invariants from transaction/revision policy, file-versus-stdin transport, reviewer preferences, recovery-envelope behavior, and human-facing presentation. It requires contract/capability negotiation, focused contextual extraction, and library delegation while retaining the visible `AI Redliner` fallback without a new author guard.
19
+ - **Batch-start source binding (WP-04)**: Strong document-operation targets are compiled once against the immutable source DOM and carried through structural index/fingerprint drift with rollback-aware session identities. Independent edits no longer need manual bottom-up sorting; same-source writes, incompatible revision/format combinations, and unsafe capture fan-out fail before mutation with causal conflict codes. Unique references to paragraph text created elsewhere in the same batch become explicit internal capture dependencies.
20
+ - **Machine-actionable recovery (WP-05)**: Operation, package-facade, example-session, and compact CLI failures now carry recovery envelope version 1 with stable stage/category/action metadata, bounded corrective context, and authorization flags. Failed and partial mutation results include an explicit original-vs-output retry plan and operation indexes. `apply --require-complete` exits with code 3 for partial work while preserving legacy behavior without the flag.
21
+ - **Compact shell-agent protocol (WP-06)**: CLI contract version 5 adds `operations-stdin` and `agent-profile-v1`. `--operations -` accepts UTF-8 operation arrays/envelopes without a temporary operations file, while explicit `--profile agent` combines atomic rollback and complete-success exit behavior and reports its effective settings. `AGENTS.md` is now a 527-word routing card, and the 349-word `docs/AGENT_FAST_START.md` carries the ordinary edit contract. Ambient project configuration was deliberately deferred because it would save only the profile flag while adding hidden state.
22
+ - **Agent rollout audit (WP-07)**: The observational benchmark now compares canonical Node, legacy file-based CLI, compact stdin/profile CLI, and the development session example while verifying accepted/rejected text, comment preservation, independent batch permutations, recovery behavior, and cross-author attribution. The checked run records 82.75% fewer ordinary instruction words, one fewer shell tool turn (33.33%), and 82.22–89.96% smaller localized session requests than canonical Node envelopes without claiming unmeasured provider/model latency.
15
23
  - **Explicit paragraph restoration (`type: 'restore'`)**: Restores or counterproposes another reviewer's pending whole-paragraph deletion as a separately tracked sibling paragraph. The source deletion remains untouched; the restored paragraph receives its own inserted paragraph mark, content insertion, sanitized paragraph properties, and fresh `w14:paraId`. Single paragraphs and contiguous ranges are supported, with full Accept/Reject lifecycle verification and structured refusals at unsafe table-row, move, section-break, and terminal-paragraph boundaries.
16
24
  - **Compact mutation CLI contract (WP09b)**: CLI contract version 3 removes `documentXml`, OOXML/package artifacts, full inspection data, and full validation issue arrays from normal `apply`, `accept`, `reject`, and `delete-comments` stdout. Mutation responses retain actionable errors, per-operation receipts, output durability fields, code/count validation summaries, and a derived `completion` flag that cannot report success for failed, partial, or unwritten work.
17
25
  - **Word-native deleted-section editing (WP09e)**: An explicit rejected-view `insert` operation can split a foreign deletion at an exact anchor-relative offset into sibling `del(A) / ins(B) / del(A)` carriers. Contiguous paragraph restorations now follow their untouched deleted source block, matching Microsoft Word's ordering. Ambiguous anchors and unsupported structural split boundaries remain fail-closed.
package/README.md CHANGED
@@ -20,13 +20,45 @@ Converts AI-generated or programmatic text/markdown edits into valid Office Open
20
20
  - Zero host dependencies: works in Node.js, browsers, Deno, and similar JS runtimes with DOM parsing support
21
21
  ## Documentation Index
22
22
 
23
- | Document | Description |
24
- |---|---|
25
- | **[README.md](./README.md)** | Library overview, installation, quick start, and public API reference |
26
- | **[AGENTS.md](./AGENTS.md)** | AI coding agent quick reference, targeting rules, and complete CLI workflow |
23
+ | Document | Description |
24
+ |---|---|
25
+ | **[README.md](./README.md)** | Library overview, installation, quick start, and public API reference |
26
+ | **[docs/AGENT_FAST_START.md](./docs/AGENT_FAST_START.md)** | Compact ordinary-edit protocol for structured tools and shell-only agents |
27
+ | **[AGENTS.md](./AGENTS.md)** | Short repository launch card for task routing and contributor verification |
28
+ | **[docs/AGENT_KNOWLEDGE_BASE.md](./docs/AGENT_KNOWLEDGE_BASE.md)** | Full agent reference, CLI workflow, operation examples, error recovery, options, and gotchas |
27
29
  | **[ARCHITECTURE.md](./ARCHITECTURE.md)** | Contributor architecture, module responsibilities, end-to-end data flow, and contracts |
28
30
  | **[docs/TESTING.md](./docs/TESTING.md)** | Complete testing guide, test lanes, independent oracle validation, and Word visual review checklist |
29
- | **[CHANGELOG.md](./CHANGELOG.md)** | Release history, breaking changes, and migration notes |
31
+ | **[CHANGELOG.md](./CHANGELOG.md)** | Release history, breaking changes, and migration notes |
32
+
33
+ ## Repository Layout
34
+
35
+ The package exposes three levels of API:
36
+
37
+ | Level | Entry point | Use it for |
38
+ |---|---|---|
39
+ | Host-independent OOXML API | `index.js` | Paragraph/range transforms and exported OOXML utilities in browsers, Node.js, or another DOM-capable runtime |
40
+ | Standalone document XML runner | `services/standalone-operation-runner.js` | Applying operations to a complete `word/document.xml` string |
41
+ | Node/DOCX API and CLI | `node/index.js`, `bin/docx-redline.js` | Reading, changing, validating, and writing complete `.docx` ZIP packages |
42
+
43
+ Implementation folders have distinct roles: `core/` holds shared OOXML and
44
+ targeting primitives; `pipeline/` handles ingestion, diffing, markdown, lists,
45
+ and serialization; `engine/` performs reconciliation; `services/` coordinates
46
+ document operations and package artifacts; `node/` contains Node-only ZIP and
47
+ whole-document code. Tests are directly runnable `tests/*.mjs` files, while
48
+ `tests/helpers/` and `tests/fixtures/` contain support code and data.
49
+
50
+ Contributors and coding agents should start with the routing table in
51
+ [AGENTS.md](./AGENTS.md#pick-the-route) before exploring the tree. The full
52
+ dependency and ownership map is in [ARCHITECTURE.md](./ARCHITECTURE.md).
53
+
54
+ For document-operation JSON, choose operations by the desired output structure,
55
+ not by the everyday meaning of the type name. `redline` and `replace` provide
56
+ ordinary text replacement; `list-change` and `table-reconciliation` provide
57
+ structural intent; and ordinary `insert` is a compatibility alias of the
58
+ redline path unless it includes a rejected-view target and anchor. In every
59
+ ordinary text-bearing operation, `modified` is the complete desired content for
60
+ the target. See the [operation model](./docs/AGENT_KNOWLEDGE_BASE.md#operation-model-choose-by-output-shape)
61
+ and the [JSON schema](./docs/schemas/document-operations.schema.json).
30
62
 
31
63
  ## Install
32
64
 
@@ -112,10 +144,13 @@ import { inspectDocumentParts } from '@ansonlai/docx-redline-js';
112
144
  const inventory = inspectDocumentParts({ documentXml, commentsXml, numberingXml });
113
145
  ```
114
146
 
115
- Inspection returns exact paragraph text, target IDs/fingerprints, headings,
116
- table/list context, revision authors, and joined comment anchors. Filters such
117
- as `search`, `indexes`, `range`, `revisedOnly`, `inTable`, and `skipEmpty`
118
- limit output. `revisionView` accepts `accepted`, `rejected`, or `current`.
147
+ Inspection returns exact paragraph text, target IDs/fingerprints, headings,
148
+ table/list context, revision authors, and joined comment anchors. Filters such
149
+ as `search`, `indexes`, `range`, `revisedOnly`, `inTable`, and `skipEmpty`
150
+ limit output. Search is a case-insensitive substring match; `around` adds nearby
151
+ drafting context, while `limit` and `after` page direct hits. `revisionView`
152
+ accepts `accepted`, `rejected`, or `current`. Returned paragraphs identify
153
+ matches versus context and include `humanReference` for user-facing summaries.
119
154
 
120
155
  For complete `.docx` buffers in Node:
121
156
 
@@ -128,21 +163,62 @@ const result = await document.applyOperations(operations, {
128
163
  const outputBuffer = result.toBuffer();
129
164
  ```
130
165
 
131
- The Node facade performs edits, artifact merges, package wiring, validation,
132
- and commit as one transaction. It defaults to strict targets and returns the
133
- untouched input with `written: false` on atomic failure. It is isolated from
134
- the root/browser dependency graph.
135
-
136
- Install `@xmldom/xmldom` alongside the package when using the Node facade or
137
- CLI; it remains an optional peer so browser consumers do not install a DOM shim.
138
-
139
- ### Agent CLI
166
+ The Node facade performs edits, artifact merges, package wiring, validation,
167
+ and commit as one transaction. It defaults to strict targets and returns the
168
+ untouched input with `written: false` on atomic failure. It is isolated from
169
+ the root/browser dependency graph.
170
+
171
+ Install `@xmldom/xmldom` alongside the package when using the Node facade or
172
+ CLI; it remains an optional peer so browser consumers do not install a DOM shim.
173
+
174
+ #### Example agent session wrapper (development only)
175
+
176
+ [`examples/agent-session-wrapper.mjs`](./examples/agent-session-wrapper.mjs)
177
+ demonstrates how a custom agent harness can keep one `DocxDocument` open, return
178
+ short revision-bound target handles, apply safe defaults once, and translate a
179
+ narrow edit request into canonical document operations:
180
+
181
+ ```js
182
+ import { readFile } from 'node:fs/promises';
183
+ import { createExampleAgentSession } from './examples/agent-session-wrapper.mjs';
184
+
185
+ const session = createExampleAgentSession(await readFile('contract.docx'), {
186
+ profile: { author: 'Editor' }
187
+ });
188
+ const inspection = session.inspect({ search: 'termination', around: 2 });
189
+ const clause = inspection.targets.find(target => target.role === 'match');
190
+ const result = await session.applyEdits([{
191
+ target: clause.handle,
192
+ replacements: [{
193
+ find: 'The Company may terminate',
194
+ replace: 'Either party may terminate'
195
+ }]
196
+ }]);
197
+ ```
198
+
199
+ This file is a testable sample, not a package export or supported alternate
200
+ mutation engine. It delegates to `@ansonlai/docx-redline-js/node`, is excluded
201
+ from the published package files, and is intended to help MCP servers, Claude
202
+ skills, OpenCode tools, and other custom harnesses design thin integrations.
203
+ The sample binds each handle to the inspected package revision and view, returns
204
+ new handles after successful mutations, and expands localized exact replacements
205
+ into complete desired paragraph text before delegating to the canonical redline
206
+ operation. Duplicate matches require an explicit `occurrence`; missing,
207
+ ambiguous, overlapping, and conflicting patches fail before document mutation.
208
+ From a source checkout, run `npm run benchmark:agent` to compare its native
209
+ execution and serialized request size with a canonical stateless Node workflow.
210
+ The example and its benchmark are excluded from the published package. The
211
+ benchmark explicitly does not claim to measure LLM reasoning or provider/tool
212
+ latency. Checked comparative results are in the
213
+ [agent protocol rollout audit](./docs/validation-reports/2026-09-12-agent-protocol-rollout.md).
214
+
215
+ ### Agent CLI
140
216
 
141
- ```bash
142
- docx-redline extract contract.docx --range 10:30
143
- docx-redline preflight contract.docx --operations operations.json --author "Editor"
144
- docx-redline apply contract.docx --operations operations.json --author "Editor" --output reviewed.docx
145
- docx-redline validate reviewed.docx
217
+ ```bash
218
+ docx-redline extract contract.docx --search "termination" --around 3
219
+ docx-redline preflight contract.docx --operations operations.json --author "Editor"
220
+ docx-redline apply contract.docx --operations operations.json --author "Editor" --output reviewed.docx
221
+ docx-redline validate reviewed.docx
146
222
  ```
147
223
 
148
224
  ```bash
@@ -155,21 +231,47 @@ docx-redline apply contract.docx --target "Typo fix" --modified "Fixed typo" --n
155
231
  # Cross-author edit inside another reviewer's pending insertion
156
232
  docx-redline apply contract.docx --target "Another author's clause" --modified "Revised clause" --existing-revisions slice-cross-author --output reviewed.docx
157
233
 
158
- # High-assurance atomic batch
159
- docx-redline apply contract.docx --operations operations.json --atomic --output reviewed.docx
234
+ # High-assurance atomic batch with nonzero exit on any incomplete result
235
+ docx-redline apply contract.docx --operations operations.json --atomic --require-complete --output reviewed.docx
236
+
237
+ # Agent shell path: JSON is emitted by a serializer, not interpolated by the shell
238
+ node emit-operations.mjs | docx-redline apply contract.docx --operations - --profile agent --compact --output reviewed.docx
160
239
  ```
161
240
 
162
241
  All commands emit JSON on stdout. `apply` defaults:
163
242
  - **Author**: Defaults to `'AI Redliner'` (or `DOCX_REDLINE_AUTHOR` environment variable).
164
243
  - **Output overwrite**: Destination files provided via `--output` overwrite by default. Pass `--no-overwrite` or `--no-clobber` to safeguard existing destination files. The source input is never overwritten unless `--in-place` is specified.
165
244
  - **Existing revisions**: Defaults to `'merge-same-author'`. Pass `--existing-revisions slice-cross-author` to edit inside another reviewer's pending insertions with native carrier slicing.
166
- - **Transactionality**: Defaults to `atomic: false` (applies valid operations and reports any failures). Pass `--atomic` for all-or-nothing rollback on any operation error.
245
+ - **Transactionality**: Defaults to `atomic: false` (applies valid operations and reports any failures). Pass `--atomic` for all-or-nothing rollback on any operation error.
246
+ - **Complete-success exit**: Pass `--require-complete` when a progressive `partial` result must exit with code `3`; errors exit with code `2`. Without the flag, partial results retain the legacy zero exit code, so always inspect `completion`.
247
+ - **Agent profile**: `--profile agent` enables complete-success exit behavior while retaining the ordinary progressive transaction and existing-revision defaults. Compose it with `--atomic` or an explicit `--existing-revisions` policy when intended, and verify the resolved `effectiveOptions`.
248
+ - **Operations from stdin**: `--operations -` reads the same array or `{ operations, expectedRevision }` envelope accepted from a file. Feed it from a JSON serializer or structured process API, not shell-interpolated legal text.
249
+ - **Compact stdout**: `--compact` emits one-line mutation JSON. It changes serialization only, not operation semantics.
167
250
  - **Tracked changes**: Defaults to `generateRedlines: true`. Pass `--no-redlines` when clean direct text edits are desired.
168
251
  - **Inline edits**: Use `--target <text>` with `--modified <text>` or `--comment <text>` for quick one-liners without creating a JSON file.
169
- - **Compact mutation results**: `apply`, `accept`, `reject`, and `delete-comments` omit full OOXML/package payloads and inspection text from stdout. They report `written`, `outputPath`, per-operation results and receipts, compact validation counts, and a derived `completion` boolean. Use `validate` when full issue arrays are needed.
170
-
171
- See [the agent workflow in AGENTS.md](./AGENTS.md#agent-document-workflow-cli) and the
172
- [operation JSON Schema](docs/schemas/document-operations.schema.json).
252
+ - **Compact mutation results**: `apply`, `accept`, `reject`, and `delete-comments` omit full OOXML/package payloads and inspection text from stdout. CLI operation results omit duplicate nested receipt bodies; the ordered top-level `receipts` array is authoritative. Successful exact target-match diagnostics are omitted and equivalent-whitespace matches retain only mode/count. Node and standalone-runner results remain unchanged. Use `validate` when full issue arrays are needed.
253
+
254
+ Inspection commands default to 20 direct matches and a 48 KiB soft response
255
+ budget when no explicit positional scope is supplied. Use `--limit` with
256
+ `--after <paragraph-index>` to continue, `--around N` (aliases `--context` and
257
+ `-C`) to include nearby paragraphs, and `--all` only for deliberate unbounded
258
+ inspection. Every retained target is complete; an individually oversized
259
+ paragraph is returned whole with an `oversizeItem` marker. Machine `index` and
260
+ `ref` fields are for targeting and pagination, not user-facing Word locations;
261
+ use `humanReference`, `provision`, or `nearestHeading` in reports.
262
+
263
+ `docx-redline version` reports contract version 7 and the additive
264
+ `command-help-v1`, `inspection-context-v1`, `bounded-inspection-v1`,
265
+ `human-document-references-v1`, `batch-start-source-binding`,
266
+ `recovery-envelope-v1`, `require-complete-exit`, `operations-stdin`,
267
+ `agent-safety-profile-v2`, `deduplicated-cli-receipts`, and
268
+ `compact-cli-json-v1` capabilities. Wrappers should negotiate only the
269
+ capabilities they use. Run `docx-redline <command> --help` for that command's
270
+ machine-readable options, behavior, exit codes, and compact examples.
271
+
272
+ See the [compact agent fast start](./docs/AGENT_FAST_START.md), the
273
+ [skill/harness authoring contract](./docs/SKILL_AUTHORING.md), and the
274
+ [operation JSON Schema](docs/schemas/document-operations.schema.json).
173
275
 
174
276
  ### Configuration (call once at startup)
175
277
 
@@ -203,7 +305,7 @@ Common result fields:
203
305
  | Field | Purpose |
204
306
  |-------|---------|
205
307
  | `status` | Operation status: `'ok'`, `'partial'`, `'no-op'`, or `'error'`. |
206
- | `error` | Present on failure; includes a stable `code` such as `PARSE_ERROR`, `TARGET_NOT_FOUND`, `PARTIAL_TARGET`, `EXISTING_REVISIONS`, `DIFF_TOKEN_LIMIT`, or `BATCH_OPERATION_FAILED`. |
308
+ | `error` | Present on failure; retains a stable `code` and adds recovery envelope version, stage, category, bounded context, and a machine-readable recovery action. |
207
309
  | `written` | CLI/facade boolean indicating whether the output file was successfully written to disk. |
208
310
  | `completion` | CLI-only boolean that is `true` only when a destination was written, top-level status is neither error nor partial, and no operation result failed. |
209
311
  | `rolledBack` | Present and `true` when an atomic batch encountered an error and rolled back all changes. |
@@ -369,7 +471,17 @@ import {
369
471
  import { getParagraphText } from '@ansonlai/docx-redline-js/core/paragraph-targeting.js';
370
472
  ```
371
473
 
372
- Use `applyOperationsToDocumentXml(...)` for mixed batches. It stably runs comments before text-changing operations so replacements cannot invalidate their original anchors. Other operation types retain their relative order. Batch results retain each operation's original 1-based index and expose the actual `executionOrder`.
474
+ Use `applyOperationsToDocumentXml(...)` for mixed batches. It stably runs comments before text-changing operations so replacements cannot invalidate their original anchors. Other operation types retain their relative order. Batch results retain each operation's original 1-based index and expose the actual `executionOrder`.
475
+
476
+ Before mutation, the runner resolves strong source descriptors against the
477
+ immutable batch-start document and binds them to session-local source
478
+ identities. Independent edits therefore do not need to be manually sorted when
479
+ an earlier structural rewrite changes later paragraph indexes or fingerprints.
480
+ Targets that deliberately refer to uniquely created paragraph text are compiled
481
+ into an internal capture dependency. True overlap is not guessed: incompatible
482
+ writes to one source fail before mutation with `OVERLAPPING_SOURCE_TARGETS` or
483
+ `REVISION_ORDER_CONFLICT`, and mutating capture fan-out without distinct
484
+ selectors fails with `CAPTURE_FANOUT_CONFLICT`.
373
485
 
374
486
  Threaded replies use a comment operation with no body target:
375
487
 
@@ -392,12 +504,23 @@ serialization. Accuracy remains the controlling constraint: each operation has
392
504
  an internal savepoint so an error or no-op cannot leak a partial edit or consumed
393
505
  revision ID into later operations.
394
506
 
395
- Batches are atomic by default: any operation error returns the original
396
- `documentXml`, `hasChanges: false`, empty package artifacts, and
397
- `rolledBack: true`. The default `continueOnError: true` still attempts the full
398
- batch so `results` describes what would have applied. Callers that intentionally
399
- consume partial results must pass `{ atomic: false }`; use
400
- `{ continueOnError: false }` to stop after the first error.
507
+ Batches are progressive by default (`atomic: false`): valid operations commit
508
+ while failed operations remain unapplied and are reported in `results`. Pass
509
+ `{ atomic: true }` when any operation error must return the original
510
+ `documentXml`, `hasChanges: false`, empty package artifacts, and
511
+ `rolledBack: true`. The default `continueOnError: true` still attempts the full
512
+ batch so `results` describes every operation; use `{ continueOnError: false }`
513
+ to stop after the first error.
514
+
515
+ Every failed or partial mutation includes `retryPlan`. Its `base` is `original`
516
+ after rollback/no commit and `output` after a progressive partial commit;
517
+ `committedIndexes`, `failedIndexes`, and `unattemptedIndexes` identify the safe
518
+ replay scope. Errors use recovery envelope version 1 and always report
519
+ `sameArgumentsSafe: false`. Follow `error.recovery.action`; do not infer a retry
520
+ from prose. Authorization-sensitive actions, such as resolving comments, are
521
+ marked with `requiresUserAuthorization: true`. For `EXISTING_REVISIONS`, the
522
+ non-normalizing surgical recommendation is `slice-cross-author`; accepting or
523
+ rejecting prior revisions still requires explicit authority.
401
524
 
402
525
  Comment anchors use exact matching first, then a unique ASCII-space/NBSP
403
526
  equivalent match that preserves source offsets and text. Missing anchors return
@@ -449,10 +572,14 @@ guidance. Callers should pass `{ strictTargets: true }` and use strict descripto
449
572
 
450
573
  ### Mutation Receipts
451
574
 
452
- Both single-operation (`applyOperationToDocumentXml`) and batch
453
- (`applyOperationsToDocumentXml`) results expose commit-aware **Mutation Receipts**
454
- (`result.receipt` on single results and per-item `results[i].receipt`, plus `result.receipts`
455
- for the full batch).
575
+ Both single-operation (`applyOperationToDocumentXml`) and batch
576
+ (`applyOperationsToDocumentXml`) results expose commit-aware **Mutation Receipts**
577
+ (`result.receipt` on single results and per-item `results[i].receipt`, plus `result.receipts`
578
+ for the full batch).
579
+
580
+ This full receipt shape is retained by the Node facade and standalone runner.
581
+ Only compact CLI JSON removes duplicate `results[i].receipt` bodies and keeps
582
+ the ordered top-level `receipts` array.
456
583
 
457
584
  ```js
458
585
  const result = await applyOperationsToDocumentXml(documentXml, operations, 'Agent');
@@ -541,7 +668,8 @@ const restoration = await applyOperationToDocumentXml(
541
668
  documentXml,
542
669
  {
543
670
  type: 'restore',
544
- target: { paragraphId: '1A2B3C4D', revisionView: 'rejected' },
671
+ // restore targets default to the rejected view, where deleted text exists
672
+ target: { paragraphId: '1A2B3C4D', exactText: 'Original deleted paragraph text.' },
545
673
  modified: 'Restored or adjusted paragraph text.'
546
674
  },
547
675
  'Editor'
@@ -551,6 +679,8 @@ const restoration = await applyOperationToDocumentXml(
551
679
  // restoration follows the complete deleted source block. Unchanged legacy
552
680
  // validation defects are retained as baseline issues; newly generated errors
553
681
  // fail closed before commit.
682
+ // inspect/extract descriptors report their revisionView, and each fingerprint
683
+ // is computed from the same view as exactText. Keep those fields together.
554
684
 
555
685
  // To insert run-level text at a location visible only in the rejected view,
556
686
  // provide explicit rejected-view intent and an exact anchor-relative offset.
@@ -650,8 +780,10 @@ invariant with a fresh seed. See [Release validation in docs/TESTING.md](./docs/
650
780
 
651
781
  ## Architecture & Contributing
652
782
 
653
- - **[ARCHITECTURE.md](./ARCHITECTURE.md)**: Detailed module layout, end-to-end reconciliation flow, and contributor fast orientation.
654
- - **[AGENTS.md](./AGENTS.md)**: Concise quick reference for AI coding agents and CLI automation.
783
+ - **[ARCHITECTURE.md](./ARCHITECTURE.md)**: Detailed module layout, end-to-end reconciliation flow, and contributor fast orientation.
784
+ - **[AGENTS.md](./AGENTS.md)**: Fast-start routing and operational guardrails for AI coding agents.
785
+ - **[docs/AGENT_FAST_START.md](./docs/AGENT_FAST_START.md)**: Minimal ordinary-edit contract for agent integrations.
786
+ - **[docs/AGENT_KNOWLEDGE_BASE.md](./docs/AGENT_KNOWLEDGE_BASE.md)**: Full agent reference for APIs, operations, CLI automation, recovery, and gotchas.
655
787
  - **[docs/TESTING.md](./docs/TESTING.md)**: Comprehensive testing model, test lanes, independent oracle checks, and visual review checklist.
656
788
  - **[CHANGELOG.md](./CHANGELOG.md)**: Version history, migration guides, and deprecation schedules.
657
789
 
@@ -424,9 +424,14 @@ export function resolveTargetParagraph(xmlDoc, options = {}) {
424
424
  );
425
425
  }
426
426
  if (descriptor.fingerprint && descriptor.fingerprint !== actualFingerprint) {
427
+ const alternateView = revisionView === 'rejected' ? 'accepted' : 'rejected';
428
+ const alternateFingerprint = createParagraphFingerprint(byId, { revisionView: alternateView });
429
+ const viewHint = descriptor.fingerprint === alternateFingerprint
430
+ ? ` The supplied fingerprint matches the ${alternateView} view; set target.revisionView to "${alternateView}" or use a fingerprint extracted from the ${revisionView} view.`
431
+ : '';
427
432
  throw createTargetError(
428
433
  'TARGET_FINGERPRINT_MISMATCH',
429
- `Target paragraphId "${descriptor.paragraphId}" no longer matches its source fingerprint.`,
434
+ `Target paragraphId "${descriptor.paragraphId}" no longer matches its source fingerprint.${viewHint}`,
430
435
  cachedEntry ? [serializeTargetCandidate(cachedEntry)] : null
431
436
  );
432
437
  }
@@ -438,9 +443,16 @@ export function resolveTargetParagraph(xmlDoc, options = {}) {
438
443
  );
439
444
  }
440
445
  if (cleanTargetText && actualText !== normalizeWhitespaceForTargeting(cleanTargetText)) {
446
+ const alternateView = revisionView === 'rejected' ? 'accepted' : 'rejected';
447
+ const alternateText = normalizeWhitespaceForTargeting(
448
+ extractCanonicalParagraphText(byId, { revisionView: alternateView })
449
+ );
450
+ const viewHint = alternateText === normalizeWhitespaceForTargeting(cleanTargetText)
451
+ ? ` The supplied text matches the ${alternateView} view; set target.revisionView to "${alternateView}".`
452
+ : '';
441
453
  throw createTargetError(
442
454
  'TARGET_TEXT_MISMATCH',
443
- `Target paragraphId "${descriptor.paragraphId}" no longer matches the supplied text.`,
455
+ `Target paragraphId "${descriptor.paragraphId}" no longer matches the supplied text.${viewHint}`,
444
456
  cachedEntry ? [serializeTargetCandidate(cachedEntry)] : null
445
457
  );
446
458
  }