Webhook receiver: Plane deliveries trigger a tick (PAD-7)

agentd webhook-serve (agentd/webhook.py, stdlib): verifies X-Plane-Signature
(HMAC-SHA256 hex of the body, constant-time; 401 on missing/bad), routes by
data.project to a configured tenant (others 202), coalesces deliveries within
3 s into one tick, runs one more tick when deliveries arrive during a tick,
and retries every 15 s for up to 2 min while the lock is held (tick command
exit 75: flock -E 75 in the cron scripts, cli tick on Busy). Ticks run in a
systemd scope so restarting the receiver never kills one. Log:
<log_dir>/webhook.log; GET /healthz.

Config: webhook section (key names only, PLANE_WEBHOOK_SECRET scrubbed from
child envs like the Plane tokens), notify: {kind: none} as a no-op hook
called on every state move; the unused per-project webhook_secret_key is
gone (Plane webhooks are workspace-level). systemd unit for the LXC and
tools/plane-webhook.py to create/rotate the Plane webhook as the workspace
admin (secret straight into the Vault, never printed).
This commit is contained in:
jj.wang
2026-10-21 13:24:04 +00:00
parent 72681db46b
commit 6dc7e72ac8
14 changed files with 651 additions and 9 deletions
+12 -1
View File
@@ -13,6 +13,18 @@ agentd:
comment_max_chars: 6000
cli_terminal: oregon # identity used by `agentd new/comment/state/assign`
# Plane webhook receiver (`agentd webhook-serve`, docs/runbook.md "Webhook"); leave the section out to run on cron only.
webhook:
bind: 127.0.0.1
port: 8790
path: /plane
secret_key: PLANE_WEBHOOK_SECRET # Vault key name of the Plane webhook secret (workspace-level webhook)
tick_command: [cron/agentd-tick.sh] # exits 75 when another tick holds the lock (flock -E 75)
debounce_seconds: 3
retry_seconds: 15
retry_window_seconds: 120
notify: {kind: none} # notification hook: only `none` (no-op) exists today
terminals:
win10:
transport: warpgate-ssh
@@ -72,7 +84,6 @@ projects:
GWENT:
id: 79cb5a60-aa4f-4138-9864-1dd70426e665
key_prefix: GW
webhook_secret_key: PLANE_WEBHOOK_GWENT
states: {backlog: Backlog, todo: Todo, running: In Progress, waiting: Waiting, review: Review, done: Done}
reviewer: oregon # Plane user that gets [review] items
answerer: oregon # Plane user that gets [question]/[blocked] and failures (default: reviewer)