Verified Commit 9ae10520 authored by Dmitry Gruzd's avatar Dmitry Gruzd 2️⃣ Committed by GitLab
Browse files

feat(skills): add orbit skill for Knowledge Graph queries via glab api

parent ee5878e6
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ If agent teams are available, create an agent team for each major section of the
| `CLAUDE.md` / `AGENTS.md` | Agent context. Must stay identical — CI enforces this. |
| `crates/*/README.md` | Per-crate docs |
| `crates/indexer/AGENTS.md` | Indexer agent context |
| `skills/orbit/` | Agent skill for Knowledge Graph queries. `SKILL.md`, `references/recipes.md`, `references/troubleshooting.md` are hand-written and need updates when API behavior or response shape changes. `references/query_language.md` is byte-equal-synced from `docs/source/queries/` (CI-enforced via `orbit-skill-docs-sync`, no manual action needed). |

## Gathering context

@@ -44,6 +45,7 @@ Use `glab` to check epics, issues, and MRs for context on what shipped recently.
- Crate renames, splits, or new crates not reflected in `CLAUDE.md`
- People or epic changes not in `README.md`
- Stale config references in `docs/dev/runbooks/server_configuration.md`
- New orbit API endpoints, query types, response-format changes, or user-visible features (e.g. indexing progress added in !1015) not reflected in `skills/orbit/SKILL.md`, `references/recipes.md`, or `references/troubleshooting.md`. CI only enforces byte-equal sync of `query_language.md` — the rest of the skill's hand-written prose (discovery workflow, recipes, gotchas, agent guidelines) won't flag itself as stale.

## Fixing

@@ -52,6 +54,7 @@ Use `glab` to check epics, issues, and MRs for context on what shipped recently.
3. Edit the doc to match
4. Run `mise run lint:docs` to validate
5. If you touched CLAUDE.md, mirror the change to AGENTS.md
6. If your change alters orbit API behavior (new endpoint, new query type, new response field, new user-visible feature), update `skills/orbit/SKILL.md` and `skills/orbit/references/` (especially `recipes.md` and `troubleshooting.md`) to reflect it. CI only catches byte-equal drift of `query_language.md`; everything else in the skill is manual.

## Self-improvement

+2 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ Use `AGENTS.md` "Where to find things" as your index. Examples of drift to watch

- MR adds a new crate → `AGENTS.md` crate map and `README.md` architecture section need updating
- MR changes the query DSL or proto definitions → `docs/design-documents/querying/` may describe old behavior
- MR adds/changes public API surface or user-visible features → `skills/orbit/SKILL.md`, `skills/orbit/references/recipes.md`, `skills/orbit/references/troubleshooting.md` may need new content. CI only enforces byte-equal sync of `query_language.md`; the rest of the hand-written skill prose (discovery workflow, recipes, gotchas, agent guidelines) won't flag itself as stale. Example: indexing progress added in !1015.
- MR modifies auth or redaction logic → `docs/design-documents/security.md` may be stale
- MR adds a CI job or changes enforcement → `AGENTS.md` "What CI enforces" list is incomplete
- MR changes Helm charts or infra → `README.md` Helm Charts table and `docs/dev/runbooks/server_configuration.md` may drift
@@ -51,6 +52,7 @@ Only flag real drift. Skip cosmetic issues, formatting, and things markdownlint/
- **SSOT desync**: `README.md` tables (repos, epics, infra, people, helm charts) don't reflect structural changes in the MR
- **AGENTS.md desync**: crate map, CI enforcement list, or "where to find things" table is outdated after the MR
- **New undocumented surface**: new gRPC endpoint, server mode, config option, or ontology node/edge type with no doc coverage
- **Stale agent skill**: hand-written parts of `skills/orbit/` (SKILL.md, recipes.md, troubleshooting.md) don't reflect new API behavior. Byte-equal `query_language.md` is CI-enforced separately; this bullet is for the prose that isn't.

## Commenting

+5 −0
Original line number Diff line number Diff line
@@ -23,6 +23,11 @@ pre-commit:
      glob:
        - "AGENTS.md"
        - "CLAUDE.md"
    - name: orbit-skill-docs-sync
      run: diff docs/source/queries/query_language.md skills/orbit/references/query_language.md
      glob:
        - "docs/source/queries/query_language.md"
        - "skills/orbit/references/query_language.md"
    - name: ontology-schema
      run: mise run ontology:validate
      glob: "fixtures/ontology/**/*.yaml"
+4 −0
Original line number Diff line number Diff line
@@ -359,3 +359,7 @@ description = "Check for broken links in markdown files"
depends = ["lint:markdown", "lint:vale", "lint:links"]
run = "echo 'All doc linters passed'"
description = "Run all documentation linters"

[tasks."skill:sync:orbit"]
run = "cp docs/source/queries/query_language.md skills/orbit/references/query_language.md"
description = "Sync upstream docs into the Orbit agent skill (skills/orbit/references/)"

skills/orbit/SKILL.md

0 → 100644
+132 −0
Original line number Diff line number Diff line
---
name: orbit
description: Query the GitLab Knowledge Graph (Orbit) via the /api/v4/orbit REST endpoints using `glab api`. Use for code-structure questions (who calls this function, where is this symbol defined), cross-project dependency and blast-radius analysis, merge-request and contributor queries, and any question answerable by traversing GitLab's unified entity graph (projects, users, MRs, issues, pipelines, files, definitions, vulnerabilities).
version: 0.1.0
license: MIT
metadata:
  audience: developers
  keywords: orbit, knowledge-graph, gkg, graph, query, glab, api
  workflow: ai
---

# Orbit (GitLab Knowledge Graph) skill

