---
layout: layouts/base.njk
title: DOCX MCP Traceability Matrix | Safe DOCX
description: Generated OpenSpec-to-test scenario mapping for the DOCX MCP package.
contentClass: content
permalink: /trust/traceability/safe-docx/
---

# Safe-Docx TS OpenSpec Traceability Matrix

> Auto-generated by `packages/safe-docx/scripts/validate_openspec_coverage.mjs`.
> Do not hand-edit this file.

This matrix maps OpenSpec `#### Scenario:` entries to Allure story mappings extracted from `*.test.ts` files.

## Change: `add-accept-tracked-changes`

| Scenario | Status | Allure Test Files | Notes |
|---|---|---|---|
| accept_changes produces clean document body with no revision markup | covered | `src/tools/add_accept_tracked_changes.test.ts` |  |
| accepted document opens cleanly in Microsoft Word | covered | `src/tools/add_accept_tracked_changes.test.ts` |  |
| original document is not mutated | covered | `src/tools/add_accept_tracked_changes.test.ts` |  |

## Change: `add-auto-normalization-on-open`

| Scenario | Status | Allure Test Files | Notes |
|---|---|---|---|
| conflicting `session_id` and `file_path` is rejected | covered | `src/tools/add_auto_normalization_on_open.test.ts` |  |
| document is normalized on open by default | covered | `src/tools/add_auto_normalization_on_open.test.ts` |  |
| document tools accept file-first entry without pre-open | covered | `src/tools/add_auto_normalization_on_open.test.ts` |  |
| existing session reuse is non-blocking and warns via metadata | covered | `src/tools/add_auto_normalization_on_open.test.ts` |  |
| _bk_* IDs stable across normalization | covered | `src/tools/add_auto_normalization_on_open.test.ts` |  |
| new session creation includes normalization | covered | `src/tools/add_auto_normalization_on_open.test.ts` |  |
| normalization stats in session metadata | covered | `src/tools/add_auto_normalization_on_open.test.ts` |  |
| reuse policy selects most-recently-used session | covered | `src/tools/add_auto_normalization_on_open.test.ts` |  |
| skip_normalization bypasses preprocessing | covered | `src/tools/add_auto_normalization_on_open.test.ts` |  |

## Change: `add-extract-revisions-tool`

| Scenario | Status | Allure Test Files | Notes |
|---|---|---|---|
| changed paragraphs inside table cells are extracted | covered | `src/tools/extract_revisions.test.ts` |  |
| deleted-only paragraph has empty after text | covered | `src/tools/extract_revisions.test.ts` |  |
| extracting revisions from a document with insertions and deletions | covered | `src/tools/extract_revisions.test.ts` |  |
| extracting revisions from a document with no tracked changes | covered | `src/tools/extract_revisions.test.ts` |  |
| extracting revisions includes associated comments | covered | `src/tools/extract_revisions.test.ts` |  |
| inserted-only paragraph has empty before text | covered | `src/tools/extract_revisions.test.ts` |  |
| invalid limit is rejected | covered | `src/tools/extract_revisions.test.ts` |  |
| invalid offset is rejected | covered | `src/tools/extract_revisions.test.ts` |  |
| missing session context returns error | covered | `src/tools/extract_revisions.test.ts` |  |
| new edit invalidates extraction cache | covered | `src/tools/extract_revisions.test.ts` |  |
| offset beyond total returns empty page | covered | `src/tools/extract_revisions.test.ts` |  |
| paginating through revisions with offset and limit | covered | `src/tools/extract_revisions.test.ts` |  |
| property-only changes are included in extraction | covered | `src/tools/extract_revisions.test.ts` |  |
| real DOCX redline with tracked changes extracts correctly | covered | `src/tools/extract_revisions.test.ts` |  |
| repeated extraction at same revision uses cache | covered | `src/tools/extract_revisions.test.ts` |  |
| retrieving subsequent pages with offset | covered | `src/tools/extract_revisions.test.ts` |  |
| session document is unchanged after extraction | covered | `src/tools/extract_revisions.test.ts` |  |
| structurally-empty inserted paragraphs are filtered out | covered | `src/tools/extract_revisions.test.ts` |  |
| two-file comparison then extraction workflow | covered | `src/tools/extract_revisions.test.ts` |  |

