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