Folds the 2026-06-26 vision-revision pressure-test into the canonical docs. The spec moves from Proposed to Ratified; the decisions it produced land in the docs it said it would amend, with ADRs recording each load-bearing reversal. - README.md: reframe north star (AI-era contact-center engine, not Asterisk successor); persona; revised pillars (add data-ownership, demote WASM, promote spend-control); update 'what it is/isn't'. - ARCHITECTURE.md: replace three-plane framing with fused per-call vertical + composable horizontal platform; remove control<->media hot-path gRPC hop; make the agent tap the central interface; add DX spine + GUI-as-API-client + k8s declarative/operational model. Also: 'too slow to police' -> 'too slow to enforce' (terminology). - PORT_PLAN.md: recharacterize as capability checklist (not template); graduate contact-center capabilities to first-class domain; Rust-native trunk SIP rows; WASM demoted; thin-slice + capability ladder phasing. - ADR-0001: marked Superseded by ADR-0003. - ADR-0002 (new): north star + fused per-call core. - ADR-0003 (new): Rust-native trunk SIP, no SBC shield. - ADR-0004 (new): GPL-3.0-or-later license. - ADR-0005 (new): Valkey as event bus + state store. - ADR-0006 (new): WebRTC-first ingress; SIP endpoint deferred. - vision-revision spec: status -> Ratified 2026-06-26.
63 lines
3.3 KiB
Markdown
63 lines
3.3 KiB
Markdown
# ADR-0005 — Event bus & state store: Valkey
|
|
|
|
- **Status:** Accepted
|
|
- **Date:** 2026-06
|
|
- **Closes:** the event-bus open-decision carried in the founding docs (NATS vs. Kafka vs. Redis Streams)
|
|
|
|
## Context
|
|
|
|
The fused per-call core ([ADR-0002](0002-north-star-and-fused-core.md)) needs:
|
|
|
|
- a **bus** for cross-service control events (replacing Asterisk's internal Stasis bus for
|
|
anything crossing the boundary),
|
|
- a **KV state store** replacing `astdb` + sorcery / realtime config state,
|
|
- **presence sets** for MWI/BLF signaling aggregation.
|
|
|
|
The founding docs listed the choice as NATS vs. Kafka vs. Redis Streams.
|
|
|
|
## Decision
|
|
|
|
**Valkey** — the Linux-Foundation BSD-3-Clause fork of Redis 7.2.4 (wire-protocol-compatible drop-in).
|
|
|
|
### Why not "Redis"
|
|
|
|
Redis relicensed in March 2024 to **RSALv2 + SSPLv2** — **not OSI-open-source**, and license-incompatible with this project's posture (FOSS-clean + GPL-3.0-or-later per [ADR-0004](0004-license.md)).
|
|
Recommending "Redis" undercuts the data-ownership pillar ([ADR-0002](0002-north-star-and-fused-core.md)) and the clean-license story. Valkey is *Redis-the-thing* with a compatible license, maintained by the community (AWS, Google, Oracle, et al.).
|
|
|
|
### Why Valkey fits the wedge specifically
|
|
|
|
- **Collapses bus + state store + presence into one dependency.** A solo operator runs one process
|
|
with `compose up`. NATS is a cleaner pure-bus but doesn't also replace `astdb`/sorcery; Kafka is
|
|
structural overkill at self-hosting scale and violates the one-binary / operational-simplicity
|
|
pillar.
|
|
- One tool, three roles:
|
|
- **streams + consumer groups** → CDR/CEL/analytics pipeline fanout and replay,
|
|
- **pub/sub** → presence / MWI / BLF signaling,
|
|
- **KV** → state store (config + runtime state replacing `astdb`/sorcery).
|
|
|
|
### Alternatives
|
|
|
|
- **Kafka — rejected.** Structural overkill at self-hosting scale; operational weight violates
|
|
the operational-simplicity pillar.
|
|
- **NATS — retained as a config-pluggable alternative.** An operator outgrowing Valkey (notably
|
|
needing NATS JetStream's durable streaming model at larger scale) can swap it in. The bus
|
|
backend seam stays **pluggable** at the config boundary, not architecture-load-bearing.
|
|
|
|
## Constraints (load-bearing, not preferences)
|
|
|
|
1. **The 20ms media loop never rides the bus.** Media timing stays in-core on dedicated timing
|
|
threads ([ADR-0002](0002-north-star-and-fused-core.md) §7; vision-revision §7). The bus carries
|
|
control / cross-service events only — not latency-pinned media — so Valkey's sub-ms local
|
|
latency is plenty.
|
|
2. **The bus is NOT the source of truth for billing- or call-loss-critical state.** Valkey
|
|
persistence (RDB/AOF) is async-ish — fine for transport / replay / fleeting retention, **wrong**
|
|
for "the CDR that proves what we billed." CDR and recordings emit **durably to object storage**
|
|
in their own services; the bus only *flows* events into that pipeline and lets services *react*.
|
|
|
|
## Consequences
|
|
|
|
- **Positive:** one OSS dep for bus + state + presence; self-hostable and license-clean; pluggable
|
|
to NATS later without architecture changes; aligns with operational-simplicity.
|
|
- **Negative:** Valkey is "good enough" at each role, not best-of-breed for each — accepted
|
|
deliberately for the ops-simplicity pillar.
|