## Change: `add-footnote-support`

| Scenario | Status | Allure Test Files | Notes |
|---|---|---|---|
| add footnote successfully | covered | `src/tools/add_footnote_support.test.ts` |  |
| delete footnote successfully | covered | `src/tools/add_footnote_support.test.ts` |  |
| empty document returns empty array | covered | `src/tools/add_footnote_support.test.ts` |  |
| error when after_text not found | covered | `src/tools/add_footnote_support.test.ts` |  |
| error when anchor paragraph not found | covered | `src/tools/add_footnote_support.test.ts` |  |
| error when deleting reserved type | covered | `src/tools/add_footnote_support.test.ts` |  |
| error when note not found | covered | `src/tools/add_footnote_support.test.ts` |  |
| markers absent from edit matching | covered | `src/tools/add_footnote_support.test.ts` |  |
| markers present in document view | covered | `src/tools/add_footnote_support.test.ts` |  |
| read all footnotes | covered | `src/tools/add_footnote_support.test.ts` |  |
| update footnote successfully | covered | `src/tools/add_footnote_support.test.ts` |  |

## Change: `add-multi-agent-plan-merge-phase-1`

| Scenario | Status | Allure Test Files | Notes |
|---|---|---|---|
| init_plan returns revision-bound context | covered | `src/tools/add_multi_agent_plan_merge_phase_1.test.ts` |  |
| init_plan uses file-first session resolution | covered | `src/tools/add_multi_agent_plan_merge_phase_1.test.ts` |  |
| merge_plans can return diagnostics without hard failure | covered | `src/tools/add_multi_agent_plan_merge_phase_1.test.ts` |  |
| merge_plans fails by default when conflicts exist | covered | `src/tools/add_multi_agent_plan_merge_phase_1.test.ts` |  |
| merge_plans reports base-revision conflict | covered | `src/tools/add_multi_agent_plan_merge_phase_1.test.ts` |  |
| merge_plans reports duplicate step IDs | covered | `src/tools/add_multi_agent_plan_merge_phase_1.test.ts` |  |
| merge_plans reports insert-slot collision | covered | `src/tools/add_multi_agent_plan_merge_phase_1.test.ts` |  |
| merge_plans reports overlapping replace ranges | covered | `src/tools/add_multi_agent_plan_merge_phase_1.test.ts` |  |
| merge_plans reports unknown-range conflict for same paragraph | covered | `src/tools/add_multi_agent_plan_merge_phase_1.test.ts` |  |
| merge_plans returns merged artifact when no conflicts | covered | `src/tools/add_multi_agent_plan_merge_phase_1.test.ts` |  |

## Change: `add-run-level-formatting-visibility`

| Scenario | Status | Allure Test Files | Notes |
|---|---|---|---|
| TOON output shows inline formatting tags at run boundaries by default | covered | `src/tools/add_run_level_formatting_visibility.test.ts` |  |
| show_formatting=false suppresses inline tags | covered | `src/tools/add_run_level_formatting_visibility.test.ts` |  |
| writable tag vocabulary matches replace_text new_string vocabulary | covered | `src/tools/add_run_level_formatting_visibility.test.ts` |  |

## Change: `add-safe-docx-batch-apply-and-strict-anchor-resolution`

| Scenario | Status | Allure Test Files | Notes |
|---|---|---|---|
| MCP catalog omits open_document | covered | `src/tools/add_safe_docx_batch_apply_and_strict_anchor_resolution.test.ts` |  |
| canonical names are advertised | covered | `src/tools/add_safe_docx_batch_apply_and_strict_anchor_resolution.test.ts` |  |
| document tools accept file-first entry without pre-open | covered | `src/tools/add_safe_docx_batch_apply_and_strict_anchor_resolution.test.ts` |  |
| legacy aliases are rejected inside plan operations | covered | `src/tools/add_safe_docx_batch_apply_and_strict_anchor_resolution.test.ts` |  |
| legacy aliases are unavailable | covered | `src/tools/add_safe_docx_batch_apply_and_strict_anchor_resolution.test.ts` |  |
| open_document call is rejected as unsupported | covered | `src/tools/add_safe_docx_batch_apply_and_strict_anchor_resolution.test.ts` |  |

## Change: `add-safe-docx-docx-helper-tools`

