Inspiration
A production table breaks at 3am. Before anyone can fix it, someone has to answer, by hand: what downstream dashboards and tables are now serving wrong data? Who owns them? Which are customer-facing right now? And where do I write this down so nobody re-investigates it tomorrow? That's 30–60 minutes of frantic clicking through lineage graphs — every single incident.
DataHub already knows the entire dependency graph. I wanted an agent that turns that knowledge into instant, actionable incident response — and, crucially, writes the result back into the catalog so the knowledge compounds instead of evaporating.
What it does
Ripple is a data-incident triage agent for DataHub. Given a broken asset's URN, it:
- Reads context — traverses downstream lineage across every hop (Snowflake → dbt → Looker / PowerBI / Tableau), pulling ownership and platform, through the DataHub MCP Server / SDK.
- Reasons — ranks the blast radius by criticality (customer-facing dashboards and owned production tables first) and assigns a severity (SEV1–3).
- Acts + writes back — applies an
incidenttag, saves a runbook into the asset's documentation, and raises a native DataHub Incident entity, so the next engineer or agent inherits full context.
On a seeded demo it lights up 8 affected assets across 5 platforms, 3 of them customer-facing, in one command.
It also does root-cause (upstream) analysis, column-level blast radius (which column traces to the break), and an auto-trigger watch loop. It ships two front-ends: a rich terminal UI and a read-only web dashboard with an interactive lineage graph (light/dark themes, no external JS).
How I built it
- DataHub Core quickstart + the
showcase-ecommercedata pack for a realistic catalog. A seeder script emits a purpose-built incident scenario — a source table fanning out to 5 dbt/warehouse tables and 3 BI dashboards, with owners and column-level lineage — so the demo is dramatic and reproducible. - The agent talks to DataHub through the Python SDK (
DataHubGraph, GraphQLsearchAcrossLineage,MetadataChangeProposalWrapper,mce_builder) and the self-hosted MCP Server (wired into Claude Code during development to validate query shapes against the live graph). - Key design choice: facts are deterministic, prose is LLM-generated. Lineage traversal, owner resolution, and criticality ranking are plain code — the LLM only writes the human-readable narrative. This keeps the impact analysis trustworthy and the demo reproducible.
- The whole read → reason → write workflow is packaged as a reusable DataHub Agent Skill (
skills/incident-triage/) for any MCP-compatible client. - UIs: Rich for the terminal; FastAPI + a dependency-free custom SVG renderer for the web graph.
Challenges I ran into
- Docker's default 16 GB disk filled up, pushing OpenSearch past its flood watermark. The only symptom was
searchAcrossLineagereturningall shards failed— nothing pointed at disk. datahub docker quickstart --restore-indicesfinished cleanly but rebuilt only the search index, not the graph relationship edges — so lineage stayed empty until a fulldatahub docker nuke.- The GraphQL
addTagmutation refuses to apply a tag whose entity doesn't exist yet (Urn does not exist); I had to create the tag entity first and emitGlobalTagsvia the SDK. SchemaMetadata.platformrequires a fulldataPlatformURN, with a cryptic"Provided urn urn" is invaliderror.- Drawing an accurate lineage DAG meant reading multiple aspect types — dashboards express their inputs via
DashboardInfo.datasets, notUpstreamLineage.
Accomplishments I'm proud of
- A complete read → reason → write loop against live DataHub — an agent that acts on the catalog, not just a read-only query tool.
- Four capabilities beyond the core (root-cause, column-level, auto-trigger, native incidents) plus two polished UIs — all working end-to-end.
- A reusable Agent Skill designed to be contributed back to DataHub.
What I learned
- DataHub's metadata model and aspect system — lineage (table and column), tags, incidents, schema, documentation — and how to emit each via the SDK.
- How DataHub's search index and graph index differ, and how they fail (and recover).
- That the most trustworthy agent design keeps the LLM out of the fact-gathering path entirely.
What's next for Ripple
- Assertion-failure event subscriptions to replace the polling auto-trigger, so triage fires the moment a data-quality check fails.
- Auto-remediation PRs — when a schema change breaks a downstream model, generate the fix and open a pull request.
- Notifications & routing (Slack / PagerDuty), impact quantification from usage stats, and ML-asset support via DataHub's end-to-end ML lineage.
Built With
- css
- datahub
- docker
- fastapi
- graphql
- html
- javascript
- mcp
- opensearch
- python
- uvicorn
Log in or sign up for Devpost to join the conversation.