Draft: feat(query): remove the JSON Query DSL
What does this MR do and why?
Orbit had two query languages: the original JSON Query DSL and GQL, a read-only openCypher subset. This MR removes the JSON DSL, so GQL is the only language for queries, named queries, skills, and docs. A JSON request now fails with a message telling the caller to send GQL. The frontend seam stays, so another language can be added later the same way GQL was.
Related Issues
Relates to https://gitlab.com/gitlab-org/orbit/knowledge-graph/-/work_items/1258
Merge after gitlab-org/gitlab!261947 (merged), which makes Rails send GQL for every user and removes the orbit_gql_queries flag. Until that ships, users with the flag off fail every query. The GQL security review is done: https://gitlab.com/gitlab-com/gl-security/product-security/appsec/threat-models/-/merge_requests/109.
Testing
mise test:fast(2,651), local (222), and container tests (196) pass.mise lint:codeandcargo shearare clean.- GDK end to end with the Rails MR: REST, MCP, named queries, templates, skills, and the dashboard editor work for a user who had the flag off. JSON requests are rejected, and
schema/dslreturns404. - A JSON request now returns:
the JSON Query DSL was removed; send GQL text with language QUERY_LANGUAGE_GQL.
Performance Analysis
GQL queries go through the same compiler and pipeline as before. Only the JSON entry point is gone.
- This merge request does not introduce any performance regression. If a performance regression is expected, explain why.
[skip pinned-version-check]: the formatter files changed here (graph.rs, gql/encode/tests.rs) only rewrite test inputs from JSON to GQL. Output shapes are unchanged.
Agent context: long-form analysis, file-by-file walkthroughs, profiler output, alternatives considered
Compiler
- Deleted the
json_dslmodule,build.rs,config/schemas/graph_query.schema.json,passes/errors.rs, and thejsonschemadependency. Inputno longer derivesDeserialize;parse_inputis gone.Frontendkeeps a singleGqlvariant plusFrontend::names().compile,compile_model,compile_local, andvalidate_normalizekeep the explicit frontend argument andmatchon it, so a new variant is compiler-enforced. The preset is renamed tovalidate_normalize_gql.canonical_hashno longer skips the cursor key.- Validator tests build invalid inputs by parsing GQL and mutating the result (
mutated(),assert_input_rejects()), so defensive validation stays covered with no JSON in the codebase. - Wildcard path finding (
[*1..3]) stays supported on purpose.
Server
query_frontend(language)returnsResult<Frontend, String>and rejectsQUERY_LANGUAGE_JSONwith INVALID_ARGUMENT.GetQueryDslreturns NOT_FOUND. Theget_query_dslagent command is removed.- One skills catalog:
SKILL.gql.mdbecameSKILL.md(v0.34.0). The JSON references and recipes are deleted. The remote repo map helper (scripts/remote_repo_map.py) now sends GQL. I checked every subcommand against the GDK graph, and its unit tests (scripts/dev/test_remote_repo_map.py) cover literal escaping, the query builders, and splitting ID lists at 500. Thequery_graphprompt is the GQL prompt (v2.0.0).get_query_dsl.ymlis deleted. - Named queries use a
Languageenum (Gqlonly) and frontend-keyed YAML (query: {gql: ...}).
Proto
- Comments updated and the Rust and Go stubs regenerated. Enum values and the
GetQueryDslRPC stay for wire compatibility, so Rails, Workhorse, and Go clients still compile. No[deprecated]attribute, because prost with clippy-D warningswould fail.
Fixtures and tooling
- Scenario and plan-shape fixtures drop their
json:keys. JSON-only fixtures are deleted. The testkit iteratesFrontend::names()and panics on unknown keys. - Removed the profiler JSON path, the JSON fuzz targets, the
orbit dslCLI subcommand, theskill:sync:orbittask, and theorbit-skill-docs-synchook.query_dslis bumped to 13.0.0.
Docs
query-language.mdis now a GQL reference.intermediary_llm_query_language.mdis deleted. Added "Adding a frontend" and "Compilation security" sections toorbit_query_frontend.md.
Follow-ups
- Rails: map gRPC NOT_FOUND and INVALID_ARGUMENT to proper MCP errors (MCP shows a generic internal error today).
- glab: remove the
orbit dslcommand. - Proto: remove
GetQueryDsland rename the zero enum value once clients are bumped. - Unbounded-query errors still say "add filters or node_ids", which is JSON-era wording.
- Unreachable
AggExpr::Collectand planner Incoming/Both traversal paths. - GQL unknown label or relationship errors don't list valid candidates.
feat(query): remove the JSON Query DSL (db42257d)