| Scenario | Status | Allure Test Files | Notes |
|---|---|---|---|
| add root comment to target range | covered | `src/tools/add_safe_docx_docx_helper_tools.test.ts` |  |
| add threaded reply linked to parent comment | covered | `src/tools/add_safe_docx_docx_helper_tools.test.ts` |  |
| auto-repair fixes known safe issues | covered | `src/tools/add_safe_docx_docx_helper_tools.test.ts` |  |
| comment parts are bootstrapped when missing | covered | `src/tools/add_safe_docx_docx_helper_tools.test.ts` |  |
| merge_runs consolidates adjacent format-identical runs | covered | `src/tools/add_safe_docx_docx_helper_tools.test.ts` |  |
| redline validation runs when original baseline is provided | covered | `src/tools/add_safe_docx_docx_helper_tools.test.ts` |  |
| replace_text can normalize fragmented runs before search | covered | `src/tools/add_safe_docx_docx_helper_tools.test.ts` |  |
| replace_text performs formatting-preserving replacement | covered | `src/tools/add_safe_docx_docx_helper_tools.test.ts` |  |
| simplify_redlines merges adjacent same-author tracked wrappers | covered | `src/tools/add_safe_docx_docx_helper_tools.test.ts` |  |
| simplify_redlines reports tracked-change author summary | covered | `src/tools/add_safe_docx_docx_helper_tools.test.ts` |  |
| validate packed or unpacked DOCX inputs | covered | `src/tools/add_safe_docx_docx_helper_tools.test.ts` |  |

## Change: `add-safe-docx-layout-format-controls`

| Scenario | Status | Allure Test Files | Notes |
|---|---|---|---|
| build-time tooling may be external but optional | covered | `src/tools/add_safe_docx_layout_format_controls.test.ts` |  |
| format paragraph spacing by paragraph ID | covered | `src/tools/add_safe_docx_layout_format_controls.test.ts` |  |
| format table row height and cell padding | covered | `src/tools/add_safe_docx_layout_format_controls.test.ts` |  |
| invalid layout values are rejected with structured error | covered | `src/tools/add_safe_docx_layout_format_controls.test.ts` |  |
| no spacer paragraphs are introduced | covered | `src/tools/add_safe_docx_layout_format_controls.test.ts` |  |
| npx runtime remains Python-free | covered | `src/tools/add_safe_docx_layout_format_controls.test.ts` |  |
| paragraph IDs remain stable after layout formatting | covered | `src/tools/add_safe_docx_layout_format_controls.test.ts` |  |

## Change: `add-safe-docx-ts-formatting-parity`

| Scenario | Status | Allure Test Files | Notes |
|---|---|---|---|
| auto-tagged explicit definition gets role model styling | covered | `src/add_safe_docx_ts_formatting_parity.test.ts` |  |
| defined term bolding via <definition> role model | covered | `src/add_safe_docx_ts_formatting_parity.test.ts` |  |
| field-aware visible text does not destroy fields | covered | `src/add_safe_docx_ts_formatting_parity.test.ts` |  |
| fingerprint ignores volatile attributes | covered | `src/add_safe_docx_ts_formatting_parity.test.ts` |  |
| formatting-based header detection | covered | `src/add_safe_docx_ts_formatting_parity.test.ts` |  |
| header semantics accepted via tags for backward compatibility | covered | `src/add_safe_docx_ts_formatting_parity.test.ts` |  |
| insert_paragraph preserves header/definition semantics | covered | `src/add_safe_docx_ts_formatting_parity.test.ts` |  |
| pagination rules deterministic for zero offset | covered | `src/add_safe_docx_ts_formatting_parity.test.ts` |  |
| post-edit invariants prevent empty paragraph stubs | covered | `src/add_safe_docx_ts_formatting_parity.test.ts` |  |
| read_file JSON mode returns node metadata | covered | `src/add_safe_docx_ts_formatting_parity.test.ts` |  |
| read_file returns TOON schema with structure columns | covered | `src/add_safe_docx_ts_formatting_parity.test.ts` |  |
| replace_text preserves mixed-run formatting | covered | `src/add_safe_docx_ts_formatting_parity.test.ts` |  |
| stable style IDs within a session | covered | `src/add_safe_docx_ts_formatting_parity.test.ts` |  |

