notify: wire the webhook sink behind an opt-in env var - #215
Conversation
The WebhookSink (Slack / generic JSON POST on turn completion) was fully
implemented, redaction-safe, and tested — but never attached to a Notifier, so
deadcode flagged its entire machinery (NewWebhookSink, Emit, text, redactLinks,
log, eventType, readSnippet) as unreachable.
Wire it via a small, testable helper, MaybeAddWebhookSink(n, env, logf):
- reads ZERO_NOTIFY_WEBHOOK_URL (+ optional ZERO_NOTIFY_WEBHOOK_SUMMARY)
- no-op when the URL is unset/blank, so it is safe to call unconditionally
- sourcing the URL from the environment keeps the secret token out of any
on-disk config file
Attached at both notifier construction sites:
- headless exec: failed deliveries log to stderr (never stdout); the sink
redacts before logging
- TUI: logf=nil so a delivery failure can't corrupt the alt-screen
The sink stays gated by the existing Mode/focus policy (verified by
TestNotifierOffSuppressesSinks), so a webhook only fires when notifications are
enabled (e.g. --notify both) — no change to default behavior. Opt-in and
fail-closed: with the env var unset nothing is attached.
deadcode: 100 -> 93 unreachable funcs (the 7 WebhookSink entries become
reachable); no new dead code. gofmt/vet/build(host+linux+windows)/test -race/
staticcheck(no new)/govulncheck(0) all pass.
|
Consolidating the audit-backlog work into a single PR with one commit per change (per request). This change is preserved verbatim as a commit there. |
Zero automated PR reviewVerdict: No blockers found Blockers
Validation
ScopeHead: This deterministic review checks validation status and basic diff hygiene. A human reviewer still owns product judgment and design quality. |
|
Caution Review failedPull request was closed or merged during review No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
WalkthroughAdds opt-in webhook fan-out for run notifications. A new ChangesWebhook Notification Fan-out
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Summary
The
WebhookSink(best-effort Slack / generic JSON POST when a turn completes or awaits input) was fully built, redaction-safe, and unit-tested — but never attached to aNotifier.deadcodetherefore flagged its whole machinery as unreachable, and the v16 audit listed it as "wire or removenotify.WebhookSink". This wires it.What changed
notify.MaybeAddWebhookSink(n, env, logf):ZERO_NOTIFY_WEBHOOK_URL(and optionalZERO_NOTIFY_WEBHOOK_SUMMARY)exec— failed deliveries log to stderr (never stdout, which may carry stream-json); the sink redacts before logginglogf=nil, because the TUI owns the alt-screen and a stderr write would corrupt the displayBehavior / safety
ZERO_NOTIFY_WEBHOOK_URLunset, nothing is attached and behavior is identical to before.TestNotifierOffSuppressesSinksprovesMode==offsuppresses sinks), so a webhook only delivers when notifications are enabled (e.g.--notify both). No change to default notification behavior.Verification
WebhookSinkentries (NewWebhookSink,Emit,text,redactLinks,log,eventType,readSnippet) become reachable; no new dead code.go test ./...(-raceon notify) · staticcheck (no new) · govulncheck (0) all green.Summary by CodeRabbit
Release Notes
ZERO_NOTIFY_WEBHOOK_URLenvironment variable for integration with external systemsZERO_NOTIFY_WEBHOOK_SUMMARYenvironment variable allows customizing the run summary in webhook payloads