docs: ratify vision revision across README/ARCHITECTURE/PORT_PLAN + ADRs 0002-0006
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.
This commit is contained in:
76
docs/adr/0003-sip-rust-native-trunk.md
Normal file
76
docs/adr/0003-sip-rust-native-trunk.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# ADR-0003 — SIP strategy: Rust-native trunk SIP, no SBC shield
|
||||
|
||||
- **Status:** Accepted
|
||||
- **Date:** 2026-06
|
||||
- **Supersedes:** [ADR-0001](0001-sip-strategy.md)
|
||||
- **Origin:** [vision-revision](../superpowers/specs/2026-06-26-vision-revision-design.md) §5
|
||||
|
||||
## Context
|
||||
|
||||
ADR-0001 layered the SIP strategy: own the Rust parser, but front the public edge with a
|
||||
proven **Kamailio + rtpengine** SBC to rent the "20-year device/carrier interop tail." That tail
|
||||
is real for a generic PBX — thousands of desk-phone quirks, NAT behaviors, carrier glare.
|
||||
|
||||
Reconsidered under the AI-era contact-center scope ([ADR-0002](0002-north-star-and-fused-core.md)),
|
||||
the tail **collapses**: rutster talks to a few **documented, cooperative SIP-trunk providers
|
||||
(Telnyx, Bandwidth, Twilio SIP)**, IP-allowlisted, not thousands of far-end desk-phone UAs. An
|
||||
inbound/outbound SIP-trunk client against cooperative carriers is tractable in `rsip` / `ezk`,
|
||||
bounded by carrier documentation, not device quirks.
|
||||
|
||||
The C SBC shield, meanwhile, directly contradicts the wedge:
|
||||
|
||||
- It puts **C at the most-exposed seam** (the public internet) — gutting the memory-safety
|
||||
headline *at the one place it matters most*.
|
||||
- It **terminates media twice** — rtpengine at the edge, rutster's media plane inside —
|
||||
breaking "terminate media once" / "one auditable boundary."
|
||||
|
||||
## Decision
|
||||
|
||||
Own trunk SIP **and** media termination directly in the Rust core; IP-allowlist the handful of
|
||||
trunk providers. **No Kamailio + rtpengine shield. No pjproject FFI.**
|
||||
|
||||
- Parser: `rsip` (message types/parsing). Sans-IO transaction/dialog/core: the `ezk` family.
|
||||
No hostile bytes ever hit a C parser. **Fuzzed.**
|
||||
- The memory-safety thesis becomes **literally true at the wire**: hostile bytes hit a fuzzed
|
||||
Rust parser first, at the edge of *our* trust boundary.
|
||||
- Interop surface is **bounded by carrier docs** (a finite, knowable set), not the unbounded
|
||||
device tail ADR-0001 rented the shield for.
|
||||
|
||||
### Scope boundary — this ADR is about *trunk* SIP, not *endpoint* SIP
|
||||
|
||||
Inbound SIP **endpoint** registration (desk/soft phones: `REGISTER`, BLF/MWI, DTMF variants,
|
||||
per-device NAT/provisioning) is a **different axis** and is **deferred** — it re-imports the
|
||||
unbounded device-interop tail this ADR deliberately closes. Human-participant ingress is
|
||||
**WebRTC**. See [ADR-0006](0006-ingress-posture.md).
|
||||
|
||||
## Topology
|
||||
|
||||
```
|
||||
hostile internet trusted core
|
||||
───────────────► (carrier trunk) ──► rutster control + media plane
|
||||
(SIP trunks, (native Rust SIP parser +
|
||||
far-end UAs) transaction/dialog core,
|
||||
owned end-to-end here)
|
||||
```
|
||||
|
||||
WebRTC ingress ships **first** and is unaffected (WebRTC signaling is app-defined, not SIP), so
|
||||
first-call never blocks on SIP.
|
||||
|
||||
## Consequences
|
||||
|
||||
- **Positive:** memory-safety headline *literally true* at the wire; one media-termination point;
|
||||
no C operational dependency (no Kamailio/rtpengine config/deploy/expertise); no pjproject
|
||||
license/threading/`unsafe` entanglement; the trunk client is bounded by carrier docs, not device
|
||||
quirks.
|
||||
- **Negative / cost:** we own a (bounded) SIP-trunk client early; carrier-specific interop must be
|
||||
maintained as trunks are added.
|
||||
- **Mitigation:** WebRTC-first ordering means first-call doesn't block on SIP; the thin-slice
|
||||
steps 1–4 (media core → tap → brain → barge-in) all land before step 5 (real PSTN trunk).
|
||||
- **Graduation:** unlike ADR-0001, there is no shield to retire — the question is only how the
|
||||
trunk client matures in production.
|
||||
|
||||
## References
|
||||
|
||||
- [ADR-0001](0001-sip-strategy.md) — superseded (the layered Kamailio+rtpengine + Rust-core plan)
|
||||
- [ADR-0002](0002-north-star-and-fused-core.md) — the fused-vertical reframe this SIP decision enables
|
||||
- [ADR-0006](0006-ingress-posture.md) — WebRTC-first ingress; SIP endpoint deferred
|
||||
Reference in New Issue
Block a user