Skip to content

Compat: Add minVersionForCollab option to declarative model and deprecate CompatibilityMode#27212

Open
scottn12 wants to merge 20 commits into
microsoft:mainfrom
scottn12:updateDecModelForPolicy
Open

Compat: Add minVersionForCollab option to declarative model and deprecate CompatibilityMode#27212
scottn12 wants to merge 20 commits into
microsoft:mainfrom
scottn12:updateDecModelForPolicy

Conversation

@scottn12
Copy link
Copy Markdown
Contributor

@scottn12 scottn12 commented Apr 30, 2026

Description

This PR updates the declarative model to accept any (valid) minVersionForCollab. This is intended to replace the existing CompatibilityMode type (deprecated in this PR), which accepts either "1" or "2". This was done to ensure the declarative model is aligned to support the latest changes to the cross-client compat policy (see #27064).

The following are the major changes in this PR:

  • MinimumVersionForCollab promoted from a beta to public API. This was done so it could be used in public declarative model APIs.
  • CompatibilityMode param in createDOProviderContainerRuntimeFactory() now also acceptsMinimumVersionForCollab (previously only the CompatibilityMode type).
  • Deprecated CompatibilityMode type (will be removed in 3.0).
  • Deprecated minVersionForCollabOverride (will be removed in 3.0).

Reviewer Guidance

  • Promoting MinimumVersionForCollab will require API council review. If it's easier, this can be split into a separate PR.

Misc

AB#72040

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 30, 2026

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

Based on the diff (310 lines, 25 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

Toggle the reviewer checkboxes above to adjust, then tick the box below to start:

  • Start review

@scottn12 scottn12 marked this pull request as ready for review May 1, 2026 14:51
@scottn12 scottn12 requested a review from a team as a code owner May 1, 2026 14:51
Copilot AI review requested due to automatic review settings May 1, 2026 14:51
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Fluid declarative model and service client APIs to support specifying an explicit minVersionForCollab (now aligned with the newer cross-client compatibility policy), while deprecating the legacy CompatibilityMode abstraction.

Changes:

  • Promote MinimumVersionForCollab to a @public API in @fluidframework/runtime-definitions.
  • Add optional minVersionForCollab?: MinimumVersionForCollab parameters to Tinylicious/Azure client container create/load flows and plumb through to the declarative model runtime factory creation.
  • Deprecate CompatibilityMode (and minVersionForCollabOverride) while keeping compatibilityMode required for now to select runtime defaults.

Reviewed changes

Copilot reviewed 29 out of 30 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pnpm-lock.yaml Adds workspace links for @fluidframework/runtime-definitions where newly imported.
packages/service-clients/tinylicious-client/src/TinyliciousClient.ts Adds minVersionForCollab param and forwards it into runtime factory creation.
packages/service-clients/tinylicious-client/package.json Adds dependency on @fluidframework/runtime-definitions.
packages/service-clients/tinylicious-client/api-report/tinylicious-client.public.api.md Reflects new optional minVersionForCollab API surface.
packages/service-clients/tinylicious-client/api-report/tinylicious-client.beta.api.md Reflects new optional minVersionForCollab API surface.
packages/service-clients/tinylicious-client/api-report/tinylicious-client.alpha.api.md Reflects new optional minVersionForCollab API surface.
packages/service-clients/end-to-end-tests/azure-client/src/test/AzureClientFactory.ts Updates test factory typing to include optional minVersionForCollab.
packages/service-clients/azure-client/src/interfaces.ts Extends internal factory hook typing to accept optional minVersionForCollab.
packages/service-clients/azure-client/src/AzureClient.ts Adds minVersionForCollab param(s) and forwards into runtime factory creation.
packages/service-clients/azure-client/package.json Adds dependency on @fluidframework/runtime-definitions.
packages/service-clients/azure-client/api-report/azure-client.public.api.md Reflects new optional minVersionForCollab API surface and deprecates CompatibilityMode export.
packages/service-clients/azure-client/api-report/azure-client.legacy.public.api.md Same as public API report for legacy build.
packages/service-clients/azure-client/api-report/azure-client.legacy.beta.api.md Same as public API report for legacy beta build.
packages/service-clients/azure-client/api-report/azure-client.beta.api.md Same as public API report for beta build.
packages/runtime/runtime-definitions/src/compatibilityDefinitions.ts Promotes MinimumVersionForCollab from @beta to @public.
packages/runtime/runtime-definitions/api-report/runtime-definitions.public.api.md API report updated to include MinimumVersionForCollab as public.
packages/runtime/runtime-definitions/api-report/runtime-definitions.legacy.public.api.md API report updated to include MinimumVersionForCollab as public.
packages/runtime/runtime-definitions/api-report/runtime-definitions.legacy.beta.api.md Updates extracted tag for MinimumVersionForCollab to public.
packages/runtime/runtime-definitions/api-report/runtime-definitions.legacy.alpha.api.md Updates extracted tag for MinimumVersionForCollab to public.
packages/runtime/runtime-definitions/api-report/runtime-definitions.beta.api.md Updates extracted tag for MinimumVersionForCollab to public.
packages/framework/fluid-static/src/utils.ts Introduces helper to resolve min-version and runtime defaults; keeps compatibility-mode mapping.
packages/framework/fluid-static/src/types.ts Marks CompatibilityMode deprecated in favor of minVersionForCollab.
packages/framework/fluid-static/src/treeRootDataObject.ts Plumbs minVersionForCollab through declarative tree runtime factory creation.
packages/framework/fluid-static/src/rootDataObject.ts Plumbs minVersionForCollab through declarative DO-provider runtime factory creation.
packages/framework/fluid-static/src/compatibilityConfiguration.ts Adds deprecated-import lint suppression for now-deprecated CompatibilityMode.
packages/framework/fluid-static/api-report/fluid-static.public.api.md Marks CompatibilityMode deprecated in extracted API.
packages/framework/fluid-static/api-report/fluid-static.legacy.public.api.md Marks CompatibilityMode deprecated in extracted legacy API.
packages/framework/fluid-static/api-report/fluid-static.legacy.beta.api.md Marks CompatibilityMode deprecated and reflects added minVersionForCollab param in legacy beta API.
packages/framework/fluid-static/api-report/fluid-static.beta.api.md Marks CompatibilityMode deprecated in extracted beta API.
packages/framework/fluid-static/api-report/fluid-static.alpha.api.md Marks CompatibilityMode deprecated in extracted alpha API.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment thread packages/framework/fluid-static/src/utils.ts Outdated
Comment thread packages/framework/fluid-static/src/rootDataObject.ts Outdated
scottn12 and others added 2 commits May 1, 2026 10:56
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@jason-ha
Copy link
Copy Markdown
Contributor

jason-ha commented May 1, 2026

Rather than keeping these two types separate, where practical in API surface have them as a single input.

  • Internally, at the outermost bottleneck filter for CompatibilityMode and convert to the appropriate min version.
  • In API be sure to note what values are deprecated since most callers are using a CompatibilityMode enumeration.
    • Be sure to update in repo use to the non-deprecated pattern. (Do a test build where CompatibilityMode doesn't exist. That change can be kept in a branch that stages the breaking change.)

@scottn12
Copy link
Copy Markdown
Contributor Author

scottn12 commented May 5, 2026

Rather than keeping these two types separate, where practical in API surface have them as a single input.

  • Internally, at the outermost bottleneck filter for CompatibilityMode and convert to the appropriate min version.

  • In API be sure to note what values are deprecated since most callers are using a CompatibilityMode enumeration.

    • Be sure to update in repo use to the non-deprecated pattern. (Do a test build where CompatibilityMode doesn't exist. That change can be kept in a branch that stages the breaking change.)

@jason-ha, updated in latest to do this

Copy link
Copy Markdown
Contributor

@jason-ha jason-ha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to clean up more of the internal APIs but can be done later.

Comment thread packages/framework/fluid-static/src/utils.ts Outdated
Comment thread packages/framework/fluid-static/src/rootDataObject.ts Outdated
Comment on lines +251 to +257
minVersionForCollab: minVersionForCollabOverride,
minVersionForCollab: minVersionForCollabOverride ?? minVersionForCollab,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the preferred logic is:

  • if compatibilityMode is semver (not "1" | "2"), then use it independent of minVersionForCollabOverride
  • else minVersionForCollabOverride if defined
  • else compatibilityMode promoted to semantic version

The subtle difference is that minVersionForCollabOverride really is ignored when new pattern is used.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed minVersionForCollabOverride in latest so this should be simpler now

Comment thread packages/framework/fluid-static/src/compatibilityConfiguration.ts
Comment thread packages/service-clients/azure-client/src/interfaces.ts Outdated
Comment thread packages/service-clients/odsp-client/src/odspClient.ts Outdated
Comment thread packages/service-clients/azure-client/src/AzureClient.ts
@scottn12 scottn12 requested a review from a team as a code owner May 19, 2026 20:07
@scottn12 scottn12 requested a review from jason-ha May 19, 2026 20:32
@github-actions
Copy link
Copy Markdown
Contributor

🔗 No broken links found! ✅

Your attention to detail is admirable.

linkcheck output


> fluid-framework-docs-site@0.0.0 ci:check-links /home/runner/work/FluidFramework/FluidFramework/docs
> start-server-and-test "npm run serve -- --no-open" 3000 check-links

1: starting server using command "npm run serve -- --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-docs-site@0.0.0 serve
> docusaurus serve --no-open

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

> fluid-framework-docs-site@0.0.0 check-links
> linkcheck http://localhost:3000 --skip-file skipped-urls.txt

Crawling...

Stats:
  288859 links
    1925 destination URLs
    2175 URLs ignored
       0 warnings
       0 errors


Copy link
Copy Markdown
Contributor

@jason-ha jason-ha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good
You will need a second change set and 3.0 breaking issue under #23271 to deprecate the *Client methods.
There is a 3.0 issue for removing 1 from CompatibilityMode and I think that can transition to straight up CompatibilityMode removal.

Comment on lines +4 to +5
"rootDir": "../",
"outDir": "../../lib",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha! I just cleaned up to test packages that weren't following the standard pattern ( #27322 ).

Put gen-version is quite inflexible. So, this pattern makes sense.
Please just add a comment that this deviates to accommodate gen-version.

import type { IMember } from "@fluidframework/fluid-static";
import type { ISharedMap, IValueChanged } from "@fluidframework/map/legacy";

export { pkgVersion } from "../packageVersion.js";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love to have some explanation here.
gen-version doesn't make a lot of sense on its own for a test-only package. I think we want to note that it is used to get the current client version.
(A more [logically] ideal value would be something that is shared from FF package; though I don't think we would want to actually try to support that.)
It would also be awesome to rename the constant, which we can do from the export statement with pkgVersion as minVersionForCollab or pkgVersion as currentVersion or pkgVersion as latestVersion or ???

Comment on lines 113 to 117
"build:test": [
"^api-extractor:esnext",
"^build:esnext",
"^tsc"
]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to have build:genver added.
Will conflict with #27265 but I expect this will merge first as that one is waiting on another PR to merge.

}>;
public async createContainer<T extends ContainerSchema>(
containerSchema: T,
minVersionForCollab: MinimumVersionForCollab = "2.0.0",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can OdspClient work with 1.x?
Instead of MinimumVersionForCollab might want to use 2.${bigint}.${bigint} or

MinimumVersionForCollab & `2.${string}`  // which requires visit in 3.0
  or
Exclude<MinimumVersionForCollab, `1.${string}`>  // which allow MinV4C to float up to 3

* DDSes to use) will not be included here but rather on the FluidContainer class itself.
*
* Returned by {@link TinyliciousClient.createContainer} and {@link TinyliciousClient.getContainer} alongside the FluidContainer.
* Returned by `TinyliciousClient.createContainer` and `TinyliciousClient.getContainer` alongside the FluidContainer.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you want to use qualifiers to retain the link.
See https://deepwiki.com/microsoft/tsdoc/2.3-declaration-references#2-syntax-and-grammar
I think adding :(1) to what was there before should work.

let view: TreeView<typeof Table>;

if (location.hash) {
({ container } = await client.getContainer(location.hash.slice(1), containerSchema, "2"));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't trust our linting to catch all cases - here is one that was missed.
Highly recommend a test build with deprecated methods removed. That change can be kept as stash for when the break is made.

---
`createTreeContainerRuntimeFactory` no longer accepts `minVersionForCollabOverride`

The `minVersionForCollabOverride` property on the `props` argument of `createTreeContainerRuntimeFactory` has been removed.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a beta breaking change. It will need to be kept until 2.110 - file deprecation issue under #26499.

};
const odspClient = new OdspClient(clientProps);
const { container, services } = await odspClient.createContainer(containerSchema);
const { container, services } = await odspClient.createContainer(containerSchema, "2.0.0");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use a higher number? We don't want anyone to set 2.0.0 if they could be setting 2.100.0 - especially if onboarding.

* semver string or a legacy `CompatibilityMode` value — into a precise
* `MinimumVersionForCollab`.
*
* TODO: This can be removed when the deprecated CompatibilityMode is removed - AB#73679
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think a preferred format is

Suggested change
* TODO: This can be removed when the deprecated CompatibilityMode is removed - AB#73679
* TODO: AB#73679: This can be removed when the deprecated CompatibilityMode is removed

* In "1" mode we support full interop between 2.x clients and 1.x clients,
* while in "2" mode we only support interop between 2.x clients.
*
* @deprecated Specify the minimum Fluid Framework version directly via the
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[No need to change] I think it would be okay to NOT deprecate CompatiblityMode because it isn't a type that customers use - it mostly adds noise our codebase making it look funny when we use it because we have to.
The deprecation is done via the method overrides.

/**
* The CompatibilityMode selected determines the set of runtime options to use. In "1" mode we support
* full interop with true 1.x clients, while in "2" mode we only support interop with 2.x clients.
* The `minVersionForCollab` determines the set of runtime options to use.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I don't think this description is very accurate. Probably worth reworking this.

* The CompatibilityMode selected determines the set of runtime options to use. In "1" mode we support
* full interop with true 1.x clients, while in "2" mode we only support interop with 2.x clients.
* The `minVersionForCollab` determines the set of runtime options to use.
* For a 1.x `minVersionForCollab` we support full interop with true 1.x clients.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: these specifics probably belong in a @remarks block. The summary block should be reserved for a brief semantic description.

/**
* See {@link CompatibilityMode} and compatibilityModeRuntimeOptions for more details.
* Minimum Fluid Framework version required for collaboration. Accepts a
* {@link @fluidframework/runtime-definitions#MinimumVersionForCollab} semver string;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit

Suggested change
* {@link @fluidframework/runtime-definitions#MinimumVersionForCollab} semver string;
* {@link @fluidframework/runtime-definitions#MinimumVersionForCollab} SemVer string;

* @param schema - The schema for the container
* @param compatibilityMode - Compatibility mode
* @param rootDataObjectFactory - A factory that can construct the root data object.
* @param config - Resolved minimum version for collab (required) and optional runtime option overrides.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: It was a miss that we permitted the abbreviation "collab" in the type name for "MinVersionForCollab". Our guidelines generally call to avoid using abbreviations that aren't truly ubiquitous. "Min", for example, is well understood. "Collab" less so.

At the very least, I would request that we expand "collab" to "collaboration" in documentation and any contexts where we aren't referring to the "MinVersionForCollab" type directly.

/**
* See {@link CompatibilityMode} and compatibilityModeRuntimeOptions for more details.
* Minimum Fluid Framework version required for collaboration. Accepts a
* {@link @fluidframework/runtime-definitions#MinimumVersionForCollab} semver string;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit

Suggested change
* {@link @fluidframework/runtime-definitions#MinimumVersionForCollab} semver string;
* {@link @fluidframework/runtime-definitions#MinimumVersionForCollab} SemVer string;

*
* @deprecated Specify the minimum Fluid Framework version directly via the
* `minVersionForCollab` parameter, which accepts a
* {@link @fluidframework/runtime-definitions#MinimumVersionForCollab} semver string. The
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit

Suggested change
* {@link @fluidframework/runtime-definitions#MinimumVersionForCollab} semver string. The
* {@link @fluidframework/runtime-definitions#MinimumVersionForCollab} SemVer string. The

/**
* Maps CompatibilityMode to a semver valid string that can be passed to the container runtime.
* Resolves the `compatibilityMode` input — either a `MinimumVersionForCollab`
* semver string or a legacy `CompatibilityMode` value — into a precise
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit

Suggested change
* semver string or a legacy `CompatibilityMode` value into a precise
* SemVer string or a legacy `CompatibilityMode` value into a precise

* @param containerSchema - Container schema for the new container.
* @param compatibilityMode - Compatibility mode the container should run in.
* @param minVersionForCollab - Minimum Fluid Framework version required for collaboration, as a
* `MinimumVersionForCollab` semver string (e.g. `"1.0.0"`, `"2.0.0"`).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit (PascalCase "SemVer", and omit the typing information, since that's already captured by the type-system)

Suggested change
* `MinimumVersionForCollab` semver string (e.g. `"1.0.0"`, `"2.0.0"`).
* SemVer string (e.g. `"1.0.0"`, `"2.0.0"`).

/**
* Creates a new detached container instance in the Azure Fluid Relay.
* @typeparam TContainerSchema - Used to infer the the type of 'initialObjects' in the returned container.
* (normally not explicitly specified.)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
* (normally not explicitly specified.)
* This does not normally need to be specified explicitly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Same feedback for instances below)

* @param containerSchema - Container schema for the new container.
* @param compatibilityMode - Legacy {@link @fluidframework/fluid-static#CompatibilityMode} value.
* @returns New detached container instance along with associated services.
* @deprecated Pass a `MinimumVersionForCollab` semver string (e.g. `"2.0.0"`) instead. The legacy
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit

Suggested change
* @deprecated Pass a `MinimumVersionForCollab` semver string (e.g. `"2.0.0"`) instead. The legacy
* @deprecated Pass a `MinimumVersionForCollab` SemVer string (e.g. `"2.0.0"`) instead. The legacy

* @param containerSchema - Container schema used to access data objects in the container.
* @param compatibilityMode - Compatibility mode the container should run in.
* @param minVersionForCollab - Minimum framework version required for collaboration, as a
* `MinimumVersionForCollab` semver string (e.g. `"1.0.0"`, `"2.0.0"`).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit

Suggested change
* `MinimumVersionForCollab` semver string (e.g. `"1.0.0"`, `"2.0.0"`).
* SemVer string (e.g. `"1.0.0"`, `"2.0.0"`).

* @param version - Unique version of the source container in Azure Fluid Relay.
* @param compatibilityMode - Compatibility mode the container should run in.
* @param minVersionForCollab - Minimum framework version required for collaboration, as a
* `MinimumVersionForCollab` semver string (e.g. `"1.0.0"`, `"2.0.0"`).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit

Suggested change
* `MinimumVersionForCollab` semver string (e.g. `"1.0.0"`, `"2.0.0"`).
* SemVer string (e.g. `"1.0.0"`, `"2.0.0"`).

* @param version - Unique version of the source container in Azure Fluid Relay.
* @param compatibilityMode - Legacy {@link @fluidframework/fluid-static#CompatibilityMode} value.
* @returns Loaded container instance at the specified version.
* @deprecated Pass a `MinimumVersionForCollab` semver string (e.g. `"2.0.0"`) instead. The legacy
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit

Suggested change
* @deprecated Pass a `MinimumVersionForCollab` semver string (e.g. `"2.0.0"`) instead. The legacy
* @deprecated Pass a `MinimumVersionForCollab` SemVer string (e.g. `"2.0.0"`) instead. The legacy

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants