Skip to content
Docs for briefcase-ai v3.3.0see what’s new.

Deterministic Replay

Re-execute a saved decision against a ReplayEngine and compare the new output to the one you recorded — so a model swap, a prompt edit, or a dependency bump can’t silently change what your system decides.

replay For: regression & verification

How it works

  1. Persist a DecisionSnapshot to a storage backend (this is the original you’ll compare against).

  2. Replay it through ReplayEngine, which re-executes the decision and compares the new output to the recorded one.

  3. Interpret the ReplayResultoutputs_match, status, and policy_violations tell you whether the decision held and what to do next.

flowchart LR
    A[Recorded decision<br/>in storage] --> B[ReplayEngine.replay]
    B --> C{outputs_match?}
    C -->|True| D[Reproducible — ship]
    C -->|False| E[Regression — investigate]

Install

Terminal window
pip install briefcase-ai[replay]
from briefcase.replay import ReplayEngine, ReplayPolicy, ReplayStats

Persist, then replay

import briefcase
from briefcase import DecisionSnapshot, Input, Output
from briefcase.storage import SqliteBackend
from briefcase.replay import ReplayEngine
briefcase.init()
decision = DecisionSnapshot("classify_ticket")
decision.add_input(Input("text", "Reset my password", "string"))
decision.add_output(Output("category", "account_access", "string"))
decision.with_execution_time(12.5)
backend = SqliteBackend.in_memory()
decision_id = backend.save_decision(decision)
engine = ReplayEngine(backend)
result = engine.replay(decision_id, "strict")
print(result.status)
print(result.outputs_match)
print(result.replay_output)
print(result.execution_time_ms)
print(result.policy_violations)

ReplayEngine(backend) takes a storage backend. replay(decision_id, mode) takes the mode explicitly.

Strict vs. tolerant

The mode decides how exactly the replayed output must match the original. Pick it from how deterministic the decision is supposed to be.

ModeMatches whenReach for it when
"strict"The replayed output is identical to the originalThe decision is meant to be deterministic — a fixed classifier, temperature=0, a routing rule. Any difference is a regression.
"tolerant" (default)Minor differences are allowedThe output is free-form or sampled (a generated reply, a summary) where wording can vary but meaning should not.

Interpreting a ReplayResult

ReplayResult is what you act on. The table maps each field to the decision it should drive.

FieldWhat it tells youWhat to do
status"success" or a failure status for the replayA non-success status means the replay itself couldn’t complete (decision missing, load error) — fix the harness before trusting the result.
outputs_matchTrue when the replayed output matches the originalFalse on a decision that used to be stable is a regression — investigate the change you just made.
replay_outputThe output produced during this replayDiff it against the original to see exactly what drifted.
policy_violationsList of policy rules the replay violatedNon-empty means a specific field broke its match rule — read it to know which field and why.
execution_time_msReplay execution time in millisecondsA large swing can flag a performance regression even when the output still matches.
original_snapshotThe recorded decision being replayedThe baseline for the comparison and your audit reference.

Replay with a policy

A ReplayPolicy declares how each output field must match. Combine exact-match fields with similarity-threshold fields when one decision has both a structured label and free text.

from briefcase.replay import ReplayPolicy
policy = ReplayPolicy("output-consistency")
policy.with_exact_match("category")
policy.with_similarity_threshold("summary", 0.95)
result = engine.replay_with_policy(decision_id, policy, "strict")
print(result.status)
print(result.policy_violations)

Here category must match exactly (a misroute is unacceptable) while summary only has to stay 95% similar (wording may vary).

Replay in batches

Verify a whole regression set at once instead of one decision at a time.

results = engine.replay_batch([decision_id], "strict", 4)
for result in results:
print(result.status, result.outputs_match)

replay_batch(decision_ids, mode, max_concurrent) replays many decisions concurrently, bounded by max_concurrent.

Aggregate replay statistics

from briefcase.replay import ReplayStats
stats = engine.get_replay_stats([decision_id])
print(stats.total_replays)
print(stats.successful_replays)
print(stats.exact_matches)
print(stats.success_rate)
print(stats.average_execution_time_ms)

success_rate across your regression set is the one number to watch release over release: a drop means more decisions changed than you expected.

Key classes

ClassWhy it matters
ReplayEngineLoads a persisted decision from a backend and re-executes it — the entry point for every replay.
ReplayResultOutcome of a single replay; the fields you act on to catch a regression.
ReplayPolicyPer-field match rules for replay_with_policy so structured and free-text fields can be judged differently.
ReplayStatsAggregate counts and rates across many replays — your release-over-release health signal.

Where this fits

Replay is the start of the Replay & Verify act: re-run a stored decision, then measure how far it moved over time and prove the record is intact.