Skip to content

feat(tree): Add complete schema compatibility diagnostics via new alpha APIs - #28218

Open
Joshua Smithrud (Josmithr) wants to merge 18 commits into
microsoft:mainfrom
Josmithr:tree/more-informative-schema-descrepency-information
Open

Joshua Smithrud (Josmithr) wants to merge 18 commits into
microsoft:mainfrom
Josmithr:tree/more-informative-schema-descrepency-information

Conversation

@Josmithr

Copy link
Copy Markdown
Contributor

Description

Schema compatibility results now explain all detected schema differences, not only the first failures.
The alpha API provides a complete difference list and separate lists of differences that prevent viewing, upgrading, or "equivalence".
This lets applications distinguish accepted differences from compatibility failures.

The analysis compares the view schema, current stored schema, and effective upgrade target.
It includes the root and detached node definitions, as well as staging annotations and persisted metadata.
Diagnostic entries have stable locations and ordering, contain JSON-compatible values, and do not expand recursive schema references.

Compatibility decisions and diagnostic failures now use shared comparison rules.
The existing viewing analysis supplies viewing failures and staged-upgrade information before the upgrade target is constructed.
Stored-schema comparisons report failures in both directions between the current schema and that target.
The checker derives compatibility flags from the corresponding failure lists.
Accepted structural and metadata differences remain separate from these decisions.

Boolean-only callers (the existing beta API) use the same stored-schema comparison rules and can stop at the first failure.
The internal failure representation does not depend on the new alpha diagnostic types.
Existing compatibility behavior, beta diagnostic output, and staged-upgrade accounting are preserved.

Diagnostic collection remains eager. Future optimizations can be considered as needed.

Validation

Differential checks during consolidation matched the baseline for 4,802 schema and policy combinations and 104,991 stored-schema comparison cases.
These checks covered compatibility flags, beta diagnostics, and staged-upgrade status.
Regression tests cover complete failure reporting, detached definitions, constructability, diagnostic locations, and serialization.
After the latest changes, source and test builds, formatting, CLI lint, and all 78 focused tests pass.

Reviewer Guidance

The review process is outlined in the pull request guidelines.

Focus on the separation between difference discovery and compatibility policy, and on the mapping from semantic failures to diagnostic entries.
Every failed compatibility check must have at least one diagnostic entry, while accepted differences must not change compatibility flags.

@github-actions github-actions Bot added area: framework Framework is a tag for issues involving the developer framework. Eg Aqueduct area: tools area: dds Issues related to distributed data structures area: contributor experience area: repo Repo related work area: website public api change Changes to a public API area: dds: tree changeset-present base: main PRs targeted against main branch labels Sep 14, 2026
@github-actions

github-actions Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

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

