Skip to content

feat(diff): composite — merge footnote/endnote content edits across reviewers (NoteOps composition) #231

Description

@JSv4

Follow-on from the DocxDiff N-way consolidate work (PR #228).

Current behavior

The composite merger does not compose note-scope (footnote/endnote) diffs across reviewers. A reviewer's edit to footnote/endnote content is not merged into the consolidated output. Base notes survive (a reviewer's body edits land, base footnotes are preserved on accept — fixed under PR #228), and a Debug.Assert tripwire in IrCompositeMarkupRenderer guards against a silent note-diff drop (the merger always produces NoteOps == null today). So this is a missing capability, not silent data loss.

The two-way DocxDiff engine already diffs note scopes (IrEditScript.NoteOps, footnotes then endnotes, mirroring WmlComparer.GetRevisions); the composite path simply doesn't merge them yet.

Desired

Extend the composite merger to compose per-note diffs across reviewers — analogous to body composition:

  • Disjoint note edits by different reviewers compose; same-span note edits conflict (per ConflictResolution policy).
  • Attribute each note revision to its contributing reviewer.
  • Render the composed notes (remove the NoteOps-null tripwire once implemented) and represent them in the consolidated revisions + edit-script JSON.

Pointers

  • Docxodus/Ir/Diff/IrCompositeMerger.cs (currently builds IrCompositeScript with NoteOps = null)
  • Docxodus/Ir/Diff/IrCompositeMarkupRenderer.cs (the Debug.Assert(script.NoteOps is null …) tripwire to remove)
  • Two-way precedent: IrEditScript.NoteOps, IrNoteDiff, the note-scope rendering in IrMarkupRenderer.
  • Design context: docs/architecture/ir_diff_engine.md § N-way composite / Consolidate (v1 limitation list).

Acceptance criteria

  • Two reviewers editing footnote/endnote text → composed + per-reviewer attributed in the consolidated notes; same-span note edits recorded as a conflict.
  • reject ≡ base (including notes) under all policies; no silent loss; the NoteOps-null tripwire is removed.
  • Regression: base 2-way parity stays 179/179; full suite green.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions