Say so at startup when a security-relevant alert is unconfigured, instead of skipping silently #107
Closed
opened 2026-08-22 11:59:44 +00:00 by mathias
·
1 comment
No Branch/Tag Specified
main
fix/pipeline-writes-158
fix/edit-path-io-192
fix/create-regular-188
fix/guard-special-179
fix/linkcheck-keeps-write-178
fix/write-dir-redirect-173
fix/tunnel-detect-174
fix/pipeline-root-157
w3/154-mcp-auth-wiring
fix/tunnel-traversal
test/in-brain-targets-171
fix/brain-scan-root-157
fix/graph-wiki-root-157
fix/vectorstore-root-157
fix/notes-root-157
fix/search-root-157
fix/brainwide-root-157
fix/raw-symlinks-153
feat/symlink-tripwire-157
fix/rest-auth-149
fix/123-brain-edit-envelope-check
feat/106-page-aware-extraction
fix/105-source-drift-on-main
fix/104-surface-merge-conflicts-on-main
agent/b1-compile-on-ingest
agent/104-surface-merge-conflicts
agent/105-source-drift
agent/107-loud-unconfigured-alerting
feat/brain-read-edit
fix/capture-i1-refusal-names-target
renovate/configure
feat/consolidate-single-harness
icebox/cmd-routing
feat/brain-pending-promote
fix/close-session-classification-refresh
fix/capture-summarywriter
v0.24.0
v0.23.1
v0.23.0
v0.22.0
v0.21.1
v0.21.0
v0.20.1
v0.20.0
v0.19.1
v0.19.0
v0.18.4
v0.18.3
v0.18.2
v0.18.1
v0.18.0
v0.17.0
v0.16.1
v0.16.0
v0.15.0
v0.14.0
v0.13.2
v0.13.1
v0.13.0
v0.12.1
v0.12.0
v0.11.2
icebox/cmd-routing-2026-07-01
v0.11.1
v0.11.0
v0.10.0
v0.9.0
v0.8.0
v0.7.0
v0.6.0
v0.5.0
v0.4.1
v0.4.0
v0.3.0
v0.2.0
v0.1.0
Labels
Clear labels
agent/ready
blocked/client
blocked/supplier
blocked/upstream
risk/high
risk/low
risk/medium
size/l
size/m
size/s
size/xs
status:dispatch
status:dispatched
status:review
status:reviewing
type/chore
type/decision
type/docs
type/feat
type/fix
type/ops
type/research
type/test
Meets the agent-ready contract; authorizes unattended execution
Waiting on the client
Waiting on a supplier
Waiting on an upstream project or vendor
Irreversible, security-relevant, or control plane
Reversible, local, test-covered
Touches shared state, deploys or data
Too big - split it
Under two days
Under half a day
Under an hour
Maintenance, no behaviour change
Human decision required; never agent/ready
Documentation only
New capability
Corrects broken behaviour
Infrastructure, deploy, runtime
Investigate; output is a finding, not code
Test coverage only
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: mathias/hyperguild#107
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Small hardening, from the #100 post-mortem.
What happened
buildNotifier()returns a nil interface whenBRAIN_NTFY_URLis unset, and every consumer skips a nil notifier silently. That is correct for an unconfigured homelab — the service should run without a notification stack. It is wrong for an alert whose whole purpose is that someone finds out.Two alerts were dark in production and nothing said so: the governance-rewrite alert (#97) and the audit-degradation alert (
DegradingSink), the latter since it shipped. Both were found by firing a real event and watching nothing arrive.The cost of the current design is that "configured and working" and "never configured" are byte-identical in behaviour: no error, no warning, no log line. The only difference is a message that never arrives, which nobody notices, because nobody is waiting for an alert they have never seen.
Proposal
At startup, log at WARN once per unconfigured alerting dependency:
Not an error, not a refusal to start: an unconfigured homelab must still boot. Just a line that makes the absence visible at the only moment anyone is reading the logs anyway.
caveman: machine say out loud when alarm not plugged inBRAIN_NTFY_URLis unset, naming what will not fireBRAIN_LOKI_URLis the obvious sibling (audit records fall back to a slog sink, which is fine, but should be stated)Why it is worth the ten lines
One log line would have turned a live-fire test into a five-second discovery. The general rule is recorded at brain
wiki/hyperguild/failures/a-nil-notifier-is-indistinguishable-from-an-alert-that-never-fires: for anything whose value is "someone finds out", prefer loud-on-unconfigured over silent skip.Risk: LOW — logging only.
Refs: #100, #97.
Merged via PR #140 (squash, merge commit
c6341f020ab781179d2a642b1796f2a49d45820c), a rebase of the now-closed PR #108 onto current main. Verification performed before merge:alertingWarningsandTestAlertingWarningsfrom PR #108's original commit (1ff6af4a...) and diffed against #140's HEAD (67c30394...): zero difference in either the function body/comments or the test. Themain()call site (for _, w := range alertingWarnings(os.Getenv) { logger.Warn(w) }) is also identical.main.goon the branch:BRAIN_LLM_TERTIARY_URL/Tertiaryrouter block (lines 274-277) andCLAUDE_INGEST_SKIP_PROJECTS(line 452) are both present, and neither appears in the PR's diff (confirmed the diff touches only the newalertingWarningsfunc + call site + test).buildAuditSink(main.go:193-210): unsetBRAIN_LOKI_URLalready logs"capture audit: slog sink (BRAIN_LOKI_URL unset)"at Info and returnsaudit.NewSlogSink, which is a genuinely functional sink (Reservealways grants,Recordwrites every audit entry via slog) — not a stub. So unlikeBRAIN_NTFY_URLunset (a true silent failure — no code path announces it), Loki-unset is already stated. Distinguishing the two is sound, not an oversight.TestAlertingWarnings— mutatedalertingWarningsto always return the warning: the "configured notifier is silent" case failed as expected. Mutated it to never return a warning: the "notifier unconfigured" case failed on all three required substrings (BRAIN_NTFY_URL,brain_edit_root,audit). Both mutations caught; test reverted to baseline afterward (working tree left clean).go build ./...,go vet ./...,go test ./... -race -count=1— all 31 testable packages green, zero FAIL lines.success—CI / Lint / Test / Vetrun 7947, 36s.All "done when" clauses satisfied: WARN-at-startup naming
BRAIN_NTFY_URL,brain_edit_root, audit degradation; BRAIN_LOKI_URL sibling addressed with a verified, sound justification rather than silently skipped; test covers both configured and unconfigured cases and was proven to actually discriminate them.