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.
249 lines
20 KiB
Markdown
249 lines
20 KiB
Markdown
# Rutster — Asterisk Capability Checklist
|
||
|
||
This is the **capability checklist**, not the architecture spine. It walks the Asterisk
|
||
subsystem surface as a completeness audit — *"what must a telephony system handle"* — and
|
||
assigns every capability a **disposition** in the rutster architecture, with a one-line
|
||
rationale. We keep the checklist; we **reject** the Asterisk channel/bridge/dialplan model
|
||
as the architecture (see [ADR-0002](adr/0002-north-star-and-fused-core.md)). The crate/service
|
||
boundaries fall out of the "Core / Service" rows; the threat model hangs off the "attack
|
||
surface" of each row.
|
||
|
||
Grounded against the Asterisk 22.10.1 tree (~1.18M LOC C/H).
|
||
|
||
## Disposition legend
|
||
|
||
| | Disposition | Meaning |
|
||
|---|---|---|
|
||
| 🦀 | **Core** | In the hardened, memory-safe Rust core. Reserved for the hot media path, call model, and signaling glue — fast, always-present, trusted. |
|
||
| 🧩 | **Plugin (WASM)** | Sandboxed extension. Logic that benefits from isolation and third-party extensibility. Cannot crash the core or cross tenant boundaries. |
|
||
| ☁️ | **Service** | Independent microservice. Stateful, independently-scaled, or business/billing logic. Talks over API + event bus. |
|
||
| 🔌 | **Edge / FFI** | Wrap mature external C (pjproject/spandsp) or front with an SBC. Used where a pure-Rust rewrite is a tar pit. |
|
||
| ⛔ | **Drop** | Legacy hardware or dead protocol. Gone. |
|
||
| 🔁 | **Replace** | Capability survives but the mechanism is entirely redesigned (no 1:1 mapping). |
|
||
|
||
## Design rules (the heuristics behind every row)
|
||
|
||
1. Hot media path & the call model → **Core**. Trusted, fast, always-on. Inside the fused
|
||
per-call vertical.
|
||
2. Anything that benefits from isolation or third-party extension → **Plugin** *(now softened —
|
||
WASM demoted out of the core story per [ADR-0002](adr/0002-north-star-and-fused-core.md); the
|
||
agent **tap** is the primary extension point for in-call logic).*
|
||
3. Stateful, independently-scaled, or business/billing logic → **Service**. Around the core,
|
||
horizontal platform.
|
||
4. ~~Mature C that's a tar pit to rewrite (SIP) → **Edge/FFI**, with a pure-Rust ambition.~~
|
||
*Reversed for SIP by [ADR-0003](adr/0003-sip-rust-native-trunk.md): Rust-native trunk SIP, no
|
||
C SBC shield. FFI retained only for mature codec/DSP/EQ libraries (libopus, speexdsp, WebRTC APM).*
|
||
5. Legacy hardware / dead protocols → **Drop**.
|
||
6. Security & multi-tenancy are cross-cutting — never a row, always a property. **Spend / abuse
|
||
control is constitutive**, pulled into the boundary, not externalized.
|
||
|
||
---
|
||
|
||
## 1. Signaling & channel drivers (`channels/`, `res/res_pjsip*`)
|
||
|
||
| Asterisk subsystem | Module(s) | Disp. | Rationale |
|
||
|---|---|---|---|
|
||
| SIP signaling (trunk) | `chan_pjsip` + `res_pjsip*` (48 mods) | 🦀 Core | **Decided (ADR-0003):** **Rust-native trunk SIP**, no C SBC shield. `rsip` + `ezk` sans-IO transaction/dialog core. The *trunk* interop surface is bounded by carrier docs (Telnyx/Bandwidth/Twilio SIP, IP-allowlisted) — the device interop tail ADR-0001 rented a shield for *collapses* under the contact-center scope. Hostile bytes hit a fuzzed Rust parser first → memory-safety thesis literally true at the wire. |
|
||
| ↳ outbound registration (to carriers) | `res_pjsip_outbound_registration` | 🦀 Core | Trunk side; bounded register-to-carrier. State in the state store (Valkey, [ADR-0005](adr/0005-event-bus.md)). |
|
||
| ↳ **inbound endpoint registration (desk/soft phones)** | `res_pjsip_registrar` | ⛔ **Deferred — community edge** | **Split from trunk.** An inbound endpoint server re-imports the *unbounded device interop tail* ADR-0003 deliberately closed (Polycom/Yealink/Zoiper `REGISTER`, BLF/MWI, DTMF variants, per-device NAT/provisioning). In an SSO/browser-agent UX, the desk-phone demographic has collapsed. Out-of-tree SBC-style adapter (fronting the public API / B2B-SIP) for anyone who needs it — **outside the trust boundary**, so its tail can't compromise the wedge. See [ADR-0006](adr/0006-ingress-posture.md). |
|
||
| ↳ SDP / media negotiation | `res_pjsip_session`, `_sdp_rtp` | 🦀 Core | Offer/answer drives the media plane directly. |
|
||
| ↳ auth | `res_pjsip_outbound_authenticator_digest`, etc. | 🦀 Core | Digest + token auth, deny-by-default, rate-limited. Security-critical. |
|
||
| ↳ NAT / ICE / rtcp | `res_pjsip_nat`, `res_rtp_asterisk` ICE | 🦀 Core | ICE/STUN/TURN via `str0m`/`webrtc-rs`. |
|
||
| ↳ pub/sub (presence, MWI, BLF) | `res_pjsip_pubsub`, `_exten_state`, `_mwi` | 🦀 Core + ☁️ | Signaling in core; presence/MWI state aggregation as a service. |
|
||
| ↳ T.38 fax | `res_pjsip_t38` | ☁️ Service | Isolate fax entirely (see §5). |
|
||
| WebRTC signaling (agent ingress) | `chan_websocket`, `res_http_websocket` | 🦀 Core | **First-party human-participant ingress** ([ADR-0006](adr/0006-ingress-posture.md)). The browser is the softphone: SSO in, one peer-connection, DTLS-SRTP + ICE handled by the browser, zero device-provisioning tail. Also the modern hosted UX and the escalation path (rung 2): agent clicks *take this call* → WebRTC leg + audiohook/barge handoff. WSS + DTLS-SRTP via the media stack. |
|
||
| External media | `chan_audiosocket` | 🦀 Core | Modern, relevant pattern (stream media to an external process); keep as a media tap/source API. |
|
||
| Local console audio | `chan_console` | 🧩 Plugin | Dev/testing convenience; not core. |
|
||
| RTP-only pseudo-channel | `chan_rtp`, `chan_bridge_media` | 🦀 Core | Media-plane primitives. |
|
||
| IAX2 | `chan_iax2` | ⛔ Drop | Dead inter-Asterisk protocol. SIP trunks instead. |
|
||
| TDM / analog / ISDN | `chan_dahdi`, `sig_analog`, `sig_pri`, `sig_ss7` | ⛔ Drop | No hardware era. PSTN via SIP trunk / SBC. |
|
||
| H.323 | `addons/chan_ooh323` | ⛔ Drop | Dead protocol. |
|
||
| SCCP / Skinny, MGCP | (Skinny/MGCP) | ⛔ Drop | Dead protocols. |
|
||
| Unistim | `chan_unistim` | ⛔ Drop | Dead vendor protocol. |
|
||
| XMPP / Jingle | `chan_motif`, `res_xmpp` | ⛔ Drop | Dead path. |
|
||
|
||
---
|
||
|
||
## 2. Media plane (`main/rtp_engine.c`, `res_rtp_asterisk`, `bridges/`, `main/dsp.c`)
|
||
|
||
| Asterisk subsystem | Module(s) | Disp. | Rationale |
|
||
|---|---|---|---|
|
||
| RTP / RTCP engine | `rtp_engine.c`, `res_rtp_asterisk` | 🦀 Core | **Crown jewel.** Built on `str0m`/`webrtc-rs`, sans-IO, dedicated timing (not the shared tokio pool). |
|
||
| SRTP / DTLS | `res_srtp` | 🦀 Core | Mandatory-by-default encryption. |
|
||
| Bridging framework | `main/bridge.c` | 🦀 Core | The 2-party + N-party call topology engine. |
|
||
| ↳ softmix conference mixer | `bridges/bridge_softmix` | 🦀 Core | N-party mixing on the hot path. |
|
||
| ↳ simple / native-RTP bridge | `bridge_simple`, `bridge_native_rtp` | 🦀 Core | Direct media flow (re-INVITE peers together) when no mixing needed. |
|
||
| ↳ holding bridge | `bridge_holding` | 🦀 Core | Parking/hold media state. |
|
||
| ↳ native DAHDI bridge | `bridge_native_dahdi` | ⛔ Drop | Hardware. |
|
||
| DSP (DTMF/MF detect, silence, tone) | `main/dsp.c` | 🦀 Core | Media-plane primitive; exposed to plugins as events. |
|
||
| Echo cancellation | (hardware / sw) | 🔌 Edge/FFI | No mature pure-Rust EC; FFI speexdsp / WebRTC APM. |
|
||
| Audio hooks (tap/inject/volume) | `main/audiohook.c` | 🦀 Core | Primitive behind recording, ChanSpy, whisper/barge. |
|
||
| Music on hold | `res_musiconhold` | 🦀 Core | Just a media source; small, keep in core (asset from object storage). |
|
||
| Jitter buffer | `func_jitterbuffer`, abstract jb | 🦀 Core | Quality-critical; part of the RTP path. |
|
||
|
||
---
|
||
|
||
## 3. Call model & PBX core (`main/`)
|
||
|
||
| Asterisk subsystem | Module(s) | Disp. | Rationale |
|
||
|---|---|---|---|
|
||
| Channel abstraction | `main/channel.c` (`ast_channel`) | 🦀 Core | The unifying "leg" object (signaling + media state). Reimagined as a `Channel`/leg. |
|
||
| PBX / dialplan engine | `main/pbx.c` | 🔁 Replace | → declarative routing (data) + event-driven apps. No `extensions.conf`. |
|
||
| Call features (transfer/park/pickup) | `res_features`, `res_parking` | 🦀 Core | Call-control primitives, exposed via the API. |
|
||
| Scheduler / taskprocessor / threadpool | `main/sched.c`, `taskprocessor.c`, `threadpool.c` | 🦀 Core | tokio for control; dedicated timing threads + timer wheel for the 20ms media loop. |
|
||
| Internal message bus (Stasis) | `main/stasis*.c` | 🔁 Replace | In-core dispatcher for intra-core; external event bus (NATS/Kafka) for cross-service. |
|
||
| Module loader | `main/loader.c` | 🔁 Replace | → WASM host + service registry. No in-process `.so`. |
|
||
| ACL / named ACL | `main/acl.c`, `res_named_acl` | 🦀 Core | Security primitive; policy-driven. |
|
||
| astdb (internal KV) | `main/db.c` | 🔁 Replace | → state store (**Valkey** KV, [ADR-0005](adr/0005-event-bus.md)). |
|
||
|
||
---
|
||
|
||
## 4. Dialplan & programmability (`pbx/`, `res_agi`, `res_ari`, `manager`)
|
||
|
||
| Asterisk subsystem | Module(s) | Disp. | Rationale |
|
||
|---|---|---|---|
|
||
| `extensions.conf` dialplan | `pbx_config` | 🔁 Replace | Declarative routing as data (GitOps) for the 90% case. |
|
||
| AEL / Lua dialplan | `pbx_ael`, `pbx_lua` | ⛔ Drop | Replaced by WASM call-flow + routing config. |
|
||
| Realtime dialplan | `pbx_realtime` | 🔁 Replace | Routing in the config/state layer. |
|
||
| Call files / spool | `pbx_spool` | 🔁 Replace | → originate via API. |
|
||
| Macro / Gosub / Stack | `app_stack`, `app_macro` | 🔁 Replace | → WASM call-flow logic. |
|
||
| AGI / FastAGI | `res_agi` | 🔁 Replace | → WASM plugins + gRPC. Same "external program controls a call," sandboxed and typed. |
|
||
| ARI (REST + stasis apps) | `res_ari*`, `res_stasis*` | 🦀 Core | **Becomes THE API** — the control-plane resource model. `api-docs/*.json` is the reusable spec. |
|
||
| AMI (manager) | `main/manager*.c` | 🔁 Replace | Drop the plaintext TCP protocol → mTLS gRPC + RBAC + audit log. |
|
||
| CLI | `main/cli.c` | 🔁 Replace | Thin CLI that's an API client, not an in-process console. |
|
||
| DUNDi (distributed routing) | `pbx_dundi` | ⛔ Drop | Dead/niche. |
|
||
| ENUM lookup | `func_enum` | 🧩 Plugin | Routing-time lookup; pluggable. |
|
||
|
||
---
|
||
|
||
## 5. Applications (`apps/`) — the contact-center domain
|
||
|
||
> **Scope lift** ([vision-revision](superpowers/specs/2026-06-26-vision-revision-design.md) §4): the
|
||
> contact-center capabilities Asterisk kept as apps are **rutster's core domain**, not peripheral.
|
||
> This is the difference between "Asterisk successor" and "AI-era contact-center engine." Every row
|
||
> here is load-bearing for the wedge (the thing LiveKit will never ship).
|
||
|
||
| Asterisk app | Module | Disp. | Rationale |
|
||
|---|---|---|---|
|
||
| Dial / originate | `app_dial`, `app_originate` | 🦀 Core | Core call origination, exposed via the API. |
|
||
| Queues / ACD | `app_queue` | ☁️ Service (**domain core**) | Stateful, independently scaled. **First-class** — ACD is the beating heart of a contact center, not a peripheral app. The AI self-serve + human-escalation loop (capability ladder) is an ACD-shaped problem. |
|
||
| Voicemail | `app_voicemail` | ☁️ Service | Stateful storage + business logic; isolate it. |
|
||
| Conferencing | `app_confbridge` | 🦀 Core + ☁️ | Mixing in core (softmix); orchestration/features as a service. |
|
||
| MeetMe | `app_meetme` | ⛔ Drop | DAHDI-timing legacy; ConfBridge supersedes. |
|
||
| Recording | `app_mixmonitor`, `app_monitor` | 🦀 Core + ☁️ | Audiohook tap in core; storage/lifecycle as a recording service (object-storage-backed, retention policy, tenant-scoped — **durable, not on the bus**). |
|
||
| ChanSpy / whisper / barge | `app_chanspy` | 🦀 Core | Audiohook primitive; gated by RBAC. **The escalation primitive** (rung 2). |
|
||
| Answering-machine detect | `app_amd` | 🦀 Core + 🧩 | DSP primitive in core; policy/thresholds as a plugin. |
|
||
| IVR primitives (playback/read/say) | `app_playback`, `app_read`, `app_sayunixtime`, `app_directory` | 🦀 Core | Media primitives (play/collect-digits/say) exposed via the API/tap. The IVR *flow* dissolves into the agent; these are the primitives left over. |
|
||
| Echo / test | `app_echo`, `app_milliwatt` | 🦀 Core | Trivial diagnostics. |
|
||
| FollowMe | `app_followme` | 🧩 Plugin | Routing policy → plugin/service. |
|
||
| Speech recognition | `app_speech_utils`, `res_speech` | ☁️ Service | Modern ASR is external; expose as a service integration. |
|
||
| Fax | `res_fax`, `res_fax_spandsp` (T.38) | ☁️ Service (FFI) | Niche, isolate fully; spandsp via FFI. Optional. |
|
||
| **Supervisor / agent-state** | (scattered manager/AMI surfaces) | ☁️ Service (**domain core**) | **First-class.** Agent presence, state, real-time monitoring, coaching/whisper — the contact-center operator surface. Pure API client (the dashboard). |
|
||
| **Dialer (predictive/progressive)** | (custom/`app_dial`-derived) | ☁️ Service (**domain core**) | **First-class.** Outbound campaign dialing with pacing — where the in-boundary spend/abuse gate (§10) *bites hardest*; structurally co-located. |
|
||
|
||
---
|
||
|
||
## 6. Telephony features / subscriptions
|
||
|
||
| Asterisk subsystem | Module(s) | Disp. | Rationale |
|
||
|---|---|---|---|
|
||
| Presence / BLF | `res_pjsip_pubsub`, `res_pjsip_exten_state` | 🦀 Core + ☁️ | Signaling in core; state aggregation service. |
|
||
| MWI (message-waiting) | `res_mwi_external`, `app_voicemail` MWI | ☁️ Service | Tied to the voicemail service. |
|
||
| STIR/SHAKEN (attestation) | `res_stir_shaken` | ☁️ Service | **Keep — modern, anti-robocall/fraud.** Core to the security story. |
|
||
| Call recording lifecycle | `app_mixmonitor` + storage | ☁️ Service | Object-storage backed, retention policy, tenant-scoped. |
|
||
| CDR (call detail records) | `cdr/`, `cdr_*` | ☁️ Service | Event stream → billing/analytics pipeline. |
|
||
| CEL (channel event logging) | `cel/`, `cel_*` | ☁️ Service | Folded into the unified event bus + analytics. |
|
||
|
||
---
|
||
|
||
## 7. Codecs & formats (`codecs/`, `formats/`)
|
||
|
||
| Codec / format | Module | Disp. | Rationale |
|
||
|---|---|---|---|
|
||
| G.711 a-law / µ-law | `codec_alaw`, `codec_ulaw`, `codec_a_mu` | 🦀 Core | Trivial, ubiquitous. Native Rust. |
|
||
| G.722 (HD) | `codec_g722` | 🦀 Core | Common wideband. Native Rust. |
|
||
| Opus | (external `codec_opus`) | 🦀 Core (FFI) | WebRTC default; libopus via FFI. |
|
||
| Sample-rate resample | `codec_resample` | 🦀 Core | Needed for any transcoding/mixing. |
|
||
| GSM | `codec_gsm` | 🧩 Plugin (FFI) | Optional; FFI libgsm. |
|
||
| G.726 / G.729 | `codec_g726` / (external) | 🧩 Plugin (FFI) | Optional; G.729 now patent-free. |
|
||
| Speex / iLBC / LPC10 / ADPCM / codec2 | `codec_speex`, `codec_ilbc`, … | ⛔ Drop | Obsolete; drop or community plugin. |
|
||
| Hardware transcode | `codec_dahdi` | ⛔ Drop | Hardware. |
|
||
| File formats (wav/sln/ogg-opus) | `format_wav`, `format_sln`, … | 🦀 Core | Small set for prompts/recordings in core; rest as plugins. |
|
||
| Legacy file formats (gsm/g729/g726 files) | `format_*` | 🧩 Plugin | Optional. |
|
||
|
||
---
|
||
|
||
## 8. Config, state & data (`res_config_*`, `res_sorcery*`)
|
||
|
||
| Asterisk subsystem | Module(s) | Disp. | Rationale |
|
||
|---|---|---|---|
|
||
| `.conf` files | `main/config.c` | 🔁 Replace | Config-as-data (declarative, validated, GitOps). |
|
||
| Sorcery (object config abstraction) | `res_sorcery*` | 🔁 Replace | Typed config + state-store layer. |
|
||
| Realtime backends (ODBC/PgSQL/SQLite/cURL/LDAP) | `res_config_*` | 🔁 Replace | One config/state service with pluggable backends. |
|
||
| HTTP media cache | `res_http_media_cache` | 🦀 Core | Prompt/asset fetch → object storage + cache. |
|
||
| Security event logging | `res_security_log` | 🦀 Core | Structured audit log; security-critical. |
|
||
|
||
---
|
||
|
||
## 9. Management & APIs
|
||
|
||
| Asterisk surface | Module(s) | Disp. | Rationale |
|
||
|---|---|---|---|
|
||
| ARI (REST resource model + event WS) | `res_ari*` | 🦀 Core | The control-plane API. Reuse the resource model. |
|
||
| AMI (plaintext TCP admin) | `manager*.c` | 🔁 Replace | → mTLS gRPC + RBAC + audit. No plaintext admin channel. |
|
||
| HTTP server | `res_http*` | 🦀 Core | TLS-only; axum/hyper. |
|
||
| CLI | `cli.c` | 🔁 Replace | API-client CLI. |
|
||
|
||
---
|
||
|
||
## 10. New subsystems (no Asterisk equivalent)
|
||
|
||
These are the "modern" deltas — load-bearing, not optional polish.
|
||
|
||
| Subsystem | Disp. | Purpose |
|
||
|---|---|---|
|
||
| WASM plugin host | 🧩 **Demoted (candidate)** | **Out of the core story** ([ADR-0002](adr/0002-north-star-and-fused-core.md)). The agent **tap** is the extension point for in-call logic; ops-simplicity wants one binary. Softly retained as a *candidate* mechanism for community call-flow/routing plugins — undecided vs. webhooks/scripting. |
|
||
| Multi-tenancy / isolation | 🦀 Core | Per-tenant keys, quotas, media separation, RBAC. |
|
||
| Toll-fraud / spend / abuse engine | 🦀 Core (**promoted**) | **Constitutive, not a service** ([ADR-0002](adr/0002-north-star-and-fused-core.md)). Spend caps, pacing caps, deny-by-default routing, rate limits, pattern detection — **co-located with trunk termination inside the boundary** so a runaway brain structurally can't exceed spend/pacing (it doesn't hold the wire). This is what makes the boundary *auditable* on spend. |
|
||
| Secrets / KMS | 🦀 Core | Vault/KMS integration; no plaintext credentials in config. |
|
||
| Observability (OTel) | 🦀 Core | Distributed traces that follow a single call across services. |
|
||
| Event bus | ☁️ Service | **Valkey** ([ADR-0005](adr/0005-event-bus.md)): streams + consumer groups (CDR/CEL/analytics), pub/sub (presence/MWI/BLF), KV (state store). Pluggable to NATS later at a config seam. The 20ms media loop never rides the bus. |
|
||
| SBOM / supply chain | — | cargo-deny, SBOM generation, reproducible builds. |
|
||
| Fuzzing harness | — | Continuous fuzzing of every wire parser (SIP/SDP/RTP). |
|
||
|
||
---
|
||
|
||
## Phasing → the thin-slice first proof + capability ladder
|
||
|
||
The old Phase 0–4 capability-rolldown is **replaced** (see [vision-revision §10–11](superpowers/specs/2026-06-26-vision-revision-design.md)) by a **brutally thin vertical slice** that proves the *combination* (the wedge) first, then a **capability ladder** that grows the contact center feature by feature. The spearhead proves the hardest, most-differentiating part before trunk integration piles on.
|
||
|
||
### The thin-slice first proof (spearhead)
|
||
|
||
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 ([ADR-0003](adr/0003-sip-rust-native-trunk.md)).
|
||
6. **Add the spend cap** — hard-stop at threshold. Proves the boundary.
|
||
|
||
Steps 1–4 *are* the reflex loop. Keep the dev loop on WebRTC ingress until step 5.
|
||
|
||
### The capability ladder (the grand vision, incrementally)
|
||
|
||
| 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 (§5) |
|
||
| 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 |
|
||
|
||
## Open decisions
|
||
|
||
- ~~**SIP:** FFI pjproject vs. SBC front vs. pure-Rust.~~ **Decided — ADR-0003:** Rust-native trunk SIP, no SBC shield.
|
||
- ~~**License**~~ **Decided — ADR-0004:** GPL-3.0-or-later.
|
||
- ~~**Event bus:** NATS vs. Kafka vs. Redis Streams.~~ **Decided — ADR-0005:** Valkey.
|
||
- ~~**Ingress:** WebRTC vs. inbound SIP endpoint.~~ **Decided — ADR-0006:** WebRTC-first; SIP endpoint deferred.
|
||
- **WASM runtime** — `wasmtime` component model, *if* WASM is retained at all (demoted to candidate per [ADR-0002](adr/0002-north-star-and-fused-core.md)). Uncoupled from the critical path.
|
||
- **Plugin mechanism** — WASM vs. webhooks vs. scripting for community call-flow/routing extensions. Deferred.
|
||
- **Agent-tap protocol** — presumptively WSS + core-as-client + clean PCM + core-authoritative playout (see ARCHITECTURE.md, "Agent tap"). To harden against the thin-slice first proof, *not* a decided ADR yet.
|