Inspiration

Blast started from one observation: DataHub already knows exactly what sits downstream of any table, but it has no opinion on whether a given change actually breaks any of it. That's the gap between a lineage graph and a code reviewer. A renamed column sails through CI and merges clean; the failure shows up two hops later, in a dashboard, days after the PR is closed and forgotten. Existing tools โ€” DataHub's own Impact Analysis included โ€” stop at "these are connected." Blast asks the harder question: does this actually break, who needs to know, and can it just be fixed โ€” and writes the answer back into DataHub itself.

What it does

Blast is two agents that share one job: catch the breakage before it ships, and don't let the org forget it happened.

๐Ÿงจ blast-scan โ€” catches it before merge

Runs on every pull request. It reads whatever file changed โ€” a dbt model, raw DDL, a Terraform resource, honestly almost anything โ€” asks an LLM what actually changed about it, resolves that thing to a DataHub URN, and walks DataHub's lineage graph for everything downstream. Then, instead of just listing what's connected, it asks a second question for each downstream asset: given this specific change, does this thing actually break?

  • ๐Ÿ”ด Hard break โ€” a downstream model selects a column that no longer exists
  • ๐ŸŸก Silent risk โ€” a type change a SUM() runs over; nothing errors, the number is just wrong forever
  • ๐ŸŸข Safe โ€” nothing about this asset touches the change
  • ๐ŸŸ  Needs review โ€” Blast can't confidently reason about it, so it says so instead of guessing

The report goes on the PR as a comment, with a color-coded Mermaid graph and a line most tools skip entirely:

"stg_orders has been flagged for 3 predicted breaking changes in the last 90 days."

That number isn't decoration โ€” it's read live from DataHub, because blast-scan writes every finding back as an incident on the dataset, and recomputes a blast_risk_score (0-100) as a real DataHub Structured Property. You can go look at the entity in DataHub's own UI and watch that score climb across two PRs. The institutional memory isn't a Blast-only concept living in a PR comment โ€” it's on the asset itself.

๐Ÿ› ๏ธ Splint โ€” turns the warning into a fix

Comment /blast-fix on a PR Blast flagged, and Splint re-runs the same interpret โ†’ resolve โ†’ classify pipeline, pulls the real source file for each broken downstream model, rewrites the SQL to match the upstream change, and opens a follow-up PR for review. It's honest about partial results too โ€” if it fixes two out of three flagged models, it says so and lists the third with the actual reason it couldn't (source file not found, fix was a no-op, whatever it is), instead of a vague "done."

A warning that nobody has to act on gets ignored eventually. A warning with a fix attached gets reviewed.

How I built it

  • DataHub MCP Server for lineage reads and entity search, with a hand-rolled GraphQL client as the automatic fallback
  • OpenAI for the actual reasoning โ€” interpreting diffs and classifying breakage
  • Reusable GitHub Actions workflows so any repo can adopt Blast by dropping in a five-line YAML file instead of vendoring Python
  • Mermaid for the dependency graph, rendered natively in the PR comment
  • PyGithub for reading PR files, posting comments, and opening Splint's fix PRs

Adopting Blast

Adopting Blast doesn't mean vendoring any Python into your project. It's two reusable GitHub Actions workflow files, copied in as-is: one that runs blast-scan on every pull request, one that wires up the /blast-fix comment trigger for Splint. Add three repository secrets โ€” DATAHUB_SERVER, DATAHUB_TOKEN, OPENAI_API_KEY โ€” and that's the whole install. There's no per-repo config file to maintain either, since entity resolution goes straight through DataHub search instead of a local mapping file someone has to keep in sync.

Accomplishments that I am proud of

Delivered as a reusable, drop-in workflow. Blast isn't a script someone has to vendor and maintain โ€” it ships as two workflow_call GitHub Actions files that any repo can adopt by pasting in a five-line wrapper and adding three secrets. No per-repo config file, no local mapping to keep in sync. Making it something another team could actually plug into their own CI, not just a demo that runs on my machine, was a deliberate design goal from the start.

Diagnoses the break, not just the connection. Blast doesn't just tell you two things are connected โ€” it tells you, in plain language, why the downstream thing breaks, quoting the actual column and the actual line of reasoning. That's the difference between a lineage viewer and a code reviewer, and it's the part that actually saves someone from having to trace the logic themselves at 6pm before a release.

A risk score computed from real incident history. It would have been easy to hard-code a demo number that climbs on cue. Instead blast_risk_score is recomputed from actual incident history every single run, written as a real DataHub Structured Property, live-tested end to end against a running instance โ€” including the bootstrap step that defines the property in the first place. Watching that number visibly change in DataHub's own UI because of something Blast wrote, not something I typed into a demo script, was the moment this stopped feeling like a hackathon toy.

What's next for Blast

Org-wide risk visibility. Every table Blast touches already carries a live blast_risk_score in DataHub. Rolling those up into a single view would let a platform team see which tables are quietly fragile across the whole org, before the next migration touches them โ€” not just one PR at a time.

Proactive owner notifications. Blast already resolves and names the team that owns a broken downstream asset right on the PR comment. The natural next step is pushing that straight to Slack or Teams the moment a hard break is found, so the right person hears about it before the PR is even reviewed, not after.

Built With

  • datahub
  • github-actions
  • mcp
  • mermaid
  • openai
  • python
Share this project:

Updates