@ansonlai/docx-redline-js 0.2.1 → 0.4.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.
Files changed (86) hide show
  1. package/AGENTS.md +36 -10
  2. package/README.md +83 -6
  3. package/adapters/xml-adapter.js +73 -10
  4. package/core/list-targeting.js +3 -0
  5. package/core/paragraph-targeting.js +33 -7
  6. package/core/redline-validation.js +22 -0
  7. package/core/types.js +122 -27
  8. package/core/xml-query.js +3 -1
  9. package/dist/docx-redline-js.esm.js +1124 -545
  10. package/dist/docx-redline-js.esm.js.map +4 -4
  11. package/dist/docx-redline-js.esm.min.js +79 -78
  12. package/dist/docx-redline-js.esm.min.js.map +4 -4
  13. package/docs/TESTING.md +687 -0
  14. package/docs/VALIDATION.md +81 -2
  15. package/docs/WORD-MANUAL-REVIEW.md +138 -0
  16. package/docs/plans/2026-08-30-reliability-testing-improvements.md +488 -0
  17. package/docs/plans/2026-09-01-performance-and-complexity-reduction.md +210 -0
  18. package/docs/plans/{2026-03-01-release-0.1.4-design.md → completed/2026-03-01-release-0.1.4-design.md} +2 -0
  19. package/docs/plans/{2026-03-01-release-0.1.4.md → completed/2026-03-01-release-0.1.4.md} +5 -3
  20. package/docs/plans/{2026-05-31-architectural changes.md → completed/2026-05-31-architectural changes.md } +2 -0
  21. package/docs/plans/completed/2026-08-02-reliability-improvements.md +1155 -0
  22. package/docs/test-comparison-dashboard.html +95 -0
  23. package/docs/validation-reports/2026-08-30-phase-1-word-visual-preflight.md +22 -0
  24. package/docs/validation-reports/2026-08-30-phase-2-word-visual-preflight.md +24 -0
  25. package/docs/validation-reports/2026-08-30-phase-3-coverage.md +73 -0
  26. package/docs/validation-reports/2026-09-02-multilevel-bullets-visual-review.md +82 -0
  27. package/docs/validation-reports/2026-09-02-multimodal-visual-samples.md +114 -0
  28. package/docs/validation-reports/2026-09-02-visual-failures-preflight.md +79 -0
  29. package/engine/format-extraction.js +1 -1
  30. package/engine/formatting-removal.js +84 -99
  31. package/engine/oxml-engine.js +176 -83
  32. package/engine/reconstruction-mapper.js +276 -79
  33. package/engine/reconstruction-mode.js +20 -6
  34. package/engine/reconstruction-writer.js +117 -72
  35. package/engine/run-builders.js +3 -3
  36. package/engine/surgical-mode.js +3 -2
  37. package/engine/table-mode.js +27 -16
  38. package/index.d.ts +95 -3
  39. package/index.js +14 -13
  40. package/orchestration/list-structural-fallback.js +16 -39
  41. package/package.json +22 -4
  42. package/pipeline/diff-engine.js +174 -55
  43. package/pipeline/ingestion-export.js +39 -24
  44. package/pipeline/ingestion-paragraph.js +7 -5
  45. package/pipeline/list-generation.js +27 -18
  46. package/pipeline/patching.js +2 -3
  47. package/pipeline/pipeline.js +65 -36
  48. package/pipeline/serialization.js +13 -5
  49. package/scripts/build-test-dashboard.mjs +43 -0
  50. package/scripts/check-types.mjs +16 -24
  51. package/scripts/export-validation-fixtures.mjs +191 -45
  52. package/scripts/fetch-superdoc-corpus.mjs +61 -0
  53. package/scripts/generate-test-dashboard.mjs +199 -0
  54. package/scripts/inspect-visual-evidence.mjs +271 -0
  55. package/scripts/lib/minimal-zip.mjs +199 -18
  56. package/scripts/lib/word-coverage-catalogue.mjs +207 -0
  57. package/scripts/lib/word-coverage-metadata.mjs +93 -0
  58. package/scripts/lib/zip-reader.mjs +64 -0
  59. package/scripts/package-superdoc-word-fixtures.ps1 +64 -0
  60. package/scripts/prepare-corpus-word-visual-review.mjs +84 -0
  61. package/scripts/prepare-superdoc-word-corpus.mjs +284 -0
  62. package/scripts/prepare-word-review.mjs +77 -0
  63. package/scripts/prepare-word-visual-review.mjs +90 -0
  64. package/scripts/render-agenda-multilevel.mjs +70 -0
  65. package/scripts/render-case22.mjs +73 -0
  66. package/scripts/render-case40.ps1 +35 -0
  67. package/scripts/render-multilevel-bullet-images.py +58 -0
  68. package/scripts/render-multilevel-bullet-visual.ps1 +32 -0
  69. package/scripts/render-multilevel-cases.mjs +80 -0
  70. package/scripts/report-coverage-gaps.mjs +103 -0
  71. package/scripts/report-word-coverage.mjs +71 -0
  72. package/scripts/sample-multimodal-visual-check.mjs +221 -0
  73. package/scripts/test-multilevel-bullet-visual.mjs +187 -0
  74. package/scripts/word-com-corpus-suite.ps1 +43 -0
  75. package/scripts/word-com-corpus-visual-suite.ps1 +116 -0
  76. package/scripts/word-com-differential.ps1 +158 -16
  77. package/scripts/word-com-suite.ps1 +19 -0
  78. package/scripts/word-com-visual-suite.ps1 +132 -0
  79. package/services/comment-engine.js +51 -46
  80. package/services/comment-locator.js +0 -1
  81. package/services/comment-package.js +11 -10
  82. package/services/numbering-service.js +1 -1
  83. package/services/revision-comment-management.js +31 -10
  84. package/services/standalone-docx-plumbing.js +45 -34
  85. package/services/standalone-operation-runner.js +315 -75
  86. package/services/table-reconciliation.js +23 -11
