Inspiration
At 2:47am an upstream team renames a column and tells nobody. By 9:07am the revenue dashboard reads zero, and Finance notices before the data team does. Every data engineer knows that morning: blame the pipeline, grep the logs like your life depends on it, and find, hours later, a schema change nobody bothered to announce. It's never good when your boss notices first.
Pre-merge schema bots catch renames when someone opens a PR. Plenty of scary bugs still ship: nobody reviewed the PR, the review missed meaning, or prod drifted overnight. What struck us is not that agents can investigate the pager - they can. It's that every one of those agents forgets. The next night, the same break, the same investigation, from zero. The understanding dies in a chat transcript nobody can query.
This is not an LLM-only problem. Nightshift is hybrid by design: deterministic Sentinel and presence guards for the precise bits, Claude for the investigation and the morning prose. The context platform was sitting right there - DataHub - so the night has to be written back into the graph.
What it does
Nightshift is an on-call team of Claude agents wired into DataHub. When the pager goes off, a shift:
- Recalls before it investigates. The first tool call asks the graph whether this shape of failure has been seen before, on this asset or anywhere upstream.
- Walks lineage only for what memory doesn't cover, upstream from the broken dashboard to the exact table, reading the SQL of each transformation.
- Names one root cause, never a list of suspects, respecting the timeline: a fresh break was caused by something that changed tonight.
- Fixes from the real schema. The proposed dbt change uses the columns the catalog actually holds.
- Leaves the graph smarter than it found it: incident opened and resolved in DataHub, a postmortem written into the dataset's documentation for humans, a machine-readable memory and a searchable failure-mode tag for the next agent, and a column-presence assertion in the Validations tab (value-level not-null checks stay a dbt/CI follow-up).
The second time a pipeline breaks the same way, Nightshift does not investigate. It remembers. An investigation becomes a lookup.
Measured on our demo graph (DataHub's showcase-ecommerce, 1,000+ entities):
| Night 1 (cold) | Night 3 (memory) | |
|---|---|---|
| Investigation tool calls | 14 | 5, including exactly the 2 reads memory prescribed |
| Shift wall-clock | 2.2 min | 1.1 min |
| Lineage re-walked | full path | none |
By night 3 the agent recognized a recurrence, reframed the incident from a SQL problem to a process problem, escalated to the model's owner, and proposed a dbt source test so CI would block the regression. The graph gets smarter with every run. Literally.
How we built it
- Hybrid on purpose (allowed and encouraged for this track): deterministic Sentinel fingerprinting + column-presence guards +
immunize_graphfor the precise bits; Claude Agent SDK for investigation, root-cause prose, and draft fix PRs. - Claude Agent SDK driving two MCP servers per shift:
- the official DataHub MCP server for the whole read surface (search, schemas,
get_lineage_paths_betweenwith transformation SQL); - our Nightshift MCP server for everything OSS agents were missing:
open_incident,resolve_incident,guard_column,remember_incident,recall_incident_memory,find_datasets_with_failure_mode,immunize_graph,open_fix_pr.
- the official DataHub MCP server for the whole read surface (search, schemas,
- The write surface we had to build: DataHub OSS has no MCP tool and no SDK path for incidents (GraphQL
raiseIncident/updateIncidentStatus) or external assertions (AssertionInfosource EXTERNAL +AssertionRunEventtimeseries). We built both against the raw APIs, and upstreamed them as a skill PR todatahub-project/datahub-skills. - Memory lives in the graph itself, in three registers at once: documentation (prose, for the human at 9am), a structured property (JSON, for the next agent), and a failure-mode tag (searchable by everyone). Nightshift itself is stateless: any MCP-capable agent pointed at the same graph inherits the memory.
- The demo runs on DataHub's own showcase-ecommerce datapack: a realistic cross-platform graph (Snowflake, dbt, PowerBI, Tableau) where we plant a silent upstream rename.
Challenges we ran into
- The mutation that lied about its name.
updateIncidentStatustakes anIncidentStatusInput, not theUpdateIncidentStatusInputthe naming convention promises. Our first live shift ended with an incident stuck ACTIVE; introspection settled it. The fix is in our upstreamed skill so the next team doesn't lose a night to it. - The graph had its own skeletons. Our first agent run ignored the break we planted and diagnosed a pre-existing flaw in the showcase datapack (
order_datestored as TEXT end-to-end). It was right, and wrong for the night. That failure taught the runbook its sharpest rule: respect the timeline. An old flaw explains a chronic problem, never a fresh break. - A packaging bug in
acryl-datahub1.7.0 breaksdatahub datapackfrom PyPI (missing resource file). Found while building, reported upstream as #19028. Workaround in the README quick start.
Accomplishments we're proud of
- The compounding loop is measured, not claimed. Every number above comes from replayable shift reports in the repo.
- Real write-back: judges can open the DataHub UI after a shift and see the incident resolved, the postmortem in the docs, the assertion in Validations, the tag on the dataset.
- An upstream contribution that outlives the hackathon: the OSS incidents-and-assertions skill, plus a packaging bug report.
What we learned
Lineage doesn't just help an agent explain a break. It changes what the agent does: the fix is correct because the graph said what was actually connected. And memory changes the economics: context makes an agent smart once; write-back makes it smarter every night.
What's next
- Guard-triggered shifts: assertions Nightshift left behind paging Nightshift itself. The loop closes without a human pager at all.
- Cross-asset generalization:
find_datasets_with_failure_modealready answers "where else could this happen?" The next step is fixing those before they break. - Landing the upstream skill and following the maintainers' preferred shape for it.
Try it / built on
Live product: Nightshift → open /app→ Live → Break the pipeline → Wake the night shift. Real DataHub, real agent, real write-back.
Judge route: JUDGING.md.
Local: make demo. Built on the DataHub MCP Server and Agent Context Kit. Apache 2.0. We'd love to present this at a town hall.
Built With
- 2.0
- agent
- apache
- claude
- context
- datahub
- dbt
- mcp
- python
- sdk
- server
- typescript
Log in or sign up for Devpost to join the conversation.