## Change: `update-safe-docx-download-defaults-and-stable-node-ids`

| Scenario | Status | Allure Test Files | Notes |
|---|---|---|---|
| Anchors unchanged after dual download | covered | `src/tools/update_safe_docx_download_defaults_and_stable_node_ids.test.ts` |  |
| Default download returns both variants | covered | `src/tools/update_safe_docx_download_defaults_and_stable_node_ids.test.ts` |  |
| Download response reports variant and cache details | covered | `src/tools/update_safe_docx_download_defaults_and_stable_node_ids.test.ts` |  |
| Explicit variant override returns subset | covered | `src/tools/update_safe_docx_download_defaults_and_stable_node_ids.test.ts` |  |
| Generating clean artifact does not invalidate redline anchors | covered | `src/tools/update_safe_docx_download_defaults_and_stable_node_ids.test.ts` |  |
| Inserting new paragraph does not renumber unrelated IDs | covered | `src/tools/update_safe_docx_download_defaults_and_stable_node_ids.test.ts` |  |
| Missing intrinsic IDs are backfilled once | covered | `src/tools/update_safe_docx_download_defaults_and_stable_node_ids.test.ts` |  |
| New edit invalidates previous revision cache | covered | `src/tools/update_safe_docx_download_defaults_and_stable_node_ids.test.ts` |  |
| Open response advertises download defaults | covered | `src/tools/update_safe_docx_download_defaults_and_stable_node_ids.test.ts` |  |
| Re-opening unchanged document yields same IDs | covered | `src/tools/update_safe_docx_download_defaults_and_stable_node_ids.test.ts` |  |
| Repeat download reuses cached artifacts | covered | `src/tools/update_safe_docx_download_defaults_and_stable_node_ids.test.ts` |  |
| Two identical signature-block paragraphs remain uniquely addressable | covered | `src/tools/update_safe_docx_download_defaults_and_stable_node_ids.test.ts` |  |

## Change: `update-safe-docx-sessionless-entry-and-session-controls`

| Scenario | Status | Allure Test Files | Notes |
|---|---|---|---|
| clear all sessions requires explicit confirmation | covered | `src/tools/update_safe_docx_sessionless_entry_and_session_controls.test.ts` |  |
| clear one session by id | covered | `src/tools/update_safe_docx_sessionless_entry_and_session_controls.test.ts` |  |
| clear sessions by file path clears all sessions for that file | covered | `src/tools/update_safe_docx_sessionless_entry_and_session_controls.test.ts` |  |
| conflicting `session_id` and `file_path` is rejected | covered | `src/tools/update_safe_docx_sessionless_entry_and_session_controls.test.ts` |  |
| document tools accept file-first entry without pre-open | covered | `src/tools/update_safe_docx_sessionless_entry_and_session_controls.test.ts` |  |
| duplicate document creates independent session | covered | `src/tools/update_safe_docx_sessionless_entry_and_session_controls.test.ts` |  |
| duplicate respects overwrite safety | covered | `src/tools/update_safe_docx_sessionless_entry_and_session_controls.test.ts` |  |
| duplicate uses timestamped destination when path is omitted | covered | `src/tools/update_safe_docx_sessionless_entry_and_session_controls.test.ts` |  |
| existing session reuse is non-blocking and warns via metadata | covered | `src/tools/update_safe_docx_sessionless_entry_and_session_controls.test.ts` |  |
| flexible-whitespace fallback ignores spacing variance | covered | `src/tools/update_safe_docx_sessionless_entry_and_session_controls.test.ts` |  |
| open_document remains callable with deprecation warning | covered | `src/tools/update_safe_docx_sessionless_entry_and_session_controls.test.ts` |  |
| quote-normalization scenarios are test-mapped in Allure coverage | covered | `src/tools/update_safe_docx_sessionless_entry_and_session_controls.test.ts` |  |
| quote-normalized fallback matches smart quotes and ASCII quotes | covered | `src/tools/update_safe_docx_sessionless_entry_and_session_controls.test.ts` |  |
| quote-optional fallback matches quoted and unquoted term references | covered | `src/tools/update_safe_docx_sessionless_entry_and_session_controls.test.ts` |  |
| reuse policy selects most-recently-used session | covered | `src/tools/update_safe_docx_sessionless_entry_and_session_controls.test.ts` |  |

