Add Orbit entity context API

What does this MR do and why?

Adds GET /api/v4/orbit/context so Orbit clients can resolve graph entity references into compact Merge Request and Issue summaries. Rails applies normal permissions and returns indistinguishable not_found results for missing or inaccessible records. The endpoint supports ordered batches and raw or LLM-oriented output.

References

Related to https://gitlab.com/gitlab-org/orbit/knowledge-graph/-/work_items/1262

Screenshots or screen recordings

Not applicable. This change adds an API endpoint without UI changes.

Before After
No entity context endpoint Permission-aware entity context endpoint

How to set up and validate locally

  1. Enable the knowledge_graph feature flag and ensure the Orbit licensed feature is available.

  2. Configure a Knowledge Graph-enabled namespace for the user.

  3. Run:

    bundle exec rspec ee/spec/requests/api/orbit/data_context_spec.rb
    bundle exec rubocop ee/lib/api/orbit/data.rb \
      ee/app/services/analytics/orbit/context_service.rb \
      ee/app/services/analytics/orbit/context_llm_formatter.rb \
      ee/lib/api/entities/orbit/context.rb \
      ee/spec/requests/api/orbit/data_context_spec.rb
    scripts/lint-doc.sh doc/api/orbit.md
    bin/rake gitlab:openapi:v3:check_docs

MR acceptance checklist

Evaluated against the MR acceptance checklist.

Agent context details

Contract

The endpoint accepts one to 20 repeated refs[] parameters in Type[id] form. Supported types are MergeRequest, Issue, and the WorkItem alias, which normalizes to Issue. It preserves input order and reports entry-level invalid_ref, unsupported_type, or not_found errors.

Raw output follows this shape:

{
  "version": "1.0.0",
  "entities": [
    {
      "ref": "MergeRequest[123]",
      "type": "MergeRequest",
      "id": 123,
      "found": true,
      "summary": {}
    }
  ]
}

response_format=llm returns a compact text/plain key/value rendering.

Mechanics and safeguards

  • Reuses Orbit authentication, license and feature gates, granular read_knowledge_graph authorization, enabled-namespace checks, and the orbit_query rate limit.
  • Bulk-loads the requested records and bounded related data. Reviewers and assignees are limited to 10, labels to 20, and linked entities to 10 per parent.
  • Applies read_merge_request, read_issue, and read_pipeline checks. Forbidden and missing records have the same response.
  • Quotes table and column identifiers in the bounded window queries.
  • Keeps the beta route hidden from generated OpenAPI, matching the existing Orbit endpoints.

Validation

bundle exec rspec ee/spec/requests/api/orbit/data_context_spec.rb
24 examples, 0 failures, 2 expected pending

bundle exec rubocop <five changed Ruby files>
5 files inspected, no offenses detected

scripts/lint-doc.sh doc/api/orbit.md
Markdownlint: 0 errors
Vale: 0 errors, 0 warnings, 0 suggestions

bin/rake gitlab:openapi:v3:check_docs
OpenAPI v3 documentation is up to date

The request specs cover authentication and authorization gates, malformed requests, mixed batches, permission filtering, both response formats, rate limiting, bounded collections, pipeline visibility, and query growth.

Alternatives considered

The endpoint could call existing per-type REST endpoints, but that would require several requests and duplicate identifier resolution in clients. Resolving in Rails keeps local database identifiers and permission checks with the application that owns them. Free-form graph queries remain available for fields outside the compact summaries.

Example requests

curl --request GET \
  --header "PRIVATE-TOKEN: <token>" \
  --url "https://gitlab.example.com/api/v4/orbit/context?refs[]=MergeRequest%5B123%5D&refs[]=Issue%5B456%5D"

curl --request GET \
  --header "PRIVATE-TOKEN: <token>" \
  --url "https://gitlab.example.com/api/v4/orbit/context?refs[]=Issue%5B456%5D&response_format=llm"
Edited by Dmitry Gruzd

Merge request reports

Loading
Loading