Skip to main content

SPEC-0017: Providers View, Runtime Registry, and Connect Wizard

SPEC · SPEC-0017 · Status · draft · Date · 2026-07-18 · Implements · ADR-0020 · Requires · SPEC-0001, SPEC-0002, SPEC-0015

Overview

Providers become first-class, runtime-configurable objects (ADR-0020): a DB-backed registry that ingestion resolves live, a Providers view grouping every line by family (webhook · push / queue · pull) with trust and health, a connect-provider wizard, and an honest catalog of available-but-unimplemented sources. Verification semantics themselves (SPEC-0001) and adapter mechanics (SPEC-0002) are unchanged — this spec governs where provider configuration lives and how operators manage it.

Requirements

Requirement: Runtime Provider Registry

Provider configuration SHALL live in a DB-backed registry: name, family (webhook|queue), kind, trust mode, enabled flag, encrypted secret, kind-specific config, and health/rate fields. Webhook routing and the pull-adapter runner SHALL resolve providers from the registry at request/poll time, so registry changes take effect without restart. Provider secrets SHALL be stored encrypted using the existing envelope — never plaintext.

Scenario: Wizard-created provider is live immediately

  • WHEN a new generic webhook provider is created through the UI
  • THEN its ingestion URL accepts (and trust-checks) calls without a process restart

Requirement: Environment Config Import

Providers configured via environment/deployment config SHALL be imported into the registry at boot as an idempotent seed (create-if-absent, never clobber operator edits). After import the registry is authoritative; env changes to an existing provider SHALL NOT silently override registry state.

Scenario: Boot with existing registry

  • WHEN the service boots with env config for a provider the registry already holds
  • THEN the registry row wins and no duplicate provider appears

Requirement: Providers View

The Providers view SHALL group connected providers by family with per-provider glyph, kind, trust chip (SPEC-0001 vocabulary — signed/token/open/queue), in-rate, last-seen, enabled state, and a configure affordance. Secrets SHALL never render — only configured/missing status.

Scenario: Trust at a glance

  • WHEN the operator opens the Providers view
  • THEN every connected line shows its enforced trust mode as a chip, and no secret material appears anywhere in the page

Requirement: Connect Provider Wizard

Connecting SHALL be a wizard (SPEC-0015 wizard pattern). Webhook path: choose source → choose trust mode (signed only where a real scheme exists; token as the default for generic senders; open only behind an explicit warning) → provide/generate the secret → receive the copyable ingestion URL. Queue path: choose an implemented adapter and provide connection settings (e.g. Redis stream/list/pubsub). The wizard SHALL end with the provider registered, enabled, and visible on the view.

Scenario: Homelab sender lands on token

  • WHEN the operator connects a generic homelab sender and accepts defaults
  • THEN the provider is created with token trust and the final step shows the URL and the token exactly once in the standard reveal pattern

Scenario: Open requires intent

  • WHEN the operator selects open
  • THEN the wizard requires an explicit acknowledgement of the risk before proceeding

Requirement: Provider Catalog

The view SHALL show implemented-but-unconnected kinds as connectable and not-yet-implemented kinds (e.g. SQS, NATS, AMQP) as available catalog cards that describe what connecting will mean but expose no functional connect path. Catalog entries SHALL be visually distinct from connected and connectable states — the UI never fakes a backend that does not exist.

Scenario: Catalog honesty

  • WHEN the operator opens the SQS catalog card
  • THEN it reads as planned/available with no wizard entry point that would dead-end

Requirement: Provider Lifecycle

Operators SHALL be able to disable (stop accepting/polling, keep history), re-enable, rotate the secret (token/signed webhook kinds), and remove a provider. Removal SHALL require confirmation and SHALL NOT delete previously ingested events or todos.

Scenario: Disable stops the line

  • WHEN a webhook provider is disabled
  • THEN its ingestion URL rejects new calls while existing events and todos remain queryable