Quickstart

Everything below runs on localhost — a control plane, a handful of demo workloads, and a load generator. Two implementations, identical behavior: Go (the reference) and Rust (the system being built out).

Run it

Go (phase0 — the reference implementation)

cd phase0
make test     # unit tests: flag evaluator, picker, canary state machine, store
make e2e      # full system against real gRPC traffic on localhost (~10 s)
make demo     # live 5-scenario walkthrough (~2 min, prints as it goes)

Rust (the current workspace)

cd rust
export CARGO_TARGET_DIR=/tmp/dona-target   # optional; keeps builds off a full disk
cargo test --workspace    # current workspace tests; audited baseline: 285 passed
./demo.sh                 # live 5-scenario walkthrough (~2 min, mutually authenticated)

Prerequisites: Go 1.22+ for the Go tree; a stable Rust toolchain for the Rust workspace. No cluster, no Docker, no cloud account — the demo is plain processes talking real gRPC over localhost.

Audited on 2026-07-07: the recorded Rust baseline was 285 passed, 0 failed, 3 ignored across the workspace. The Go reference suite remains the conformance peer, pinned to the same cross-language fixtures. The demo runs mutually authenticated: bootstrap token → SPIFFE SVID → encrypted control and data planes.

What the demo shows — five scenarios

demo.sh / make demo starts the control plane (donad), registers demo workloads (2× v1 in us-east and eu-west, 1× v2 in us-east), and drives traffic through the SDK while you watch the per-variant split change.

1. Baseline

All traffic lands on stable v1. The load generator prints a rolling per-variant summary — the observable evidence for everything that follows.

2. Feature flag: route a cohort at the network layer

dona flag set --service demo.greeter --flag use-v2 --match group=beta:v2

A targeting rule sends the beta group to v2 — per request, inside the client process, no redeploy. With 4 of 20 synthetic users in beta you see ~20% of traffic shift to v2 while the beta cohort itself is 100% v2. Remove the flag and traffic snaps back.

3. Canary: auto-promote on healthy metrics

dona rollout --service demo.greeter --canary v2 --stable v1 \
  --steps 10,40,100 --step-seconds 8 --max-error 2 --min-requests 20

The canary controller steps v2's traffic weight 10% → 40% → 100%, dwelling at each step and judging the live per-variant error rate reported by the SDK. Healthy metrics → the rollout reaches 100% and the state machine lands on promoted.

4. Bad release: auto-rollback

A v3 workload starts with an injected 60% failure rate and a rollout begins. As soon as the canary's error rate breaches the threshold (with at least --min-requests samples, so one unlucky call can't kill a release), traffic returns to stable instantly and the state machine lands on rolled_back. No human in the loop.

5. Sovereignty: constraint → deny → audit

The client attaches x-data-region: eu-west to every call. The constraint filters the eligible endpoint set before any flag or canary decision: only the eu-west v1 endpoint is eligible, so 100% of constrained traffic lands there even while v2/v3 weights exist. Then the client asks for ap-south, which nobody serves:

status: PermissionDenied
message: "dona: no endpoint of demo.greeter satisfies
          residency constraint \"ap-south\""

Denied and audited — never misrouted. The demo finishes by grepping the control-plane log for the AUDIT trail: every constrained decision, allow and deny, client-side filter and server-side enforcement.

Poke at it yourself

While the demo (or your own donad) is running, dona is the operator surface:

dona status demo.greeter        # endpoints, weights, flags, rollout state, per-variant stats
dona flag set ... / flag rm ... # flag management
dona rollout ...                # start a canary

Next: Concepts explains the machinery — sticky bucketing, the rollout state machine, and the audit model.