Notifications and approvals
Outbound webhooks and a Telegram bot for sealed/failed/promoted/needs_approval events, plus /approve and /reject from chat.
Goal#
Get a status ping — never a diff, never file contents — the moment a worker seals or a worktree is promoted, and optionally approve or reject a session from Telegram instead of the CLI. Two independent channels, both opt-in: generic outbound webhooks (any URL — Slack, Discord, n8n, Zapier, your own receiver) and a Telegram long-polling bot.
Steps#
-
Add one or more webhooks to
orch.yaml:notify: webhooks: - url: "https://example.com/orch-hook" events: [sealed, failed, promoted, needs_approval] # omit = all secret_env: ORCH_WEBHOOK_SECRETEvery delivery is a
POSTwith a JSON body —event,workspace,project,session,agent,status,exit,verdict,guard_lines,usage.in/out,log_path,ts— and, whensecret_envnames a set environment variable, anX-Orch-Signatureheader: the hex HMAC-SHA256 of the raw body under that secret. Verify it before trusting the payload. -
Send a synthetic event to check the wiring:
orch notify test [--event sealed|failed|promoted|needs_approval] -
Add a Telegram bot (talk to
@BotFatherfor a token; message the bot once sogetUpdatescan see your chat id):notify: telegram: bot_token_env: ORCH_TELEGRAM_TOKEN chat_allowlist: [123456789] events: [sealed, failed, promoted, needs_approval]orch daemonstarts the long-poll worker automatically whennotify.telegram.bot_token_envis set. To run it on its own:orch notify telegram runFrom an allowlisted chat:
/status,/approve <session>,/reject <session>(mark failed + prune the worktree). A message from any other chat id getsorch: unauthorized chatand nothing else runs. -
Require approval before a clean seal is eligible to merge:
promote: require_approval: trueA session that seals
okthen firesneeds_approvalinstead of being merge-ready;/approve <session>(ororch worktree promote <session>) still does the actual merge.
n8n / Zapier#
Both platforms speak plain HTTP — point their "catch webhook" trigger node at
your receiver URL and put that URL in notify.webhooks[].url. No Orchemax-specific
node needed: n8n's Webhook node and Zapier's "Catch Hook" trigger both parse
the JSON body directly; add a Code/Filter step on event if you only want to
react to needs_approval, and verify X-Orch-Signature in that step if the
webhook is reachable from outside your network.
What never leaves the machine#
Payloads carry status and summary only — guard verdict lines, file counts, token usage — never a diff or file content. Code stays local; only the event above crosses the wire, and only to the URLs/chats you configured.