feat(cli): ordo replay — replay recorded decisions against a rule change#147
Merged
Conversation
… change
ordo replay reads a JSONL of captured decisions ({rule_name, input, code,
output} — what ordo-server's upcoming --capture-io writes, and what a business
app's own decision log looks like) and re-runs every input through the current
project ruleset. It reports which decisions stayed consistent, which FLIPPED
(code/output changed vs the captured baseline, with a diff), which errored, and
which named an unknown ruleset — the safety net for changing a rule.
- --write-tests fixates the captured decisions as tests/<rule>.json regression
cases (deduped by input), so production traffic becomes a regression suite
- --fail-on-flip exits non-zero for CI gating; default is report-only
- --ruleset overrides the per-record rule; accepts a file or '-' for stdin
- --json emits the full bucketed summary + per-record diffs
Reuses the execution + diff logic of ordo test via a new pub(crate)
test_runner::diff_result wrapper (keeps TestCase/TestExpectation private).
Tests: tests/replay.rs drives the real binary through every bucket + the
write-tests -> ordo test loop + stdin + fail-on-flip.
Pama-Lee
added a commit
that referenced
this pull request
Jul 6, 2026
… change (#147) ordo replay reads a JSONL of captured decisions ({rule_name, input, code, output} — what ordo-server's upcoming --capture-io writes, and what a business app's own decision log looks like) and re-runs every input through the current project ruleset. It reports which decisions stayed consistent, which FLIPPED (code/output changed vs the captured baseline, with a diff), which errored, and which named an unknown ruleset — the safety net for changing a rule. - --write-tests fixates the captured decisions as tests/<rule>.json regression cases (deduped by input), so production traffic becomes a regression suite - --fail-on-flip exits non-zero for CI gating; default is report-only - --ruleset overrides the per-record rule; accepts a file or '-' for stdin - --json emits the full bucketed summary + per-record diffs Reuses the execution + diff logic of ordo test via a new pub(crate) test_runner::diff_result wrapper (keeps TestCase/TestExpectation private). Tests: tests/replay.rs drives the real binary through every bucket + the write-tests -> ordo test loop + stdin + fail-on-flip.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The safety net for changing a rule: replay last week's real decisions and see which ones flip.
ordo replay <captured.jsonl>reads a JSONL of captured decisions —{rule_name, input, code, output}, the shape ordo-server's upcoming--capture-iowrites (PR-2), and also what a business app's own decision log looks like — and re-runs everyinputthrough the current project ruleset.What it reports
Each record lands in a bucket:
ordo test)--write-testsFlags
--write-tests— fixate the captured decisions astests/<rule>.jsonregression cases (deduped by input). Production traffic → regression suite.--fail-on-flip— exit non-zero when any decision flips (CI gating); default is report-only, exit 0.--ruleset <name>— replay all records against one rule, ignoring per-recordrule_name.-reads JSONL from stdin;--jsonemits the full bucketed summary + per-record diffs.Why it works so cleanly
A test case is
{input, expect:{code, output}}— the same shape as a captured{input, code, output}decision. So capture → regression is a near-passthrough. Reuses the execution + diff logic ofordo testvia a newpub(crate) test_runner::diff_resultwrapper (keepsTestCase/TestExpectationprivate); compiles each distinct ruleset once and caches it.Tests
tests/replay.rsdrives the real binary through every bucket, the--write-tests→ordo testloop (incl. idempotent dedup), stdin (replay -),--fail-on-flipexit code, and--rulesetoverride.cargo test -p ordo-cligreen (35 tests);clippy --all-targets -- -D warningsclean.Verify locally
```bash
ordo init demo && cd demo
printf '%s\n' '{"rule_name":"loan-approval","input":{"amount":5000},"code":"APPROVED"}'
'{"rule_name":"loan-approval","input":{"amount":20000},"code":"APPROVED"}' > cap.jsonl # 2nd is a planted flip
ordo replay cap.jsonl # 1 consistent, 1 flipped (APPROVED → REJECTED)
ordo replay cap.jsonl --write-tests && ordo test
```
Part 1 of 2 — PR-2 adds ordo-server
--capture-ioto produce the JSONL this consumes.