Skip to content

[Fusion] Support parent entity calls in satisfiability validator#9792

Merged
glen-84 merged 1 commit into
mainfrom
gai/support-parent-entity-call-in-satisfiability
May 28, 2026
Merged

[Fusion] Support parent entity calls in satisfiability validator#9792
glen-84 merged 1 commit into
mainfrom
gai/support-parent-entity-call-in-satisfiability

Conversation

@glen-84

@glen-84 glen-84 commented May 28, 2026

Copy link
Copy Markdown
Member

Summary

  • Add a parent entity call edge to the satisfiability validator's source-schema transition logic. When a direct lookup on the stuck type can't be satisfied (e.g. keyless Category reached via Product.category), the validator now walks the access path back to the nearest ancestor whose declaring type has a lookup in the target schema, validates that lookup's {key} requirement against the prefix position, and accepts the transition if it succeeds. This unblocks the federation-gateway-audit parent-entity-call suite.
  • Extract the duplicated ValidateSourceSchemaTransition and path-traversal logic from SatisfiabilityValidator and RequirementsValidator into a new SourceSchemaTransitionHelper, with each caller passing in its own resx keys and requirement-validation closure. The two near-duplicates had already drifted; consolidating prevents future drift and is where the new edge lands cleanly.
  • Consolidate the new strict parent-call with the existing permissive lookupDirectives.Count == 0 branch into one linear flow: direct lookup → strict parent-call → one-to-one path fallback → error. The old branch's CanTransitionThroughPath mixed two jobs — "some ancestor on the path has a lookup + field in the target schema" and "every field on the path exists in the target schema" — gated only on the type having no direct lookup. The first job is the same shape as the new parent-call and is now handled by it (with key-requirement validation rather than existence-only); the second remains as the trailing one-to-one fallback. The existing Type_Without_Lookup_But_Parent_Has_Lookup test now passes via the validated parent-call instead of the existence check.
  • Un-skip ParentEntityCall in SatisfiabilityValidatorTests.
  • Known limitation (called out in a comment): the parent-call branch does not replay suffix fields through the normal field-access rules (@require, @partial, @provides). The main satisfiability loop covers most cases implicitly, but a theoretical gap exists when this edge enables a (type, schema) combination the forward-from-Query traversal does not reach. Closing that gap properly would require restructuring the validator around fixed-point reachability over (type, schema) nodes with lookups as additional entry points; tracking as a Validator V2 follow-up rather than expanding this PR.

Test plan

  • dotnet test src/HotChocolate/Fusion/test/Fusion.Composition.Tests --filter "FullyQualifiedName~SatisfiabilityValidatorTests|FullyQualifiedName~RequirementsValidatorTests" — 63 passed, 1 skipped (RequiresCircular, separate blocker), 0 failed on net8.0, net9.0, and net10.0.
  • Full HotChocolate.Fusion.Composition.Tests — 497 passed, 1 skipped, 0 failed across all three TFMs.

Copilot AI review requested due to automatic review settings May 28, 2026 14:56

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.

Pull request overview

Adds support for "parent entity calls" in the Fusion satisfiability validator so that keyless types reachable via an ancestor field (e.g. Product.category where Category has no lookup in the target schema) are accepted by walking up the access path to an ancestor whose declaring type has a lookup in the target schema and validating that lookup's {key} requirement against the prefix position. The duplicated source-schema transition logic in SatisfiabilityValidator and RequirementsValidator is factored into a new SourceSchemaTransitionHelper so the new branch lands cleanly in one place, and a previously skipped federation-gateway-audit test is enabled.

Changes:

  • Introduce SourceSchemaTransitionHelper with linear flow: direct lookup → parent entity call (with key-requirement validation) → one-to-one path fallback → error.
  • Replace duplicated ValidateSourceSchemaTransition / CanTransitionToSchemaThroughPath bodies in SatisfiabilityValidator and RequirementsValidator with calls into the helper, and add a PathNode.EnumerateFromLeaf() extension used by the satisfiability caller.
  • Un-skip SatisfiabilityValidatorTests.ParentEntityCall.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/HotChocolate/Fusion/src/Fusion.Composition/Satisfiability/SourceSchemaTransitionHelper.cs New shared helper centralizing direct lookup, parent-call, and path-fallback transition checks.
src/HotChocolate/Fusion/src/Fusion.Composition/SatisfiabilityValidator.cs ValidateSourceSchemaTransition now delegates to the helper, passing a leaf-first path and a requirement-validation closure.
src/HotChocolate/Fusion/src/Fusion.Composition/Satisfiability/RequirementsValidator.cs Same delegation, using RequirementsValidator_* resx keys and threading cycle-detection through the closure.
src/HotChocolate/Fusion/src/Fusion.Composition/Extensions/PathNodeExtensions.cs Adds EnumerateFromLeaf() extension used to materialize a leaf-first path list.
src/HotChocolate/Fusion/test/Fusion.Composition.Tests/SatisfiabilityValidatorTests.cs Removes the Skip on ParentEntityCall now that the validator accepts the case.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@glen-84 glen-84 merged commit ea36a50 into main May 28, 2026
144 checks passed
@glen-84 glen-84 deleted the gai/support-parent-entity-call-in-satisfiability branch May 28, 2026 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants