feat(webhook): pin local-webhook 0.10.0 — standing watches stop duplicating owned work - #171
Merged
Merged
Conversation
…cating owned work Bumps services.agent-box.webhook.rev/sha256 to local-channels efa2531 (local-webhook 0.10.0, defangdevs/local-channels#11), which fixes the self-spawning this box hit twice on 2026-08-02: five hook-* sessions for CI on PRs a session was already driving, three of the four hook slots gone, all from two docs merges. Nothing was misconfigured — CI-outcome events bypass ignoreSenders by design, and dispatch never asked whether a session peer had just taken the same delivery. 0.10.0 adds two brakes on the dispatch path only (session delivery is untouched, so "merge on green" still works): a CI event overrides ignoreSenders only when it reports a FAILURE, and no CI event spawns while a live session peer's own filter already claims the topic. Non-CI events — a new issue, someone else's PR — still spawn regardless of who is subscribed, because topics are repo-granular while ownership is object-granular. Peer IPC sockets are now named "<filter key>.<pid>.sock" so the ingress owner can resolve a live peer to its subscriptions; that is internal to webhook.py's own state dir, and nothing in this module reads those names. Also documented in the two places an agent actually looks: the guide's standing watch section and `agent-box-webhook --help` both now say a watch will not double up on work you own. tests/webhook.nix asserts the new behaviour end-to-end, and had to change to keep passing — its dispatch delivery is a workflow_run FAILURE on the repo the peer session is subscribed to, which is now precisely the suppressed case. It therefore proves both directions on a real box: the delivery is accepted, the daemon logs "not spawning ... session agent-main is subscribed to it" and no hook-* session appears; after the peer unsubscribes, the same delivery spawns the session with the framed prompt as before. The socket-name assertion moved to instances/agent-main.*.sock. Checks run (aarch64-linux): module-generated-up-to-date, module-single-file, webhook-route, multi-user. The webhook VM test is x86_64-only and runs in CI — the assertions above are unverified locally. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PsqGhkpjsb4kKAdVz25xKN
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Companion to defangdevs/local-channels#11 (merged as
efa2531), which closes defangdevs/local-channels#10.Motivation
This box hit the same failure twice on 2026-08-02: five
hook-*sessions spawned for CI on PRs a session was already driving — two while #168 went through CI, three more when merging #168 and #169 put CI on master. Three of the four hook slots went with them, from two documentation merges. Nothing was misconfigured: CI-outcome events bypassignoreSendersby design, anddispatch_event()never asked whether a session peer had just taken the same delivery.Changes
services.agent-box.webhook.rev/sha256→ local-channelsefa2531(local-webhook 0.10.0). Two brakes, dispatch path only: a CI event overridesignoreSendersonly when it reports a failure, and no CI event spawns while a live session peer's own filter already claims the topic. Session delivery is untouched, so "merge on green" still works. Non-CI events (new issue, someone else's PR) still spawn regardless of who is subscribed — topics are repo-granular while ownership is object-granular.agent-box-webhook --helpboth now state that a watch will not double up on work you own.tests/webhook.nixcovers the new behaviour end-to-end.0.10.0 renames peer IPC sockets to
<filter key>.<pid>.sockso the ingress owner can resolve a live peer to its subscriptions. That is internal towebhook.py's own state dir; nothing in this module reads those names.Why the VM test had to change
Its dispatch delivery is a
workflow_runfailure ondefangdevs/agent-boxwhile the peer session is subscribed to that repo (pinned) — exactly the case 0.10.0 now suppresses, so the old assertions would have failed. The test now proves both directions on a real box:200), the daemon logsnot spawning for workflow_run on defangdevs/agent-box — session agent-main is subscribed to it, and nohook-*session appears.hook-*session appears with the framed prompt + trusted preamble as before.The socket-name assertion moved to
instances/agent-main.*.sock, which also pins the new naming contract.User-visible / security effects
Fewer spawned sessions, none of them for work a live session owns. No change to the ingress, HMAC verification, the
401fail2ban key, socket ownership, or the settings surface. No AWS, IAM, networking, or migration impact.Operational note: this box's
github:defangdevs/*standing watch is currently unsubscribed as a stop-gap. It gets restored after this lands and the box rebuilds onto the new pin.Checks run
nix build -L .#checks.aarch64-linux.{module-generated-up-to-date,module-single-file,webhook-route,multi-user}— pass.nix eval .#checks.x86_64-linux.webhook.drvPathevaluates.The
webhookVM test is x86_64-only, so the new assertions are unverified locally — CI is their first real run.🤖 Generated with Claude Code
https://claude.ai/code/session_01PsqGhkpjsb4kKAdVz25xKN