Agent stack build plans · № 4 · Hermes CI/CD healer
Architecture
Five hops, two of them yours. Everything with a name here is the real name.
GitHub Actions
Workflow run fails on
acme/reportd. GitHub fires the repo webhook: JSON payload, signed with your shared secret as X-Hub-Signature-256. The payload does not contain job logs — remember that for hop 4.↓ HTTPS POST across the public internet
A server GitHub can reach you build this
Hermes listens on
http://your-server:8644/webhooks/ci-heal — so port 8644 must be reachable from GitHub. A small VPS is the boring, reliable answer; a tunnel from a homelab box works too. Terminate TLS in front of it if it’s on the open internet. Hermes gives you the listener, not the reachability.↓
Hermes gateway — webhook platform
The
hermes gateway daemon’s webhook platform, configured under platforms.webhook.extra: port 8644, the HMAC secret (GitHub X-Hub-Signature-256 validation is built in, alongside GitLab-token and generic schemes), rate_limit (30/min documented default) and max_body_bytes. Invalid signature → dropped before any model is invoked.↓
Route:
ci-heal
A named route with
events (which deliveries it accepts), filters (the loop-breaker — skip runs on the agent’s own ci-heal/* branches), an optional script transform hook, a prompt template interpolating payload fields (docs’ example syntax: {pull_request.title}), and deliver targets for the report. The prompt template is the product spec in imperative form — it lives on the prompts page.↓ rendered prompt starts an agent run
Hermes agent run → terminal tool → Docker backend
Hermes ships six terminal backends (
local, docker, ssh, singularity, modal, daytona); this plan mandates docker. Hardened by Hermes: all capabilities dropped, no-new-privileges, 256-process limit, 512 MB tmpfs /tmp — the docs’ own framing is “the container itself is the security boundary.” Inside it, driven by the route prompt glue, not magic: gh run view --log-failed to fetch the logs the payload lacks, git clone + checkout of the broken branch, reproduce, patch, re-run the tests. The image with git, gh, and your toolchain is yours to bake you build this. Every command passes through the approvals layer (approvals.mode smart | manual | off, approvals.deny globs, plus a hardline blocklist even --yolo can’t switch off).↓ only if the suite is green
The PR
gh pr create from a fresh ci-heal/* branch: diagnosis, diff, sandbox test output in the body. Opened, never merged.The report
Route
deliver targets: github_comment on the failed run, and/or telegram / discord. This delivery path alone — failure → explanation in chat — is Hermes’s documented GitHub Actions use case.Where state lives
~/.hermes/config.yaml— gateway, webhook platform, routes, terminal backend, approvals. Precedence: CLI args > config.yaml >.env> defaults.~/.hermes/.env— the webhook secret and your model + GitHub tokens. Never in config.yaml, never in the repo.- The sandbox is disposable. Clones are ephemeral; nothing the agent does persists outside the PR branch it pushes. That’s the property the whole design leans on.
The two honesty notes
- Log ingestion is glue. No webhook anywhere ships job
logs in the payload. “Ingest the logs” means: the route prompt
tells the agent to run
ghand read them. Ifghisn’t in the image or the token lacks scope, the agent is diagnosing blind — traps covers the failure smell. - Reachability is infrastructure. If you can’t accept an inbound POST from GitHub, none of this fires. Budget that first, not last (setup, stage 2).