About the project

Inspiration

When a merge request shows up, the first thing reviewers do is not read the diff. They ask three questions: What depends on this? Any active vulnerabilities here? Who needs to review it? All three answers already exist in GitLab Orbit — the typed graph of every project, MR, vulnerability, and team in a namespace. The problem is that nobody's job is to put those answers on the MR, so nobody does. Reviewers approve blind or burn ten minutes tab-juggling between GitLab, Snyk, and Slack threads. OrbitLens is the agent that does that job — automatically, on the MR, every time.

What it does

OrbitLens is a GitLab Duo Custom Agent with one attached Skill: orbit-mr-impact-review. When invoked on a merge request, it:

  1. Issues three narrow Orbit: Query Graph calls — direct dependents of the project, active HIGH/CRITICAL vulnerabilities, owning team.
  2. Picks up to three suggested reviewers from dependent-project ownership and recent author activity.
  3. Posts exactly one comment on the MR via Create Merge Request Note, idempotent per MR head SHA, with two template variants: a populated version when Orbit has data, and an empty-graph version (table-shaped, transparent about empty results) when the project hasn't been deeply indexed yet.

Published to the GitLab AI Catalog as OrbitLens — SDLC Impact Reviewer. Anyone with a Duo-enabled GitLab project can install it.

How I built it

I validated the design before committing to the platform. First I built a standalone Node.js + React reference app that ran the same prompt + Query DSL against an in-memory Orbit stub — to prove the persona, the worked examples, and the three-question framing all held end-to-end. That code is preserved as design provenance.

Then I ported the design to the Duo Agent Platform's actual primitives:

  • skills/orbit-mr-impact-review/SKILL.md — markdown + YAML front matter, the task playbook the agent loads at runtime. Six sections: when it fires, the Orbit queries, the reviewer- picking heuristic, two comment templates, worked examples, and hard guardrails (never approve, never rewrite, never double-post).
  • agents/orbit-impact-reviewer.md — mirrors the Custom Agent's identity (display name, description, three-tool whitelist, attached skill, the exact system prompt) so the prompt is reviewable via PR rather than buried in a UI text field.
  • GitLab UI configuration — created the agent, attached the skill, enabled exactly three tools (Orbit: Query Graph, Orbit: Get Graph Schema, Create Merge Request Note), published to the AI Catalog.

End-to-end validated on a real MR on the provisioned project — agent ran, made real Orbit queries, posted a real comment.

Challenges I ran into

  • Understanding the Agent / Skill / Flow trichotomy. The right decomposition isn't obvious from the docs — Custom Agent is the publishable identity, Skill is the task playbook in git, Flow coordinates multiple agents. I initially built only a Skill and almost shipped without an Agent until I re-read the rule that the Catalog requires an agent or flow, not a skill alone.

  • The Orbit: Query Graph payload contract isn't documented. The agent had to round-trip through several error responses on its first invocation to discover that the DSL must be wrapped under a top-level query: key and that columns: "*" is required. I baked the discovered contract into the SKILL.md so future runs skip the discovery dance.

  • Auto-discovery for skill loading is fuzzy. Saying "review this MR" triggered a default code-review behavior; the skill only fired reliably when I named it explicitly via @OrbitLens run the orbit-mr-impact-review skill on this MR.

  • Write-side tools gate on human approval the first time. This was surprising mid-flow — I initially read it as an error. It's a good platform safety, but worth documenting.

  • The reference-app → platform pivot. Once I understood that Duo brokers its own model, my Gemini-SDK reference implementation couldn't be the submission. I preserved it as design proof, expunged it from the submission branch, and pivoted the entire repo surface around the SKILL.md + agent file.

Accomplishments that I'm proud of

  • A real, published agent in the GitLab AI Catalog that anyone with a Duo project can install — not a local prototype.
  • End-to-end validation with a real comment landing on a real MR.
  • A SKILL.md that's captured ground truth — the validated DSL payload shape and the snake_case tool names are baked in, so the next builder skips the discovery iterations I had to run.
  • A tight tool whitelist — exactly three tools — that makes the agent's behavior predictable enough to debug and defend.
  • Both comment-template variants (populated + empty-graph) — the agent handles fresh / docs-only projects gracefully without fabricating data.
  • The prompt and playbook live in git, MIT-licensed, diffable via merge request — not in a UI text field.

What I learned

  • The Skill format is more powerful than it looks. A markdown file plus a few platform-provided tools = a working agent. No SDK, no runtime to host.
  • Tool whitelists matter more than tool capability. Constraint reads as design intent. A small, focused tool list reads stronger to judges than "agent can do anything."
  • Iterative reasoning beats polished animation. When the agent narrates its own retry on a query, viewers see real reasoning happen. That's more compelling than any canvas visualization.
  • "Prompts in git" is a real DevOps argument. UI-only agent config is hard to review, harder to roll back. Pulling the prompt into a markdown file the platform reads makes the agent's behavior changeable via PR — same workflow as code.

What's next for OrbitLens

  • orbit-release-gate — second skill, already stubbed as a draft in the repo. Block merge of MRs that introduce HIGH+ vulnerabilities per Orbit; gate via a GitLab status check.
  • orbit-owner-routing — auto-route newly-opened issues to the team that owns the affected project.
  • orbit-vuln-blast-radius — given a CVE, open draft MRs across every project that depends on the affected dependency.
  • Auto-fire on merge_request.opened — wire up a Flow so the skill runs automatically without needing the slash command. The manual trigger is good for demo; auto-fire is the real workflow.
  • Test against a real codebase. The hackathon-provisioned project has no indexed source, so all Orbit queries returned empty. The empty-graph template covers this gracefully, but the populated-variant template needs real-world validation.

Built With

  • agent
  • gitlab
  • gitlab-ai-catalog
  • gitlab-duo
  • gitlab-duo-agent-platform
  • gitlab-orbit
  • markdown
  • skill
Share this project:

Updates