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.

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:code and cargo shear are 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/dsl returns 404.
  • 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_dsl module, build.rs, config/schemas/graph_query.schema.json, passes/errors.rs, and the jsonschema dependency.
  • Input no longer derives Deserialize; parse_input is gone.
  • Frontend keeps a single Gql variant plus Frontend::names(). compile, compile_model, compile_local, and validate_normalize keep the explicit frontend argument and match on it, so a new variant is compiler-enforced. The preset is renamed to validate_normalize_gql.
  • canonical_hash no 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) returns Result<Frontend, String> and rejects QUERY_LANGUAGE_JSON with INVALID_ARGUMENT.
  • GetQueryDsl returns NOT_FOUND. The get_query_dsl agent command is removed.
  • One skills catalog: SKILL.gql.md became SKILL.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. The query_graph prompt is the GQL prompt (v2.0.0). get_query_dsl.yml is deleted.
  • Named queries use a Language enum (Gql only) and frontend-keyed YAML (query: {gql: ...}).

Proto

  • Comments updated and the Rust and Go stubs regenerated. Enum values and the GetQueryDsl RPC stay for wire compatibility, so Rails, Workhorse, and Go clients still compile. No [deprecated] attribute, because prost with clippy -D warnings would fail.

Fixtures and tooling

  • Scenario and plan-shape fixtures drop their json: keys. JSON-only fixtures are deleted. The testkit iterates Frontend::names() and panics on unknown keys.
  • Removed the profiler JSON path, the JSON fuzz targets, the orbit dsl CLI subcommand, the skill:sync:orbit task, and the orbit-skill-docs-sync hook. query_dsl is bumped to 13.0.0.

Docs

  • query-language.md is now a GQL reference. intermediary_llm_query_language.md is deleted. Added "Adding a frontend" and "Compilation security" sections to orbit_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 dsl command.
  • Proto: remove GetQueryDsl and 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::Collect and planner Incoming/Both traversal paths.
  • GQL unknown label or relationship errors don't list valid candidates.

feat(query): remove the JSON Query DSL (db42257d)

Edited by Aaron Algutifan

Merge request reports

Loading
Loading