Skip to content

feat(composition): entity caching directives, proto config types, and generated bindings (1/6)#2944

Draft
SkArchon wants to merge 3 commits into
mainfrom
milinda/entity-caching-1-composition-proto
Draft

feat(composition): entity caching directives, proto config types, and generated bindings (1/6)#2944
SkArchon wants to merge 3 commits into
mainfrom
milinda/entity-caching-1-composition-proto

Conversation

@SkArchon

@SkArchon SkArchon commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Part 1 of 4 — split out from #2777 (jensneuse/entity-caching-v2).

Stack: this PR → router (2/4) → playground/studio (3/4) → benchmark/docs/tooling (4/4).

What's included

  • composition: @openfed__entityCache / @openfed__queryCache / @openfed__requestScoped directive definitions, extraction in normalization-factory.ts, ConfigurationData types, warnings, and tests (incl. fuzz + mapping-rules suites)
  • proto: additive DataSourceConfiguration fields 17–21 and new messages (EntityCacheConfiguration, RootFieldCacheConfiguration, EntityKeyMapping, EntityCacheFieldMapping, CachePopulateConfiguration, CacheInvalidateConfiguration, RequestScopedFieldConfiguration) — purely additive, wire-compatible with older routers (DiscardUnknown parsing)
  • generated bindings: router/gen, connect-go, connect (incl. graphqlmetrics regen side-effects), composition-go bundle
  • shared: router-config serializer for the new proto fields

Notes

  • Rebased onto current main (2026-06-10): composition conflicts resolved (warnings/imports unions), the six directive definition-data blocks ported to main's central src/directive-definition-data module (newDirectiveDefinitionData factory style), tests adapted to the BatchNormalizer class API, and the composition-go bundle dropped (package was removed on main, chore: remove composition-go #2830). Full composition suite green (1301 tests).
  • Old routers ignore the new config fields (caching no-ops); new routers with old configs see empty config (caching off). Rollout order is free.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Add federation caching directives and request-scoped fields for entity/query TTLs, cache populate/invalidate, and explicit argument-to-key mappings.
  • Configuration

    • Runtime/router and engine configurations now surface entity/root-field cache, populate/invalidate rules, and request-scoped field settings.
  • User-facing Validation & Warnings

    • Improved diagnostics for directive placement, key/mapping shape, TTL values, batch/list constraints, and redundant/missing directive usage.
  • Tests

    • Extensive test suites covering entity caching, mapping rules, warnings, and edge cases.

Diff cleanup