@@ -0,0 +1,488 @@
1
+ # Reliability and Testing Improvement Plan — Round 3
2
+
3
+ **Status:** Complete — Phases 1–4 complete
4
+
5
+ This plan follows the completed
6
+ `completed/2026-08-02-reliability-improvements.md` plan. It selects four of the
7
+ next-step opportunities identified while completing that work:
8
+
9
+ 1. Preserve and target structural tabs and complex fields correctly.
10
+ 2. Extend the synthetic DOCX packager for related Word parts.
11
+ 3. Add behavior-focused tests in the least-covered production paths.
12
+ 4. Turn the Word catalogue into an explicit task/structure coverage matrix
13
+ (selected recommendation 6 from the review).
14
+
15
+ The published library remains host-independent JavaScript. Microsoft Word COM,
16
+ ZIP assembly, downloaded corpus documents, and other platform-specific tooling
17
+ remain development-only.
18
+
19
+ ## Baseline
20
+
21
+ As of 2026-08-30:
22
+
23
+ - `npm test`: 30/30 test files pass.
24
+ - Synthetic Microsoft Word differential: 25/25 cases pass.
25
+ - Reviewed SuperDoc Microsoft Word differential: 20/20 documents pass.
26
+ - Coverage: 79.96% lines/statements, 80.95% functions, 69.52% branches.
27
+ - The synthetic packager supports `word/document.xml` and optional numbering,
28
+ but not the complete related-part graph needed for comments, notes,
29
+ headers/footers, or relationship-backed hyperlinks.
30
+ - A paragraph containing `w:tab` cannot currently be targeted consistently
31
+ through reconstruction.
32
+ - Reconstruction adjacent to a complex field can discard `w:fldChar` and
33
+ `w:instrText` scaffolding.
34
+
35
+ Coverage percentages are diagnostic baselines, not correctness scores or
36
+ release thresholds. Each phase below is accepted through observable behavior.
37
+
38
+ ## Production API compatibility
39
+
40
+ | Phase | Expected impact |
41
+ |---|---|
42
+ | 1 | **Conditional production behavior.** Correct output changes around tabs and fields; public signatures should remain unchanged. |
43
+ | 2 | **Not breaking.** Development-only fixture packaging and Word automation. |
44
+ | 3 | **Not breaking unless a test exposes a production defect.** Test additions alone are development-only; any resulting runtime fix must document its own compatibility impact before implementation. |
45
+ | 4 | **Not breaking.** Test metadata, reporting, and contributor workflow only. |
46
+
47
+ If implementation reveals that an established public text representation for
48
+ tabs or fields must change, stop and update this compatibility section and the
49
+ changelog before landing that behavior.
50
+
51
+ ---
52
+
53
+ ## Phase 1 — Structural tabs and complex fields
54
+
55
+ **Status:** Complete (2026-08-30)
56
+
57
+ ### Problem
58
+
59
+ Word structures such as tabs and fields occupy positions in visible document
60
+ content but are not ordinary `w:t` text:
61
+
62
+ - Paragraph targeting currently omits `w:tab`, while ingestion/reconstruction
63
+ expects a complete contiguous text range. A target containing the visible tab
64
+ therefore fails before the Word oracle can run.
65
+ - A complex field consists of `w:fldChar` begin/separate/end nodes,
66
+ `w:instrText`, and visible result runs. Reconstruction adjacent to its result
67
+ can retain the visible text while losing the field itself.
68
+
69
+ Both failures are dangerous in legal and administrative documents: the visible
70
+ text may appear plausible even though alignment or an automatically generated
71
+ reference has been destroyed.
72
+
73
+ ### Work
74
+
75
+ 1. Define one canonical visible-text representation for `w:tab` across
76
+ ingestion, targeting, offsets, exact-text assertions, and reconstruction.
77
+ Prefer `\t`; do not collapse it to a space.
78
+ 2. Represent complex field scaffolding as inert structural spans. Field
79
+ instructions must not become editable visible text, and edits adjacent to a
80
+ field result must not split, duplicate, reorder, or discard the field nodes.
81
+ 3. Preserve the distinction among a field instruction, its displayed result,
82
+ and surrounding editable text. Do not update or evaluate fields in the JS
83
+ engine.
84
+ 4. Add focused automated tests for tabs at the beginning, middle, and end of a
85
+ run; edits on either side of a field; multiple fields; and field results
86
+ split across runs.
87
+ 5. Add synthetic Word cases for at least one tab-bearing administrative layout
88
+ and one locked complex field. Require the original structural elements and
89
+ verify exact Accept All and Reject All behavior in Word.
90
+ 6. Add both shapes to deterministic fuzz/invariant testing once their text
91
+ representation is stable.
92
+
93
+ ### Acceptance
94
+
95
+ - Tab-bearing paragraph targets resolve without normalization or whitespace
96
+ loss, and accept/reject round trips preserve exact tabs.
97
+ - Adjacent edits preserve `w:fldChar` begin/separate/end ordering and
98
+ `w:instrText` byte content.
99
+ - `validateRedlineOoxml` reports no structural errors.
100
+ - The new synthetic packages open in Word without repair; Word sees tracked
101
+ revisions; Accept All matches intent; Reject All restores the source.
102
+ - Existing 25 synthetic and 20 corpus Word cases remain green.
103
+
104
+ ### Completion record
105
+
106
+ - Paragraph targeting and reconstruction now use literal `\t` for `w:tab`,
107
+ including leading and trailing tabs; the standalone runner no longer trims
108
+ those target boundaries.
109
+ - Complex-field begin/instruction/separate/end nodes are retained as inert,
110
+ zero-width reconstruction sentinels. Their cached display runs remain inside
111
+ the field and are not revised when only adjacent text changes.
112
+ - Added `tests/structural_tab_field_tests.mjs` plus deterministic tab/field fuzz
113
+ shapes. Focused assertions cover field ordering, exact instruction bytes,
114
+ valid run parents, split cached results, and exact Accept/Reject text.
115
+ - Added three synthetic Word cases: tab-aligned administrative text, boundary
116
+ tabs, and a locked PAGE field. The catalogue is now 28 cases; Word 16.0 build
117
+ 16.0.20326 passed 28/28, and the reviewed SuperDoc lane passed 20/20.
118
+ - AI visual preflight inspected Word-produced final and markup renderings for
119
+ all three new cases. It initially exposed a duplicated visible PAGE result in
120
+ markup; the sentinel mapping was corrected and the repeat preflight passed.
121
+ See `docs/validation-reports/2026-08-30-phase-1-word-visual-preflight.md`.
122
+ - Final verification: 31/31 JavaScript test files, isolation, declarations,
123
+ lint, build, 100 deterministic fuzz cases, and 80.01% statement/line,
124
+ 80.95% function, and 69.71% branch coverage all pass.
125
+
126
+ ---
127
+
128
+ ## Phase 2 — Richer synthetic DOCX package fixtures
129
+
130
+ **Status:** Complete (2026-08-30)
131
+
132
+ ### Problem
133
+
134
+ The current synthetic fixture builder creates a deliberately minimal package.
135
+ That is sufficient for body paragraphs, numbering, bookmarks, internal links,
136
+ content controls, and tables, but it cannot independently test structures that
137
+ require additional package parts and relationships.
138
+
139
+ ### Work
140
+
141
+ 1. Extend the script-local package builder with explicit, optional support for:
142
+
143
+ - `word/comments.xml` and comment anchors/references;
144
+ - `word/footnotes.xml` and `word/endnotes.xml`;
145
+ - header and footer parts, including section references;
146
+ - document relationships for external hyperlinks;
147
+ - the required `[Content_Types].xml` overrides and relationship entries.
148
+
149
+ 2. Keep every addition opt-in so the smallest fixtures remain easy to inspect.
150
+ Do not add a ZIP dependency to runtime library code.
151
+ 3. Validate relationship targets, content-type declarations, referenced IDs,
152
+ and required separator entries for footnotes/endnotes before writing a
153
+ package.
154
+ 4. Add package-level assertions that distinguish edited parts from untouched
155
+ parts and hash untouched entries where appropriate.
156
+ 5. Add at least one English legal or administrative Word differential case for
157
+ each supported related-part family. Expected results must come from edit
158
+ intent or Word's original source text, never from this library's own
159
+ accept/reject helpers.
160
+ 6. Document the fixture schema and small reusable constructors in
161
+ `docs/TESTING.md`.
162
+
163
+ ### Acceptance
164
+
165
+ - Synthetic fixtures containing comments, notes, headers/footers, and external
166
+ hyperlinks open in desktop Word without repair.
167
+ - Word Accept All and Reject All pass for every new case.
168
+ - Required parts, content types, and relationships are validated before Word
169
+ runs.
170
+ - Untouched package parts remain byte-identical.
171
+ - Runtime dependency and isolation checks prove that packaging/COM code has not
172
+ entered `index.js`, `core/`, `engine/`, `pipeline/`, or runtime services.
173
+
174
+ ### Completion record
175
+
176
+ - `scripts/lib/minimal-zip.mjs` now accepts opt-in comments, footnotes,
177
+ endnotes, header/footer parts, and external hyperlink relationships in
178
+ addition to numbering. It generates relationships and content-type overrides
179
+ without adding a runtime ZIP dependency.
180
+ - Pre-emission validation covers well-formed roots, unique relationship IDs and
181
+ part names, external targets, document relationship references, comment/note
182
+ IDs, and required note separator IDs `-1` and `0`.
183
+ - Added reusable escaped constructors in
184
+ `tests/fixtures/word-package-parts.mjs` and comprehensive positive/negative
185
+ package tests in `tests/minimal_docx_package_tests.mjs`.
186
+ - Related parts are byte-compared after packaging, recorded by SHA-256 in each
187
+ fixture sidecar, and rechecked by the Word differential before Word opens the
188
+ package.
189
+ - Added five English legal/administrative cases. Word 16.0 build 16.0.20326
190
+ passed 33/33 synthetic cases; the reviewed SuperDoc lane remains 20/20.
191
+ - AI visual preflight inspected final and markup renderings for all five new
192
+ cases. It prompted self-contained superscript formatting for note references;
193
+ the repeated preflight passed. See
194
+ `docs/validation-reports/2026-08-30-phase-2-word-visual-preflight.md`.
195
+ - Final verification: 32/32 JavaScript test files, isolation, declarations,
196
+ lint, build, and 80.35% statement/line, 81.29% function, and 69.60% branch
197
+ coverage all pass.
198
+
199
+ ---
200
+
201
+ ## Phase 3 — Behavior-focused coverage in thin production paths
202
+
203
+ **Status:** Complete (2026-08-30)
204
+
205
+ ### Targets
206
+
207
+ The current report covers 442 of 546 functions, leaving 104 functions
208
+ unexecuted. Module loading can execute declarations and top-level statements
209
+ without invoking a function, so line coverage alone hides the sharpest gaps:
210
+
211
+ | Priority | Area | Current signal | Why it is a problem area |
212
+ |---|---|---:|---|
213
+ | P0 | `services/numbering-helpers.js` | 23.55% lines, **0/18 functions** | Allocates and merges package identifiers; a collision can corrupt lists or relationships. |
214
+ | P0 | `orchestration/route-plan.js` | 23.75% lines, **0/6 functions** | Chooses the editing path; a wrong route can bypass the safeguards of the intended mode. |
215
+ | P0 | `orchestration/list-markdown.js` | 24.11% lines, **0/6 functions** | Converts user intent into list structure and is currently visible only through module loading. |
216
+ | P0 | `pipeline/patching.js` | 52.08% lines, 50% functions | Directly mutates reconstructed content; missed boundaries can lose or duplicate text. |
217
+ | P0 | `engine/format-span-application.js` | 62.56% lines, 40% functions | Applies formatting over offsets; split-run and boundary mistakes are visually subtle. |
218
+ | P1 | `orchestration/list-structural-fallback.js` | 57.19% lines, 47.05% functions, 55% branches | Large fallback path with list-level, adjacency, and failure decisions. |
219
+ | P1 | `engine/table-mode.js` | 75.93% lines, **26.08% branches** | Most table decisions are not exercised despite acceptable line coverage. |
220
+ | P1 | `core/table-targeting.js` | 74.67% lines, 45.83% branches | Ambiguous cells and partial matches can target the wrong administrative data. |
221
+ | P1 | `services/standalone-operation-runner.js` | 74.05% lines, 59.57% branches | The largest module coordinates targeting, artifacts, ordering, and rollback. |
222
+ | P1 | `pipeline/pipeline.js` | 79.94% lines, 58.33% functions, 56% branches | Central orchestration still has untested modes and error paths. |
223
+ | P2 | adapters and defensive package validation | mixed | Lower-risk fallbacks and host-specific diagnostics; cover after reachable content-changing paths. |
224
+
225
+ The goal is not to inflate a global percentage. It is to exercise meaningful
226
+ decisions, error contracts, and collision/rollback behavior that are currently
227
+ easy to change unnoticed.
228
+
229
+ ### Coverage method
230
+
231
+ 1. Add a detailed JSON coverage artifact and a small reporting script, exposed
232
+ as `npm run coverage:gaps`, that lists every uncovered production function
233
+ with file, name, and source line. Keep the existing summary for trend
234
+ history.
235
+ 2. Classify each uncovered function before writing a test:
236
+
237
+ - **reachable behavior** — cover through a public or supported deep-import
238
+ entry point;
239
+ - **pure helper with meaningful boundaries** — direct unit tests are
240
+ appropriate;
241
+ - **defensive/environment-specific** — exercise with a realistic injected
242
+ failure where possible;
243
+ - **unreachable or obsolete** — delete it, or document why it remains.
244
+
245
+ 3. Rank gaps using four questions: can failure lose/corrupt content, can it edit
246
+ the wrong target, is it on a public/common path, and has the code recently
247
+ changed? Content loss/corruption and wrong-target risks are always P0.
248
+ 4. For each selected function, use a behavior set rather than a single smoke
249
+ call: normal case, boundary case, malformed/unsupported input, no-op, and
250
+ collision or rollback case where applicable.
251
+ 5. Prefer tests that enter through the public API and naturally traverse
252
+ several internal functions. Use direct helper tests to cover algorithms and
253
+ boundary values, not to manufacture execution without observable behavior.
254
+ 6. Pair function coverage with branch decision tables. A function is not
255
+ considered adequately tested merely because its first line executed.
256
+ 7. Do not add `c8 ignore` annotations to improve the score. An exclusion needs
257
+ a written environment or reachability reason and review alongside the code.
258
+ 8. Track both the number of newly executed functions and the behaviors added.
259
+ A working milestone is at least 40 additional previously-unexecuted
260
+ production functions, moving global function coverage toward 88% and branch
261
+ coverage toward 75%. These are navigation targets, not sufficient acceptance
262
+ criteria by themselves.
263
+
264
+ ### Work
265
+
266
+ 1. Generate the uncovered-function inventory and attach the P0/P1/P2 ranking.
267
+ Record which branches are public behavior, defensive impossibilities, or
268
+ obsolete code. Update the inventory after each test group so effort moves to
269
+ the next actual gap.
270
+ 2. Add numbering tests for missing parts, existing abstract/instance ID
271
+ collisions, malformed numbering XML, multiple list styles, and deterministic
272
+ allocation across independent documents. Exercise every reachable function
273
+ in `numbering-helpers.js`, including relationship/content-type merging and
274
+ idempotent repeated calls.
275
+ 3. Add route-plan tests covering every supported operation route, ambiguous
276
+ inputs, table/list precedence, unsupported/native fallbacks, and stable error
277
+ results. Express the routes as a decision table and require one positive and
278
+ one rejection/fallback case per route.
279
+ 4. Add list-markdown and structural-fallback tests for ordered/unordered lists,
280
+ nesting and level changes, adjacent insertion/deletion, formatting, existing
281
+ numbering, and failure without partial mutation. Ensure all public and
282
+ reachable internal functions in `list-markdown.js` execute through real list
283
+ scenarios rather than import-only tests.
284
+ 5. Add standalone runner tests for mixed-operation ordering, package artifacts,
285
+ `continueOnError`, atomic/non-atomic results, and target snapshot invalidation.
286
+ 6. Add patching/format-span boundary tests at offset zero, run boundaries,
287
+ whitespace, tabs/breaks, overlapping formatting, empty spans, and the final
288
+ character. Assert exact XML plus accept/reject text.
289
+ 7. Add table decision tests for duplicate cell text, merged cells, nested
290
+ tables, row/column additions, partial table targets, format-only edits, and
291
+ clean failure without modifying untargeted cells.
292
+ 8. Add pipeline tests for each routing mode, parse and diff failures, no-op
293
+ behavior, existing revisions, formatting removal, and generated package
294
+ artifacts.
295
+ 9. Delete unreachable branches when evidence shows they are obsolete rather
296
+ than writing artificial tests solely to execute them.
297
+ 10. Record before/after function and branch counts for every targeted file, plus
298
+ the global snapshot, after the behavioral cases land.
299
+
300
+ ### Acceptance
301
+
302
+ - Every P0 module has a documented function inventory and focused regression
303
+ tests for all reachable content-changing functions.
304
+ - No reachable function in `numbering-helpers.js`, `route-plan.js`, or
305
+ `list-markdown.js` remains at zero hits; any retained uncovered function has a
306
+ reviewed reachability/environment explanation.
307
+ - At least 40 previously-unexecuted production functions are exercised, unless
308
+ the inventory proves that fewer than 40 are reachable—in which case obsolete
309
+ functions are removed and the remainder are explicitly justified.
310
+ - P0 and P1 branch decisions have named behavior cases even where coverage-tool
311
+ instrumentation groups multiple decisions onto one line.
312
+ - New tests assert outputs and error contracts, not merely that functions ran.
313
+ - The report fails if a targeted file loses covered functions relative to the
314
+ new Phase 3 baseline. No global percentage is used as the sole gate; per-file
315
+ changes are reviewed alongside the added behavior matrix.
316
+ - `npm test`, isolation, types, lint, and deterministic fuzz checks pass.
317
+ - Any production defect discovered by the new tests receives its own changelog
318
+ and compatibility assessment before being fixed.
319
+
320
+ ### Completion record
321
+
322
+ - Added detailed Istanbul JSON output plus `npm run coverage:gaps`. The report
323
+ inventories uncovered production functions by file/name/line and priority,
324
+ and fails when a target file loses covered functions or branches relative to
325
+ `tests/coverage-data/phase3-baseline.json`.
326
+ - Added five behavior matrices for numbering/routing/list markdown,
327
+ patching/format spans, structural list fallback, table/pipeline decisions,
328
+ and standalone highlighting/rollback. They assert results, exact structural
329
+ properties, stable errors, no mutation, and package-artifact behavior.
330
+ - Production function coverage increased from 437/540 to 496/542, exercising
331
+ at least 59 formerly cold functions. Production covered branches increased
332
+ from 2,333 to 2,919; the final c8 snapshot is 87.92% statements/lines, 73.90%
333
+ branches, and 91.80% functions.
334
+ - Every function in the five P0 targets is covered. All functions are also
335
+ covered in list structural fallback, table mode/targeting, and pipeline. The
336
+ only retained P1 gaps are nine inert default logging callbacks and one
337
+ non-injectable last-resort paragraph constructor, reviewed in
338
+ `tests/coverage-data/phase3-reviewed-gaps.json`.
339
+ - Existing and new tests cover mixed batch ordering, numbering/comment
340
+ artifacts, `continueOnError`, atomic/non-atomic outcomes, stale snapshots,
341
+ table ambiguity/nesting, list levels, formatting overlaps, and pipeline
342
+ parse/no-op/validation modes. No production defect or compatibility change
343
+ was found.
344
+ - The full evidence and before/after table are recorded in
345
+ `docs/validation-reports/2026-08-30-phase-3-coverage.md`.
346
+
347
+ ---
348
+
349
+ ## Phase 4 — Explicit task/structure coverage matrix
350
+
351
+ **Status:** Complete (2026-08-30)
352
+
353
+ ### Problem
354
+
355
+ The Word catalogue currently has useful `category` and `task` labels, while the
356
+ SuperDoc scenarios record `shape` and free-form coverage labels. These show what
357
+ individual cases do, but they do not reveal which combinations are covered,
358
+ planned, intentionally excluded, or impossible in the current harness.
359
+
360
+ ### Work
361
+
362
+ 1. Define a shared vocabulary for:
363
+
364
+ - task: replace, insert, delete, format, comment, accept/reject, list change,
365
+ table reconciliation, and mixed batch;
366
+ - structure: plain paragraph, multi-paragraph, formatted runs, list, table,
367
+ bookmark, hyperlink, content control, tab/break, field, comment, note,
368
+ header/footer, section boundary, and prior revisions;
369
+ - oracle: JS exact round trip, runtime validator, XSD, LibreOffice, synthetic
370
+ Word, real-document Word, AI Word visual preflight, and human Word visual
371
+ review.
372
+
373
+ 2. Normalize synthetic and corpus metadata to this vocabulary without removing
374
+ human-readable review notes.
375
+ 3. Add a deterministic report command that prints the task-by-structure matrix
376
+ and identifies uncovered combinations. Store machine-readable exclusions
377
+ with reasons such as “requires related-part packager” rather than silently
378
+ treating absence as coverage.
379
+ 4. Make catalogue validation reject unknown labels, missing oracle metadata,
380
+ duplicate scenario identities, and claims unsupported by the actual fixture.
381
+ 5. Use the report to choose new tests based on risk and structural diversity,
382
+ not simply to increase the case count.
383
+ 6. Add a planned `npm run review:word:prepare` helper that selects all new or
384
+ changed Word cases plus a rotating release sample and writes a review
385
+ manifest under ignored `tmp/` storage. The helper may prepare disposable
386
+ accepted/rejected copies, but it must never mark a visual check as passed.
387
+ 7. Add periodic AI visual preflights using the local Word UI and screenshots:
388
+ after layout-sensitive phases, after every five to ten new Word cases, for
389
+ every new structure family, and before the human release sample. Record the
390
+ exact cases/views, Word build, screenshot evidence, observed failures, and
391
+ uncertainty. AI review remains advisory and must not open sensitive/private
392
+ documents without explicit authorization.
393
+ 8. Require human review for every new structure/operation, every affected case
394
+ after layout-sensitive engine or package changes, all cases using normalized
395
+ text comparison, and any unexplained automated Word failure.
396
+ 9. Before each release, visually inspect all new/changed cases, at least 20% of
397
+ unchanged synthetic cases on a rotating basis, and at least one legal and one
398
+ administrative SuperDoc result. Record Word version/build and the All Markup,
399
+ Accept All, and Reject All result for each selection.
400
+ 10. Document the process in `docs/TESTING.md`, use
401
+ `docs/WORD-MANUAL-REVIEW.md` as the checklist/template, and retain the signed
402
+ report with release-validation artifacts.
403
+
404
+ ### Acceptance
405
+
406
+ - One command produces a stable, reviewable matrix for synthetic and SuperDoc
407
+ cases.
408
+ - Every case declares task, structure, and oracle metadata from validated
409
+ vocabularies.
410
+ - Every empty high-priority matrix cell is either backed by a planned test or an
411
+ explicit exclusion with a reason and dependency.
412
+ - Adding a new case updates the matrix automatically.
413
+ - The test guide explains how contributors use the report to select the next
414
+ case.
415
+ - The matrix distinguishes automated Word semantics from human Word visual
416
+ review, records AI visual preflights separately, and identifies cases whose
417
+ manual review is missing or stale.
418
+ - Each layout-sensitive phase and each group of five to ten new Word fixtures
419
+ receives an AI visual preflight unless no authorized local documents are
420
+ available; skipped preflights have a recorded reason.
421
+ - Release validation includes a recorded human sign-off with the reviewer,
422
+ Word build, selected cases, and results for all three Word views.
423
+
424
+ ### Completion record
425
+
426
+ - Added a shared, validated vocabulary covering nine tasks, fifteen structures,
427
+ eight independent oracles, and explicit missing/current/stale human-review
428
+ state. All 33 synthetic and 20 reviewed SuperDoc cases now resolve to declared
429
+ canonical metadata without removing their descriptive labels.
430
+ - Added `npm run report:word:coverage`, which deterministically reports the live
431
+ 53-case task/structure matrix, individual case identities in JSON mode,
432
+ missing/stale human review, and every uncovered high-priority cell.
433
+ - Added machine-readable high-priority cells and eight explicit planned gaps,
434
+ each with a reason and dependency. Catalogue validation rejects unknown
435
+ labels, missing oracle/review metadata, duplicate identities, stale gap
436
+ dispositions, and structure/task claims unsupported by the fixture.
437
+ - Added `npm run review:word:prepare -- --cycle=N`. It conservatively selects
438
+ changed catalogue families, a rotating 20% synthetic sample, and one legal
439
+ plus one administrative SuperDoc case. Every view and human-sign-off field is
440
+ emitted as `pending`; the helper cannot certify a review.
441
+ - The matrix records eight synthetic AI visual preflights from Phases 1 and 2
442
+ separately from automated Word semantics. No human sign-off is fabricated:
443
+ the current report correctly lists all 53 cases as missing human review, and
444
+ the signed three-view review remains an operational release gate.
445
+ - Added focused matrix tests and contributor/reviewer instructions in
446
+ `docs/TESTING.md` and `docs/WORD-MANUAL-REVIEW.md`.
447
+ - Validation passed with 33/33 JavaScript suites, 33/33 synthetic Word cases,
448
+ 20/20 real-document Word cases, isolation, declarations, lint, and build.
449
+ Coverage after the Phase 4 tooling tests is 80.60% statements/lines, 70.13%
450
+ branches, and 82.02% functions.
451
+
452
+ ---
453
+
454
+ ## Execution order
455
+
456
+ ```text
457
+ Phase 1 (tabs and fields) ───────────────┐
458
+ ├─> Phase 4 (coverage matrix)
459
+ Phase 2 (related-part package fixtures) ─┘
460
+
461
+ Phase 3 (thin-path behavioral tests) can proceed independently, but any newly
462
+ discovered runtime defect must be scoped and documented before implementation.
463
+ ```
464
+
465
+ Phase 1 supplies two important structural shapes. Phase 2 unlocks the package
466
+ families currently missing from synthetic Word validation. Phase 4 should use
467
+ those stable capabilities rather than encoding temporary harness limitations as
468
+ the final matrix. Phase 3 can run alongside them because it mostly targets
469
+ lower-level routing and numbering behavior.
470
+
471
+ ## Verification commands
472
+
473
+ ```bash
474
+ npm test
475
+ npm run test:isolation
476
+ npm run check:types
477
+ npm run lint
478
+ npm run test:coverage
479
+ npm run coverage:gaps # detailed production function inventory
480
+ npm run test:word # Windows + desktop Microsoft Word
481
+ npm run test:corpus:word # pinned local corpus + Word
482
+ npm run review:word:prepare -- --cycle=0 # pending human-review set
483
+ node scripts/export-validation-fixtures.mjs
484
+ FUZZ_SEED=1 FUZZ_ITERATIONS=12000 node tests/roundtrip_fuzz_tests.mjs
485
+ ```
486
+
487
+ Release validation continues to include the ECMA-376 transitional XSD and
488
+ LibreOffice lanes described in `docs/VALIDATION.md`.