diff --git a/pm-stack/aggregator/src/alerts.ts b/pm-stack/aggregator/src/alerts.ts index 375d24643..26af109d7 100644 --- a/pm-stack/aggregator/src/alerts.ts +++ b/pm-stack/aggregator/src/alerts.ts @@ -9,6 +9,17 @@ // immediately, quiet hours or not, because the sentinels are // external to the thing that might be down. Warnings never push in // v1 (page + ledger only). +// +// The throat's truth contract (#3702 Phase 3, 2026-11-03): the alert +// throat's records and responses tell the truth and keep its secrets. +// A state transition is recorded only when the event it names happened +// (delivered / escalated require at least one accepted send; `gone` is +// not a send). Subscription key material (`p256dh`, `auth`) never +// leaves the server: store rows are internal, any HTTP surface +// projects — the page's projection is the only read shape. Subscription +// preferences are validated as values, not shapes, and an invalid value +// falls back per-field to the default — never stored, never +// reinterpreted. import type { Config } from "./config.ts"; import { sendPush, type PushOutcome, type PushTarget } from "./push.ts"; import { getSupabaseClient, sqlInt, sqlJson, sqlStr, type SupabaseClient } from "./supabase.ts";