@ansonlai/docx-redline-js 0.5.4 → 0.6.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 (51) hide show
  1. package/AGENTS.md +78 -697
  2. package/ARCHITECTURE.md +13 -1
  3. package/CHANGELOG.md +5 -0
  4. package/README.md +140 -30
  5. package/core/paragraph-targeting.js +14 -2
  6. package/dist/docx-redline-js.esm.js +113 -33
  7. package/dist/docx-redline-js.esm.js.map +3 -3
  8. package/dist/docx-redline-js.esm.min.js +75 -75
  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 +868 -0
  12. package/docs/TESTING.md +20 -1
  13. package/docs/schemas/document-operations.schema.json +5 -1
  14. package/docs/validation-reports/2026-09-12-agent-protocol-rollout.md +82 -0
  15. package/engine/oxml-engine.js +80 -13
  16. package/engine/run-builders.js +5 -15
  17. package/index.d.ts +17 -1
  18. package/node/cli.js +111 -27
  19. package/node/docx-document.js +120 -69
  20. package/node/index.d.ts +6 -2
  21. package/package.json +10 -3
  22. package/scripts/generate-cross-author-slicing-fixtures.ps1 +25 -25
  23. package/services/batch-operation-orchestrator.js +215 -120
  24. package/services/document-inspection.js +5 -3
  25. package/services/document-operation-applier.js +52 -34
  26. package/services/document-operation-contract.js +10 -6
  27. package/services/document-operation-mutations.js +51 -5
  28. package/services/document-operation-session.js +4 -0
  29. package/services/error-recovery.js +174 -0
  30. package/services/operation-batch-compiler.js +394 -0
  31. package/services/operation-preflight.js +91 -72
  32. package/services/standalone-operation-runner.d.ts +17 -1
  33. package/docs/plans/2026-09-05-structural-revisions-and-fidelity-oracles.md +0 -1669
  34. package/docs/plans/2026-09-08-cross-author-revision-slicing.md +0 -1399
  35. package/docs/plans/completed/2026-03-01-release-0.1.4-design.md +0 -33
  36. package/docs/plans/completed/2026-03-01-release-0.1.4.md +0 -110
  37. package/docs/plans/completed/2026-05-31-architectural changes.md +0 -593
  38. package/docs/plans/completed/2026-08-02-reliability-improvements.md +0 -1155
  39. package/docs/plans/completed/2026-08-30-reliability-testing-improvements.md +0 -488
  40. package/docs/plans/completed/2026-09-01-performance-and-complexity-reduction.md +0 -669
  41. package/docs/plans/completed/2026-09-03-agent-friendly-document-workflows.md +0 -427
  42. package/docs/plans/completed/2026-09-04-comment-anchor-and-cli-reliability.md +0 -519
  43. package/docs/plans/completed/PERFORMANCE-CONSOLIDATION.md +0 -69
  44. package/docs/plans/completed/structural-revision-capability-matrix.md +0 -115
  45. package/docs/test-comparison-dashboard.html +0 -4338
  46. package/docs/validation-reports/2026-08-30-phase-1-word-visual-preflight.md +0 -22
  47. package/docs/validation-reports/2026-08-30-phase-2-word-visual-preflight.md +0 -24
  48. package/docs/validation-reports/2026-08-30-phase-3-coverage.md +0 -73
  49. package/docs/validation-reports/2026-09-02-multilevel-bullets-visual-review.md +0 -82
  50. package/docs/validation-reports/2026-09-02-multimodal-visual-samples.md +0 -114
  51. package/docs/validation-reports/2026-09-02-visual-failures-preflight.md +0 -79
