docs: capture vision revision — self-hosted AI-era contact-center engine
Records the decisions from pressure-testing the four founding docs: - North-star reframe: the engine for the AI-era contact center, not an Asterisk-protocol successor (Asterisk's map = checklist, not template) - Fused per-call vertical + composable horizontal platform (tightens the three-plane model; removes the control<->media hot-path gRPC hop) - Rust-native trunk SIP, IP-allowlisted; drops the Kamailio/rtpengine C shield (reverses ADR-0001, to be formalized as ADR-0003) - Pillars re-weighted: +data-ownership, spend-control promoted to constitutive, WASM demoted out of the core story - Developer-first DX spine (config-as-code, AEL lesson, engine+batteries) - GUI as pure API client (FreePBX model) + k8s declarative/operational split - Sequenced thin-slice first proof + capability ladder For review before applying to README/ARCHITECTURE/PORT_PLAN and writing ADR-0002 (identity) and ADR-0003 (SIP). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RUtgQTo3wHGXP1TixHr4gd
This commit is contained in:
174
docs/superpowers/specs/2026-06-26-vision-revision-design.md
Normal file
174
docs/superpowers/specs/2026-06-26-vision-revision-design.md
Normal file
@@ -0,0 +1,174 @@
|
||||
# Rutster — Vision Revision: the self-hosted AI-era contact-center engine
|
||||
|
||||
- **Status:** Proposed — for review
|
||||
- **Date:** 2026-06-26
|
||||
- **Origin:** A pressure-test of the four founding docs (README, ARCHITECTURE, PORT_PLAN, ADR-0001). This document records the decisions that pressure-test produced.
|
||||
- **Amends:** `README.md`, `docs/ARCHITECTURE.md`, `docs/PORT_PLAN.md`
|
||||
- **Reverses:** `docs/adr/0001-sip-strategy.md` (to be formalized as a new ADR-0003)
|
||||
|
||||
---
|
||||
|
||||
## TL;DR
|
||||
|
||||
> **rutster** — the open-source engine for self-hosting an AI-first contact center on commodity trunking: high-containment AI self-serve, seamless human takeover when it breaks down, and a closed ML loop that learns from every escalation — all on infrastructure and data **you** own.
|
||||
|
||||
"Spiritual successor to Asterisk" means successor to its **place in the world** — *the self-hostable engine a technical builder uses to stand up a call center* — not successor to its protocols or its architecture. Asterisk's subsystem map (the PORT_PLAN) is a capability **checklist**, not a template.
|
||||
|
||||
---
|
||||
|
||||
## What changed, and why (the pressure-test in brief)
|
||||
|
||||
The founding docs were architecturally rich but anchored to "memory-safe successor to Asterisk." Six load-bearing premises were stressed; the vision that survived is sharper and, in several places, reversed:
|
||||
|
||||
1. **North star moved** — from "Asterisk successor" (a consolidating PBX category, and a 1.18M-LOC feature-parity death-march) to **"the engine for the AI-era contact center."** Same Rust media core, aimed at a category AI is actively disrupting instead of one Teams Phone/UCaaS already ate.
|
||||
2. **The competitor stopped being Asterisk.** It became **LiveKit** (horizontal media infra, no contact-center domain), **cloud CCaaS** (Five9/Genesys/NICE/Amazon Connect — un-self-hostable, AI bolted on), **cheap cloud AI-voice** (Vapi/Retell — your calls and data on their infra), and **dated OSS** (Vicidial/FreePBX — Asterisk-era PHP+C). rutster's slot — *self-hostable + AI-native + owns the contact-center domain + memory-safe* — is genuine white space.
|
||||
3. **The wedge is a coherent combination, not a silver bullet** — no-GC real-time determinism **+** one secure auditable boundary **+** operational simplicity. Strongest for regulated/high-trust phone-agent work (PCI / HIPAA / TCPA).
|
||||
4. **The architecture tightened** — from pure three-plane microservices to a **fused per-call vertical + composable horizontal platform.**
|
||||
5. **ADR-0001 reversed** — the Kamailio + rtpengine C shield is dropped in favor of **Rust-native trunk SIP.**
|
||||
6. **Pillars re-weighted** — memory-safety and security-as-product survive *stronger*; **data-ownership** added; **in-boundary spend control** promoted to constitutive; **WASM demoted** out of the core story.
|
||||
|
||||
---
|
||||
|
||||
## 1. North star & identity
|
||||
|
||||
rutster is **the open-source engine for building the modern, AI-era contact center** — the swiss-army-knife toolkit, where "modern" means AI is native, not bolted on.
|
||||
|
||||
- It is a **framework / engine**, not a turnkey product. Asterisk won because contact centers were *built on it* (Vicidial, GOautodial, a thousand integrator builds) — it never tried to *be* Five9. rutster inherits that position. The moment it chases GUI-complete feature-parity with billion-dollar CCaaS, it dies; as the engine others build on, breadth is a strength and scope stays bounded.
|
||||
- Asterisk's capability map is a **completeness checklist** ("what must a telephony system handle"), explicitly **not** an architecture template. We keep the checklist; we reject the channel/bridge/dialplan model as the spine.
|
||||
|
||||
## 2. Target persona
|
||||
|
||||
The modern equivalent of the 2006 Linux-nerd-who-stood-up-Asterisk-for-an-SMB. Concretely: the **CLI/IDE/AI-comfortable self-hosting technical builder** — the person who runs Claude Code in a terminal, lives in an editor with an AI pair, versions everything in git, and self-hosts on principle.
|
||||
|
||||
- **Not** the no-code admin clicking a flow-designer canvas. The builder serves the non-technical operator downstream, exactly as integrators did on top of Asterisk.
|
||||
- This narrowing is deliberate and correct **for an engine**. It also liberates the design (see §8): you can make the authoring layer *powerful* because the audience codes and has AI assistance — no "dumb it down for non-programmers" tax.
|
||||
|
||||
## 3. The wedge
|
||||
|
||||
Against each competitor:
|
||||
|
||||
| Competitor | What they are | rutster's edge |
|
||||
|---|---|---|
|
||||
| **LiveKit** | Horizontal real-time media infra (Go) | rutster owns the **contact-center domain** (ACD, IVR, queues, recording, CDR, dialer, supervisor, agent-state) LiveKit will never ship; fused secure core; self-hostable |
|
||||
| **Cloud CCaaS** (Five9, Genesys, NICE, Amazon Connect, Twilio Flex) | Proprietary, full contact center, AI bolted on | Self-hostable, AI-native, auditable, no per-seat/minute lock-in |
|
||||
| **Cloud AI-voice** (Vapi, Retell, Bland) | Cheap managed voice bots | You own your **calls and training data**; it's a *contact center* (human escalation, queues), not a single bot |
|
||||
| **Dated OSS** (Vicidial, FreePBX) | Self-hostable, Asterisk-era | Modern, AI-native, memory-safe Rust |
|
||||
|
||||
The **technical wedge** is the coherent combination, not any single capability:
|
||||
|
||||
1. **No-GC real-time determinism** — tight turn-taking / barge-in / jitter behavior in a no-GC loop. The one thing a Go SFU + external agent structurally can't match on quality.
|
||||
2. **One secure auditable boundary** — trunk termination + media + spend/abuse control + audit in a single memory-safe trust domain. One thing to certify, not a 3-vendor chain.
|
||||
3. **Operational simplicity** — one binary, one bill, one deploy.
|
||||
|
||||
**Honest caveat (recorded so we don't kid ourselves):** the agent *brain* (STT/LLM/TTS) is necessarily external — audio leaves the box to reach it, same as LiveKit. The real-time edge therefore lives in the **local reflexes that don't need the brain** (VAD killing TTS the instant the caller speaks, jitter, pacing, DTMF), not the brain round-trip. The moat is the *whole*, and it is strongest where self-hosting + audit + data-ownership are buying criteria.
|
||||
|
||||
## 4. Architecture identity — fused per-call vertical, composable horizontal platform
|
||||
|
||||
The core owns the **per-call vertical** end-to-end as one deterministic, auditable trust domain:
|
||||
|
||||
```
|
||||
carrier SIP trunk ─► media termination (RTP/SRTP + local real-time reflexes)
|
||||
│
|
||||
├─► clean audio tap ──► external agent brain (STT/LLM/TTS)
|
||||
│
|
||||
└─► in-boundary spend / abuse gate
|
||||
```
|
||||
|
||||
**Horizontal platform** concerns are services *around* the core, independently scaled: number inventory, billing rollup, analytics, multi-region orchestration, the management API, and the agent **brain** itself.
|
||||
|
||||
This is tighter than the founding three-plane model:
|
||||
|
||||
- The **control↔media gRPC hop on the per-call hot path** (founding ARCHITECTURE) is removed.
|
||||
- The **spend gate** and the **agent tap** — which the founding PORT_PLAN externalized (a `☁️ Service` and the app plane respectively) — are pulled **into** the boundary, because they are constitutive of the wedge.
|
||||
- It is neither a monolith nor pure microservices: **fused where fusion buys determinism + security + simplicity; composable where independent scaling matters.**
|
||||
|
||||
## 5. SIP — Rust-native trunk SIP (supersedes ADR-0001)
|
||||
|
||||
Own trunk SIP **and** media termination directly in the Rust core; IP-allowlist the handful of trunk providers. **No Kamailio + rtpengine shield.**
|
||||
|
||||
- ADR-0001 rented the "20-year device interop tail" via a proven C SBC. Under the AI-voice contact-center scope, that tail **collapses**: you talk to a few documented trunk providers (Telnyx, Bandwidth, Twilio SIP), not thousands of desk-phone/carrier quirks. An inbound/outbound SIP-trunk client against cooperative carriers is tractable in `rsip` / `ezk`.
|
||||
- The C shield put **C at the most exposed seam** (the public internet) and terminated media **twice** — both directly contradicting the wedge. Dropping it makes the memory-safety thesis *literally true*: hostile bytes hit a fuzzed Rust parser first.
|
||||
- **Cost accepted:** we own a (bounded) SIP-trunk client early. **Mitigation:** WebRTC ingress ships first and is unaffected, so first-call never blocks on SIP.
|
||||
|
||||
## 6. Pillars (revised)
|
||||
|
||||
| Pillar | Change | Note |
|
||||
|---|---|---|
|
||||
| Memory-safety | ▲ stronger | Now literally true at the wire (no C edge) |
|
||||
| Security-as-product | ▲ stronger | The single auditable boundary **is** the moat; compliance is a buying criterion |
|
||||
| In-boundary spend/abuse control | ▲ promoted | From `☁️ service / table stakes` to **constitutive** — co-located with trunk termination, structurally impossible for a 3-vendor stack |
|
||||
| **Data ownership** | ✦ new | Calls + training data never leave the operator's infra — the self-host wedge *and* the ML-loop fuel |
|
||||
| WASM plugin sandbox | ▼ demoted | Out of the core story. The agent brain is external (the **tap** is the extension point); ops-simplicity wants one binary. Softly retained as a *candidate* mechanism for community call-flow/routing plugins — but undecided vs. webhooks/scripting |
|
||||
|
||||
## 7. Why no hardware (the visceral rationale)
|
||||
|
||||
Drop TDM / DAHDI / zaptel entirely (PORT_PLAN already ⛔'d it). The rationale, stated so it isn't just a line item: **every kernel-recompile, every `ztdummy`-on-UHCI timing hack, every `HZ=1000` ritual existed because telephony was shackled to a hardware clock living in a kernel module.** rutster is all userspace Rust + commodity trunking. **"Kernel to desk" becomes "container to desk" — never recompile a kernel for a phone call again.**
|
||||
|
||||
The timing *obsession* survives — it just moves into userspace Rust with **dedicated timing threads** (not the shared tokio pool). The thing that justified the suffering is first-class; the suffering is designed out.
|
||||
|
||||
## 8. DX spine — developer-first authoring
|
||||
|
||||
The engine is **headless and API-complete.** The persona authors via **code + config-as-text**: git-versioned, CLI-driven, IDE-native, AI-assistant-friendly (typed, schema'd, well-documented, LSP-friendly). **Terraform/Rails for call centers, not Squarespace.**
|
||||
|
||||
- **The AEL lesson** (from the person who wrote the DCAP exam): *better isn't enough.* AEL was superior to `extensions.conf` and still lost — it arrived after the muscle memory had set. An authoring layer must win **on contact** and meet people where their muscle memory already is. In 2026 that muscle memory is **code + an AI pair**, not a config syntax or a visual canvas.
|
||||
- **"Boom" + swiss-army-knife, reconciled:** an opinionated **batteries-included reference distro** (`compose up`, point a trunk at it, start taking calls) on top of a **composable framework** (build anything in code). Home Assistant model, not raw dialplan.
|
||||
- **Call-flow authoring is a first-class design surface** — owned by the DCAP author, designed with the AEL lesson baked in. The AI-era twist: part of the old dialplan **dissolves into the agent** (the model improvises the conversation). The authoring layer becomes the **routing, escalation, and business scaffolding *around* an AI that writes half the flow at runtime** — genuinely new design space, not "dialplan 2.0."
|
||||
|
||||
## 9. GUI & extension architecture
|
||||
|
||||
**The GUI is a pure API client, never an insider** — FreePBX↔Asterisk, modernized.
|
||||
|
||||
- **Not a plugin in the core.** A web GUI must not share an address space / lifecycle / attack surface with the latency-pinned media engine inside the one secure boundary.
|
||||
- **A separate application.** The **official reference GUI** ships in the batteries-included distro (so "boom" includes a usable UI) but holds **no privilege a third party couldn't get.** The ecosystem can build rival GUIs.
|
||||
- **Discipline:** the official GUI is built **only** on the public API — no backdoors. That guarantees API completeness. (Learn from FreePBX's leaky abstraction: coupling to Asterisk's config *files* caused the "don't hand-edit or it'll clobber you" war.)
|
||||
- **Config-as-code vs. GUI-mutation tension → the Kubernetes model.** Declarative desired-state (config-as-code, git, reconciled by the engine) **plus** an API/CLI/GUI for live operational state and ad-hoc actions, all through **one API**, single source of truth. The GUI is the *dashboard*, not a side-channel. *Manifests + kubectl + dashboard, for call centers.*
|
||||
- **Bonus — scope guard:** the GUI can only surface what the API already does, so it can't drag the engine toward Five9-parity.
|
||||
|
||||
## 10. First proof (the spearhead)
|
||||
|
||||
**The full thin slice:** a real call → core → external STT/LLM/TTS brain → barge-in + spend cap. It proves the *combination* (which is the wedge), and "I called my Rust box and an AI answered the phone" is the momentum fuel a solo multi-year build needs.
|
||||
|
||||
It is only survivable if built **brutally thin and sequenced so each step is its own proof** — never a big bang:
|
||||
|
||||
1. WebRTC media loopback (terminate RTP/SRTP, echo audio to a browser) — proves the media core
|
||||
2. Add the **tap** (route audio to an external echo process and back) — proves the tap interface
|
||||
3. Swap echo for the **brain** (ideally a single speech-to-speech API, e.g. OpenAI Realtime, to collapse STT+LLM+TTS into one integration) — proves agent integration
|
||||
4. Add **barge-in** (VAD-driven playout kill) — proves the reflex
|
||||
5. Replace WebRTC ingress with a real **PSTN trunk** call — proves the trunk client
|
||||
6. Add the **spend cap** (hard-stop at threshold) — proves the boundary
|
||||
|
||||
Steps 1–4 *are* the reflex loop — the hard, most-differentiating part proves itself before trunk integration piles on. Keep the dev loop on WebRTC ingress until step 5.
|
||||
|
||||
## 11. Capability ladder (the grand vision, incrementally)
|
||||
|
||||
Proof that "AI-first contact center" decomposes into shippable, independently-demoable rungs:
|
||||
|
||||
| Rung | Capability | Reuses |
|
||||
|---|---|---|
|
||||
| 1 | **Self-serve** — AI answers, contains the call | the thin-slice first proof |
|
||||
| 2 | **Escalation** — human agent barges in / takes over when AI breaks down | the audiohook/barge primitive PORT_PLAN already kept |
|
||||
| 3 | **Measurement** — containment rate, where/why AI failed | CDR + analytics on calls *you own* |
|
||||
| 4 | **Self-improvement** — every takeover → auto-labeled training data → loop | rungs 1–3 compounding |
|
||||
|
||||
**ML "self-train," honestly:** not autonomous magic (the persona has no ML team). The engine **captures the perfect training signal** — every human takeover auto-labeled *"AI failed here → human did this"* — and provides the loop to act on it: containment analytics, eval sets that regression-test against past failures, prompt/KB suggestions, optional fine-tune export. All on the operator's own infra. Uniquely enabled by owning the whole call.
|
||||
|
||||
## 12. Out of scope (deliberately) & open decisions
|
||||
|
||||
- **Adoption / trust / go-to-market** — "why would anyone route real calls through a brand-new Rust platform?" A positioning question, flagged for its own session.
|
||||
- **License** — still undecided (carried over from founding docs).
|
||||
- **Plugin mechanism** — WASM vs. webhooks vs. scripting for community call-flow/routing extensions.
|
||||
- **The agent-tap protocol** — the single most important interface in the system (raw PCM over WebSocket/TCP vs. gRPC streaming vs. SDK-joins-the-call). A design decision for the framework-layer phase.
|
||||
- **Event bus** — NATS vs. Kafka vs. Redis Streams (carried over).
|
||||
|
||||
---
|
||||
|
||||
## Document impact (what this revision changes in the repo)
|
||||
|
||||
| Doc | Change |
|
||||
|---|---|
|
||||
| `README.md` | Reframe north star (AI-era contact-center engine, not Asterisk-successor); add the persona; revise pillars (add data-ownership, demote WASM, promote spend-control); update "what it is/isn't"; mark SIP decided |
|
||||
| `docs/ARCHITECTURE.md` | Replace three-plane framing with fused per-call vertical + composable platform; remove control↔media hot-path gRPC hop; make the agent tap the central interface; add DX spine and GUI-as-API-client + k8s declarative/operational model |
|
||||
| `docs/PORT_PLAN.md` | Recharacterize as "the checklist, not the spine"; graduate contact-center capabilities (queues/ACD/IVR/recording/CDR/dialer/supervisor) from peripheral to core domain library; update SIP rows (Rust-native trunk, no Kamailio); update WASM/plugin rows; replace phasing with the capability ladder + thin-slice first proof |
|
||||
| `docs/adr/0001-sip-strategy.md` | Add `Superseded by ADR-0003` header |
|
||||
| **New** `docs/adr/0002-north-star-and-fused-core.md` | The identity reframe: AI-era contact-center engine + fused-vertical architecture |
|
||||
| **New** `docs/adr/0003-sip-rust-native-trunk.md` | Rust-native trunk SIP, no SBC shield (supersedes ADR-0001) |
|
||||
Reference in New Issue
Block a user