Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions agentrace/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,12 @@ def cmd_check(args) -> int:

flagged = 0
total_findings = 0
has_high = False
for r in runs:
findings = analyse(r)
if args.severity:
findings = [f for f in findings if f.severity == args.severity]
has_high = has_high or any(f.severity == "high" for f in findings)
if args.severity:
findings = [f for f in findings if f.severity == args.severity]
if not findings:
Expand All @@ -105,7 +109,6 @@ def cmd_check(args) -> int:
"[dim]These are hints, not verdicts: go read the run.[/]"
)
# Exit non-zero only on high severity, so this is usable in CI without being a nuisance.
has_high = any(f.severity == "high" for r in runs for f in analyse(r))
return 1 if (has_high and args.strict) else 0


Expand Down Expand Up @@ -201,7 +204,7 @@ def main(argv: list[str] | None = None) -> int:

c = sub.add_parser("check", help="flag suspicious results")
c.add_argument("--severity", choices=["high", "medium", "low"], help="only this severity")
c.add_argument("--strict", action="store_true", help="exit 1 if any high severity finding")
c.add_argument("--strict", action="store_true", help="exit 1 if any displayed high severity finding")
c.set_defaults(func=cmd_check)

s = sub.add_parser("show", help="read one run in full")
Expand Down
20 changes: 20 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import pytest

from agentrace import cli
from agentrace.checks import Finding
from agentrace.parse import AgentRun


Expand Down Expand Up @@ -152,3 +153,22 @@ def test_check_prints_bracketed_description_literally(monkeypatch, capsys):

assert cli.cmd_check(Namespace(severity=None, strict=False)) == 0
assert "run [bold]pwned[/bold] test" in capsys.readouterr().out


def test_check_analyses_each_run_once_and_strict_respects_severity(monkeypatch):
start = datetime(2026, 1, 1, tzinfo=UTC)
runs = [
AgentRun("toolu_one", "one", "p", "r", start, start + timedelta(seconds=1)),
AgentRun("toolu_two", "two", "p", "r", start, start + timedelta(seconds=1)),
]
calls = []

def fake_analyse(run):
calls.append(run.tool_use_id)
return [Finding("test", "high", "message")]

monkeypatch.setattr(cli, "_load", lambda args: runs)
monkeypatch.setattr(cli, "analyse", fake_analyse)

assert cli.cmd_check(Namespace(severity="low", strict=True)) == 0
assert calls == ["toolu_one", "toolu_two"]
Loading