feat(server): add named query discovery RPC

What does this MR do and why?

Since presets moved server-side, the Orbit graph explorer can no longer show the query text when a preset is selected — clients only hold names, so the DSL becomes visible only after executing. This adds a discovery RPC that lists the server-defined named queries with their name, description, and DSL rendered for the calling user, letting the editor populate on selection without clients owning query text again. A Rails follow-up exposes it as GET /api/v4/orbit/templates.

Relates to #955

Testing

  • Unit tests cover the new handler: catalog is non-empty, every entry renders to valid placeholder-free JSON, and identity bindings resolve to the caller's user id.
  • Verified end-to-end with grpcurl against a local mise run dev server backed by GDK: all six embedded named queries returned with bindings and example parameters rendered.

Performance Analysis

Unary RPC over the in-memory embedded catalog (currently six templates); no ClickHouse or Rails round-trip involved.

  • 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

New surface

  • gkg.proto: ListNamedQueries(ListNamedQueriesRequest) returns (ListNamedQueriesResponse); NamedQueryDefinition { name, description, query_dsl }. query_dsl is the rendered query DSL as a JSON string, executable as-is.
  • crates/gkg-server/src/grpc/service.rs: handler authenticates via the standard JWT context, builds named_queries::BindingValues { current_user_id } from claims, and renders each embedded template with NamedQuery::render using example_parameters() for $param placeholders — the same combination the build script uses to compile every template, so render failures here are unreachable in practice and mapped to internal.
  • Rust stubs regenerated via cargo build --features regenerate-protos; Go stubs (clients/gkgpb) via mise proto:go (CI gate proto-go-check).

Rendering semantics

  • $binding (currently only current_user_id) resolves from JWT claims, so the catalog is per-user and the returned DSL reproduces exactly what QUERY_TYPE_NAMED execution would run.
  • $param placeholders are filled with each parameter's declared example value, producing executable JSON rather than placeholder syntax.

Alternatives considered

  • Echoing the rendered DSL inside the query response (injected before the result JSON is sent). Dropped: it only populates the editor after execution, changes the raw response schema (schema + RAW_OUTPUT_FORMAT_VERSION churn), and doesn't give clients a catalog. A discovery RPC restores populate-on-select and lets the frontend drop its hardcoded preset list entirely.
  • Route naming: the REST leg will be GET /api/v4/orbit/templates (matches existing single-word orbit routes); the gRPC/server-side concept keeps the canonical "named query" term per CONTEXT.md.

Docs updated in this MR

  • docs/design-documents/querying/README.md: replaced the "There is no discovery RPC" statement with the as-built catalog description.
  • docs/dev/agents-reference-index.md: named-query row now mentions ListNamedQueries.

Follow-ups (separate MRs, other repos)

  • Rails: GET /api/v4/orbit/templates proxying this RPC.
  • Frontend: drive the preset dropdown and editor population from the catalog instead of NAMED_QUERY_TEMPLATES; display-text/i18n decision needed since description is untranslated YAML text.

%{all_commits}

Merge request reports

Loading