Repository navigation
Description
Implementation slice (c) of the #1254 design (note: doc/2026-11-01T03-54-00Z_design_pwa_push_notifications.md, PR #3314; epic #1184). Depends on slice (b) push plumbing.
The engine: pollers over /api/attention.json, /api/quota.json, /api/health; class triggers exactly per design §1 — including the quota-doctrine rules (quota-wall only well before reset or on sole-door pools; routine exhaustion is silent); dedupe by (class, objectRef, state-fingerprint); 6h per-item cooldown; quiet hours (default 23:00–07:00 America/Chicago, per-subscription) with midday + window-end digests; the two-item breakthrough set (sole-door quota wall, 48h blocked-age); needs-drew escalation ladder (+24h batched reminder, +48h breakthrough-eligible, then weekly digest); every send appended to notifications.jsonl.
Defaults ship as the design §1 recommended set unless Drew rules otherwise on the design note Q1 before this lands — check the note/PR for his ruling first.
Acceptance:
- Each class fires in a fixture-driven test (enter-state fires once, stay-state never re-fires, state change re-fires)
- Quiet-hours sends defer to the digest; breakthrough set sends immediately
- Escalation ladder advances and stops on acted-on (item leaves tier / Drew comment or action)
- Send log records class, ref, timestamp for every send and suppression
Activity
dezren39 commentedon Nov 1, 2026
Design amendment (PR #3314 @76e898324, Codex P2): the engine consumes the full attention view incl. drewExtra (non-session needs-drew items), and this slice also extends /api/attention.json to carry the drewExtra entries. Add fixture coverage: a non-session needs-drew item (decision/task/gap) fires entry + blocked-age escalation.
feat(aggregator): alert throat — sentinel intake, Supabase ledger, We…
dezren39 commentedon Nov 3, 2026
🤖 Agent note · consumer contract now stated
Design #3702 Phase 3 (audit task 5613, 2026-11-03) has stated the alert throat's truth contract in the code —
pm-stack/aggregator/src/alerts.tsmodule header (PR #4977) — and closed the audit on #3702. What this means for this slice's dashboard classes:mergeQuietvalidates quiet prefs as values (hour 00–23, minute 00–59, per-field fallback to default; aggregator(alerts): mergeQuiet accepts out-of-range times (99:99, 24:60) — a malformed quiet window is silently reinterpreted instead of falling back to the default #3686) andinQuietHoursis the only suppression clock. New classes must consult it for non-incident classes exactly as the engine does — and must not invent a second interpretation of stored strings.delivered/escalatedrequire at least one accepted send (runAlertTickgates onsent > 0, aggregator(alerts): runAlertTick marks incidents delivered when every push send failed — critical incidents are silently lost, never retried #3685/PR fix(aggregator): retry failed incident pushes (#3685) #3690);goneis not a send.mergeClassescurrently passes any boolean key through; aggregator(alerts): bound mergeClasses keys to a class registry (#3702 disposition 4) #4981 will bound keys to a class registry once this slice names its classes. When you land them, expect the registry to become the allowlist.developing-today commentedon Nov 3, 2026
agent-note:v1
state: triaged (coverage pass)
Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 40 (priority/normal). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
Found via: coverage pass 2026-11-03
68 remaining items
dezren39 commentedon Nov 4, 2026
agent-note:v1
event: picked_up
task: 8700
lane: 1a180ae5-384f-4e71-8d77-08f7b1652c75
worker: repo-worker-code
execution_lane: openchamber-scheduled-lane
issue: #3317
kind: small_fix
state_checked: 2026-11-04T22:44Z — issue #3317 OPEN; no held/user-owned/do-not-merge/do-not-auto-edit labels; no open PR for queue/8700-3317-notification-engine.
resume: existing worktree /home/user/git/fleet/8700-3317-notification-engine is clean and tracks the pushed task branch.
next: resume the checkpointed digest, acted-on/escalation, and sole-door detection work; verify and open a PR.
dezren39 commentedon Nov 4, 2026
agent-note:v1
event: parked
task: 8700
lane: 1a180ae5-384f-4e71-8d77-08f7b1652c75
worker: repo-worker-code
execution_lane: openchamber-scheduled-lane
kind: small_fix
state_checked: 2026-11-04T22:57Z — issue #3317 OPEN; no hard-stop labels; no competing PR for the task branch.
artifact: queue/8700-3317-notification-engine at 3dbc9c68c8fe93210b1329bead632c6c9f5709e1, pushed; worktree /home/user/git/fleet/8700-3317-notification-engine.
implemented: derives weekly digest-only blocked-age reminder candidates with week-specific fingerprints; regression test covers weekly cadence and digest decision.
tests: bun test test/alerts.test.ts test/notifications.test.ts — 56 pass, 0 fail; git diff --check pass. bun run typecheck remains blocked by existing src/item-history.ts GhKind error.
reason: run-budget handoff; acceptance incomplete, so no PR opened.
resume: implement the durable per-subscription digest queue, quiet-window/noon batching, cancellation/acted-on escalation ladder, and production sole-door route detection; verify and open PR. Labels now show queue/parked + status/parked; work/assigned remains.
dezren39 commentedon Nov 5, 2026
🤖 Agent note · handed off