docs: propagate ADR-0007/0008 to README, ARCHITECTURE, PORT_PLAN, AGENTS

ADR-0007 (rent the trunk) + ADR-0008 (FOB/green-zone doctrine) propagation
into the narrative docs that orient contributors + readers. No code changes.

README:
- Wedge bullet 2: 'one secure auditable boundary' now lists media + local
  reflexes + spend + tap + audit (was: trunk termination + media + spend).
  Adds the honest caveat that PSTN media inside the boundary is the on-prem
  *graduation* (ADR-0007), not a day-one claim.
- 'Is / isn't': 'isn't a TDM/PSTN-hardware PBX — *and not a SIP stack.*'
  No first-party SIP (ADR-0007). PSTN reach is rented transport.
- Memory-safety pillar: 'rutster parses no SIP at all' — entire first-party
  wire surface is WebRTC/RTP/SRTP + WebSocket tap/ingress, all memory-safe
  Rust. The carrier-SIP interop tail lives outside the trust boundary.
- Spearhead step 5: 'Add a real phone number via rented transport' (was:
  'Replace WebRTC ingress with a real PSTN trunk call'). Re-aims at the
  AI-telephony frontier; no first-party SIP stack.
- References: 0007 supersedes 0003 in the highlighted ADR list.

ARCHITECTURE:
- New 'FOB and the green zone' section after the fused-vertical framing —
  names the build-vs-reuse doctrine with the FOB member list + green-zone
  member list, and restates memory-safety precisely ('FOB is 100%
  memory-safe Rust; the green zone is trusted OSS kept outside the
  boundary — not an over-claim that every byte is Rust').
- 'Inside the boundary': 'Carrier trunk — rented transport, not first-party'
  replaces 'Trunk SIP termination — Rust-native.' PSTN audio arrives as
  a media-leg ingress from a rented CPaaS raw-media fork or an out-of-tree
  SBC for on-prem sovereignty.
- Biggest technical risk: 'No longer the SIP stack — because rutster no
  longer builds one.' Retires ADR-0003's named schedule risk; redirects
  to 'the reflex loop itself' (turn-taking, VAD-driven barge-in, jitter,
  pacing) — which is also the differentiator.

PORT_PLAN:
- Design rule 4: 'rent it, don't own it' replaces ADR-0003's 'Rust-native
  trunk SIP, no SBC shield.' ADR-0007 restores the rule's original instinct.
- SIP signaling (trunk) row: disposition flipped to 🔌 Rented / out-of-tree.
- Outbound registration row: disposition flipped to 🔌 Rented / out-of-tree
  (handled by the rented transport or out-of-tree SBC; rutster parses no SIP).
- Spend/abuse engine row: 'co-located with call origination + the tap inside
  the boundary' (was: 'co-located with trunk termination'). rutster mediates
  both the provider call-control API and the brain tap — the brain never
  holds the wire.
- Spearhead step 5: 'Add a real phone number via rented transport.'
- Open decisions: SIP line updated to 'Re-decided — ADR-0007.'

AGENTS.md:
- ADR list: adds 0007 and 0008 with annotations; marks 0003 as superseded
  by 0007.
- Key decisions to respect: prepends the FOB/green-zone doctrine as the
  *the* build-vs-reuse rule. 'When in doubt, default to green zone — the
  FOB earns its members, it doesn't collect them. This is why the trunk is
  rented (ADR-0007) and Valkey reused (ADR-0005), not rebuilt. Don't pull
  green-zone plumbing into the core.'
This commit is contained in:
opencode controller
2026-06-29 20:26:51 -04:00
parent 3c3197e57a
commit 7616878bb1
4 changed files with 76 additions and 34 deletions

View File

@@ -24,7 +24,7 @@ rutster/
│ ├── rutster/ # binary: axum signaling server + media driver + static page
│ ├── rutster-media/ # str0m WebRTC + Opus<->PCM codec boundary
│ ├── rutster-call-model/ # the Channel/Leg object embryo
│ ├── rutster-signaling-sip/ # stub until spearhead step 5
│ ├── rutster-trunk/ # stub until spearhead step 5
│ ├── rutster-tap/ # stub until spearhead step 2
│ └── rutster-spend/ # stub until spearhead step 6
├── fuzz/ # (planned) placeholder cargo-fuzz harness dir
@@ -170,10 +170,12 @@ Before proposing changes to the architecture, read in this order:
thin-slice phasing (20 min).
4. [`docs/adr/`](docs/adr/) — every ADR. Load-bearing decisions, not optional reading:
- [ADR-0002](docs/adr/0002-north-star-and-fused-core.md) — north star + fused vertical
- [ADR-0003](docs/adr/0003-sip-rust-native-trunk.md) — Rust-native trunk SIP (no SBC)
- [ADR-0003](docs/adr/0003-sip-rust-native-trunk.md) — ~~Rust-native trunk SIP~~ **superseded by [ADR-0007](docs/adr/0007-trunk-rented-transport.md)**
- [ADR-0004](docs/adr/0004-license.md) — GPL-3.0-or-later
- [ADR-0005](docs/adr/0005-event-bus.md) — Valkey as bus + state store
- [ADR-0006](docs/adr/0006-ingress-posture.md) — WebRTC-first ingress
- [ADR-0007](docs/adr/0007-trunk-rented-transport.md) — rent the trunk transport; no first-party SIP stack
- [ADR-0008](docs/adr/0008-fob-and-green-zone.md) — the FOB / green-zone build-vs-reuse doctrine
5. [`docs/superpowers/specs/`](docs/superpowers/specs/) — design specs in flight. Read the
latest one to know what's currently being built and what's explicitly deferred.
- [2026-06-26 vision-revision](docs/superpowers/specs/2026-06-26-vision-revision-design.md) —
@@ -188,6 +190,12 @@ and "why isn't X here?" questions. Consult it before adding anything.
## Key decisions to respect
- **The FOB / green-zone doctrine** (ADR-0008) — *the* build-vs-reuse rule. Build it in the
memory-safe Rust **FOB** only if it's hot-path, security-constitutive, or differentiating; otherwise
reuse trusted, **actively-maintained** OSS in the **green zone**, at arm's length (its own process /
container / trust domain). When in doubt, default to green zone — the FOB earns its members, it
doesn't collect them. This is why the trunk is rented (ADR-0007) and Valkey reused (ADR-0005), not
rebuilt. Don't pull green-zone plumbing into the core.
- **License:** `GPL-3.0-or-later` on every crate manifest (ADR-0004). Strong copyleft in the
Asterisk lineage. Don't introduce deps that conflict (`cargo deny check licenses` enforces).
- **WebRTC stack:** `str0m` (sans-IO). Not `webrtc-rs`. Chosen because the sans-IO design maps
@@ -233,13 +241,13 @@ These are explicitly deferred per the slice-1 spec's out-of-scope table. Adding
would break the sequencing that the spearhead depends on:
- ❌ Dedicated timing thread for the media loop (deferred to step 4, barge-in)
- ❌ TLS on the HTTP signaling surface (deferred to step 5, PSTN trunk)
- ❌ TLS on the HTTP signaling surface (deferred to step 5, rented-transport PSTN)
- ❌ Authn / authz / multi-tenancy on `/v1/sessions` (deferred to step 6, spend cap)
- ❌ Trickle ICE (deferred until NATs demand it)
- ❌ The tap itself (deferred to step 2 — slice 1 only *pre-paves* the seam)
- ❌ The brain / STT / LLM / TTS (deferred to step 3)
- ❌ Barge-in / VAD-driven playout kill (deferred to step 4)
- ❌ PSTN trunk / SIP client (deferred to step 5)
- ❌ PSTN via rented transport / CPaaS media-leg ingress (deferred to step 5; no first-party SIP — ADR-0007)
- ❌ Spend cap / abuse gate (deferred to step 6)
- ❌ Browser-based automated e2e tests / Selenium / Playwright (deferred post-slice-1)
- ❌ Docker / compose (deferred to a later rung)