Overview

This document records the automation flow used to handle GitHub deployment failures through Hermes. The workflow is:
  1. GitHub emits a deployment failure or workflow failure event.
  2. Cloudflare Tunnel exposes the local Hermes webhook listener to the public Internet.
  3. Hermes receives the webhook and matches it to a dynamic subscription.
  4. Hermes loads the deploy-failed-investigation skill.
  5. The skill investigates the failure, attempts a local fix, and reports findings to Telegram.
  6. Hermes stops before commit or push and waits for user confirmation.

Goals

  • Catch deployment failures from GitHub Actions or deployment events.
  • Keep the webhook endpoint publicly reachable.
  • Run an investigation workflow automatically.
  • Report concise findings to Telegram.
  • Avoid committing or pushing until explicitly confirmed.
  • Record repeat mistakes in Hermes memory and repository notes.

Components

1. Hermes webhook listener

The webhook platform listens on the local machine, typically on port 8644. Health check:
curl http://localhost:8644/health

2. Cloudflare Tunnel

A named Cloudflare tunnel exposes the local listener through a stable public hostname. Current setup:
  • Tunnel name: hermes-webhook
  • Tunnel ID: 4a606722-8ca4-4ac2-8344-62fe6719f84c
  • Hostname: gh-webhooks.kokweng.net
  • Origin: http://localhost:8644
Tunnel config:
tunnel: 4a606722-8ca4-4ac2-8344-62fe6719f84c
credentials-file: /Users/gremlin/.cloudflared/4a606722-8ca4-4ac2-8344-62fe6719f84c.json

ingress:
  - hostname: gh-webhooks.kokweng.net
    service: http://localhost:8644
  - service: http_status:404
Run command:
cloudflared tunnel run hermes-webhook

3. Hermes webhook subscription

Current subscription:
  • Name: github-deploy-failed
  • Event: workflow_run
  • Delivery: telegram
  • Telegram chat ID: 72815965
  • Prompt: Telegram-friendly deployment failure alert
  • Skill: deploy-failed-investigation
Subscription source of truth:
~/.hermes/webhook_subscriptions.json

4. Investigation skill

The deploy-failed-investigation skill is stored at:
/Users/gremlin/.hermes/skills/devops/deploy-failed-investigation/SKILL.md
That skill tells Hermes to:
  • sync /Users/gremlin/Dev/monorepo with main
  • inspect the webhook payload and GitHub logs if needed
  • debug and fix the issue locally
  • report findings and fixes to Telegram
  • pause before commit or push
  • record repeat mistakes in Hermes memory and AGENTS.md
For GitHub Actions workflows:
  • Use workflow_run when tracking workflow completion or failure
For deployments that are tied to environments:
  • Use deployment_status when tracking deployment state transitions

Telegram-friendly prompt

The current prompt is intentionally short:
Deployment failed

Repo: {repository.full_name}
Workflow: {workflow_run.name}
Branch: {workflow_run.head_branch}
Status: {workflow_run.conclusion}

Next step: summarize the likely cause and what to check first.
This keeps Telegram alerts readable while still carrying enough context for investigation.

Webhook URL

GitHub should call the public Cloudflare URL, not localhost.
https://gh-webhooks.kokweng.net/webhooks/github-deploy-failed
Important:
  • localhost works only on the local machine.
  • GitHub must use the public hostname.
  • If the tunnel changes, GitHub must be updated to the new active endpoint.

Secret rotation note

Recreating a webhook subscription generates a new secret. If the subscription is removed and re-added:
  • update the GitHub webhook secret
  • re-test delivery
  • confirm hermes webhook list shows the new subscription state

Verification

Check subscription

hermes webhook list

Check local listener

curl http://localhost:8644/health

Check public endpoint

curl -I https://gh-webhooks.kokweng.net/webhooks/github-deploy-failed
A POST should return a normal webhook response, not 530.
  • ~/.hermes/webhook_subscriptions.json
  • ~/.hermes/.cloudflared/config.yml
  • ~/.hermes/skills/devops/deploy-failed-investigation/SKILL.md
  • /Users/gremlin/Dev/monorepo/docs/shared/index.mdx
  • /Users/gremlin/Dev/monorepo/docs/docs.json