diff --git a/ROADMAP.md b/ROADMAP.md index c60554c..bcba1b2 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -4,7 +4,6 @@ Longer-term backlog. Near-term state lives in `AGENTS.md` → Current state. ## Payments & subscriptions -- Per-profile SMTP override (schema fields exist from the keysat-smtp-emails plan; needs the form + send path). - Rail-preference editing UI — only matters when two providers on one profile both serve the same rail; settable today via `PUT /v1/admin/merchant-profiles/:id/rail-preferences/:rail`. - **Auto-charge silently lapses a subscription on a 200-with-failure response (money-path bug; elevated above the other parked payments items).** `try_auto_charge_zaprite` returns `Ok(true)` on *any* HTTP 2xx (`subscriptions.rs:1403-1410`), reading the order `status` only for a log line. If Zaprite returns 200 carrying a `FAILED`/`DECLINED`/`EXPIRED` order status, the daemon fires `auto_charge_initiated` and then waits for an `order.paid` webhook that never arrives — the subscription silently lapses, no error surfaced, the customer churns. Safe fix (no production data needed): treat any non-`PAID` terminal order status as not-success and fall through to the manual-pay path — a conservative fail-safe, ~10 lines + a mock-provider test. (Found during the 2026-06-17 adjudication; it replaces the old "harden Zaprite failure-body shapes" item, which was already satisfied for non-2xx responses — those route correctly to WARN + `auto_charge_failed` audit + webhook + manual-pay fallback.) ## Agent compatibility & scoped API keys @@ -36,6 +35,24 @@ Longer-term backlog. Near-term state lives in `AGENTS.md` → Current state. Submission criteria themselves remain unpublished; reach out to Start9 when ready. (Icon-render and the source-available license are intentionally not treated as blockers.) +## Operability & alerts + +- **Surface internal failure conditions to the operator via StartOS-native notifications / health checks** — + NOT a bespoke email/SMTP subsystem. The need is real and not covered by the webhook-delegation model: when + the failure IS the webhook path (a dead-lettered endpoint, or the operator's receiver being down), a webhook + can't report it, and the operator's own email pipeline is downstream of the same webhooks. So Keysat must own + an out-of-band operator-visible channel — and on StartOS that channel is the OS notification/health surface, + not a mailer Keysat ships itself. Conditions worth alerting on (the surviving kernel of the dropped email plan): + payment-provider auth dead (repeated 401s ⇒ key revoked/rotated), a webhook endpoint hitting dead-letter, + master self-license expiring-soon / expired, and (optional) renewals failing across the pool. The health-check + path is already wired; verify the `start-sdk` 1.3.2 notification API before committing to a delivery mechanism. + Background + the original alert catalog (Tier 1/2/3, throttling) live in the superseded + `plans/keysat-smtp-emails.md`. **Buyer-facing email and the per-profile SMTP send path are dropped** (decided + 2026-06-18): operators selling via Keysat already own their buyer relationship and email pipeline through their + own app + the existing webhooks, so Keysat emailing buyers is redundant and a branding/double-send liability. + The dormant `merchant_profiles.smtp_*` columns (migration 0020) are now dead weight — left in place (a removal + migration isn't worth it) and flagged in `src/merchant_profiles.rs`. + ## Licensing model - Evaluate Elastic License v2 vs the current custom `LicenseRef-Keysat-1.0` (parked decision).