quench
foundry github ↗

Triage the incident.
Approve the fix.

quench is a CI incident-triage agent. It ingests a failed GitHub Actions run, investigates with read-only tools, diagnoses the root cause with cited evidence, and drafts one recommended action. Every write waits for a human yes.

ci · run 28951398431failed
zaakirio/crucible master 268a1fd view run ↗
  • python19s
  • lab-ui6s
  1. actions/checkoutok
  2. actions/setup-nodeok
  3. Run npm ciexit 1
  4. npm run lintskipped
  5. npm run buildskipped
agent investigationstreaming
  1. classifyhaiku first pass: dependency, 85% confidence
  2. fetch_runci · push to master · concluded failure
  3. fetch_jobspython succeeded · lab-ui failed at "Run npm ci"
  4. fetch_failure_evidence".github:106 Process completed with exit code 1."
  5. fetch_commit_diff268a1fd "Redesign banner: gauged crucible vessel…"
  6. list_recent_runs2 recent same-workflow runs: failure / failure
  7. record_diagnosisdependency · recommends open_fix_pr
  8. open_fix_prWRITE · waiting for human approval
claude-haiku-4-5 → claude-sonnet-5cost $0.0684dry-run ●
diagnosis
failure_class
dependency
root_cause
The 'lab-ui' job failed at step 'Run npm ci', which points to a dependency failure.
confidence
85%
evidence · 5 cited
  • jobjob concluded 'failure': lab-ui
  • stepfailed step name: Run npm ci
  • annotation.github:106 exit code 1
  • commitcommit 268a1fd
  • recent2 runs: failure/failure
human approval required

proposed write: open_fix_pr · draft-only · dry-run

open_fix_pr → zaakirio/crucible

a rejected approval blocks the write — a dedicated eval proves it

Rendered from the recorded triage of zaakirio/crucible run 28951398431, one of the 12 real CI-failure fixtures. Reference run: dry-run, no writes.

every triage lands in one of ten failure classes — this run:

dependency lint test build security_audit performance infra regression flaky unknown
failure annotation · fetched read-only from the run
".github:106 Process completed with exit code 1."

How a triage runs

The evals assert the trajectory, not just the final text: did it fetch evidence before proposing an action, classify the failure correctly, pause for approval before any write, stay within budget, and cite real log evidence.

  1. Ingest.

    A failed workflow run comes in as repo plus run id.

  2. Investigate, read-only.

    Fetch the run, its jobs and failed steps, the failure annotations, the failing commit diff, and recent runs of the same workflow to gauge flakiness. Read tools have no side effects.

  3. Classify and diagnose.

    A cheap claude-haiku-4-5 first pass, then a claude-sonnet-5 investigation that records a structured diagnosis: failure_class, root_cause, confidence, cited evidence, flakiness_assessment, recommended_action.

  4. Act, behind approval.

    Re-run failed jobs, post a diagnostic comment, or open a fix PR. Each is a tool marked needsApproval, defaults to dry-run, and renders an approval card in the UI that gates continuation. A rejected approval blocks the write, and a dedicated eval proves it.

  5. Stay in budget.

    A hard cap on steps, tokens, and dollars, summed across every model call, with an explicit stop.

record_diagnosis · the same reference triage, as the agent recorded it
{
  "failure_class":        "dependency",          // haiku first pass: 85% confidence
  "root_cause":           "The 'lab-ui' job failed at step 'Run npm ci',
                           which points to a dependency failure.",
  "evidence": [
    { "kind": "job",        "quote": "job concluded 'failure': lab-ui" },
    { "kind": "step",       "quote": "failed step name: Run npm ci" },
    { "kind": "annotation", "quote": ".github:106 Process completed with exit code 1." },
    { "kind": "commit",     "quote": "commit 268a1fd" },
    { "kind": "recent_runs","quote": "2 recent same-workflow runs (failure/failure)" }
  ],
  "recommended_action":   "open_fix_pr"          // WRITE tool -> waits for approval
}

The real console

Screenshots of the running app, not comps. Left rail: the incidents. Center: the streamed agent trajectory. Right: the structured diagnosis and a live cost meter that sums real dollars from token usage across both models.

quench incident console before a run: twelve recorded incidents in the left rail, a failing lab-ui job for zaakirio/crucible in the center, a zeroed cost meter on the right
A real recorded failure from zaakirio/crucible, queued for triage. Dry-run badge shown.
quench mid-triage: the trajectory shows classify, fetch run, fetch jobs, fetch evidence, and the right rail already carries a dependency diagnosis with five cited pieces of evidence
The trajectory streams tool by tool; the diagnosis fills in with evidence quotes pulled from the run itself.
quench at the approval gate: record diagnosis is done and the open fix PR write tool is paused, waiting for a human yes
The stop that matters: open fix PR is a write, so the agent pauses and waits for a human before anything touches the repo.

Quickstart

Set a provider key for live diagnosis and a GITHUB_TOKEN for live log fetching; a deterministic reference mode drives the same tool loop against recorded failures in CI. The full matrix (live models, live GitHub, live writes) is in the README.

quench · zsh
npm install
npm test        # 30 unit tests
npm run eval    # 14 trajectory evals, 78 assertions
npm run build
npm run dev     # http://localhost:3000