dare_messaging_service sketched + parked (2026-05-14)

DARE.CO.UK · PARKED SKETCH · 2026-05-18

Mirrored from ~/.claude/.../memory/project_dare_messaging_service_parked.md. This is a design sketch parked for future build — read for context, not as a current deliverable.

Notification micro-service architecture sketched and parked with resume conditions; opt-in SMS/push/email when reports ready or watch-items trip; Twilio + Pushover the recommended v1 providers


Sketched 2026-05-14 at Dan’s request (“a service that runs and can be consumed” — same shape as the publishing + sitemap pipelines). Parked. Full design + provider tradeoff catalogue at https://devreports.dare.co.uk/dare_messaging_service_sketch_2026-05-14. Index entry in REPORT_PATTERNS under *_messaging_service_*.html and *_notification_*.html (xlab-co/toolkit commit a7fe5de).

Why: Dan wants the option to be SMS’d (or otherwise alerted) when named reports are ready or when watch-item thresholds trip. The micro-service framing matches feedback_park_with_resume_conditions.md — design now, build when a workflow actually needs it.

Recommended v1 (when triggered): - ~/bin/notify-portfolio synchronous CLI with --channel sms|push|telegram|email|voice + --to <alias> + --subject/--body/--link. - Primary providers: - SMS → Twilio (already in portfolio for audrey contact form; shared billing) - Push → Pushover (one-off $5 lifetime; zero per-message cost; designed for personal alerting; the strongest “Dan, look at this” channel) - Fallback / specialty: - SMS fallback → sms.to (already in portfolio per CLAUDE.md; cheaper for UK) - Visual previews → Telegram Bot API (free, rich) - Long-form / digest → Resend email (already in portfolio) - Critical / out-of-band → voip.ms AI-voice (Dan has beta access) - Recipient indirection: --to dan resolves via ~/.config/notify/recipients.yaml to the underlying phone/key/email; adding a second human (a client check-in) is a one-file edit. - Creds: all op:// references into Code Shared vault — every provider’s credentials narrowly scoped per feedback_layered_guardrail_stack.md. - Opt-in from any script: --notify <channel>:<recipient> flag on dare_sitemap_regen, dare_404_audit, dare_dashboard_refresh, etc. — off by default. Cron stays quiet on success; pings only on watch-item or failure.

Update 2026-05-14 (later session): Dan opened a Pushover account — “pushover api looks good. opened up an account so that can be parked for later.” That’s the v1 push-channel credential ready.

Update 2026-05-14 (evening): Dan has the Pushover user key in hand. Still needs the application token (separately created at https://pushover.net/apps/build — each Pushover account has one user key but multiple app tokens, one per integration). Pushover’s send API requires both — the app identifies WHO is sending; the user key identifies WHO RECEIVES. Without app token, the user key alone can’t send anything.

When the build triggers, the wiring is: 1. Dan creates a Pushover application at https://pushover.net/apps/build (~2 min) — name suggestion portfolio-notify or dare-pipeline; type Application; description “Portfolio cron alerts + report-ready pings” 2. Store both in op://Code Shared/Pushover dare-pipeline/{user_key,app_token} via 1Password desktop. Category: Password (NOT API Credential per feedback_1password_api_credential_category_trap). Both fields CONCEALED. 3. notify-portfolio v1 reads via op:// references — no plaintext anywhere 4. First integration: --notify push:dan flag on dare_dashboard_refresh.sh for cron-failure alerts (probably the highest-value first trigger)

The account itself is half-ready (user key present, app token pending); the build trigger is still gated by an actual workflow needing it (per feedback_just_in_time_permission_grants). Likely build-trigger surface: audrey commerce alerts (per tomorrow’s stand-up framing — order alerts, low-stock, A/B significance, daily revenue digest).

Resume conditions: - Dashboard cron misses a day and silence becomes a load-bearing problem (push-on-failure becomes worth it). - An audrey commerce alert needs SMS (high-value order, low-stock trigger) — turns the service into customer-facing value. - A dogwood booking flow needs SMS confirmation — service-quality improvement. - A second report category genuinely needs out-of-band notification (today, the “Dan reads devreports when he sits down” cadence is enough).

Pitfalls catalogue (full version in the sketch report): delivery reliability (provider outage fallback, rate-limit, recipient offline), content shape (truncation, JSON escaping, link-shortener mangling), recipient privacy (phone redaction in logs, env-var leakage, accidental commit), cost surprise (cron storm rate-limiting, voice 3am calls, fallback bill drift), provider drift (API version pin, weekly self-test probe, locked-account escalation via the other channel), composition (sequencing report → publish → notify, –require-200 url-resolve check, default-quiet-on-success).

Build first (when triggered): 1. notify-portfolio CLI v1 — SMS via Twilio + push via Pushover only 2. --notify flag on dare_sitemap_regen.py + dare_404_audit.py + dare_dashboard_refresh.sh 3. Weekly self-test cron per channel 4. Watch-item escalation to push when thresholds trip 5. Telegram channel when visual previews start mattering

Pairs with: - project_audrey_entity_twilio_* — existing Twilio account for audrey; shared-billing pattern - feedback_just_in_time_permission_grants.md — defer minting per-provider API keys until a real workflow needs them - feedback_layered_guardrail_stack.md — every provider in Code Shared, narrowly scoped - feedback_save_vs_find_alignment.md — recipient indirection is save-time-matches-find-time at the routing layer

Source: parked_sketch_dare_messaging_service_2026-05-14.md · Rendered 2026-05-18 12:53