docs(cache): amend ADR 0007 implementation sequence (d-iii, d-iv, 009g design, 009g-bis) - #1014
Merged
AnthonyMDev merged 1 commit intoJun 2, 2026
Conversation
… 009g design, 009g-bis Records the architectural decisions made during PR-009d-ii's review on sub-phase 1A.5's implementation sequence: - **PR-009d-iii** added as a small follow-up: `FieldExecutionInfo` memoizes its `CacheFieldKey`, mirroring the existing `_cacheKeyForField` cache pattern. Resolver-side cache field key resolution becomes O(1) per info. - **PR-009d-iv** added as a focused refactor: extract a shared `SelectionWalker` that deduplicates the Selection-case dispatch logic between `DefaultFieldSelectionCollector` (resolve path) and `FieldProjectionCollector` (projection path). Parameterized by per-field action + `InlineFragmentPolicy` + `DeferredFragmentPolicy`. Lands before PR-009f so the dependency tracker uses the unified helper. - **PR-009g design choice**: single-query CTE / correlated subquery on `__typename` to filter inline-fragment fields by runtime type. No two-pass round-trip. The walker still emits projections for every type case (over-fetch at the projection layer), but the SQL filters before the wire crosses, so the IO cost is bounded. - **PR-009g-bis** added as an optional, profile-gated PR: cross-phase `FieldExecutionInfo` sharing. `FieldProjectionCollector.collect(...)` emits `(Set<FieldProjection>, FieldSelectionGrouping)`; executor's `groupFields` accepts the precomputed grouping for cache-path execution sources. Combined with PR-009d-iii's info memo, this eliminates the projection-time / resolve-time recompute of `cacheFieldKey` entirely. Committed only if profiling after PR-009g shows the recompute cost matters on realistic workloads. New entries in 'Alternatives considered': - **F. Two-pass cache read** to resolve runtime type before projection. Rejected: doubles round-trips; the single-query design in PR-009g achieves the same precision without the cost. - **G. Cross-phase `FieldExecutionInfo` sharing as a Phase 1A foundation**. Deferred (not rejected): captured as the optional PR-009g-bis, gated on profiling. Calendar estimate updated: ~19 PRs (~20 with PR-009g-bis), ~5–7 weeks for Phase 1A. The d-i / d-ii split documented previously in Risk and Rollback is retained verbatim — those PRs (PR #1012, PR #1013) are already in flight; the new amendments slot between existing steps rather than restructuring them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Records the architectural decisions surfaced during review of PR-009d-i (#1012) and PR-009d-ii (#1013) on sub-phase 1A.5's implementation sequence. Docs-only — no code changes.
New entries in the implementation sequence table
PR-009d-iii —
FieldExecutionInfomemoizes itsCacheFieldKey, mirroring the existing_cacheKeyForFieldcache pattern. Small follow-up to PR-009d-ii (~30 LoC). Resolver-side cache field key resolution becomes O(1) per info.PR-009d-iv — extract a shared
SelectionWalkerthat deduplicates the Selection-case dispatch logic betweenDefaultFieldSelectionCollector(resolve path) andFieldProjectionCollector(projection path). Parameterized by per-field action +InlineFragmentPolicy+DeferredFragmentPolicy. Lands before PR-009f so the dependency tracker uses the unified helper.PR-009g design choice — the SQL-level type-conditional projection uses a single-query CTE / correlated subquery on
__typenameto filter inline-fragment fields by runtime type. No two-pass round-trip.PR-009g-bis (NEW, optional) — cross-phase
FieldExecutionInfosharing.FieldProjectionCollector.collect(...)emits(Set<FieldProjection>, FieldSelectionGrouping); the executor'sgroupFieldsaccepts the precomputed grouping for cache-path execution sources. Combined with PR-009d-iii's info memo, this eliminates the projection-time / resolve-time recompute ofcacheFieldKeyentirely. Gated on profiling after PR-009g.New 'Alternatives considered' entries
F. Two-pass cache read to resolve runtime type before projection. Rejected — doubles round-trips; the single-query CTE design in PR-009g achieves the same precision without the cost.
G. Cross-phase
FieldExecutionInfosharing as a Phase 1A foundation. Deferred (not rejected) — captured as the optional PR-009g-bis, gated on profiling. The collector-then-resolver dataflow is design-compatible; landing the foundation now doesn't preclude the optimization later.Calendar estimate
Updated from ~17 PRs to ~19 PRs (~20 if PR-009g-bis lands), ~5–7 weeks for Phase 1A.
Why these decisions weren't in the original ADR
The d-i/d-ii split was anticipated in the original ADR's Risk and Rollback section. The d-iii (info memo) and d-iv (walker extraction) cleanups came out of PR-009d-ii's review — the cache field key resolution was duplicated between the executor's
resolveCacheKeyand the new collector'scacheFieldNames, which prompted the refactor into a sharedSelection.Field.cacheFieldKey(...)helper, which in turn made the memoization opportunity visible. The walker extraction surfaced when reviewing whetherFieldProjectionCollectorshould conform toFieldSelectionCollector— the protocol-level unification was forced, but the Selection-case walk logic is genuinely duplicated and benefits from a shared helper.The PR-009g design was always TBD in the original ADR; we now have a concrete commitment (single-query CTE) and a documented rejection of the two-pass alternative.
The PR-009g-bis option emerged from the same review thread — the cross-phase sharing is a real optimization but its payoff depends on policy-resolution cost on realistic workloads, which is best evaluated after PR-009g lands and the IO over-fetch is bounded.
References
🤖 Generated with Claude Code