Engineering agent for software & cloud projects

Your errors just got an underling.

underling picks up Sentry alerts, sends Claude Code into a sandboxed clone of your repo to find and fix the bug, then hands you a draft pull request. You stay the boss. It does the digging.

How it works

From stack trace to draft PR, while you're still in standup.

  1. 1

    Sentry rings the bell

    A Sentry issue alert hits POST /sentry/callback. underling verifies the HMAC signature and records the culprit, exception and stack frames as an event.

  2. 2

    It grabs a fresh clone

    The Sentry project maps to a GitHub repo. underling clones it onto a new branch, underling/sentry-<issue>. One investigation per issue, even across restarts.

  3. 3

    Claude Code digs in

    Headless Claude Code, with the Codex and auto-task plugins, investigates and fixes the bug inside a sandbox, committing to the branch and nothing else.

  4. 4

    You get a draft PR

    underling pushes the branch and opens a draft PR that links the Sentry issue and includes Claude's summary. Review it, merge it, or close it.

Safety

A helpful underling, not a loose cannon.

The agent that writes the fix never holds the keys to ship it. Every boundary is deliberate.

  • Sandbox always on

    Claude Code runs with its sandbox enabled and file writes limited to the clone. underling won't ship with the sandbox off.

  • No secrets in the child

    The Claude process gets only PATH, a temporary HOME and model credentials. It never sees the GitHub token or the Sentry secret.

  • underling pushes, not the agent

    Claude commits locally. underling pushes with its own token, which goes to git through the environment and never lands in .git/config.

  • Drafts only

    Every change arrives as a draft PR against your default branch. A human always decides what merges.

  • Every outcome is recorded

    PR opened, no changes, skipped or failed (with the stage and reason): each run ends in an event. A failure never blocks the next alert.

  • No surprise backlog

    Alerts older than INVESTIGATION_MAX_AGE are skipped as stale, so a first deploy doesn't start working through history.

Under the hood

Small, boring, dependable.

One static binary

Pure Go, no cgo. All it needs is a data dir and its environment variables. GET /healthz answers ok.

Event-sourced

An embedded bbolt event store keeps every alert, investigation and outcome, with checkpoints so handlers pick up where they left off.

Vertical slices

Each feature is one package: a state change (trigger → command → event) or an automation (event → reaction). Slices meet only through events.

AWS-ready

OpenTofu provisions an ECS service behind an ALB. Claude Code and Codex reach Bedrock through the task role, so there are no model API keys to manage.

Point it at your repos

Map each Sentry project id to a GitHub repo, give it a token, and run it.

# map Sentry project ids to GitHub repos
SENTRY_GITHUB_REPOS=4507=acme/checkout,4512=acme/api
SENTRY_CLIENT_SECRET=…
GITHUB_TOKEN=…
CLAUDE_PLUGIN_DIRS=/opt/plugins/codex,/opt/plugins/auto-task
INVESTIGATION_TIMEOUT=30m

$ underling -data-dir ./data -addr :8080
underling

Let someone else take the 3 a.m. stack trace.

Get underling on GitHub