Pathfinder: know what a data change breaks, before it ships
Pathfinder is a pull-request agent for data teams. When someone opens a PR that changes a data model, Pathfinder reads DataHub's lineage, traces every downstream table, dashboard, ML feature, and production ML model, decides what breaks, and posts the answer as a comment on the PR: the blast radius, the owners to notify, and a ready-made backward-compatible fix. It then writes the assessment back onto the dataset in DataHub, so the next person inherits it.
Inspiration
Every data team has the same 3am story: someone renames one column, and days later a dashboard is wrong or, worse, a machine-learning model in production starts making bad predictions. The person who made the change could not see that far. Tools like dbt docs and Recce stop at the edge of the dbt project; they cannot see the Looker dashboard or the model that reads the column. DataHub already holds the one thing that makes this solvable in the open: a cross-stack lineage graph that includes ML. We turned that graph into a guardrail that lives where engineers already work.
What it does
- Detects the change: parses the SQL/dbt diff with sqlglot to find renamed, dropped, and retyped columns and changed row filters.
- Walks the blast radius: one lineage call returns every downstream dataset, dashboard, ML feature, and production ML model, with owners.
- Judges severity deterministically: rules rank each asset breaking, partial, or safe. A production ML model outranks an internal table. Missing or unresolved lineage never returns SAFE.
- Drafts the fix: a backward-compatible alias so consumers keep working while owners migrate.
- Notifies and writes back: posts the PR comment, @-mentions the right owners, and annotates the dataset in DataHub with the verdict and a PR link.
How we built it
A GitHub Action (or CLI) is the entry point. Lineage is read two ways: the
DataHub GraphQL API (searchAcrossLineage for the cross-stack plus ML blast
radius, addLink and addTag for write-back), and the official DataHub MCP server
(mcp-server-datahub) via --via mcp, which we verified end to end. An optional
LLM only polishes the drafted fix, so verdicts are reproducible and it runs with
no API key. We seeded a realistic ML lineage graph (tables to feature to model)
with the DataHub Python emitter to prove the ML path live.
Challenges we ran into
Reliable lineage from GraphQL took work: entity(urn) treats any valid URN as
existing, and selecting properties across entity types hit a nullability
FieldsConflict. We resolve datasets by search and alias fields per type. We also
confirmed, live, that ML models are reachable through the same lineage call,
which is the heart of the project. Making the MCP path clean took a parser that
adapts to the server's own tool schemas and filters out the owners and platforms
nested inside each entity.
Accomplishments we're proud of
End to end on a real DataHub and a real GitHub PR: a column rename is flagged breaking down to a production churn_model, with a fix and owner mentions, and the verdict written back to the catalog, through both GraphQL and the official MCP server. Deterministic verdicts, 26 tests, honest limitations documented, and a self-audit.
What we learned
DataHub carries ML as a first-class citizen in lineage; the ML blast radius is real and reachable in one call. The hard part of building on it is a few API sharp edges, which we wrote up as feedback.
What's next
Traverse model to deployment, make the DataHub MCP path a first-class option, and file our GraphQL findings as issues.
Log in or sign up for Devpost to join the conversation.