Reliability & Ops
Response SLA Connections
Dual-source ball-in-court: work Slack via the runtime's Claude integration, personal Slack via the edge poller — one engine, one surface.
Situation
Follow-on to the v1 Response SLAs spec (merged to main, not yet deployed). The operator's real setup splits Slack in two: work Slack stays on the runtime-side Claude integration ("as me", company-appropriate) which now also POSTs its set to the edge; personal Slack runs on the edge poller with a personal user token.
This spec introduces a first-class connection as a tagged source of ball-in-court items, so resolution, config, and surfacing are naturally scoped per-source and never cross-contaminate — and is deliberately shaped as the seed for the future connector admin console (Workstream D), flagged to that owner before it's built.
Key decisions
A connection is a first-class, tagged source
{id, label, method, transport: 'edge-poll'|'ingest', enabled, tokenSecret|producerCn, clock/slaMinutes/windows overrides} — everything keys off its id so scoping is automatic.
No schema change needed
channel_pending.channel (v1 migration 023) already holds an adapter id; it now simply stores the connection id (slack-personal / slack-work). Since v1 isn't deployed, the column is optionally renamed channel→connection pre-deploy with no live-data migration.
Reconciliation is per-connection
The poll cron resolves only its own connection's rows; ingest connections carry a mode ('full' vs 'delta') so a full re-emit safely resolves that connection's rows without touching another's.
Auth is per-connection
Edge-poll reads env[connection.tokenSecret] and skips cleanly if unset; ingest validates the JWT common_name against the connection's registered producerCn, rejecting unknown connections or CN mismatches with 403.
Minimal runtime delta, coordinated with the OpenRouter migration
The only mallory-runtime change is a new post_pending call (mirroring the existing post_nudge) in slack-email-monitor, POSTing the full current work-Slack set to /ingest/pending.
Architecture
resolveConnection merges connection-level and method-level defaults into the effective settings the evaluator already consumes; adapters and the evaluator are otherwise unchanged, just parameterised by the registry.
Risks & guardrails
The work/personal cancel-each-other bug
Explicitly the core correctness concern this spec fixes — without per-connection scoping, resolving one Slack's items could wrongly clear the other's. A dedicated dual-source regression test seeds both and asserts each is untouched by the other's poll/ingest.
Sequencing vs the v1 deploy
v1 is merged but not deployed (blocked on wrangler re-auth); folding connections in before first deploy is preferred (one deploy, no legacy channel='slack' data) but depends on the runtime post_pending + migration coordination happening promptly.
Convergence with the future connector console
This registry is deliberately a seed, not a parallel model — needs explicit hand-off to the Workstream D owner so the eventual admin console adopts it rather than reinventing it.
Delivery
Backend
Connection type + resolveConnection in src/lib/responseSla.ts; per-connection poll/reconcile in the poll cron; /ingest/pending gains {connection, mode} + per-connection CN validation; config GET/POST includes connections.
Runtime
post_pending added to the existing slack-email-monitor job — the only mallory-runtime file touched, coordinated in timing with the OpenRouter migration.
Web
Connections list + source badge across web/src/lib/api.ts, settings/+page.svelte, WaitingCard.svelte, WaitingView.svelte.
Testing
resolveConnection defaults/fallback; two edge-poll connections don't resolve each other's rows; full vs delta ingest behaviour; wrong producer CN → 403; the dual-source regression test.
Out of scope
docs/superpowers/specs/2026-07-12-response-sla-connections-design.mdplan ·
docs/superpowers/plans/2026-07-12-response-sla-connections.md