Documentation
¶
Overview ¶
Package notify is the console's outbound webhook notification channel: a generic JSON POST for the events that mean "your safety net has a hole" — continuity gap_lost, verify problems, rotation making no progress — plus edge-triggering so a persistent condition alerts on its transition (and once on recovery), not on every cycle.
Delivery contract (mirrors ext.AuditSink's): fires off the hot path on its own goroutine, best-effort with bounded retry, rate-limited logging on failure, and can never block or crash capture. Generic JSON only — Slack, PagerDuty et al. all accept an inbound webhook; there are no per-vendor adapters.
Index ¶
Constants ¶
const ( EventContinuityGapLost = "continuity_gap_lost" EventVerifyProblem = "verify_problem" EventRotationUnhealthy = "rotation_unhealthy" EventBaselineStale = "baseline_stale" SeverityInfo = "info" SeverityWarning = "warning" SeverityCritical = "critical" )
Stable wire identifiers. Consumers (Slack/PagerDuty routing rules) key on these exact strings — producers must use the consts, never inline literals.
const DefaultRepeatEvery = 24 * time.Hour
DefaultRepeatEvery is how long an Edge stays quiet about a still-active condition before re-notifying — long enough that a persistent problem produces one reminder a day, not one per polling cycle.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Edge ¶
type Edge struct {
// contains filtered or unexported fields
}
Edge tracks per-key condition state so callers notify on the *transition* into a bad state, re-notify while it persists only after repeatEvery, and notify exactly once on recovery. Keys are caller-defined, e.g. "verify:<severity>:<server-id>".
Key identity is the caller's contract: if a key's identity churns (e.g. a DSN-derived key after a credential edit), the old entry stays active until resolved and the condition re-fires under the new key — a duplicate alert, never a lost one.
func (*Edge) Active ¶
Active reports whether key has fired and not yet resolved — for callers that must treat "cannot re-evaluate" differently while an alert is standing (e.g. a baseline source that now lists nothing).
func (*Edge) Fire ¶
Fire reports whether the caller should notify for key being in a bad state now: true on the transition into it, and again each repeatEvery while it persists. detail (optional) carries the condition's identity — a CHANGED non-empty detail is a NEW condition under the same key, so it fires immediately, bypassing (and refreshing) the repeat window.
type Event ¶
type Event struct {
// Event names the condition: continuity_gap_lost, verify_problem,
// rotation_unhealthy.
Event string `json:"event"`
Severity string `json:"severity"` // info | warning | critical
Server string `json:"server,omitempty"`
Summary string `json:"summary"`
// Details carries condition-specific strings (counts, error text).
Details map[string]string `json:"details,omitempty"`
// Resolved marks the recovery notification for a previously reported
// condition (sent once, with Severity info).
Resolved bool `json:"resolved,omitempty"`
Timestamp string `json:"timestamp"`
}
Event is the wire payload. The field set is the stable contract — additive changes only.
type Webhook ¶
type Webhook struct {
// contains filtered or unexported fields
}
Webhook posts Events to one URL from a single worker goroutine. A full queue drops the newest event (with a rate-limited warning) rather than ever blocking the caller — callers sit on the daemon's capture-adjacent loops.
func NewWebhook ¶
NewWebhook starts the delivery worker on ctx (the daemon lifetime).