@@ -11,11 +11,42 @@ import { acceptTrackedChangesInOoxml, rejectTrackedChangesInOoxml, deleteComment
11
11
  import { createSerializer, parseOoxmlSafe } from '../adapters/xml-adapter.js';
12
12
  import { createHash } from 'node:crypto';
13
13
  import { MemoryZip, unzipDocx, zipDocx } from './zip-archive.js';
14
- import { computeRevisionTokenSync, validateRevisionToken, areRevisionTokensEqual } from '../services/revision-token.js';
14
+ import { computeRevisionTokenSync, validateRevisionToken, areRevisionTokensEqual } from '../services/revision-token.js';
15
+ import { createRetryPlan, normalizeErrorWithRecovery } from '../services/error-recovery.js';
15
16
 
16
17
  configureXmlProvider({ DOMParser, XMLSerializer });
17
- const text = (entries, path) => entries.get(path)?.toString('utf8') || null;
18
- const cloneEntries = entries => new Map([...entries].map(([name, data]) => [name, Buffer.from(data)]));
18
+ const text = (entries, path) => entries.get(path)?.toString('utf8') || null;
19
+ const cloneEntries = entries => new Map([...entries].map(([name, data]) => [name, Buffer.from(data)]));
20
+
21
+ function rolledBackOperationPayload(operationResult, operationCount) {
22
+ const rollbackReceipt = receipt => {
23
+ if (!receipt || typeof receipt !== 'object') return receipt;
24
+ if (receipt.attemptedDisposition !== 'applied' && receipt.committed !== true) return { ...receipt };
25
+ return { ...receipt, committed: false, finalDisposition: 'rolled_back' };
26
+ };
27
+ const receipts = (operationResult?.receipts || []).map(rollbackReceipt);
28
+ const receiptByIndex = new Map(receipts.map(receipt => [receipt.operationIndex, receipt]));
29
+ const results = (operationResult?.results || []).map(result => ({
30
+ ...result,
31
+ ...(result.receipt ? {
32
+ receipt: receiptByIndex.get(result.index) || rollbackReceipt(result.receipt)
33
+ } : {})
34
+ }));
35
+ return {
36
+ results,
37
+ receipts,
38
+ executionOrder: operationResult?.executionOrder || [],
39
+ authorsUsed: [],
40
+ rolledBack: true,
41
+ retryPlan: createRetryPlan({
42
+ atomic: true,
43
+ rolledBack: true,
44
+ results,
45
+ receipts,
46
+ operationCount
47
+ })
48
+ };
49
+ }
19
50
 
20
51
  /**
21
52
  * Computes a package-scoped revision token over all uncompressed entries in a DOCX archive.
@@ -84,60 +115,55 @@ export class DocxDocument {
84
115
  get revisionToken() { return this.getRevisionToken(); }
85
116
  preflight(operations, author = getDefaultAuthor(), options = {}) { return preflightOperations(text(this.entries, 'word/document.xml'), operations, author || getDefaultAuthor(), { ...options, _existingCommentDetails: existingCommentDetails(this.entries) }); }
86
117
  toBuffer() { return zipDocx(this.entries); }
87
- async applyOperations(operations, options = {}) {
88
- if (options?.expectedRevision) {
118
+ async applyOperations(operations, options = {}) {
119
+ const failedApply = error => {
120
+ const results = [];
121
+ const receipts = [];
122
+ return {
123
+ status: 'error',
124
+ hasChanges: false,
125
+ written: false,
126
+ rolledBack: true,
127
+ results,
128
+ receipts,
129
+ artifactsChanged: [],
130
+ error: normalizeErrorWithRecovery(error),
131
+ retryPlan: createRetryPlan({
132
+ atomic: true,
133
+ rolledBack: true,
134
+ results,
135
+ receipts,
136
+ operationCount: Array.isArray(operations) ? operations.length : 0
137
+ }),
138
+ validation: { originalIssues: [], generatedIssues: [] },
139
+ buffer: Buffer.from(this.originalBuffer),
140
+ toBuffer: () => Buffer.from(this.originalBuffer)
141
+ };
142
+ };
143
+ if (options?.expectedRevision) {
89
144
  const tokenValidation = validateRevisionToken(options.expectedRevision);
90
145
  if (!tokenValidation.valid) {
91
- return {
92
- status: 'error',
93
- hasChanges: false,
94
- written: false,
95
- rolledBack: true,
96
- results: [],
97
- artifactsChanged: [],
98
- error: {
99
- code: tokenValidation.error?.code || 'INVALID_REVISION_TOKEN',
100
- message: tokenValidation.error?.message || 'Invalid revision token.'
101
- },
102
- validation: { originalIssues: [], generatedIssues: [] },
103
- buffer: Buffer.from(this.originalBuffer),
104
- toBuffer: () => Buffer.from(this.originalBuffer)
105
- };
146
+ return failedApply({
147
+ code: tokenValidation.error?.code || 'INVALID_REVISION_TOKEN',
148
+ message: tokenValidation.error?.message || 'Invalid revision token.'
149
+ });
106
150
  }
107
151
  if (options.expectedRevision.scope !== 'package') {
108
- return {
109
- status: 'error',
110
- hasChanges: false,
111
- written: false,
112
- rolledBack: true,
113
- results: [],
114
- artifactsChanged: [],
115
- error: {
116
- code: 'REVISION_TOKEN_SCOPE_MISMATCH',
117
- message: `Revision token scope mismatch: expected 'package', got '${options.expectedRevision.scope}'.`
118
- },
119
- validation: { originalIssues: [], generatedIssues: [] },
120
- buffer: Buffer.from(this.originalBuffer),
121
- toBuffer: () => Buffer.from(this.originalBuffer)
122
- };
152
+ return failedApply({
153
+ code: 'REVISION_TOKEN_SCOPE_MISMATCH',
154
+ message: `Revision token scope mismatch: expected 'package', got '${options.expectedRevision.scope}'.`,
155
+ expectedScope: 'package',
156
+ actualScope: options.expectedRevision.scope
157
+ });
123
158
  }
124
159
  const currentToken = computePackageRevisionToken(this.entries);
125
160
  if (!areRevisionTokensEqual(currentToken.value, options.expectedRevision.value)) {
126
- return {
127
- status: 'error',
128
- hasChanges: false,
129
- written: false,
130
- rolledBack: true,
131
- results: [],
132
- artifactsChanged: [],
133
- error: {
134
- code: 'REVISION_MISMATCH',
135
- message: `Document revision mismatch: expected '${options.expectedRevision.value}', current is '${currentToken.value}'.`
136
- },
137
- validation: { originalIssues: [], generatedIssues: [] },
138
- buffer: Buffer.from(this.originalBuffer),
139
- toBuffer: () => Buffer.from(this.originalBuffer)
140
- };
161
+ return failedApply({
162
+ code: 'REVISION_MISMATCH',
163
+ message: `Document revision mismatch: expected '${options.expectedRevision.value}', current is '${currentToken.value}'.`,
164
+ expectedRevision: options.expectedRevision,
165
+ currentRevision: currentToken
166
+ });
141
167
  }
142
168
  }
143
169
 
@@ -163,7 +189,17 @@ export class DocxDocument {
163
189
  _existingCommentDetails: existingCommentDetails(working),
164
190
  commentIdAllocator: nextCommentId(working)
165
191
  });
166
- if (result.rolledBack || result.status === 'error') return { ...result, written: false, artifactsChanged: [], validation: { originalIssues, generatedIssues: [] }, buffer: this.originalBuffer, toBuffer: () => Buffer.from(this.originalBuffer) };
192
+ if (result.rolledBack || result.status === 'error') {
193
+ return {
194
+ ...result,
195
+ ...rolledBackOperationPayload(result, Array.isArray(operations) ? operations.length : 0),
196
+ written: false,
197
+ artifactsChanged: [],
198
+ validation: { originalIssues, generatedIssues: [] },
199
+ buffer: this.originalBuffer,
200
+ toBuffer: () => Buffer.from(this.originalBuffer)
201
+ };
202
+ }
167
203
  if (!result.hasChanges) return { ...result, status: result.status || 'ok', written: false, artifactsChanged: [], validation: { originalIssues, generatedIssues: [] }, buffer: Buffer.from(this.originalBuffer), toBuffer: () => Buffer.from(this.originalBuffer) };
168
204
  working.set('word/document.xml', Buffer.from(result.documentXml));
169
205
  await ensureNumberingArtifactsInZip(zip, result.numberingXmlParts, { mergeNumberingXml: mergeNumberingXmlBySchemaOrder });
@@ -197,23 +233,26 @@ export class DocxDocument {
197
233
  this.originalBuffer = Buffer.from(output);
198
234
  const artifactsChanged = [...working].filter(([name, data]) => !originalEntries.has(name) || !data.equals(originalEntries.get(name))).map(([name]) => name);
199
235
  return { ...result, status: result.status || 'ok', written: true, artifactsChanged, validation: { originalIssues, generatedIssues: [] }, buffer: output, inspection: this.inspect(), toBuffer: () => Buffer.from(output) };
200
- } catch (error) {
201
- this.entries = originalEntries;
202
- const generatedIssues = error.issues || [{ source: 'package', code: 'PACKAGE_OPERATION_FAILED', severity: 'error', message: error.message }];
203
- return {
204
- ...(operationResult ? {
205
- results: operationResult.results || [],
206
- receipts: operationResult.receipts || [],
207
- executionOrder: operationResult.executionOrder || [],
208
- authorsUsed: operationResult.authorsUsed || []
209
- } : { results: [] }),
210
- status: 'error',
211
- hasChanges: false,
212
- written: false,
213
- rolledBack: true,
214
- artifactsChanged: [],
215
- error: { code: 'PACKAGE_OPERATION_FAILED', message: error.message },
216
- validation: { originalIssues, generatedIssues },
236
+ } catch (error) {
237
+ this.entries = originalEntries;
238
+ const generatedIssues = error.issues || [{ source: 'package', code: 'PACKAGE_OPERATION_FAILED', severity: 'error', message: error.message }];
239
+ const rollbackPayload = rolledBackOperationPayload(
240
+ operationResult,
241
+ Array.isArray(operations) ? operations.length : 0
242
+ );
243
+ return {
244
+ ...rollbackPayload,
245
+ status: 'error',
246
+ hasChanges: false,
247
+ written: false,
248
+ artifactsChanged: [],
249
+ error: normalizeErrorWithRecovery({
250
+ code: 'PACKAGE_OPERATION_FAILED',
251
+ message: error.message,
252
+ stage: 'package',
253
+ issues: generatedIssues
254
+ }),
255
+ validation: { originalIssues, generatedIssues },
217
256
  issues: generatedIssues,
218
257
  buffer: Buffer.from(this.originalBuffer),
219
258
  toBuffer: () => Buffer.from(this.originalBuffer)
@@ -301,5 +340,17 @@ export class DocxDocument {
301
340
  }
302
341
  }
303
342
 
304
- function packageFailure(source, code, message) { return { status: 'error', hasChanges: false, written: false, rolledBack: true, error: { code, message }, artifactsChanged: [], buffer: Buffer.from(source), toBuffer: () => Buffer.from(source) }; }
343
+ function packageFailure(source, code, message) {
344
+ return {
345
+ status: 'error',
346
+ hasChanges: false,
347
+ written: false,
348
+ rolledBack: true,
349
+ error: normalizeErrorWithRecovery({ code, message }),
350
+ retryPlan: createRetryPlan({ atomic: true, rolledBack: true }),
351
+ artifactsChanged: [],
352
+ buffer: Buffer.from(source),
353
+ toBuffer: () => Buffer.from(source)
354
+ };
355
+ }
305
356
  export function openDocx(input) { return new DocxDocument(input); }
package/node/index.d.ts CHANGED
@@ -27,5 +27,9 @@ export class DocxDocument {
27
27
  }
28
28
  export function computePackageRevisionToken(input: unknown): RevisionToken;
29
29
  export function openDocx(input: Uint8Array): DocxDocument;
30
- export function executeCli(argv: string[]): Promise<Record<string, unknown>>;
31
- export function runCli(argv?: string[], io?: { stdout: { write(value: string): unknown } }): Promise<number>;
30
+ export interface CliIo {
31
+ stdin?: AsyncIterable<string | Uint8Array>;
32
+ stdout: { write(value: string): unknown };
33
+ }
34
+ export function executeCli(argv: string[], io?: Partial<CliIo>): Promise<Record<string, unknown>>;
35
+ export function runCli(argv?: string[], io?: CliIo): Promise<number>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ansonlai/docx-redline-js",
3
- "version": "0.5.4",
3
+ "version": "0.6.0",
4
4
  "description": "Host-independent OOXML reconciliation engine for .docx manipulation with track changes",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -44,7 +44,13 @@
44
44
  "bin/",
45
45
  "orchestration/",
46
46
  "scripts/",
47
- "docs/",
47
+ "!scripts/benchmark-agent-workflow.mjs",
48
+ "!scripts/lib/agent-performance-cases.mjs",
49
+ "docs/AGENT_FAST_START.md",
50
+ "docs/AGENT_KNOWLEDGE_BASE.md",
51
+ "docs/TESTING.md",
52
+ "docs/schemas/document-operations.schema.json",
53
+ "docs/validation-reports/2026-09-12-agent-protocol-rollout.md",
48
54
  "index.js",
49
55
  "index.d.ts",
50
56
  "dist/",
@@ -77,10 +83,11 @@
77
83
  "scripts": {
78
84
  "build": "node scripts/build.mjs",
79
85
  "check:types": "tsc -p tsconfig.types.json && node scripts/check-types.mjs",
80
- "lint": "eslint index.js adapters core engine pipeline services orchestration scripts tests",
86
+ "lint": "eslint index.js adapters core engine pipeline services orchestration scripts examples tests",
81
87
  "test:coverage": "c8 --reporter=text --reporter=json --reporter=json-summary --reports-dir=coverage node scripts/run-tests.mjs",
82
88
  "coverage:gaps": "node scripts/report-coverage-gaps.mjs",
83
89
  "benchmark:session": "node scripts/benchmark-operation-session.mjs",
90
+ "benchmark:agent": "node scripts/benchmark-agent-workflow.mjs",
84
91
  "benchmark:targeting": "node scripts/benchmark-targeting-hot-paths.mjs",
85
92
  "benchmark:tests": "node scripts/benchmark-test-runner.mjs",
86
93
  "profile:routes": "node scripts/profile-route-selection.mjs",
@@ -76,7 +76,7 @@ try {
76
76
 
77
77
  # -------------------------------------------------------------------------
78
78
  # Scenario 1: insert-interior
79
- # Author A (Barry) inserts: "amended by this Agreement."
79
+ # Author A (John) inserts: "amended by this Agreement."
80
80
  # Author B (Anson) inserts "MASTER " before "Agreement"
81
81
  # -------------------------------------------------------------------------
82
82
  Write-Host "1. insert-interior"
@@ -85,8 +85,8 @@ try {
85
85
  $doc.Range(0, 0).Text = "Contract terms "
86
86
 
87
87
  # Author A insertion
88
- $global:word.UserName = "Barry Plasteras"
89
- $global:word.UserInitials = "BP"
88
+ $global:word.UserName = "John Doe"
89
+ $global:word.UserInitials = "JD"
90
90
  $doc.TrackRevisions = $true
91
91
  $endR = $doc.Range($doc.Content.End - 1, $doc.Content.End - 1)
92
92
  $endR.Text = "amended by this Agreement."
@@ -103,7 +103,7 @@ try {
103
103
 
104
104
  # -------------------------------------------------------------------------
105
105
  # Scenario 2: delete-interior
106
- # Author A (Barry) inserts: "The Services will process the Input to generate outputs for Customer."
106
+ # Author A (John) inserts: "The Platform will process the Data to generate deliverables for Client."
107
107
  # Author B (Anson) deletes: "generate "
108
108
  # -------------------------------------------------------------------------
109
109
  Write-Host "2. delete-interior"
@@ -112,11 +112,11 @@ try {
112
112
  $doc.Range(0, 0).Text = "Background. "
113
113
 
114
114
  # Author A insertion
115
- $global:word.UserName = "Barry Plasteras"
116
- $global:word.UserInitials = "BP"
115
+ $global:word.UserName = "John Doe"
116
+ $global:word.UserInitials = "JD"
117
117
  $doc.TrackRevisions = $true
118
118
  $endR = $doc.Range($doc.Content.End - 1, $doc.Content.End - 1)
119
- $endR.Text = "The Services will process the Input to generate outputs for Customer."
119
+ $endR.Text = "The Platform will process the Data to generate deliverables for Client."
120
120
 
121
121
  # Author B deletion inside Author A's insertion
122
122
  $global:word.UserName = "Anson Lai"
@@ -129,8 +129,8 @@ try {
129
129
 
130
130
  # -------------------------------------------------------------------------
131
131
  # Scenario 3: delete-boundary-start
132
- # Author A (Barry) inserts: "Notwithstanding the foregoing, the NDA remains in effect."
133
- # Author B (Anson) deletes: "Notwithstanding the foregoing, "
132
+ # Author A (John) inserts: "Notwithstanding anything to the contrary, the confidentiality terms remain in effect."
133
+ # Author B (Anson) deletes: "Notwithstanding anything to the contrary, "
134
134
  # -------------------------------------------------------------------------
135
135
  Write-Host "3. delete-boundary-start"
136
136
  $doc = $global:word.Documents.Add()
@@ -138,16 +138,16 @@ try {
138
138
  $doc.Range(0, 0).Text = "Section 1. "
139
139
 
140
140
  # Author A insertion
141
- $global:word.UserName = "Barry Plasteras"
142
- $global:word.UserInitials = "BP"
141
+ $global:word.UserName = "John Doe"
142
+ $global:word.UserInitials = "JD"
143
143
  $doc.TrackRevisions = $true
144
144
  $endR = $doc.Range($doc.Content.End - 1, $doc.Content.End - 1)
145
- $endR.Text = "Notwithstanding the foregoing, the NDA remains in effect."
145
+ $endR.Text = "Notwithstanding anything to the contrary, the confidentiality terms remain in effect."
146
146
 
147
147
  # Author B deletion at start of insertion
148
148
  $global:word.UserName = "Anson Lai"
149
149
  $global:word.UserInitials = "AL"
150
- $delWord = "Notwithstanding the foregoing, "
150
+ $delWord = "Notwithstanding anything to the contrary, "
151
151
  $foundPos = Find-RequiredText $doc $delWord "delete-boundary-start"
152
152
  $delRange = $doc.Range($foundPos, $foundPos + $delWord.Length)
153
153
  $delRange.Delete() | Out-Null
@@ -155,8 +155,8 @@ try {
155
155
 
156
156
  # -------------------------------------------------------------------------
157
157
  # Scenario 4: delete-boundary-end
158
- # Author A (Barry) inserts: "subject to Section 2.8 and applicable law."
159
- # Author B (Anson) deletes: " and applicable law."
158
+ # Author A (John) inserts: "subject to Section 4.2 and applicable standards."
159
+ # Author B (Anson) deletes: " and applicable standards."
160
160
  # -------------------------------------------------------------------------
161
161
  Write-Host "4. delete-boundary-end"
162
162
  $doc = $global:word.Documents.Add()
@@ -164,16 +164,16 @@ try {
164
164
  $doc.Range(0, 0).Text = "Compliance: "
165
165
 
166
166
  # Author A insertion
167
- $global:word.UserName = "Barry Plasteras"
168
- $global:word.UserInitials = "BP"
167
+ $global:word.UserName = "John Doe"
168
+ $global:word.UserInitials = "JD"
169
169
  $doc.TrackRevisions = $true
170
170
  $endR = $doc.Range($doc.Content.End - 1, $doc.Content.End - 1)
171
- $endR.Text = "subject to Section 2.8 and applicable law."
171
+ $endR.Text = "subject to Section 4.2 and applicable standards."
172
172
 
173
173
  # Author B deletion at end of insertion
174
174
  $global:word.UserName = "Anson Lai"
175
175
  $global:word.UserInitials = "AL"
176
- $delWord = " and applicable law."
176
+ $delWord = " and applicable standards."
177
177
  $foundPos = Find-RequiredText $doc $delWord "delete-boundary-end"
178
178
  $delRange = $doc.Range($foundPos, $foundPos + $delWord.Length)
179
179
  $delRange.Delete() | Out-Null
@@ -182,7 +182,7 @@ try {
182
182
  # -------------------------------------------------------------------------
183
183
  # Scenario 5: delete-straddle-baseline-insertion
184
184
  # Baseline: "Baseline start "
185
- # Author A (Barry) inserts: "inserted finish."
185
+ # Author A (John) inserts: "inserted finish."
186
186
  # Author B (Anson) deletes: "start inserted" (straddling baseline and insertion)
187
187
  # -------------------------------------------------------------------------
188
188
  Write-Host "5. delete-straddle-baseline-insertion"
@@ -191,8 +191,8 @@ try {
191
191
  $doc.Range(0, 0).Text = "Baseline start "
192
192
 
193
193
  # Author A insertion
194
- $global:word.UserName = "Barry Plasteras"
195
- $global:word.UserInitials = "BP"
194
+ $global:word.UserName = "John Doe"
195
+ $global:word.UserInitials = "JD"
196
196
  $doc.TrackRevisions = $true
197
197
  $endR = $doc.Range($doc.Content.End - 1, $doc.Content.End - 1)
198
198
  $endR.Text = "inserted finish."
@@ -209,7 +209,7 @@ try {
209
209
  # -------------------------------------------------------------------------
210
210
  # Scenario 6: multi-author-stacked
211
211
  # Baseline: "Provision "
212
- # Author A (Barry) inserts: "first draft of the proposal with initial metrics."
212
+ # Author A (John) inserts: "first draft of the proposal with initial metrics."
213
213
  # Author B (Anson) deletes: "of the proposal "
214
214
  # Author C (Chris) deletes: "initial " from the remaining text
215
215
  # -------------------------------------------------------------------------
@@ -219,8 +219,8 @@ try {
219
219
  $doc.Range(0, 0).Text = "Provision "
220
220
 
221
221
  # Author A insertion
222
- $global:word.UserName = "Barry Plasteras"
223
- $global:word.UserInitials = "BP"
222
+ $global:word.UserName = "John Doe"
223
+ $global:word.UserInitials = "JD"
224
224
  $doc.TrackRevisions = $true
225
225
  $endR = $doc.Range($doc.Content.End - 1, $doc.Content.End - 1)
226
226
  $endR.Text = "first draft of the proposal with initial metrics."