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.
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.