replay-verify
Prove the simulation is deterministic by re-running a seeded scenario and diffing its order log and world-state hash against itself and against a stored golden baseline. Produces a PASS/FAIL reproduci
Files1
View on GitHubSKILL.md.claude/skills/replay-verify/SKILL.md
GitHubReplay Verify
This skill is the reproducibility gate. Project Aegis guarantees that a given
(scenario, seed) produces the identical order log and end-state on every run
(req 03, req 04, delegation spec §2.5). /determinism-audit finds causes of
non-determinism by static scan; this skill proves the result by actually
running the sim and comparing outputs.
The rule is simple: a build whose replay diverges is not reproducible, and a non-reproducible sim is broken — even if every unit test passes.
Output: production/determinism/replay-[date].md
Parse Arguments
scenario-name— verify a single named scenario fixtureall(default) — verify every scenario fixture found--record— record/refresh the golden baseline for the target scenario(s) instead of comparing (deliberate baseline regeneration — see Phase 6)--bisect— on a detected divergence, bisect the order log to the first diverging tick and attribute it (diagnostic mode)
Arguments combine: /replay-verify convoy-intercept --bisect.
Phase 1: Detect the Sim and Replay Harness
Solution check: confirm
ProjectAegis.slnexists. The sim runs viadotnet, not the Unity editor — the deterministic core is plain .NET.Replay fixtures: glob for golden baselines, in priority order:
tests/replay/**/*.golden.json(or.baseline)tests/replay/fixtures/src/**/*Tests/**/Replay*
If none exist:
"No replay baselines found under
tests/replay/. Run/replay-verify [scenario] --recordto create the first golden baseline, or scaffold the replay harness first." Then stop unless--recordwas passed.Replay runner: locate the entry point that runs a seeded scenario headless and emits an order log + state hash. Candidates:
- a test in
*.TeststaggedReplay/Determinism - the demo (
src/ProjectAegis.Delegation.Demo) run with a--seed/--scenarioflag - a dedicated replay CLI
If no runner exists:
"No replay runner found. The sim needs a headless entry point that takes
(scenario, seed)and emits a deterministic order log + end-state hash. This is a prerequisite — seedeterminism-engineer. Recording the harness is out of scope for this gate run." Then stop.- a test in
Report: "Sim: .NET via ProjectAegis.sln. Baselines: [N found / none]. Runner: [path / not found]."
Phase 2: Run the Replay (twice + against golden)
For each in-scope scenario, run the sim three ways to separate two failure modes — intra-run non-determinism vs. baseline drift:
# Run A and Run B: same scenario+seed, two fresh processes
dotnet test ProjectAegis.sln --filter "Category=Replay&Scenario=[name]" 2>&1
# or, if a replay CLI exists:
# dotnet run --project src/ProjectAegis.Delegation.Demo -- --scenario [name] --seed [seed] --emit-log runA.log
# dotnet run --project src/ProjectAegis.Delegation.Demo -- --scenario [name] --seed [seed] --emit-log runB.log
Capture for each run: the order log (sequence of timestamped intents) and the world-state hash at the final tick (and at periodic checkpoints if emitted).
If the runner is unavailable in this environment (no dotnet on PATH, runner
missing): record status as NOT RUN — do not treat as FAIL. Ask the developer
to confirm results from local/CI, mirroring the /smoke-check NOT-RUN handling.
Phase 3: Compare
Three comparisons per scenario:
| Comparison | Question | Failure meaning |
|---|---|---|
| A vs B | Did two fresh runs of the same seed match? | Intra-run non-determinism — the sim itself is unstable (worst case) |
| A vs golden | Did this run match the recorded baseline? | Behavior drift — sim changed since the baseline was recorded |
| checkpoint hashes | Do per-tick hashes match the golden? | Localises where divergence began |
Diff the order logs line-by-line and the state hashes. Record:
- First diverging tick (if any)
- Number of diverging order-log lines
- Whether divergence is A-vs-B (CRITICAL) or only A-vs-golden (drift — may be intentional)
If --bisect: walk the order log to the first tick where hashes diverge and
report the controller/target that emitted the first differing intent. This is the
hand-off artifact for determinism-engineer to root-cause.
Phase 4: Classify the Result
| Verdict | Condition |
|---|---|
| PASS | For all scenarios: A == B and A == golden (byte-identical order log + state hash) |
| PASS (BASELINE DRIFT) | A == B for all scenarios, but A != golden — the sim is internally deterministic but behavior changed vs. the baseline. Requires a human decision: intentional change (→ re-record) or regression (→ FAIL). |
| FAIL | Any scenario has A != B — the sim is non-deterministic. Release-blocking. |
| NOT RUN | Runner unavailable; developer must confirm from local/CI. Not a FAIL by itself. |
Phase 5: Generate Report
## Replay Verify Report
**Date**: [date]
**Scope**: [scenario-name | all]
**Mode**: [verify | --record | --bisect]
**Sim runner**: [path / NOT RUN reason]
---
### Results
| Scenario | Seed | A vs B | A vs Golden | First Divergent Tick | Verdict |
|----------|------|--------|-------------|----------------------|---------|
| [name] | [seed] | MATCH | MATCH | — | PASS |
| [name] | [seed] | MATCH | DIFFER | tick 1423 | DRIFT |
| [name] | [seed] | DIFFER | — | tick 087 | FAIL |
---
### Divergence Detail *(if any)*
**[scenario] — first divergence at tick [N]:**
- Order-log lines differing: [count]
- Run A: `[first differing intent]`
- Run B / Golden: `[first differing intent]`
- Attributed to: [controller / target id] *(only with --bisect)*
---
### Verdict: [PASS | PASS (BASELINE DRIFT) | FAIL | NOT RUN]
Phase 6: Write, Gate, and Handle Drift
Present the results table and any divergence detail in conversation.
Ask: "May I write this replay verification report to production/determinism/replay-[date].md?"
Write only after approval.
Then deliver the gate verdict:
If FAIL (A != B):
"⛔ The sim is non-deterministic — two runs of the same seed diverged at tick [N]. This is release-blocking. Run
/replay-verify [scenario] --bisectto localise the cause, then/determinism-auditon the implicated namespace, and hand the bisected tick todeterminism-engineer."
If PASS (BASELINE DRIFT) — A == B but A != golden:
Use AskUserQuestion to resolve:
question: "[scenario] is internally deterministic but differs from its golden baseline. Was the behavior change intentional?"
options:
- "Intentional — re-record the baseline" (→ re-run with --record after confirming the change is correct)
- "Unintended regression — treat as FAIL" (→ stop; the change must be reverted or fixed)
- "Unsure — needs review" (→ leave verdict as DRIFT, do not advance the gate)
Only regenerate a golden baseline with explicit user confirmation, and note the reason in the commit message.
If PASS:
"✅ Sim is reproducible — all scenarios produced byte-identical order logs and state hashes across runs and against golden baselines. Safe to merge / advance the gate. Pair with
/determinism-auditfor full coverage."
If NOT RUN:
"Replay could not be executed (runner unavailable). Confirm reproducibility from local or CI before merging. NOT RUN is not a PASS."
Phase 7: Gate Integration
/replay-verify + /determinism-audit together form the sim merge gate and
are required artifacts for the Polish → Release gate:
/determinism-auditproves no known non-deterministic patterns exist (static)./replay-verifyproves the sim actually reproduces (dynamic).
Neither alone is sufficient. The release gate requires a PASS (or explicitly re-recorded baseline) here, with no open CRITICAL items in the latest audit.
Collaborative Protocol
- Never treat NOT RUN as PASS or FAIL — record it and require manual
confirmation, mirroring
/smoke-check. - Never re-record a golden baseline without explicit approval — silent re-recording hides regressions. Drift always goes to the user.
- A != B is the worst case — internal non-determinism is release-blocking and takes priority over baseline drift.
- Determinism extends to all platforms — note that a PASS in this environment does not guarantee cross-platform reproduction; flag platform-sensitive math (float/transcendental) for a target-hardware check.