Skip to content

T-IIZZ-notify-config-for-desktop-ntfy-webhook-channels-and-the-9

State: closed/done · Impact: medium · Complexity: large

notify: config declares channels (desktop, ntfy HTTP topic, webhook for Slack or Discord) and events: pr.needs_response, pr.ci_failed, task.parked, stage.ceiling_reached, phase.ready_for_review, lease.expired, session.ended, hook.blocked, orchestrator.dead_stop.

  1. Define the notify: config schema: named channels (a discriminated union on type: desktop, ntfy with topic_url, webhook with url+format slack/discord/raw) and an events map keyed by exactly the 9 canonical event names, each an array of channel names.
  2. Retire orchestrator.notify (Phase 2’s slice, lib/config/load.ts) outright — hard cutover, no compat shim — now that the top-level notify: section it said it would “absorb” is real.
  3. Meta-define every top-level key per the P5 pattern (category: 'automation', consumers, layers, applies_via, runs_in), covered by the existing meta completeness test.
  4. Regenerate the generated docs (sdlc docs generate) and the built plugin packs (agent-pants build) so conventions/sdlc-yaml.md and the three .claude-plugin//.agents//.cursor-plugin/ trees reflect the new section.
  5. Grow lib/services/notify/dispatch.ts’s notify() into channel-routing (events[event] -> channel names -> channels, best-effort per channel) and add lib/services/notify/webhook.ts (mirrors ntfy.ts: injectable fetchFn, POSTs a body shaped by format). Landed here rather than in T-2QGZ so that task’s call-site rewiring and new CLI ops have a real runtime to build on from the start, instead of both tasks touching dispatch.ts in sequence.
AreaNote
solutions/ontological/lib/config/load.tsnotify: schema; retire orchestrator.notify
solutions/ontological/lib/config/meta.tsmeta categories (unchanged; notify already listed under automation)
solutions/ontological/lib/services/notify/dispatch.tschannel-routing notify(), sendToChannel
solutions/ontological/lib/services/notify/webhook.tsnew channel sender
solutions/ontological/conventions/sdlc-yaml.md + built plugin packsregenerated, not hand-edited
  • AC-1: notify: validates channels (desktop/ntfy/webhook, each shaped per its type) and an events map whose keys are exactly pr.needs_response, pr.ci_failed, task.parked, stage.ceiling_reached, phase.ready_for_review, lease.expired, session.ended, hook.blocked, orchestrator.dead_stop — an unknown event key is a schema error (.strict()), and every top-level key carries .meta() (meta.test.ts stays green).
  • AC-2: An events.* entry naming a channel absent from channels fails config validation with an error naming the bad channel — caught at sdlc.yaml load time, not at notify-dispatch time.
  • AC-3: orchestrator.notify no longer exists in the schema (hard cutover); no code or test references it after this task.
  • AC-4: bun run solutions/ontological/cli/sdlc.ts docs generate --check and cargo run -q -p agent-pants -- check --config solutions/ontological/agent-pants.yaml are clean against the regenerated notify: reference section.
  • The notify send/notify test CLI ops, every Phase-2 call-site rewire (work.ts, hooks/run.ts, _pr_action.ts, prs.ts, merges.ts), and the two new detector wirings (lease.expired, session.ended): T-2QGZ.
  • Wiring phase.ready_for_review and orchestrator.dead_stop to a real detector: no such detection code exists on this branch yet (see T-2QGZ’s Out of scope for why these two stay config-only for now).
  • none

← Back to Tasks