Skip to content

prototype: add DDS-scoped persisted configuration - #28248

Draft
Abram Sanderson (Abe27342) wants to merge 11 commits into
microsoft:mainfrom
Abe27342:abe27342-sharedtree-history-configuration
Draft

Abram Sanderson (Abe27342) wants to merge 11 commits into
microsoft:mainfrom
Abe27342:abe27342-sharedtree-history-configuration

Conversation

@Abe27342

@Abe27342 Abram Sanderson (Abe27342) commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

This is a prototype. It is not yet ready for external review. It is likely it will be split into more manageable PRs as well, though I find it helpful to see the big picture.

Description

Adds a "DDS configuration" mechanism aimed at providing a home for persisted values which:

  • should be consistent between clients at some logical point in time
  • impact some aspect of Fluid's data handling

This mechanism works similarly to DocumentSchema at the container-runtime level. This problem space is relatively nuanced. The details around what portions of the data handling protocol these configurations affect will impact how DDSes must react to changes in the protocol.

See e.g. this table classifying certain sorts of changes:

Use of the setting Example Change rule
Selects a sender's request, and the op carries the selected value Requested ID cluster size, SharedTree op format version Receivers use the value in the op. Different sender defaults can coexist if all readers support the requests.
Selects a document policy without changing ordinary op meaning History retention, framework-supplied attribution retention Apply the policy at a defined point in the ordered history. Do not infer that earlier ops are invalid.
Changes how clients derive shared state from an op An implicit allocation rule or conflict-resolution rule All clients must use the agreed rule at the same logical processing point. Changing only a local option is not sufficient.
Changes whether an operation is allowed Removing a supported schema operation Define how to handle old operations that arrive after the change, including their local optimistic effects.

Persisted configuration consists of everything past the first row. Rows 3 and 4 are particularly tricky. This PR does not aim to make the base mechanism handle them out of the box. Such configuration changes frequently require interesting special-casing (see e.g. IdCompressor "ghost session") and careful analysis from the DDS author.

The base mechanism still aims to support those kinds of functionality by providing DDS authors information about which configuration revision ops were sent under - this is frequently enough to let them implement a scheme that mitigates issues in this realm (e.g. "drop in-flight ops, have original author of those ops notice this on ack and resubmit ops with equivalent intent").

Abram Sanderson (He/Him) and others added 4 commits September 17, 2026 14:26
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Add compositional kernel configuration, sequenced CAS, publication gating, ordered replay, and dark document capability support. Preserve legacy channels and ordinary DDS operation behavior.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Consume the prepared-message bypass before synchronous dirty listeners can submit ordinary edits. Regenerate outstanding explicit document capability requests after reconnect replay completes, outside replayed batches.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Include the new internal runtime option in the exhaustive load-test matrix without enabling the prototype.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Abe27342 Abram Sanderson (Abe27342) changed the title prototype: add DDS-scoped configuration prototype: add DDS-scoped persisted configuration Sep 18, 2026
@github-actions github-actions Bot added area: tools area: runtime Runtime related issues area: dds Issues related to distributed data structures area: repo Repo related work area: website area: tests Tests to add, test infrastructure improvements, etc area: dds: tree changeset-present base: main PRs targeted against main branch labels Sep 18, 2026
@github-actions

github-actions Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Hi! Thank you for opening this PR. Want me to review it?

Based on the diff (7015 lines, 38 files), I've queued these reviewers:

  • Correctness — logic errors, race conditions, lifecycle issues
  • Security — vulnerabilities, secret exposure, injection
  • API Compatibility — breaking changes, release tags, type design
  • Performance — algorithmic regressions, memory leaks
  • Testing — coverage gaps, hollow tests

How this works

  • Adjust the reviewer set by ticking/unticking boxes above. Reviewer toggles alone don't trigger anything.

  • Tick Start review below to dispatch the review fleet.

  • After review finishes, tick Start review again to request another run — it auto-resets after each dispatch.

  • This comment updates as new commits land; your reviewer selections are preserved.

  • Start review

Restore the original document-schema one-attempt policy and remove explicit ensure/retry APIs. Request the capability through normal desired-schema features, gate publication on active persisted state, and preserve configured detached snapshots through runtime feature inputs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Abe27342
Abram Sanderson (Abe27342) force-pushed the abe27342-sharedtree-history-configuration branch from f79eee5 to 2db0863 Compare September 18, 2026 20:21
Abram Sanderson (He/Him) and others added 6 commits September 18, 2026 15:30
Use an additive persisted string set with identity-preserving no-op unions and the existing one-attempt schema policy. Separate local type creation permission from persisted type readiness across runtime, datastore, and kernel gates, including detached rehydration.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Adopt the shared configuration facet with an opt-in factory and a persisted sequenced retention boundary. Keep legacy retention options and collaboration, fork, and undo safety.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Rebase serialized peer state to the summary boundary without changing live peer branches or locally retained forks. Cover stale peer bases, fresh load, continued editing, and local fork safety.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Exercise runtime attributes, summarizers, ordered barriers, detached transitions, snapshot replay, retention safety, and normal optimistic edit recovery on configured Trees.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Update the Tree runtime fixtures and prototype documentation for exact DDS type membership while preserving history behavior.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Abe27342
Abram Sanderson (Abe27342) force-pushed the abe27342-sharedtree-history-configuration branch from 2db0863 to a54eccb Compare September 18, 2026 22:49
@github-actions

Copy link
Copy Markdown
Contributor

🔗 No broken links found! ✅

Your attention to detail is admirable.

linkcheck output

