The self-fix pipeline (owner guide)
When a user files a problem report through Jordyn (the report_issue chat
tool), the pipeline automatically dispatches a coding agent on the repo. The
agent investigates, fixes the root cause, and opens a pull request with
workflow-verified test results. Nothing reaches production without your
merge — and when you do merge, the person who reported the bug is told, in
their own chat and by email, that their fix is live.
How a run flows
- A report is filed →
lib/support-report.tsinserts thesupport_reportsrow, then fires a GitHubrepository_dispatch(eventsupport-report) carrying only the report ref, title, body, reporter plan tier, and filing time. No user identity or diagnostics leave the app. .github/workflows/self-fix.ymlruns Claude Code headless against the repo. The agent investigates, fixes, and adds tests — it cannot commit or push; it only edits the working tree.- The workflow itself then runs
npx tsc --noEmitand the fullnpx vitest runsuite. The agent's claims are never trusted.- Green: branch
self-fix/<ref>is pushed and a PR opens, labeledself-fix, with the report, the agent's summary, and the verified test counts. - Red: an issue titled
Self-fix failed for <ref>opens with the log tails, and nothing is pushed.
- Green: branch
- You approve by merging the PR (or reject by closing it — closing notifies nobody). Merging main auto-deploys to prod on Vercel.
.github/workflows/self-fix-merged.ymlsees the mergedself-fixPR, waits ~90s for the deploy, and callsPOST /api/self-fix/resolvewith a derived-HMAC token. That runsresolveReport(ref, note)— the reporter gets a warm note in their chat timeline and an email. Double-notification is impossible: an already-resolved ref refuses a second pass.
How you find out
The moment a fix-PR opens, the workflow calls POST /api/self-fix/pr-opened
(its own HMAC purpose, self-fix-pr:v1|<ref>) and you — the saas_admin, not
the reporter — hear about it. How loudly depends on whether it shipped
itself, which the risk rules decide a moment earlier:
- Shipped on its own (most fixes): one card on your Today page under
"System", filed as an ordinary item, not a to-do — "Fixed and shipped:
<ref>… Nothing for you to do". No text, no email. You asked for a log, not a chore list (2026-10-29): an email headed "waiting for your merge", about work already live, teaches you to ignore the next one. - Needs you (it touches the database, sign-in, money, email, the prompt
or config —
scripts/self-fix-risk.mjssays which): a text through your Jordyn line, a needs-action card, and a branded email whose button is "Look at it". The email says why this one reached you when most don't.
Anything the workflow sends that isn't exactly shipped is treated as
needing you, so a typo or an older workflow can never silence a real one. If
your SMS line isn't set up, the text is skipped silently and the rest still
lands. This step never fails the workflow — the PR existing is what matters.
One-time setup: three secrets
GITHUB_DISPATCH_TOKEN(Vercel env var): create a fine-grained GitHub PAT scoped totdaniel1925/Jordnynwith Contents: read/write and Actions: read/write permissions, and add it to the Vercel project. Without it, reports still file normally — the dispatch just silently skips (one log line).ANTHROPIC_API_KEY(GitHub Actions secret): powers the coding agent. Already present if the sim-battery workflow runs.CRON_SECRET(GitHub Actions secret): must be the same value as the app'sCRON_SECRETon Vercel — the merged-PR workflow derives its callback token from it (purposeself-fix-resolve:v1|<ref>). Already present if the sim-battery workflow runs.
The safety model
- The agent never pushes to main. It cannot: it works in the Actions
runner's tree, and the workflow only ever pushes a
self-fix/<ref>branch. Your merge is the gate. - Type check and the full test suite are verified by the workflow, outside the agent, after the agent finishes. A failing suite becomes an issue, not a PR.
lib/live-draft.tsandcomponents/InlineEmailDraft.tsxare off-limits to the agent, and the workflow force-reverts them even if it disobeys.- AUTO telemetry reports (system-filed, deduped noise) never dispatch a run.
- The resolve callback is HMAC-authenticated; a bad token gets a 401 and no report is touched.
Cost note
Each dispatched run spends Anthropic API tokens — a typical investigation
and fix costs a few dollars. User-filed reports are already rate-limited to
3/hour per user, and the workflow runs one fix at a time (concurrency: self-fix), so cost is naturally bounded. Remove GITHUB_DISPATCH_TOKEN
from Vercel to switch the whole pipeline off without touching code.