Removed from this PR (−1,733 lines): the regenerated connect/src/wg/cosmo/graphqlmetrics/* TS bindings and graphqlmetrics/README.md tweak (generator drift unrelated to entity caching — these files don't exist on main and would reappear for anyone running make generate-go; worth fixing in a separate tiny PR), and the composition meta-docs (CLAUDE.md, AGENTS.md, COMPOSITION_CONVENTIONS.md → moved to the 4/4 PR).

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: daa8c372-8983-47c7-9bde-067b72f6d6d9

📥 Commits

Reviewing files that changed from the base of the PR and between 09d98fb and 51f766e.

⛔ Files ignored due to path filters (2)
  • connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go is excluded by !**/*.pb.go, !**/gen/**
  • router/gen/proto/wg/cosmo/node/v1/node.pb.go is excluded by !**/*.pb.go, !**/gen/**
📒 Files selected for processing (18)
  • composition/src/directive-definition-data/directive-definition-data.ts
  • composition/src/errors/errors.ts
  • composition/src/router-configuration/types.ts
  • composition/src/utils/string-constants.ts
  • composition/src/v1/constants/constants.ts
  • composition/src/v1/constants/directive-definitions.ts
  • composition/src/v1/constants/type-nodes.ts
  • composition/src/v1/normalization/normalization-factory.ts
  • composition/src/v1/normalization/utils.ts
  • composition/src/v1/warnings/params.ts
  • composition/src/v1/warnings/warnings.ts
  • composition/tests/v1/directives/entity-cache-fuzz.test.ts
  • composition/tests/v1/directives/entity-cache-mapping-rules.test.ts
  • composition/tests/v1/directives/entity-caching.test.ts
  • connect/src/wg/cosmo/node/v1/node_pb.ts
  • proto/wg/cosmo/node/v1/node.proto
  • shared/src/router-config/builder.ts
  • shared/src/router-config/graphql-configuration.ts
✅ Files skipped from review due to trivial changes (1)
  • connect/src/wg/cosmo/node/v1/node_pb.ts
🚧 Files skipped from review as they are similar to previous changes (16)
  • composition/src/v1/constants/type-nodes.ts
  • composition/src/v1/warnings/params.ts
  • shared/src/router-config/builder.ts
  • composition/src/utils/string-constants.ts
  • composition/src/router-configuration/types.ts
  • proto/wg/cosmo/node/v1/node.proto
  • composition/src/directive-definition-data/directive-definition-data.ts
  • composition/src/v1/constants/constants.ts
  • shared/src/router-config/graphql-configuration.ts
  • composition/src/v1/normalization/utils.ts
  • composition/tests/v1/directives/entity-caching.test.ts
  • composition/src/v1/constants/directive-definitions.ts
  • composition/src/errors/errors.ts
  • composition/src/v1/warnings/warnings.ts
  • composition/tests/v1/directives/entity-cache-fuzz.test.ts
  • composition/src/v1/normalization/normalization-factory.ts

Walkthrough

This PR adds OpenFed entity caching directives (@openfed__entityCache, @openfed__queryCache, @openfed__cacheInvalidate, @openfed__cachePopulate, @openfed__is) and request-scoped field support (@openfed__requestScoped) to the composition library. It includes validation error messages, directive definitions, a multi-phase extraction and mapping pipeline in the normalization factory, comprehensive test coverage, protobuf schema extensions, and router integration for transmitting cache configuration to the router engine.

Changes

Entity Caching and Request-Scoped Fields

Layer / File(s) Summary
Error Message Helpers
composition/src/errors/errors.ts
Comprehensive validation error messages for entity cache directives: placement rules, type compatibility, key field references, argument mapping constraints, list/scalar shape mismatches, composite key completeness, batch lookup requirements, and nested input object decomposition.
Type Contracts, Constants, and Directive Definitions
composition/src/router-configuration/types.ts, composition/src/utils/string-constants.ts, composition/src/v1/constants/constants.ts, composition/src/v1/constants/directive-definitions.ts, composition/src/v1/constants/type-nodes.ts
Router configuration types for EntityCacheConfig, RootFieldCacheConfig, FieldMappingConfig, CachePopulateConfig, CacheInvalidateConfig, and RequestScopedFieldConfig; string constants for cache directive names and keywords; GraphQL DirectiveDefinitionNode exports for cache and request-scoped directives with argument schemas and default values; REQUIRED_INT_TYPE_NODE for directive arguments.
Directive Registration and Metadata
composition/src/directive-definition-data/directive-definition-data.ts, composition/src/v1/normalization/utils.ts
Directive definition data constants with validation metadata for cache and request-scoped directives, including argument type nodes, required/optional sets, and default values; updates to initializeDirectiveDefinitionDatas() to register new directives in the normalization pipeline.
Warning Types and Diagnostic Factories
composition/src/v1/warnings/params.ts, composition/src/v1/warnings/warnings.ts
Warning parameter types and factory functions for incomplete key mappings, auto-mapping type/argument mismatches, batch key incompleteness, request-scoped single-field usage, and redundant explicit directives.
Entity Caching Extraction and Validation Pipeline
composition/src/v1/normalization/normalization-factory.ts
Multi-phase normalization: Phase 1 extracts @openfed__requestScoped fields and validates/extracts @openfed__entityCache directives; Phase 2 validates root-field cache directives (@openfed__queryCache, @openfed__cacheInvalidate, @openfed__cachePopulate) and constructs entity key mappings via explicit @openfed__is argument targeting or auto-mapping with type/nullability/list-shape validation, batch lookup constraint checking, and per-key OR-semantics composition.
Comprehensive Entity Caching Test Suite
composition/tests/v1/directives/entity-cache-fuzz.test.ts, composition/tests/v1/directives/entity-cache-mapping-rules.test.ts, composition/tests/v1/directives/entity-caching.test.ts
Three test modules covering many scenarios: directive validation, prerequisite enforcement, singular/list return auto-mapping, explicit IS mapping, composite/nested key handling, batch lookup semantics, input-object decomposition, federation behavior, edge cases, and regression tests.
Protobuf Schema and Generated Code
proto/wg/cosmo/node/v1/node.proto, connect/src/wg/cosmo/node/v1/node_pb.ts
Extends DataSourceConfiguration message with five new repeated property fields (field numbers 17–21); adds new Protobuf message types for request-scoped field configuration, entity/root-field cache configuration, entity key mappings, cache populate/invalidate operations; includes generated TypeScript serialization/deserialization classes.
Router Configuration Integration
shared/src/router-config/builder.ts, shared/src/router-config/graphql-configuration.ts
Wires entity caching, request-scoped fields, and cache configurations from composition into DataSourceConfiguration for router consumption; includes protobuf message construction, BigInt conversion of max-age/TTL values, and nested entity key mapping population.

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.68% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically identifies the main changes: adding entity caching directives, proto config types, and generated bindings as part 1 of a multi-part series.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 6

🧹 Nitpick comments (3)
composition/tests/v1/directives/entity-caching.test.ts (1)

683-691: ⚡ Quick win

Use dot-notation in @openfed__is(fields: ...) for nested key paths.

This case uses field-set syntax ("store { id }"). Prefer canonical dot-path syntax ("store.id") so the test matches the declared mapping contract directly.

Suggested test SDL tweak
-              storeKey: ProductStoreKey! `@openfed__is`(fields: "store { id }")
+              storeKey: ProductStoreKey! `@openfed__is`(fields: "store.id")

As per coding guidelines, “Nested keys use dot-notation paths ... and the @openfed__is directive references these dot-notation paths directly.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@composition/tests/v1/directives/entity-caching.test.ts` around lines 683 -
691, The test "config: `@openfed__is` can map scalar and composite keys on the
same field" uses field-set syntax in the subgraph SDL; update the
`@openfed__is`(fields: ...) usage to dot-notation by changing the second directive
from fields: "store { id }" to fields: "store.id" so the test SDL in
getConfigForType(subgraph(...)) matches the canonical nested-key contract.

Source: Coding guidelines

composition/tests/v1/directives/entity-cache-mapping-rules.test.ts (1)

2819-2901: ⚡ Quick win

Strengthen rules 40/40b/40c with exact failure assertions.

These tests only assert errors.length > 0, so unrelated failures can still pass. Pin at least the directive/error family (or exact message) like the rest of this suite.

Based on learnings, “Entity caching validation behavior and type-aware mapping rules are the canonical source of truth in test files entity-caching.test.ts and entity-cache-mapping-rules.test.ts.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@composition/tests/v1/directives/entity-cache-mapping-rules.test.ts` around
lines 2819 - 2901, The tests for rules 40/40b/40c currently only assert
errors.length > 0; tighten them to assert the specific directive/error family so
unrelated failures don't pass. In each test (named "rule 40...", "rule 40b...",
"rule 40c...") replace the loose expect(errors.length).toBeGreaterThan(0) with
an assertion that the errors include the entity-caching validation error from
openfed__entityCache/openfed__queryCache (e.g., check that some error.message
contains the canonical entity caching validation text or a unique token used
elsewhere in entity-caching.test.ts), using normalizeSubgraphFailure's returned
errors array to match on the exact message or error code for the rule. Ensure
the assertion references the same canonical message used in the
entity-caching.test.ts suite so it exactly pins the intended validation failure.

Source: Learnings

composition/tests/v1/directives/entity-cache-fuzz.test.ts (1)

27-37: ⚡ Quick win

Consolidated: explicit return types are missing across new TS test helpers/factories.

The same typing-rule violation appears in all three new test modules. Please annotate explicit return types consistently (: Subgraph, : string, and explicit helper return types) to keep contracts compiler-enforced and uniform.

As per coding guidelines, “Use explicit type annotations for function parameters and return types in TypeScript.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@composition/tests/v1/directives/entity-cache-fuzz.test.ts` around lines 27 -
37, The helper functions in the test files lack explicit return type
annotations; update getConfigForType and any other test helpers in these modules
to declare an explicit return type (rather than relying on inference).
Concretely, add a return type to getConfigForType (the function that returns
internal!.configurationDataByTypeName.get(...)) using the correct type from the
batch normalization result (the Configuration/ConfigurationData type used with
BatchNormalizationSuccess and TypeName), and ensure any other helpers in the new
test modules also have explicit parameter and return type annotations to match
the coding guideline.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@composition/AGENTS.md`:
- Around line 11-25: The fenced code block showing the key mapping pipeline in
AGENTS.md is missing a language identifier; update the triple-backtick that
opens the block to include a language (for example ```text or ```mermaid) so
markdown linting and rendering work correctly. Locate the block that lists the
pipeline symbols (extractKeyFieldSets(), KeyFieldSetData,
keyFieldSetDatasByTypeName, validateKeyFieldSets(), extractPerKeyFieldPaths(),
buildArgumentKeyMappings(), RootFieldCacheConfig.entityKeyMappings) and modify
the opening fence to add the chosen language identifier.

In `@composition/CLAUDE.md`:
- Line 105: The file CLAUDE.md contains fenced code blocks with missing language
identifiers (causing markdownlint MD040); update each triple-backtick fenced
block in CLAUDE.md to include an explicit language tag (e.g., ```bash,
```graphql, ```text) appropriate to the snippet so all code fences (the ```
blocks) have language identifiers and the file passes markdownlint.

In `@composition/src/v1/normalization/normalization-factory.ts`:
- Around line 5822-5825: The cache extraction runs too early:
processRootFieldCacheDirectives() (which calls
getOperationTypeNodeForRootTypeName()) is executed before
operationTypeNodeByTypeName is populated, so move the call that triggers cache
extraction (currently validateAndExtractEntityCachingConfigs()) to after the
step that registers/sets up renamed root operations and populates
operationTypeNodeByTypeName (the block around where operationTypeNodeByTypeName
is filled, currently after extractRequestScopedFields()). Ensure
processRootFieldCacheDirectives() is invoked only after
operationTypeNodeByTypeName exists so
`@openfed__queryCache/`@openfed__cacheInvalidate/@openfed__cachePopulate on
renamed root types (e.g., MyQuery) are discovered.
- Around line 4166-4169: The code silently returns null when inputData is
missing or not an INPUT_OBJECT_TYPE_DEFINITION; instead, before returning, emit
a directive validation error so callers know the nested field type is
scalar/unknown (which breaks auto-mapping). Update the branch that checks
inputData/Kind.INPUT_OBJECT_TYPE_DEFINITION in normalization-factory.ts to call
the factory's existing error/reporting helper (e.g., report a directive
validation error via this.report.../this.add.../this.push... error mechanism)
with a clear message mentioning the inputTypeName and the parent field, then
return null; this will ensure buildCompositeIsMapping() and callers see that an
error was recorded rather than assuming null was already reported.
- Around line 5039-5055: The call to invalidateAutoMappingWithExtraArgument
inside the fieldMappings branch is suppressing the auto-mapping warning by
passing false for the "emit warning" flag, which discards mappings but does not
log the required warning; update the invocation in normalization-factory.ts
(inside the block handling fieldMappings and the variable results) to pass the
flag that causes a warning to be emitted (i.e., true or the named parameter that
enables warnings) so that invalidateAutoMappingWithExtraArgument still clears
all mappings and returns the same control flow but also emits the auto-mapping
warning for the nested input-object case.
- Around line 4634-4646: The duplicate-mapping check crashes because
argumentInfos.find((a) => a.isFieldValue === argInfo.name)! assumes an argument
has isFieldValue equal to the field name; for composite `@openfed__is` this can be
undefined. Update the error construction in the loop that uses mappedKeyFields
and argumentInfos so it does not rely on that find: use argInfo.name directly
(or use argumentInfos.find(a => a.name === argInfo.name)?.name ?? argInfo.name)
when composing the displayed argument text, and/or guard the find with a safe
fallback to avoid throwing; keep references to mappedKeyFields, argumentInfos
and the loop that pushes invalidDirectiveError(IS, ...).

---

Nitpick comments:
In `@composition/tests/v1/directives/entity-cache-fuzz.test.ts`:
- Around line 27-37: The helper functions in the test files lack explicit return
type annotations; update getConfigForType and any other test helpers in these
modules to declare an explicit return type (rather than relying on inference).
Concretely, add a return type to getConfigForType (the function that returns
internal!.configurationDataByTypeName.get(...)) using the correct type from the
batch normalization result (the Configuration/ConfigurationData type used with
BatchNormalizationSuccess and TypeName), and ensure any other helpers in the new
test modules also have explicit parameter and return type annotations to match
the coding guideline.

In `@composition/tests/v1/directives/entity-cache-mapping-rules.test.ts`:
- Around line 2819-2901: The tests for rules 40/40b/40c currently only assert
errors.length > 0; tighten them to assert the specific directive/error family so
unrelated failures don't pass. In each test (named "rule 40...", "rule 40b...",
"rule 40c...") replace the loose expect(errors.length).toBeGreaterThan(0) with
an assertion that the errors include the entity-caching validation error from
openfed__entityCache/openfed__queryCache (e.g., check that some error.message
contains the canonical entity caching validation text or a unique token used
elsewhere in entity-caching.test.ts), using normalizeSubgraphFailure's returned
errors array to match on the exact message or error code for the rule. Ensure
the assertion references the same canonical message used in the
entity-caching.test.ts suite so it exactly pins the intended validation failure.

In `@composition/tests/v1/directives/entity-caching.test.ts`:
- Around line 683-691: The test "config: `@openfed__is` can map scalar and
composite keys on the same field" uses field-set syntax in the subgraph SDL;
update the `@openfed__is`(fields: ...) usage to dot-notation by changing the
second directive from fields: "store { id }" to fields: "store.id" so the test
SDL in getConfigForType(subgraph(...)) matches the canonical nested-key
contract.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d8dcf2de-68c4-4808-a4fa-fb729e5c8ba4

📥 Commits

Reviewing files that changed from the base of the PR and between 6029ae0 and eaced7f.

⛔ Files ignored due to path filters (2)
  • connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go is excluded by !**/*.pb.go, !**/gen/**
  • router/gen/proto/wg/cosmo/node/v1/node.pb.go is excluded by !**/*.pb.go, !**/gen/**
📒 Files selected for processing (26)
  • composition-go/index.global.js
  • composition/AGENTS.md
  • composition/CLAUDE.md
  • composition/COMPOSITION_CONVENTIONS.md
  • composition/src/errors/errors.ts
  • composition/src/router-configuration/types.ts
  • composition/src/utils/string-constants.ts
  • composition/src/v1/constants/constants.ts
  • composition/src/v1/constants/directive-definitions.ts
  • composition/src/v1/constants/type-nodes.ts
  • composition/src/v1/normalization/directive-definition-data.ts
  • composition/src/v1/normalization/normalization-factory.ts
  • composition/src/v1/normalization/utils.ts
  • composition/src/v1/warnings/params.ts
  • composition/src/v1/warnings/warnings.ts
  • composition/tests/v1/directives/entity-cache-fuzz.test.ts
  • composition/tests/v1/directives/entity-cache-mapping-rules.test.ts
  • composition/tests/v1/directives/entity-caching.test.ts
  • connect/src/wg/cosmo/graphqlmetrics/v1/graphqlmetrics-GraphQLMetricsService_connectquery.ts
  • connect/src/wg/cosmo/graphqlmetrics/v1/graphqlmetrics_connect.ts
  • connect/src/wg/cosmo/graphqlmetrics/v1/graphqlmetrics_pb.ts
  • connect/src/wg/cosmo/node/v1/node_pb.ts
  • graphqlmetrics/README.md
  • proto/wg/cosmo/node/v1/node.proto
  • shared/src/router-config/builder.ts
  • shared/src/router-config/graphql-configuration.ts

Comment thread composition/AGENTS.md Outdated
Comment on lines +11 to +25
```
@key(fields: "...") on entity type
extractKeyFieldSets() → KeyFieldSetData { documentNode, normalizedFieldSet, isUnresolvable }
keyFieldSetDatasByTypeName: Map<TypeName, Map<normalizedFieldSet, KeyFieldSetData>>
validateKeyFieldSets() → keyFieldPathsByTypeNameByFieldSet (per-key dot-notation paths)
extractPerKeyFieldPaths() → Array<{normalizedFieldSet, isUnresolvable, fieldPaths: Set<string>}>
buildArgumentKeyMappings() → EntityKeyMappingConfig[] (one per fully-satisfiable key)
RootFieldCacheConfig.entityKeyMappings → serialized to protobuf → router
```

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Specify language for fenced code block.

The code block illustrating the key mapping pipeline should specify a language identifier (e.g., text or mermaid) for proper rendering and to satisfy markdown linting rules.

📝 Proposed fix
-```
+```text
 `@key`(fields: "...") on entity type
     ↓
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
@key(fields: "...") on entity type
extractKeyFieldSets() → KeyFieldSetData { documentNode, normalizedFieldSet, isUnresolvable }
keyFieldSetDatasByTypeName: Map<TypeName, Map<normalizedFieldSet, KeyFieldSetData>>
validateKeyFieldSets() → keyFieldPathsByTypeNameByFieldSet (per-key dot-notation paths)
extractPerKeyFieldPaths() → Array<{normalizedFieldSet, isUnresolvable, fieldPaths: Set<string>}>
buildArgumentKeyMappings() → EntityKeyMappingConfig[] (one per fully-satisfiable key)
RootFieldCacheConfig.entityKeyMappings → serialized to protobuf → router
```
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 11-11: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@composition/AGENTS.md` around lines 11 - 25, The fenced code block showing
the key mapping pipeline in AGENTS.md is missing a language identifier; update
the triple-backtick that opens the block to include a language (for example
```text or ```mermaid) so markdown linting and rendering work correctly. Locate
the block that lists the pipeline symbols (extractKeyFieldSets(),
KeyFieldSetData, keyFieldSetDatasByTypeName, validateKeyFieldSets(),
extractPerKeyFieldPaths(), buildArgumentKeyMappings(),
RootFieldCacheConfig.entityKeyMappings) and modify the opening fence to add the
chosen language identifier.

Source: Linters/SAST tools

Comment thread composition/CLAUDE.md Outdated

### Directive Hierarchy

```

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Missing fenced-code language tags across docs (same MD040 root cause).

Add explicit language identifiers (for example bash, graphql, text) to these fences to satisfy markdownlint and keep docs lint-clean.

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 105-105: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@composition/CLAUDE.md` at line 105, The file CLAUDE.md contains fenced code
blocks with missing language identifiers (causing markdownlint MD040); update
each triple-backtick fenced block in CLAUDE.md to include an explicit language
tag (e.g., ```bash, ```graphql, ```text) appropriate to the snippet so all code
fences (the ``` blocks) have language identifiers and the file passes
markdownlint.

Source: Linters/SAST tools

Comment thread composition/src/v1/normalization/normalization-factory.ts
Comment thread composition/src/v1/normalization/normalization-factory.ts Outdated
Comment thread composition/src/v1/normalization/normalization-factory.ts
Comment thread composition/src/v1/normalization/normalization-factory.ts Outdated
@SkArchon SkArchon force-pushed the milinda/entity-caching-1-composition-proto branch from eaced7f to 41292d0 Compare June 10, 2026 14:25

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
composition/tests/v1/directives/entity-cache-fuzz.test.ts (1)

304-310: ⚡ Quick win

Clarify or remove the bug comment with line number references.

The comment describes a bug and references "lines 4921-4931" which are not in the provided context. This line number reference could be stale, refer to a different file, or become outdated during refactoring. Since the test expects the correct behavior (2 separate mappings), consider either:

  1. Removing the line number reference and just describing the edge case being tested
  2. Adding a file path/context to make the reference meaningful
  3. Replacing the "BUG:" prefix with "EDGE CASE:" if this documents a potential pitfall rather than an actual bug
Suggested revision
-    // BUG: Two independent `@key` directives (`@key`(fields: "id") and `@key`(fields: "sku"))
-    // each produce a single-field EntityKeyMappingConfig. But buildAutoMappings() at lines
-    // 4921-4931 merges all single-field results into ONE EntityKeyMappingConfig with both
-    // field mappings. This makes the router treat them as a composite key (AND semantics:
-    // both "id" AND "sku" must match) instead of independent keys (OR semantics: either
-    // "id" OR "sku" can be used for a cache hit). The merge is wrong — independent keys
-    // should remain separate EntityKeyMappingConfig entries.
+    // EDGE CASE: Two independent `@key` directives (`@key`(fields: "id") and `@key`(fields: "sku"))
+    // must produce separate EntityKeyMappingConfig entries (OR semantics: either "id" OR "sku"
+    // can be used for a cache hit). Incorrectly merging them into ONE EntityKeyMappingConfig
+    // would create a composite key (AND semantics: both must match), breaking cache lookups.
+    // This test verifies the correct behavior: two separate key mappings.
     test('12. Two `@key` directives, arguments satisfy both fully — should produce two key mappings', () => {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@composition/tests/v1/directives/entity-cache-fuzz.test.ts` around lines 304 -
310, Edit the comment in
composition/tests/v1/directives/entity-cache-fuzz.test.ts that starts with
"BUG:" and references specific line numbers for buildAutoMappings(); remove the
stale line number reference and either replace the "BUG:" prefix with "EDGE
CASE:" or rewrite the comment to simply describe the edge case being tested (two
independent `@key` directives producing separate EntityKeyMappingConfig entries)
so it documents intent without relying on fragile line numbers; ensure the
comment still mentions buildAutoMappings() and EntityKeyMappingConfig so readers
can locate the relevant logic.
composition/src/router-configuration/types.ts (1)

89-193: 💤 Low value

Consider using interfaces instead of type aliases for object shapes.

The coding guidelines recommend preferring interfaces over type aliases for object shapes in TypeScript. The new cache configuration types (RequestScopedFieldConfig, EntityCacheConfig, RootFieldCacheConfig, EntityKeyMappingConfig, FieldMappingConfig, CachePopulateConfig, CacheInvalidateConfig) are all pure object shapes that could use interface instead of type.

Example refactor
-export type RequestScopedFieldConfig = {
+export interface RequestScopedFieldConfig {
   fieldName: FieldName;
   typeName: TypeName;
   l1Key: string;
-};
+}

Apply similar changes to the other cache configuration types.

As per coding guidelines: "Prefer interfaces over type aliases for object shapes in TypeScript"

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@composition/src/router-configuration/types.ts` around lines 89 - 193, The
review asks to replace object-shaped type aliases with interfaces; update the
declarations for RequestScopedFieldConfig, EntityCacheConfig,
RootFieldCacheConfig, EntityKeyMappingConfig, FieldMappingConfig,
CachePopulateConfig, and CacheInvalidateConfig from "export type X = { ... }" to
"export interface X { ... }" preserving all property names, types and optional
modifiers (e.g., ?), keeping exports identical so external usage doesn't change,
and leave the existing non-object types (ConfigurationData with Sets/Arrays)
as-is; ensure there are no remaining "type" definitions for these seven symbols
and run type-check to confirm no downstream breakage.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@composition/tests/v1/directives/entity-cache-fuzz.test.ts`:
- Around line 31-37: The helper getConfigForType lacks an explicit return type;
update its signature to include the concrete type returned from
internal.configurationDataByTypeName.get(...) (for example ConfigurationData |
undefined or the exact type stored in configurationDataByTypeName) so TypeScript
explicitly knows the return type; modify the function declaration
getConfigForType(sg: Subgraph, typeName: string): <ReturnType> and ensure
<ReturnType> matches the element type of configurationDataByTypeName (use
TypeName for the key if needed) without changing the function body.

---

Nitpick comments:
In `@composition/src/router-configuration/types.ts`:
- Around line 89-193: The review asks to replace object-shaped type aliases with
interfaces; update the declarations for RequestScopedFieldConfig,
EntityCacheConfig, RootFieldCacheConfig, EntityKeyMappingConfig,
FieldMappingConfig, CachePopulateConfig, and CacheInvalidateConfig from "export
type X = { ... }" to "export interface X { ... }" preserving all property names,
types and optional modifiers (e.g., ?), keeping exports identical so external
usage doesn't change, and leave the existing non-object types (ConfigurationData
with Sets/Arrays) as-is; ensure there are no remaining "type" definitions for
these seven symbols and run type-check to confirm no downstream breakage.

In `@composition/tests/v1/directives/entity-cache-fuzz.test.ts`:
- Around line 304-310: Edit the comment in
composition/tests/v1/directives/entity-cache-fuzz.test.ts that starts with
"BUG:" and references specific line numbers for buildAutoMappings(); remove the
stale line number reference and either replace the "BUG:" prefix with "EDGE
CASE:" or rewrite the comment to simply describe the edge case being tested (two
independent `@key` directives producing separate EntityKeyMappingConfig entries)
so it documents intent without relying on fragile line numbers; ensure the
comment still mentions buildAutoMappings() and EntityKeyMappingConfig so readers
can locate the relevant logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9949845c-df6b-452c-b443-47f939f1b644

📥 Commits

Reviewing files that changed from the base of the PR and between eaced7f and 41292d0.

⛔ Files ignored due to path filters (2)
  • connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go is excluded by !**/*.pb.go, !**/gen/**
  • router/gen/proto/wg/cosmo/node/v1/node.pb.go is excluded by !**/*.pb.go, !**/gen/**
📒 Files selected for processing (19)
  • composition-go/index.global.js
  • composition/src/errors/errors.ts
  • composition/src/router-configuration/types.ts
  • composition/src/utils/string-constants.ts
  • composition/src/v1/constants/constants.ts
  • composition/src/v1/constants/directive-definitions.ts
  • composition/src/v1/constants/type-nodes.ts
  • composition/src/v1/normalization/directive-definition-data.ts
  • composition/src/v1/normalization/normalization-factory.ts
  • composition/src/v1/normalization/utils.ts
  • composition/src/v1/warnings/params.ts
  • composition/src/v1/warnings/warnings.ts
  • composition/tests/v1/directives/entity-cache-fuzz.test.ts
  • composition/tests/v1/directives/entity-cache-mapping-rules.test.ts
  • composition/tests/v1/directives/entity-caching.test.ts
  • connect/src/wg/cosmo/node/v1/node_pb.ts
  • proto/wg/cosmo/node/v1/node.proto
  • shared/src/router-config/builder.ts
  • shared/src/router-config/graphql-configuration.ts
✅ Files skipped from review due to trivial changes (1)
  • connect/src/wg/cosmo/node/v1/node_pb.ts
🚧 Files skipped from review as they are similar to previous changes (13)
  • composition/src/v1/constants/type-nodes.ts
  • composition/src/v1/warnings/params.ts
  • composition/src/v1/normalization/utils.ts
  • composition/src/v1/constants/constants.ts
  • shared/src/router-config/graphql-configuration.ts
  • composition/src/v1/warnings/warnings.ts
  • proto/wg/cosmo/node/v1/node.proto
  • composition/tests/v1/directives/entity-cache-mapping-rules.test.ts
  • composition/src/v1/normalization/directive-definition-data.ts
  • composition/src/v1/constants/directive-definitions.ts
  • composition/tests/v1/directives/entity-caching.test.ts
  • composition/src/errors/errors.ts
  • composition/src/v1/normalization/normalization-factory.ts

Comment thread composition/tests/v1/directives/entity-cache-fuzz.test.ts Outdated
@SkArchon SkArchon changed the title feat(composition): entity caching directives, proto config types, and generated bindings (1/4) feat(composition): entity caching directives, proto config types, and generated bindings (1/6) Jun 10, 2026
@SkArchon SkArchon force-pushed the milinda/entity-caching-1-composition-proto branch from 41292d0 to 09d98fb Compare June 10, 2026 16:31
@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown

Router image scan passed

✅ No security vulnerabilities found in image:

ghcr.io/wundergraph/cosmo/router:sha-88c4c15cbad4d0315be73621edf1c018040de4d6

@coderabbitai coderabbitai Bot 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
composition/src/directive-definition-data/directive-definition-data.ts (1)

1-1124: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix CI-blocking formatting issues in this file.

Line 1 onward: prettier --check is failing for this file, and the lint job exits non-zero. Please run Prettier and commit the formatting changes so CI can pass.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@composition/src/directive-definition-data/directive-definition-data.ts`
around lines 1 - 1124, Prettier formatting errors are causing CI to fail for
this file; run Prettier to reformat and commit the changes. Execute the
formatter (e.g., prettier --write) on
composition/src/directive-definition-data/directive-definition-data.ts, verify
the file compiles, then stage and commit the updated file; no logic changes are
needed—only formatting of the usages of newDirectiveDefinitionData and
newDirectiveArgumentData and the directive constant blocks in this file.

Source: Pipeline failures

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@composition/src/directive-definition-data/directive-definition-data.ts`:
- Around line 1-1124: Prettier formatting errors are causing CI to fail for this
file; run Prettier to reformat and commit the changes. Execute the formatter
(e.g., prettier --write) on
composition/src/directive-definition-data/directive-definition-data.ts, verify
the file compiles, then stage and commit the updated file; no logic changes are
needed—only formatting of the usages of newDirectiveDefinitionData and
newDirectiveArgumentData and the directive constant blocks in this file.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bf123e63-9406-4a62-9bf2-93ee28f9c0f4

📥 Commits

Reviewing files that changed from the base of the PR and between 41292d0 and 09d98fb.

⛔ Files ignored due to path filters (1)
  • connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go is excluded by !**/*.pb.go, !**/gen/**
📒 Files selected for processing (15)
  • composition/src/directive-definition-data/directive-definition-data.ts
  • composition/src/errors/errors.ts
  • composition/src/router-configuration/types.ts
  • composition/src/utils/string-constants.ts
  • composition/src/v1/constants/constants.ts
  • composition/src/v1/constants/directive-definitions.ts
  • composition/src/v1/constants/type-nodes.ts
  • composition/src/v1/normalization/normalization-factory.ts
  • composition/src/v1/normalization/utils.ts
  • composition/src/v1/warnings/params.ts
  • composition/src/v1/warnings/warnings.ts
  • composition/tests/v1/directives/entity-cache-fuzz.test.ts
  • composition/tests/v1/directives/entity-cache-mapping-rules.test.ts
  • composition/tests/v1/directives/entity-caching.test.ts
  • connect/src/wg/cosmo/node/v1/node_pb.ts
💤 Files with no reviewable changes (4)
  • connect/src/wg/cosmo/node/v1/node_pb.ts
  • composition/tests/v1/directives/entity-caching.test.ts
  • composition/src/v1/normalization/normalization-factory.ts
  • composition/tests/v1/directives/entity-cache-mapping-rules.test.ts
✅ Files skipped from review due to trivial changes (1)
  • composition/src/v1/warnings/params.ts
🚧 Files skipped from review as they are similar to previous changes (9)
  • composition/src/utils/string-constants.ts
  • composition/src/v1/constants/type-nodes.ts
  • composition/src/v1/normalization/utils.ts
  • composition/src/v1/warnings/warnings.ts
  • composition/src/v1/constants/directive-definitions.ts
  • composition/src/router-configuration/types.ts
  • composition/src/errors/errors.ts
  • composition/src/v1/constants/constants.ts
  • composition/tests/v1/directives/entity-cache-fuzz.test.ts

@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.41284% with 90 lines in your changes missing coverage. Please review.
✅ Project coverage is 47.28%. Comparing base (09679a7) to head (de55ee3).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...tion/src/v1/normalization/normalization-factory.ts 94.10% 78 Missing and 1 partial ⚠️
composition/src/errors/errors.ts 95.08% 11 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #2944       +/-   ##
===========================================
- Coverage   66.33%   47.28%   -19.06%     
===========================================
  Files         258     1107      +849     
  Lines       27539   151997   +124458     
  Branches        0    10126    +10126     
===========================================
+ Hits        18269    71875    +53606     
- Misses       7818    78309    +70491     
- Partials     1452     1813      +361     
Files with missing lines Coverage Δ
...ctive-definition-data/directive-definition-data.ts 100.00% <100.00%> (ø)
composition/src/utils/string-constants.ts 100.00% <100.00%> (ø)
composition/src/v1/constants/constants.ts 100.00% <100.00%> (ø)
...position/src/v1/constants/directive-definitions.ts 100.00% <100.00%> (ø)
composition/src/v1/constants/type-nodes.ts 100.00% <100.00%> (ø)
composition/src/v1/normalization/utils.ts 89.73% <100.00%> (ø)
composition/src/v1/warnings/params.ts 100.00% <ø> (ø)
composition/src/v1/warnings/warnings.ts 92.66% <100.00%> (ø)
router/gen/proto/wg/cosmo/node/v1/node.pb.go 27.32% <ø> (-2.43%) ⬇️
composition/src/errors/errors.ts 83.75% <95.08%> (ø)
... and 1 more

... and 852 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

… generated bindings

Extracted from jensneuse/entity-caching-v2 (PR #2777) — composition + proto layer only.

- composition: @openfed__entityCache / @openfed__queryCache / @openfed__requestScoped
  directive definitions, extraction in normalization-factory, ConfigurationData types,
  warnings, and tests (incl. fuzz + mapping rules)
- proto: additive DataSourceConfiguration fields 17-21 and new messages
  (EntityCacheConfiguration, RootFieldCacheConfiguration, EntityKeyMapping,
  EntityCacheFieldMapping, CachePopulateConfiguration, CacheInvalidateConfiguration,
  RequestScopedFieldConfiguration)
- regenerated bindings: router/gen, connect-go, connect (incl. graphqlmetrics regen
  side-effects), composition-go bundle
- shared: router-config serializer for the new proto fields

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant