016 Allows Based Schema Traversal
Status: Accepted Supersedes: ADR 010
Date: 2026-06-26
Context:
ADR 010 introduced a three-tier LookupPath fallback chain for pathExistsInSchema:
IncompleteKind() == TopKind— accept all remaining segmentsStr(part).Optional()— match named/optional fieldsAnyString— match pattern constraints
With the move to upstream CUE registry schemas (#30), the schemas are more complex than the hand-written embedded ones. The TopKind check only catches one CUE construct (_). It misses disjunctions ({a: string} | {b: string} where a field exists in one branch) and other structural allowances that CUE’s type system understands.
Verified empirically: LookupPath with Optional() cannot find fields in disjunction branches. The TopKind check doesn’t know about disjunctions at all.
Decision:
Replace the TopKind early-exit check with CUE’s Value.Allows(Selector) method as the final fallback. The new chain:
Str(part).Optional()— match named/optional fields (gives a value to continue walking)AnyString— match pattern constraints (gives a value to continue walking)Allows(Str(part))— CUE-native structural check (accept remaining path, no value to walk)
Allows delegates to CUE’s own type resolution. It returns true when the schema structurally permits a field — handling top type, disjunctions, and any future CUE constructs the SDK adds.
The Allows check is last because it’s a terminal: when it fires, we have no cue.Value to continue walking, so we accept the entire remaining path. The first two tiers are preferred because they produce a value for deeper traversal.
Test schemas are wrapped in #Root definitions to match real-world behavior. CUE registry schemas are always definitions (closed structs), and Allows correctly returns false for undefined fields on closed structs.
A fuzz test (FuzzPathExistsInSchema) verifies the function never panics on arbitrary input.
Consequences:
Benefits:
- Correct handling of disjunctions — fields in any branch are accepted
- Future CUE type system features handled by SDK, not by us
- Fuzz test provides robustness guarantee
- Test schemas match real-world closedness (definitions, not open structs)
Drawbacks:
Allowson open structs (compiled from bare CUE strings without#Def) returns true for any field. This is CUE-correct but means test schemas must use definitions to test rejection behavior.Allowson definitions with...(open definitions) returns false in CUE v0.16 — a known limitation. In practice this doesn’t affect upstream schemas since resolved definitions list all fields explicitly.
Related:
- ADR 010: LookupPath-Based Schema Traversal (superseded)
- ADR 006: CUE Schema Contract Validation