Extract alert config types, normalization, and identity helpers into internal/alerts/config while preserving the existing alerts package API through aliases and wrappers.
Move Manager callback lifecycle state into a same-package callbackBus, keeping public Set/Subscribe methods unchanged.
Harden metrics SQLite artifacts to owner-only permissions and cover permissive umask behavior.
Proof: go test -json ./internal/api -count=1; go test ./internal/alerts/... ./internal/monitoring ./internal/ai/... ./internal/websocket ./internal/config ./pkg/metrics; go test ./internal/alerts/... ./pkg/metrics
Keep the buffered EOF compatibility path for OpenAI-compatible streams that omit [DONE] but provide a terminal finish_reason, while rejecting truncated tool-call streams before they can produce executable tool calls.
Refs #1411
Refs #1412
Parse the /proc/mdstat operation keyword for mdadm arrays and propagate it through host reports, models, unified resources, monitoring views, alert metadata, and AI storage summaries.
Treat recovery and reshape as rebuild signals while silencing routine check and resync maintenance, with fallback rebuild detection only when no mdstat operation is available.
Tests cover mdstat operation parsing plus recovery, check, and resync alert behavior.
Fixes#1446
Pass keep_alive=30s on both Chat and ChatStream requests so Ollama unloads the model shortly after Patrol or one-shot analysis bursts instead of refreshing the default 5-minute residency window on every request.
Tests assert both streaming and non-streaming Ollama request bodies include the keep_alive field.
Fixes#1425
Persist approval requests as governed planned actions with context confidence and stream that plan into Pulse Assistant approvals.
Reuse the planned action identity when approved actions execute so the unified audit trail stays continuous.
Share OpenAI ChatStream finalization across DONE and clean EOF so buffered final chunks still produce tool calls and done events for OpenAI-compatible providers.\n\nFixes #1411