Skip to content

feat(aggregator): notification engine — class triggers, dedupe, quiet hours, escalation (#1254 slice c) #3317

Open

Description

@dezren39

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

  1. added
    kind/featureNew feature or capability request
    priority/normalOrdinary priority (the default)
    app/pm-stackpm-stack (Pad/Grist) in developing-today/code
    on Nov 1, 2026
  2. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    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.

  3. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 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.ts module header (PR #4977) — and closed the audit on #3702. What this means for this slice's dashboard classes:

  4. added
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    on Nov 3, 2026
  5. developing-today commented on Nov 3, 2026

    @developing-today
    Contributor

    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

  6. 68 remaining items

  7. added
    queue/claimedQueue worker lifecycle state
    and removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Nov 4, 2026
  8. dezren39 commented on Nov 4, 2026

    @dezren39
    MemberAuthor

    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.

  9. added
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    status/parkedDeliberately paused with a recorded resume condition
    and removed
    queue/claimedQueue worker lifecycle state
    on Nov 4, 2026
  10. dezren39 commented on Nov 4, 2026

    @dezren39
    MemberAuthor

    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.

  11. added
    queue/queuedHas a queued task in the Supabase agent queue
    and removed
    work/assignedQueue worker lifecycle state
    on Nov 5, 2026
  12. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · handed off

    • Agent: fleet monitor
    • Session / ID: task 8700 (repo-fleet-monitor run 2026-11-05T15:45:48Z)
    • Found via: monitor reconciliation (Duty 1 claim/label divergence repair)
    • Task: Claim evaporated: task 8700 is queued and unclaimed in repo-health-code-pilot, but this issue still carried claimed labels. Labels reset to the truth (queue/queued + status/needs-triage). Checkpoint stage at evaporation: handed_off.
    • Expectation: The next lane claim picks task 8700 up from the queued state and posts a fresh pickup note.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/pm-stackpm-stack (Pad/Grist) in developing-today/codekind/featureNew feature or capability requestpriority/normalOrdinary priority (the default)queue/parkedQueue task is parked (waiting on CI, time, or an event)queue/queuedHas a queued task in the Supabase agent queuesource/creatorFiled by the new-issue-creator jobstatus/needs-triageNot yet triaged; needs a first lookstatus/parkedDeliberately paused with a recorded resume conditiontask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions