feat(capturehttp): 503 on audit-unavailable; wire degrading sink (#54)
- Map capture.ErrAuditUnavailable → HTTP 503 (audit substrate down / confidential unauditable / floor). - main: buildAuditSink selects the DegradingSink (loki central + durable file buffer under brainDir + optional ntfy) when BRAIN_LOKI_URL is set and starts the reconcile loop; else the plain slog sink. Notifier kept as a nil interface (not typed-nil) when unconfigured so the sink and reconcile skip it cleanly. Env: BRAIN_LOKI_URL, BRAIN_NTFY_URL, BRAIN_NTFY_TOKEN, BRAIN_AUDIT_RECONCILE_INTERVAL (default 60s). Buffer at <brain>/.audit-buffer/capture.jsonl. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -113,6 +113,10 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
case errors.Is(err, capture.ErrSovereigntyRefused):
|
||||
writeJSON(w, http.StatusForbidden, map[string]string{"error": err.Error()})
|
||||
return
|
||||
case errors.Is(err, capture.ErrAuditUnavailable):
|
||||
// I5 refusal: confidential + audit sink down, or the all-tiers floor.
|
||||
writeJSON(w, http.StatusServiceUnavailable, map[string]string{"error": err.Error()})
|
||||
return
|
||||
case err != nil:
|
||||
// Pre-write validation failure (fail-closed).
|
||||
writeJSON(w, http.StatusBadRequest, map[string]string{"error": err.Error()})
|
||||
|
||||
Reference in New Issue
Block a user