Skip to content

Extend inferStartingRevisionIdState to scan side parts (comments.xml / footnotes.xml) #171

@stevenobiajulu

Description

@stevenobiajulu

Context

Discovered during peer review of #142 ([120.7] author config wiring).

The new inferStartingRevisionIdState helper in packages/docx-mcp/src/session/manager.ts is used to seed the session's RevisionIdState so AI-emitted revisions don't collide with pre-existing revision IDs in the document. It scans only document.xml today — not side parts.

The gap

Per ECMA-376, revision IDs (w:id on <w:ins>/<w:del>/*PrChange/etc.) are conceptually unique across the whole package, not per-story. Today:

  1. Session opens a document where comments.xml already contains <w:ins w:id="500"> from a prior reviewer.
  2. inferStartingRevisionIdState scans document.xml only, finds max=10, starts the session at id=11.
  3. AI calls add_comment with ctx → commentReference run wrapped in <w:ins w:id="11"> lands in document.xml. Fine so far.
  4. Eventually after ~490 more AI edits, the counter hits id=500. Now comments.xml has TWO revisions with w:id=500. Invalid OOXML.

For typical sessions with <100 edits, this is a non-issue. For long-running sessions on heavily-reviewed third-party documents, it's a real risk.

Proposal

Pre-load all word/*.xml side parts when seeding RevisionIdState:

  • word/comments.xml
  • word/footnotes.xml
  • word/endnotes.xml
  • word/commentsExtended.xml
  • word/people.xml (if it has w:id attributes)

The helper signature is already variadic (`inferStartingRevisionIdState(...docs: Document[])`) so the caller just needs to pass the side-part documents.

The blocker: side parts are loaded via zip.readText(...) which is async. Making getRevisionContextForSession async cascades to all 10 Table A MCP tools (each becomes `await getRevisionContextForSession(session)`).

Acceptance criteria

  • inferStartingRevisionIdState is called with all available side-part Documents.
  • A regression test opens a document with `comments.xml` containing a high `w:id` (e.g., 500) and asserts the session starts at id > 500.
  • The async cascade through getRevisionContextForSession and the 10 MCP tools is mechanical (each becomes async-aware).
  • Existing tests stay green.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesttracked-changesTracked changes, comments, revision markers

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions