Inspiration
Before I change a shared function, I always want to know what depends on it. The usual ways of answering that question are not great. Grep is noisy. It matches the word inside comments and strings, flags unrelated things that happen to share a name, and quietly misses callers that import the symbol under an alias. Asking an AI chat assistant is worse, because it will happily make up callers it never checked.
So we guess. We run too few tests, or too many, and sometimes we ship a regression.
The thing is, GitLab Orbit has already done the hard part. It indexes the real call and import edges of the codebase. The correct answer is sitting right there, one query away. I wanted to make getting that answer a reflex instead of a chore.
What it does
You give it a symbol (a function, method, or class) and it builds a change impact report from Orbit's graph. The report tells you four things:
- The blast radius: every caller, including the ones that reach the symbol through an import.
- The tests that actually exercise the symbol, so you know what to run.
- A risk score of LOW, MEDIUM, or HIGH, with the math shown so you can trust it.
- Suggested reviewers, pulled from the git history of the affected files.
It comes in three forms that all share the same SQL underneath: a two agent GitLab Duo flow published to the AI Catalog, an agent skill you can drop into any skill aware coding agent, and a plain CLI for when you just want the answer in a terminal.
How we built it
We index the code with Orbit Local and query the DuckDB graph it produces. The interesting part is the blast radius query. A caller usually reaches a function through an import, so the edge in the graph points at an imported symbol rather than the definition itself. The query resolves that link back to the original definition by matching module basenames, which is also what lets it work across languages. We checked it on Python and TypeScript and got the same correct answer in both.
The flow is built on the Flow Registry v1 schema, and we validated every field against the spec before publishing. Around the CLI we added clean exit codes, a JSON output mode, a 16 test pytest suite, and a CI job that re indexes the repo and asserts the blast radius for both sample languages, so the project keeps itself honest.
What we learned
The value in Orbit is the edges. Once the call and import relationships are indexed, an agent can answer dependency questions from facts instead of guessing. A thin layer of SQL on top is enough to turn that into something you would actually reach for during a normal workday.
We also learned to trust the running system over the documentation. Working against Orbit v0.79.0 turned up a few surprises, which leads to the next part.
Challenges we ran into
The biggest one was that the documented gl_reference table does not exist. The
relationships actually live in gl_edge, with kinds like CALLS, DEFINES, IMPORTS,
and CONTAINS. We figured out the real shape from a live index and wrote it down so
the next person does not lose an afternoon to it.
The indirect call problem took a while too. Because callers import the symbol, the
CALLS edge lands on an imported symbol and not the definition, so a naive query finds
nothing. Resolving that mapping is the whole reason this beats grep. Cross language
imports added a twist, since Python uses dotted module paths and TypeScript uses
relative slash paths, and basename matching is what reconciles them. One small but
annoying gotcha: a query that starts with -- gets read as a CLI flag, so we pass
SQL through a file or stdin instead.
What's next
We want to pull in SDLC context from Orbit Remote, like open merge requests that touch the blast radius and recent pipeline failures in the affected files. After that, posting the report straight onto a merge request as a comment, and ranking reviewers by who owns the specific lines rather than the whole file.
Built With
- ai-catalog
- duckdb
- duo-agent-platform
- flow-registry-v1
- gitlab-duo
- gitlab-orbit
- pytest
- python
- sql
- typescript
Log in or sign up for Devpost to join the conversation.