Prompt regression tracking
Did that prompt tweak break anything? Snapshot a run, change the prompt, snapshot again, and diff.
pytest --ghostrun-snapshot v1 --ghostrun-label "original prompt"
# ... edit your prompt ...
pytest --ghostrun-snapshot v2 --ghostrun-label "added few-shot examples"
ghostrun diff v1 v2
Comparing v1 -> v2
========================================================================
1 regression(s), 0 fix(es), 1 stable, 1 output(s) changed
REGRESSION (1)
test_support.py::test_reply
contains_intent('sorry')
judge: the text does not apologize
OUTPUT DRIFT (1)
test_support.py::test_reply [output 0] (45% similar)
--- before
+++ after
@@ -1 +1 @@
-I'm so sorry about the delay with your refund...
+Your refund request is in the queue...
FAILED: 1 regression(s) detected.
Every run also writes a _last snapshot, so ghostrun diff v1 (candidate defaults to _last) works without planning ahead.
Output drift is reported separately from regressions: a response can change substantially while still passing every assertion, which is worth seeing before it becomes a regression later.
Assertions that never executed because a test aborted at an earlier failure are reported as NOT EVALUATED, not "removed" — so a single failure doesn't masquerade as a pile of deleted checks.
CLI
ghostrun list # saved snapshots
ghostrun show v1 # outputs + verdicts for one run
ghostrun diff v1 v2 # compare
ghostrun diff v1 v2 --format json # machine-readable
ghostrun diff v1 v2 --fail-on-regression # exit 1 on any PASS -> FAIL (CI gate)
ghostrun diff v1 v2 --format github-comment -o comment.md # markdown for a PR bot
ghostrun diff v1 v2 --format junit -o ghostrun.xml # for CI test-result dashboards
Posting a regression diff as a PR comment
A regression a developer has to remember to check for locally gets missed. One that shows up inline in the PR doesn't. In a GitHub Actions workflow:
- name: Record this PR's outputs
run: pytest --ghostrun-snapshot pr-${{ github.event.pull_request.number }}
- name: Diff against main's baseline
run: |
ghostrun diff main-baseline pr-${{ github.event.pull_request.number }} \
--format github-comment -o comment.md
echo "exit_code=$?" >> "$GITHUB_OUTPUT"
id: diff
continue-on-error: true
- name: Post as a PR comment
run: gh pr comment ${{ github.event.pull_request.number }} --body-file comment.md
env:
GH_TOKEN: ${{ github.token }}
- name: Fail the job if a regression was found
if: steps.diff.outputs.exit_code == '1'
run: exit 1
--format junit instead produces standard JUnit XML, so a prompt regression shows up in whatever test-results view your CI already renders (GitHub Actions annotations, GitLab, Jenkins) without that system needing to know anything about ghostrun.