The bug
Sentry shows: "Hydration failed because the initial UI
does not match what was rendered on the server", frequency
~30 events/hour, mostly on the
/dashboard/manager/[districtId] route. You have no
idea where to start. The agent has even less.
Step 1 — context_packet with the error verbatim
{
"tool": "context_packet",
"args": {
"request": "Hydration failed on /dashboard/manager/[districtId]",
"includeInstructions": true,
"includeRisks": true,
"includeLiveHints": true,
"freshnessPolicy": "prefer_fresh",
"budgetTokens": 4000
}
} The packet returns:
- primaryContext: the layout file
app/dashboard/manager/[districtId]/layout.tsx, the loading state, and the data fetcher. - activeFindings: a Reef finding from a
prior session — "client-only date formatting in
DistrictHeaderuses Date.now() inline". - risks: "this layout reads from
manager_district; RLS-sensitive." - recommendedHarnessPattern: "read primary
→ call
file_preflighton layout.tsx → check freshness."
The activeFindings line is gold — someone already looked at this file and noted a likely client/server mismatch culprit. Skip ahead to verifying it instead of re-deriving from scratch.
Step 2 — run file_preflight on the likely file
The Reef finding might be from three weeks ago and already fixed. Ask for the file's pre-edit packet:
{
"tool": "file_preflight",
"args": {
"filePath": "app/dashboard/manager/[districtId]/layout.tsx",
"limit": 50
}
} Returns durable findings, recent diagnostic runs that covered
the file, stale diagnostic flags, conventions, and ack history.
If it reports a stale source, let the daemon catch up or run
diagnostic_refresh for that source before trusting
the finding.
Step 3 — trace_error if you need broader context
If context_packet didn't surface the right file:
{
"tool": "trace_error",
"args": {
"term": "Hydration failed",
"limit": 30
}
} Returns throw sites, catch handlers, and PL/pgSQL bodies that match. For a runtime error this usually surfaces the React/Next boundary that's emitting it (and any custom error handlers in your app).
Step 4 — live_text_search after edits
You make a fix in DistrictHeader — wrap the
time-sensitive render in a useEffect so it only
runs on the client. Now you want to confirm there are no other
instances of the same pattern. Indexed
cross_search would be stale (you just edited).
Use live_text_search:
{
"tool": "live_text_search",
"args": {
"query": "new Date(",
"pathGlob": "app/**/*.tsx",
"fixedStrings": true,
"maxMatches": 100
}
} Now you have a fresh ground-truth list of every
new Date( in your app components. Audit them, fix
any other inline-date-during-render cases.
Step 5 — verify and mine the pattern
After the fix, call verification_state for the
changed files. If this was a repeatable structural bug, use
extract_rule_template on the fix commit to draft a
YAML rule, then validate it with rule_pack_validate.
Ack findings only when they are reviewed and intentional.
Why this is faster than grep loops
The agent went from "vague bug report" to "fix shipped" in roughly 5 tool calls and ~2,000 tokens of context. The vanilla path would have looked like 12 grep calls, 6 file reads, 8,000+ tokens, and the agent missing the prior Reef finding entirely.
The Reef finding from a prior session is the key win. Every bug you debug becomes durable knowledge — the next person (or agent) gets a head start.
Tools used in this recipe
context_packet— vague request → ranked context.reef_scout— broader scout packet of facts/findings/rules.file_preflight— pre-edit findings, diagnostic freshness, conventions, and acks.reef_inspect— full evidence trail for one file/subject.trace_error— find throw/catch sites for an error term.live_text_search— exact current text on disk.verification_state— confirms current diagnostics cover changed files.extract_rule_template— propose a reusable YAML rule from a fix diff.lint_files— Mako rule-pack diagnostics.