$ start-server-and-test "npm run serve -- --host 127.0.0.1 --no-open" http://127.0.0.1:3000 check-links
1: starting server using command "npm run serve -- --host 127.0.0.1 --no-open"
and when url "[ 'http://127.0.0.1:3000' ]" is responding with HTTP status code 200
running tests using command "npm run check-links"


> fluid-framework-website@0.0.0 serve
> docusaurus serve --host 127.0.0.1 --no-open

[SUCCESS] Serving "build" directory at: http://127.0.0.1:3000/

> fluid-framework-website@0.0.0 check-links
> linkcheck http://127.0.0.1:3000 --skip-file skipped-urls.txt

Crawling...

Stats:
  658102 links
    3579 destination URLs
    3898 URLs ignored
       0 warnings
       0 errors


@github-actions

Copy link
Copy Markdown
Contributor

Bundle size comparison

Base commit: f469232c2bc8613a23c68e4edde1914da0d78f88
Head commit: a54eccbd21bd60fe837225dddeadfa332343d1ce

Notable changes

  • 🔴 fluidFrameworkAllAlpha.js: parsed 801533 → 821391 (+19858), gzip 220527 → 225520 (+4993)
  • 🔴 azureClient.js: parsed 634336 → 640221 (+5885), gzip 169989 → 171687 (+1698)
  • 🔴 odspClient.js: parsed 606600 → 612599 (+5999), gzip 163052 → 164787 (+1735)
  • 🔴 aqueduct.js: parsed 533117 → 539010 (+5893), gzip 143294 → 144937 (+1643)
  • 🔴 fluidFramework.js: parsed 415378 → 431735 (+16357), gzip 117810 → 121918 (+4108)
  • 🔴 sharedTree.js: parsed 404757 → 421107 (+16350), gzip 115252 → 119286 (+4034)
  • 🔴 containerRuntime.js: parsed 315027 → 316864 (+1837), gzip 86438 → 86937 (+499)
  • 🔴 sharedString.js: parsed 170105 → 170808 (+703), gzip 48455 → 48663 (+208)
  • 🔴 experimentalSharedTree.js: parsed 161846 → 162532 (+686), gzip 46722 → 46914 (+192)
  • 🔴 matrix.js: parsed 153720 → 154413 (+693), gzip 44381 → 44582 (+201)
  • 🔴 directory.js: parsed 65669 → 66361 (+692), gzip 18493 → 18690 (+197)
  • 🔴 map.js: parsed 45820 → 46512 (+692), gzip 14120 → 14319 (+199)
Per-bundle deltas

@fluid-example/bundle-size-tests

  • 🔴 fluidFrameworkAllAlpha.js: parsed 801533 → 821391 (+19858), gzip 220527 → 225520 (+4993)
  • 🔴 azureClient.js: parsed 634336 → 640221 (+5885), gzip 169989 → 171687 (+1698)
  • 🔴 odspClient.js: parsed 606600 → 612599 (+5999), gzip 163052 → 164787 (+1735)
  • 🔴 aqueduct.js: parsed 533117 → 539010 (+5893), gzip 143294 → 144937 (+1643)
  • 🔴 fluidFramework.js: parsed 415378 → 431735 (+16357), gzip 117810 → 121918 (+4108)
  • 🔴 sharedTree.js: parsed 404757 → 421107 (+16350), gzip 115252 → 119286 (+4034)
  • 🔴 containerRuntime.js: parsed 315027 → 316864 (+1837), gzip 86438 → 86937 (+499)
  • 🔴 sharedString.js: parsed 170105 → 170808 (+703), gzip 48455 → 48663 (+208)
  • 🔴 experimentalSharedTree.js: parsed 161846 → 162532 (+686), gzip 46722 → 46914 (+192)
  • 🔴 matrix.js: parsed 153720 → 154413 (+693), gzip 44381 → 44582 (+201)
  • loader.js: parsed 147328 → 147344 (+16), gzip 40038 → 40049 (+11)
  • odspDriver.js: parsed 106695 → 106753 (+58), gzip 33227 → 33293 (+66)
  • 🔴 directory.js: parsed 65669 → 66361 (+692), gzip 18493 → 18690 (+197)
  • 578.js: parsed 58686 → 58686 (0), gzip 17657 → 17657 (0)
  • odspPrefetchSnapshot.js: parsed 46463 → 46444 (-19), gzip 15512 → 15522 (+10)
  • 🔴 map.js: parsed 45820 → 46512 (+692), gzip 14120 → 14319 (+199)
  • 252.js: parsed 44384 → 44384 (0), gzip 13741 → 13741 (0)
  • summarizerDelayLoadedModule.js: parsed 31287 → 31287 (0), gzip 7929 → 7929 (0)
  • socketModule.js: parsed 27108 → 27078 (-30), gzip 8069 → 8103 (+34)
  • createNewModule.js: parsed 12464 → 12464 (0), gzip 4792 → 4805 (+13)
  • summaryModule.js: parsed 3888 → 3888 (0), gzip 1874 → 1874 (0)
  • connectionState.js: parsed 909 → 909 (0), gzip 500 → 500 (0)
  • sharedTreeAttributes.js: parsed 845 → 852 (+7), gzip 496 → 505 (+9)
  • debugAssert.js: parsed 429 → 429 (0), gzip 299 → 299 (0)
  • FluidFramework-HashFallback.js: parsed 419 → 419 (0), gzip 313 → 313 (0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: dds: tree area: dds Issues related to distributed data structures area: repo Repo related work area: runtime Runtime related issues area: tests Tests to add, test infrastructure improvements, etc area: tools area: website base: main PRs targeted against main branch changeset-present

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant