# ADR-0008 — The FOB and the green zone: the build-vs-reuse doctrine

- **Status:** Accepted
- **Date:** 2026-06
- **Origin:** 2026-06 strategic-relevance review — names the boundary doctrine implicit across ADRs
  0002–0007 and makes it a mechanical rule every contributor (human or agent) applies the same way.
- **Amends:** `docs/ARCHITECTURE.md` (adds the organizing metaphor), `AGENTS.md` (adds it to "key decisions")
- **Related:** [ADR-0002](0002-north-star-and-fused-core.md) (the boundary this rule governs),
  [ADR-0007](0007-trunk-rented-transport.md) (a green-zone call), [ADR-0005](0005-event-bus.md) (a
  green-zone call), [ADR-0006](0006-ingress-posture.md) (arm's-length out-of-tree adapters)

## Context

Across ADRs 0002–0007 one criterion kept deciding calls without ever being named: **what does rutster
build and own, and what does it reuse?** Fused vertical (0002), rent the trunk (0007), bundle Valkey
(0005), the out-of-tree SBC (0006) — all the same judgment, applied case by case. A solo build cannot
re-derive that judgment per decision, and multiple coding agents now work this repo and need one
explicit, mechanical rule so they classify consistently.

The failure mode this prevents is **not-invented-here**: rebuilding mature, actively-maintained OSS
inside the core and drowning the scarce solo-years in undifferentiated plumbing. The from-scratch Rust
trunk-SIP stack (superseded by [ADR-0007](0007-trunk-rented-transport.md)) was exactly that mistake.

Stated as one image: **stop building a fortress; build a secure base of operations.** Harden and own
the core — the **FOB** (forward operating base). Operate through a trusted, actively-maintained OSS
perimeter — the **green zone**. Leverage, not autarky.

## Decision

Every capability is classified **FOB** or **green zone**.

### FOB — build it, own it, in Rust

Memory-safe Rust, owned, fuzzed, **inside the trust boundary** — the surface you would certify
(PCI / HIPAA / TCPA). A capability is admitted to the FOB **only if it passes at least one** of three
tests:

1. **Hot path** — it runs on the per-call real-time loop, where a GC pause / jitter / an extra network
   hop would degrade call quality. *(media termination, jitter buffer, pacing, the reflexes.)*
2. **Security-constitutive** — it *is* the auditable boundary: the spend/abuse gate, the trust-domain
   edge, the audit surface. A 3-vendor chain structurally cannot enforce it. *(spend gate, the boundary
   itself.)*
3. **Differentiating** — it is the thing no competitor ships and a reason rutster exists. *(the reflex
   loop, the agent tap, the contact-center domain logic.)*

The FOB **may link mature OSS for internals** — libopus (codec), `str0m` (sans-IO WebRTC), speexdsp
(DSP) — as **trusted vendored dependencies**. Linking a maintained library to *implement* an FOB
capability is not a violation: you don't rewrite a codec. What makes the capability FOB is that rutster
owns it, it passes an FOB test, and the wire-facing parser is memory-safe Rust. Any vendored dep that
parses hostile bytes is fuzzed.

**Current FOB:** media termination (`rutster-media`, on `str0m`) · real-time reflexes (VAD/barge-in,
jitter, pacing) · call model (`rutster-call-model`) · the agent tap (`rutster-tap`) · the spend/abuse
gate (`rutster-spend`) · the control API + the state/bus **trait** (`rutster`).

### Green zone — reuse it, at arm's length

Trusted, **actively-maintained** OSS or an external managed service, **reused at arm's length** — its
own process, container, or trust domain, **never in the FOB's address space**, so its failures cannot
corrupt the core. A capability belongs here if it **fails all three FOB tests** and a trusted,
maintained project already does it well.

**Current green zone:** Valkey (state store + bus, [ADR-0005](0005-event-bus.md) — bundled in the
all-in-one image, external in the modular layout) · the carrier trunk (CPaaS raw-media fork /
out-of-tree SBC, [ADR-0007](0007-trunk-rented-transport.md)) · the agent brain (OpenAI Realtime or a
self-hosted STT/LLM/TTS) · the reference GUI (admin portal + call-flow builder — a pure API client) ·
object storage (recording/CDR durability) · KMS/Vault (secrets) · the OTel collector · the container
supervisor (tini/s6).

### The "actively maintained" gate is load-bearing

A green-zone dependency the FOB relies on **must** be healthy: maintained, released, production-grade,
not bus-factor-1. This single gate is what:

- **excludes** a first-party Rust SIP stack (`ezk`, bus-factor-1 / pre-1.0 — [ADR-0007](0007-trunk-rented-transport.md))
  and `webrtc-rs` (perpetual re-architecture);
- **admits** Valkey (healthy), and `str0m` **for WebRTC** (its maintained sweet spot) — while rejecting
  `str0m` for SIP (out of scope there, "not for production").

Re-audit periodically — a project can go cold (e.g. FreeSWITCH's OSS line). A green-zone dep that stops
being maintained is a defect to resolve, not a fixture.

## How to apply (every contributor, human or agent)

Before building a subsystem or adding a dependency, run the test:

1. **Does it pass an FOB test?** (hot-path **or** security-constitutive **or** differentiating)
   - **No** → green zone. Find the trusted, actively-maintained OSS/service and integrate it **at arm's
     length** (separate process / container / trust domain). **Do not rebuild it in-core.**
   - **Yes** → build it in the FOB, in Rust. For *internals* a mature library already solves (codecs,
     DSP), link that library as a trusted vendored dep — don't rewrite it. Fuzz any vendored parser that
     touches hostile bytes.
2. **Is the OSS you're about to depend on actively maintained / production-grade?** If not, it is not
   eligible for anything the FOB depends on — find another, or scope the need away.

When in doubt, default to **green zone**. The FOB earns its members; it does not collect them.

## Consequences

- **Positive:** one mechanical rule, applied identically by every human and agent; the solo-years
  concentrate on the FOB (the only part that differentiates); the memory-safety claim becomes *precise*
  rather than an over-claim; retroactively consistent with ADRs 0002–0007.
- **Negative:** the green zone is a dependency-trust surface that must be re-audited ("actively
  maintained" can decay); arm's-length integration costs some glue versus pulling things in-process.
- **Restated pillar:** **memory-safe = the FOB** (100% Rust at the boundary that holds the call), with
  mature OSS trusted at arm's length around it — *not* a claim that every byte in the deployment is Rust
  (libopus, Valkey, the SBC are not).

## Worked example — deployment packaging

The all-in-one container is the doctrine made physical: the **FOB binary** + bundled `valkey-server`
(green zone) + the reference GUI (green zone), supervised in one container; point it at a brain + CPaaS,
`docker run`, taking calls. The modular/compose layout splits the same green-zone services out to scale.
Same FOB binary underneath; only the state/bus backend seam differs (bundled vs external). *(The
deployment topology itself may get its own ADR once that design closes.)*

## References

- [ADR-0002](0002-north-star-and-fused-core.md) — fused per-call vertical + composable platform (the boundary this rule governs)
- [ADR-0007](0007-trunk-rented-transport.md) — rent the trunk (a green-zone classification)
- [ADR-0005](0005-event-bus.md) — Valkey (a green-zone classification)
- [ADR-0006](0006-ingress-posture.md) — out-of-tree adapters (arm's-length integration)