Based on the diff (2741 lines, 27 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

@github-actions

github-actions Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

🔭 PR Review Fleet Report

Note

This report is generated by an experimental AI review fleet and is provided as a beta feature. Findings are a starting point for discussion, not a gate. Use your own judgement.

Verdict: ⚠️ Approve with Suggestions

0 Alert, 0 Stop, 2 Caution

Findings

Sev # Area File What Fix
🚧 Caution M1 Testing packages/dds/tree/src/simple-tree/api/schemaDiagnostics.ts:2447 The new valueSchema mismatch branch (comparing leaf ValueSchema values, e.g. Number vs. String, when kinds.view === "leaf" && kinds.stored === "leaf") is never exercised through checkSchemaCompatibility/collectSchemaDiagnostics. No test defines two leaf node definitions sharing an identifier but differing in ValueSchema and asserts that allDiscrepancies contains a correctly-populated { mismatch: "valueSchema", location, view, stored, target } entry. A bug in the value-side selection (e.g. reading the wrong side, or the branch's omission of kinds.target from its guard condition) would go undetected. Add a test in schemaCompatibilityTester.spec.ts that builds a view leaf schema (e.g. LeafNodeSchema(id, ValueSchema.Number)) and a stored leaf schema with the same identifier but ValueSchema.String, runs checkSchemaCompatibility, and asserts status.allDiscrepancies includes { mismatch: "valueSchema", location: { nodeType: id }, view: "Number", stored: "String", target: "Number" } (or equivalent), and that this entry appears in viewDiscrepancies.
🚧 Caution M2 Testing packages/dds/tree/src/simple-tree/api/schemaDiagnostics.ts:2521-2527 The new allowUnknownOptionalFields discrepancy (added when viewNode.allowUnknownOptionalFields === true, hardcoded to {view: true, stored: false, target: false}) has zero test coverage anywhere in the diff — no schema in any spec file sets allowUnknownOptionalFields. Similarly, the stagedOptional mismatch entries produced by staging() are only indirectly exercised via checkSchemaCompatibility's boolean flags in stagedSchemaUpgrade.spec.ts; no test inspects allDiscrepancies/equivalenceDiscrepancies content to confirm the mismatch's location/view/stored/target values are correct. A regression that mislabels the location, swaps the boolean sides, or omits the entry while flags coincidentally stay correct would ship undetected. Add a test that creates an object schema with allowUnknownOptionalFields: true and compares it against a stored schema without that flag, asserting status.allDiscrepancies contains { mismatch: "allowUnknownOptionalFields", location: { nodeType: <id> }, view: true, stored: false, target: false }. Also extend the existing staged-optional-upgrade tests to assert on equivalenceDiscrepancies/allDiscrepancies content (mismatch === "stagedOptional" with the expected location), not just the canView/canUpgrade/isEquivalent booleans.

View workflow run

@Josmithr
Joshua Smithrud (Josmithr) marked this pull request as ready for review September 16, 2026 17:36
Copilot AI lite review requested due to automatic review settings September 16, 2026 17:36

Copilot AI left a comment

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.

🟡 Changes recommended

Three unresolved diagnostic-mapping findings remain, including two that can trigger assertions.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds alpha APIs for complete schema compatibility diagnostics, including all detected differences and blockers for viewing, upgrading, and equivalence.

Changes:

  • Adds deterministic, JSON-compatible diagnostic collection and classification.
  • Reuses stored-schema comparison rules for compatibility decisions.
  • Expands API exports, tests, benchmarks, documentation, and release metadata.

Review findings:

  • comparison.ts: Critical (1 vote) — nested staged comparisons can emit an unrepresentable nodeKind failure and assert.
  • schemaDiagnostics.ts: Critical (2 votes) — record comparisons can fail diagnostic mapping and assert.
  • schemaDiagnostics.ts: Moderate (1 vote) — missing targets can produce an incorrect duplicate valueSchema diagnostic.
File summaries
File Summary
packages/framework/fluid-framework/api-report/fluid-framework.alpha.api.md Updates the framework alpha API report.
packages/dds/tree/src/test/simple-tree/api/storedSchema.spec.ts Tests stored-schema diagnostics and serialization.
packages/dds/tree/src/test/simple-tree/api/stagedSchemaUpgrade.spec.ts Updates staged-upgrade compatibility tests.
packages/dds/tree/src/test/simple-tree/api/schemaCompatibilityTester.spec.ts Tests diagnostics and compatibility blockers.
packages/dds/tree/src/test/simple-tree/api/schemaCompatibility.bench.ts Benchmarks compatibility diagnostics.
packages/dds/tree/src/test/shared-tree/schematizingTreeView.spec.ts Tests cached compatibility status.
packages/dds/tree/src/test/feature-libraries/modular-schema/schemaEvolutionExamples.spec.ts Preserves schema evolution compatibility coverage.
packages/dds/tree/src/test/feature-libraries/modular-schema/comparison.spec.ts Tests complete stored-schema failure reporting.
packages/dds/tree/src/simple-tree/index.ts Exports simple-tree APIs.
packages/dds/tree/src/simple-tree/api/tree.ts Exposes alpha compatibility diagnostics.
packages/dds/tree/src/simple-tree/api/storedSchema.ts Provides stored-schema comparison diagnostics.
packages/dds/tree/src/simple-tree/api/snapshotCompatibilityChecker.ts Updates snapshot compatibility results.
packages/dds/tree/src/simple-tree/api/schemaDiagnostics.ts Collects and classifies schema diagnostics.
packages/dds/tree/src/simple-tree/api/schemaCompatibilityTester.ts Derives compatibility flags from failures.
packages/dds/tree/src/simple-tree/api/index.ts Exports diagnostic APIs and types.
packages/dds/tree/src/shared-tree/schematizingTreeView.ts Caches and exposes compatibility status.
packages/dds/tree/src/index.ts Exports tree APIs and diagnostic types.
packages/dds/tree/src/feature-libraries/modular-schema/index.ts Exports modular-schema helpers.
packages/dds/tree/src/feature-libraries/modular-schema/comparison.ts Enumerates stored-schema comparison failures.
packages/dds/tree/src/feature-libraries/index.ts Re-exports comparison helpers.
packages/dds/tree/src/entrypoints/legacy.ts Preserves legacy exports.
packages/dds/tree/src/entrypoints/beta.ts Preserves beta exports.
packages/dds/tree/src/entrypoints/alpha.ts Adds alpha type exports.
packages/dds/tree/api-report/tree.alpha.api.md Updates the tree alpha API report.
packages/dds/merge-tree/src/test/literature/dict.txt Updates spelling dictionary data.
.vscode/settings.json Adds spelling configuration.
.changeset/dirty-comics-roll.md Documents the alpha API release.
Review details

Suppressed comments (1)

packages/dds/tree/src/simple-tree/api/schemaDiagnostics.ts:661

  • When the effective target omits a definition (for example, a staged leaf that is already present in stored but not enabled by the current policy), kinds.view and kinds.stored are both "leaf" while kinds.target is undefined. This still emits a valueSchema entry with no target value, contrary to the preceding comment and duplicating the missingNode diagnostic; require the target to be a leaf before comparing value schemas.
		if (kinds.view === "leaf" && kinds.stored === "leaf") {
  • Files reviewed: 25/27 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/dds/tree/src/simple-tree/api/schemaDiagnostics.ts Outdated
@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: 400b2f1828ff7a5c671e85214dfa28bc20387fdd
Head commit: 02bb4ac6109866228402c197f7a1171c8b4b16ee

Pending — Build - client packages is running. Results will appear here when the build completes.

* @sealed
* @alpha
*/
export type SchemaCompatibilityStatusAlpha = SchemaCompatibilityStatusBeta &

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.

Leaving a comment here since its hard to find the actual API in this PR

---
Add complete schema diagnostics to the alpha API

Alpha tree views expose `allDiscrepancies` through [compatibility](https://fluidframework.com/docs/api/tree/treeview-interface#compatibility-propertysignature).

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.

"compatibility" is documented as "Description of the current compatibility status between the view schema and stored schema."

allDiscrepancies is documented as Contains every distinct discrepancy, including staging and persisted metadata differences.

This leaves me confused. What is this feature?

Stored schema do not have staging. The relationship between view schema and stored schema can't be described by a list of differences. That doesn't make sense. You won't want to list every method someone put on the view schema, or not that ever one is a class associated code and object identity instead of persisted data.

What you can compare are:

  1. The ability of this the provided view schema to view this document based on its stored schema: This logically includes canView, and the status of SchemaUpgrades.
  2. If you were going to generate a stored schema from the TreeViewConfiguration (using the ViewSchema AND the policy provided about which staged schema should be enabled), how that specific stored schema compares to the one in the document: This includes canUpgrade, as well as the potential list of differences I think your trying to include.

I think its fair to classify the existence of unknown optional fields, and persisted metadata differences under either or both scopes.

Before we added the staged schema enablement alpha options to the view config, canUpgrade was fair to put in the first category, and the docs on TreeView.compatibility were more accurate. I think they need to be updated to say TreeViewConfiguration instead of "view schema".

Additionally, assuming it is what I think it is allDiscrepancies then needs to be explicitly clarified to be a diff between the existing stored schema, and the one defined by the TreeViewConfiguration which would be used if creating a document or upgrading a schema based on it (that is assuming it really is comparing stored schema, and not doing something mostly nonsensical, like diffing simple schema for the document and view)

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'll follow up with you on this next week.

constructed
constructer
constructibility
constructability

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.

Why modify merge tree test data?

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.

Unintended. Will revert.

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

Labels

area: contributor experience area: dds: tree area: dds Issues related to distributed data structures area: framework Framework is a tag for issues involving the developer framework. Eg Aqueduct area: repo Repo related work area: tools area: website base: main PRs targeted against main branch changeset-present public api change Changes to a public API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants