Module replay

Module replay 

Source
Expand description

Replay time-travel debugging (DW-102): a PURE decision replayer.

The gateway’s request path (dataplane::proxy) weaves together route matching, authorization, rate limiting, transforms, and endpoint selection with live I/O (upstream dials, live GCRA counters, breaker state). Replay inverts that: given a captured request and a Snapshot (a compiled config generation), it re-runs the SAME decision logic with NO side effects — no network, no live counters, no breaker state — so an operator can ask “what would this recorded request do under THIS config?” and diff the answer across two generations.

§Sandbox isolation

decide is pure: it reads only its inputs (&Snapshot, &ReplayRequest) and a caller-supplied SimulatedCounter for the rate-limit simulation. It never touches the network, the filesystem, the live rate limiter, or any shared mutable gateway state. The rate-limit check uses a SIMULATED counter (not the live GCRA store), the breaker is reported from config alone (no live failure counts), and the endpoint pick is deterministic (the first healthy-by-config endpoint, no live health tracking). This is the contract that makes replay safe to run in CI and against candidate configs that have never served traffic.

§Capture source

The request detail (method, path, redacted headers, auth identity) is captured by the analytics raw table (DW-043, extended in DW-102 with optional request_headers_redacted and auth_identity columns). The capture is opt-in and redacted via the existing PII redaction patterns (ai::redaction); the replay CLI reads those rows (or an exported recording) and feeds them to decide.

§Diffing

DecisionDiff compares two ReplayDecisions (the same request under an old and a new snapshot) and reports which decision stages changed — the unit the dwara replay CLI emits per request, and the signal a CI gate exits non-zero on.

Structs§

DecisionDiff
A per-stage diff between two ReplayDecisions (the same request under an old and a new snapshot). Each field is true when that stage’s decision changed; DecisionDiff::any is the CI-gate signal (exit 1 when any stage differs).
ReplayDecision
The outcome of one stage of the replayed decision path. Each stage reports what the LIVE proxy would have decided at that point, with no side effects applied.
ReplayRequest
One captured request fed to decide. The fields mirror what the analytics raw table stores (DW-043 + DW-102): the request shape and the redacted auth identity. Headers are ALREADY redacted at capture time (the existing PII patterns); replay never sees raw secrets.
SimulatedCounter
A simulated rate-limit counter (DW-102). Replay does NOT touch the live GCRA store; instead the caller threads a counter that tracks per-key usage within a fixed window, and decide advances it the way the live limiter would. The simulation is deliberately simple (fixed-window, not GCRA): replay answers “would this request be admitted under this config’s budget?” not “what is the exact GCRA TAT?” — the decision boundary is what a diff cares about.
TransformSummary
A summary of the transforms that would apply to a matched route (DW-028). Counts (not full op lists) keep the diff output stable across unrelated key-order changes while still surfacing a change in which transforms apply.
UpstreamPick
The upstream endpoint a matched proxy route would dispatch to. The pick is deterministic for replay (the first endpoint of the resolved upstream, or the first split target’s first endpoint) — replay has no live health state, so load-balancer selection is reported as the resolved upstream name plus its first endpoint.

Functions§

decide
The pure decision function (DW-102). Re-runs the gateway’s decision path — route match, authz, simulated rate limit, transform resolution, upstream pick — against snapshot for request, with NO I/O and NO side effects on live gateway state. The rate_counter is the ONLY mutable state touched, and it is a simulated counter the caller owns (not the live limiter).