fix(dsl): require rel_types in the path_finding schema
What does this MR do and why?
The path finding schema now marks its relationship types as required and non-empty, as the server has required since !1621 (merged) and the field's description has said since !2650 (merged). Clients that validate against the schema, and agents reading the query DSL, still saw the field as optional. A path query without relationship types is still refused, now by the schema with its own message. The only query newly refused is a traversal or neighbors query carrying an unused path without them.
Related Issues
Relates to #1329 (closed). Follows !2650 (merged), now merged, as suggested in its review.
Testing
The path configuration get_query_dsl serves in the raw format, descriptions left out, before:
"required": ["type", "from", "to", "max_depth"],
"rel_types": { "type": "array", "items": { "$ref": "#/$defs/RelationshipTypeName" }, "maxItems": 10 }After:
"required": ["type", "from", "to", "max_depth", "rel_types"],
"rel_types": { "type": "array", "items": { "$ref": "#/$defs/RelationshipTypeName" }, "minItems": 1, "maxItems": 10 }The answer to a JSON path query without rel_types, before:
schema violation: path_finding requires rel_types to bound fan-out; without it the frontier expands over every edge type
After:
schema violation: "rel_types" is a required property at /path
Checked locally in this repository's CI image (Rust 1.98.1): cargo fmt --all -- --check; the unit tests of compiler, ontology, orbit-versions and orbit-server (823 pass); cargo nextest run -p integration-tests --test local (218 pass); the two data correctness tests with SCENARIO_FILTER=aggregation_over_shortest_path against ClickHouse 26.2 (both pass); cargo clippy -p orbit-server -p compiler --all-targets --all-features -- -D warnings (no warnings); scripts/check-pinned-version.sh and scripts/check-skill-version-bump.py against main. In two runs, three of the four first tries of the data correctness tests stopped at the test kit's 10 s wait for ClickHouse to answer, before any query ran, and passed on nextest's retry.
Performance Analysis
Schema only: a path query is checked for one more required key and a minimum length.
- This merge request does not introduce any performance regression. If a performance regression is expected, explain why.
Agent context: long-form analysis, file-by-file walkthroughs, profiler output, alternatives considered
Files:
config/schemas/graph_query.schema.json:PathConfig.requiredgainsrel_types, andPathConfig.properties.rel_typesgains"minItems": 1. The description stays as !2650 (merged) left it.config/versions.yaml:query_dsl12.1.9 to 12.1.10, the patch bump suggested in !2650 (merged). The$idmajor stays 12, soquery_schema_id_major_matches_query_dsl_versionholds. Path finding and aggregation queries are accepted and rejected as before, but the set of accepted queries does narrow by one shape: the top-levelpathreferencesPathConfigfor every query type, so a traversal or neighbors query that carries apathwithoutrel_types, or with an empty list, compiled before, with thepathunused, and is now refused by the schema. I kept the patch bump because thatpathhas no effect on those queries; if you count the narrowing as a change of contract, I'll bump differently.crates/orbit-server/src/tools/schema.rs:query_schema_requires_non_empty_path_rel_typespins the new shape. A path withoutrel_typesfails with an error naming it, an empty list fails, and a list of two relationship types passes.crates/integration-tests/tests/compiler/dialects/clickhouse.rs(both JSON cases oforbit_query_rejects_aggregation_over_shortest_paths),crates/integration-tests/tests/server/data_correctness/security.rs(aggregation_over_shortest_path_rejects_at_compile) andcrates/integration-tests/tests/server/data_correctness/scenarios/security/aggregation_over_shortest_path_rejects.yaml: the JSONpathgains"rel_types": ["*"].
Why those tests changed: the top-level path property references PathConfig for every query type, and the JSON frontend validates against the schema before check_aggregations runs. Without rel_types these aggregation queries were answered with the schema's required-property error instead of the "aggregation over shortest paths is not supported" rejection they pin, and the ClickHouse dialect test compares that message for equality. ["*"] is what the untyped edge of their GQL counterparts (-[*1..3]->) lowers to, so the JSON and GQL inputs of each case stay the same query.
What stays: check_path keeps its empty rel_types check. GQL lowers an untyped edge to ["*"], so it does not trip there today, but it still guards any input built without the JSON frontend, as the unit tests in passes/validate.rs do.
Nothing else reads the shape. The query language guide and the skill copy have said "Required" since !2650 (merged), so no skill file changes and the skill keeps its version. No generated or synced copy of the schema exists: the condensed DSL is built from it at runtime, and its size test still passes. No test pins the value of query_dsl. I scanned every JSON path object in the repository (tests, fixtures, the query corpus, scenarios, docs, the e2e suite) for one without rel_types or with an empty list: the only ones left are inputs parsed straight into the input type, which the schema never sees.
Issue #1046 proposes rewording the rel_types description around endpoints pinned to concrete IDs. The rule has had no such condition since !1621 (merged), !2650 (merged) took it out of the description, and this states the rule in the schema itself, so that point of #1046 has nothing left to do.
Noticed and not changed here: the structured fuzzer in crates/fuzz/src/generators.rs builds path finding queries without rel_types, so since !1621 (merged) none of them has got past check_path, and now none gets past the schema.