Query the GitLab Knowledge Graph (product name **Orbit**) from the CLI using `glab api`.
The API is **self-describing** — always call `orbit/schema` or `orbit/tools` first to discover the
authoritative ontology and query DSL before writing queries.

## Prerequisites

- `glab auth login` against an instance that has the `knowledge_graph` feature flag enabled
  for your user. FF off → every `/api/v4/orbit/*` endpoint returns `404`.
- The instance must have Orbit turned on for at least one top-level group you belong to.
  Otherwise `orbit/query` returns `403 No Knowledge Graph enabled namespaces available`.

## Endpoints

All endpoints live under `/api/v4/orbit/*` and are **user-scoped**, not project-scoped.
Do **not** pass `-R owner/repo`.

| Endpoint                    | Method | Purpose                                                  |
|-----------------------------|--------|----------------------------------------------------------|
| `orbit/status`              | GET    | Cluster health (always returns 200).                     |
| `orbit/schema`              | GET    | Graph ontology: domains, nodes, edges.                   |
| `orbit/schema?expand=A,B`   | GET    | Drill into nodes for properties and relationships.       |
| `orbit/tools`               | GET    | MCP tool manifest with the full query DSL JSON Schema.   |
| `orbit/query`               | POST   | Execute a query. **Requires `Content-Type` header.**     |

## Discovery workflow (always start here)

```bash
glab api orbit/status                                   # is the service up?
glab api orbit/schema                                   # what entities and edges exist?
glab api "orbit/schema?expand=MergeRequest,Project"     # properties of specific nodes
glab api orbit/tools                                    # full DSL JSON Schema
```

These calls are cheap and return the authoritative ontology + query-DSL schema. Prefer them over
memorised structures — the ontology evolves. Budget ≤ 1 discovery call per new entity type in a session.

## Running a query

POST to `orbit/query` requires an explicit `Content-Type`. Without it you get
`HTTP 415: The provided content-type '' is not supported.`

```bash
cat > /tmp/q.json <<'JSON'
{
  "query": {
    "query_type": "search",
    "node": {"id": "p", "entity": "Project"},
    "limit": 5
  },
  "response_format": "llm"
}
JSON

glab api --method POST orbit/query \
  --header "Content-Type: application/json" \
  --input /tmp/q.json
```

Or use the bundled wrapper, which injects the header automatically.
Invoke it by its absolute path (or put the skill's `scripts/` dir on `PATH`) —
the skill can be installed anywhere, so relative `scripts/orbit-query` only
works from inside the skill directory:

```bash
# Adjust path to wherever the skill is installed:
~/.config/opencode/skills/orbit/scripts/orbit-query /tmp/q.json
# or via stdin:
cat /tmp/q.json | ~/.config/opencode/skills/orbit/scripts/orbit-query
```

`response_format`:

- `"llm"` — compact text optimised for LLM consumption (recommended for agent use).
- `"raw"` — structured JSON suitable for `| jq`.

## Where to find more

These files are part of the skill itself and are always available alongside `SKILL.md`:

| Topic | Location |
|---|---|
| Full query DSL reference | [`references/query_language.md`](references/query_language.md) |
| Paste-ready `glab api` recipes per query type | [`references/recipes.md`](references/recipes.md) |
| Common errors and fixes | [`references/troubleshooting.md`](references/troubleshooting.md) |
| Query-body wrapper script | [`scripts/orbit-query`](scripts/orbit-query) |

External links (require internet):

- [MCP tool definitions](https://gitlab.com/gitlab-org/orbit/knowledge-graph/-/blob/main/docs/source/queries/mcp_tools.md)
- [Orbit product overview](https://gitlab.com/gitlab-org/orbit/knowledge-graph/-/blob/main/docs/source/_index.md)
- [Real query examples (`sdlc_queries.yaml`)](https://gitlab.com/gitlab-org/orbit/knowledge-graph/-/blob/main/fixtures/queries/sdlc_queries.yaml)

## Agent guidelines

1. **Always discover before querying.** Call `orbit/schema` and/or `orbit/tools` first. Do not guess
   node names, edge types, or property names — validate against the live ontology.
2. **Use `"response_format": "llm"`** for compact agent-friendly output unless piping to `jq`.
3. **Set `Content-Type: application/json` on POST.** Missing → 415.
4. **No `-R owner/repo`.** Orbit endpoints are user-scoped at the API level.
5. **Keep `limit` small while iterating** (5–10). Queries can fan out across many authorised namespaces.
6. **`query_type` dictates the top-level key:** `search` / `neighbors``node` (singular);
   `traversal` / `aggregation` / `path_finding``nodes` (array).
7. **Pagination uses `cursor: {offset, page_size}`**, not `page`/`per_page`.
   `offset + page_size` must not exceed `limit`. `page_size` max 100.
8. **`max_depth` and `max_hops` ceiling is 3.** Enforced server-side.
9. **Read-only.** All endpoints are idempotent queries — no data is modified.
10. **Stay sequential.** Run queries one at a time — `orbit/query` is rate-limited
    (see `HTTP 429` in troubleshooting). Prefer aggregation/traversal in one
    query over N separate queries.

## Contributing improvements

If any guidance here is **inaccurate or outdated** (a flag name, an endpoint path, a DSL field),
confirm with the user and open an MR to `gitlab-org/orbit/knowledge-graph` with a fix and a
`version` bump in the frontmatter. Keep changes focused — one fix per MR.

**`references/query_language.md` is synced from `docs/source/queries/query_language.md`.**
Edit the upstream file, then run `mise run skill:sync:orbit` to propagate. A Lefthook pre-commit
job (`orbit-skill-docs-sync`) will fail the commit if the two files drift.
Loading