Add intrinsically isolated mutation batch previews - #481
Merged
Conversation
JSv4
force-pushed
the
agent/issue-446-isolated-preview
branch
from
August 14, 2026 09:49
1f73500 to
4c2a993
Compare
JSv4
force-pushed
the
agent/issue-445-atomic-batches
branch
2 times, most recently
from
August 14, 2026 10:04
502aba8 to
503f0ed
Compare
JSv4
force-pushed
the
agent/issue-446-isolated-preview
branch
from
August 14, 2026 10:04
4c2a993 to
a179037
Compare
JSv4
force-pushed
the
agent/issue-445-atomic-batches
branch
from
August 14, 2026 11:11
503f0ed to
17b3efe
Compare
JSv4
force-pushed
the
agent/issue-446-isolated-preview
branch
from
August 14, 2026 11:11
a179037 to
3151a7a
Compare
… sentinels Cross-surface review findings on the isolated-preview work (#446). Preview HTML had two definitions. The typed core, stdio, Python and MCP rendered through HtmlConversionOps with comments, annotations, notes and headers/footers on; npm routed its shadow through DocxSessionOps.RenderHtml — the EDITOR's authoring profile — where comments and annotations are off and headers/footers follow pagination. The same batch previewed from a browser and from an agent therefore described materially different documents. The profile now has exactly one owner, HtmlConversionOps.PreviewDocumentOptions()/PreviewBlockOptions(), which the core consumes directly and the browser reaches through two new bridge exports, RenderPreviewHtml and RenderPreviewBlockHtml. Scoped preview diverged the same way and additionally rendered with tracked changes off — a redline preview that hid its own redlines. The npm client raised the annotation execution-metadata warning for any added annotation while .NET requires a created timestamp; npm now uses the .NET predicate. packageHash used "" as its unavailable sentinel on every surface, so a preview.packageHash == applied.packageHash replay assertion passed vacuously when neither could be hashed. It is null/None now and serializes as JSON null. Receipt change sets compared entries with CLR equality while npm compared their serialized wire objects; both sides now compare the serialized projection, the shape the transports actually publish. Docs and enum ripple the feature had not carried: PreviewBatch/previewBatch/ preview_batch in docx_mutation_api.md, npm/README.md and python/README.md (including its Lifecycle table), and MutationPreviewHtmlMode as a Python enum. Two costs are documented rather than changed, because both are public-API decisions rather than defects: receipt enrichment runs unconditionally on the apply path as well as the preview path, with no opt-out, and a preview pays a package clone plus a second open package on top of it; and the typed PreviewBatch overload is isolated only insofar as a callback addresses the shadow session it is handed, which its doc comment now states. Tests: DS469 pins revision classification against pre-existing revisions — the blind spot that made this code hard to reason about — DS470 pins the preview HTML profile to the facade rather than the editor render, DS471 pins the null packageHash on the wire, plus Python wire-decode and enum coverage.
JSv4
marked this pull request as ready for review
August 15, 2026 02:31
# Conflicts: # python/README.md # python/tests/test_atomic_batches.py # tools/python-host/Dispatcher.cs
JSv4
added a commit
that referenced
this pull request
Aug 15, 2026
Brings the structural tracked-revision work up to date with the five sibling PRs from the same stack that landed on main while this branch sat still: #479 atomic batches, #481 isolated preview, #477 introspection, #480 links/bookmarks and #482 images. One file conflicted, Docxodus.Tests/McpServerDispatcherTests.cs, and only because both sides appended tests at the same point. Both sides' tests are kept in full; none was dropped, weakened or merged together. The sole real collision was the test number MCP099, claimed independently by main's MCP099_BatchedTableStep_KeepsTableAnchorMappingInItsReceipt (from d558c00) and by this branch's tracked-changes batch test. Main's numbering is left untouched because it is already merged and referenced, so this branch's test takes the next free number instead: MCP099_TrackChangesBatchPreviewIsIsolatedAndAtomicApplyResolvesRevision -> MCP146_TrackChangesBatchPreviewIsIsolatedAndAtomicApplyResolvesRevision MCP102 and MCP103 do not collide with anything on main and keep their numbers. The batch changeset comparison converged as intended: this branch's f761e49 and main's 983c5bf made the same serialized-projection change, and the merged tree holds exactly one such comparison with no record-equality remnant. The comments part added to OwnedPartRelationships.StoryParts by 96f4c2f survives, and both sides' CHANGELOG entries accumulated under a single [Unreleased]. Verified on the merged tree: the library and the test project build with 0 errors, the full suite is 3712 passed / 0 failed / 3 skipped, and the Release builds of tools/mcp-server and tools/python-host are clean. Test-attribute counts are exactly additive across the merge (Fact 2195, Theory 173, InlineData 1545 = base plus main's additions plus this branch's), confirming no test was lost.
JSv4
added a commit
that referenced
this pull request
Aug 15, 2026
Bring the native content-control work up to date with main after PRs #479, #481, #477, #480, #482 and #485 landed. CHANGELOG.md was the only conflict: both sides added an entry at the top of [Unreleased]. Resolved by keeping both, main's #455 structural tracked revisions first and this branch's #452 native content-control operations second; the rest of main's list is unchanged. Two semantic fixes a clean textual merge would have hidden: - Renumber this branch's MCP content-control tests from MCP146/147/148 to MCP147/148/149. Main's #485 independently claimed MCP146 for MCP146_TrackChangesBatchPreviewIsIsolatedAndAtomicApplyResolvesRevision in the same file, so both sides had defined an MCP146. - docs/architecture/docx_agent_server.md: correct the tools/list count from 17 to 19 (the catalog now registers 19 tools, three lifecycle plus sixteen read/grouped-intent), add docxodus_track_changes to the docxodus_mutations batch-step list so it matches the catalog enum and the dispatcher's accepted set, and add images/content-controls to the grouped-intent enumeration.
JSv4
added a commit
that referenced
this pull request
Aug 15, 2026
Brings the native-image branch up to date with main (PRs #479, #481, #477, #480, #482, #485). Two conflicts, both additive-on-both-sides EditErrorCode collisions, resolved by keeping every code from both sides: - npm/src/types.ts: kept the eight image codes from this branch and main's unresolved_structural_revision. - python/src/docx_scalpel/enums.py: same resolution. The C# EditErrorCode enum in DocxSession.cs auto-merged and remains the single owner; all three surfaces now carry the same 58 codes.
JSv4
added a commit
that referenced
this pull request
Aug 15, 2026
Brings the branch up to date with main, which had advanced by 20 commits (PRs #479, #481, #477, #480, #482, #485 and #484). CHANGELOG.md was the only conflict: both sides appended to the same [Unreleased] / ### Added region. Resolved by keeping every entry from both sides, with this branch's idempotent mutation transaction entry ahead of main's accumulated entries. Main's block is otherwise unchanged, and the historic "[Unreleased] - .NET 8" heading further down the file is untouched. EditErrorCode gained four transaction codes on this branch and image and revision codes on main; the merged enum retains all of them, and the npm and Python mirrors carry this branch's four. The enum has no explicit ordinals and is serialized by name, so the reordering #485 introduced does not affect the wire. This PR remains MCP-transport-only: DocxSessionOps, DocxSessionJson and the WASM bridge are byte-identical to main after the merge.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
GetPackageContentHashValidation
Stacked on the atomic-batch foundation in #479.
Closes #446