Originally created by: fu351
Originally owned by: AshSgDe29071999
Three of the CLI's four machine-readable outputs serialize deterministically and compactly. One doesn't.
| command | line | call |
|---|---|---|
scan --json |
cli/main.py:242 |
json.dumps(payload, sort_keys=True, separators=(",", ":")) |
doctor --json |
cli/main.py:568 |
json.dumps(payload, sort_keys=True, separators=(",", ":")) |
log --jsonl |
cli/main.py:810 |
json.dumps(record, sort_keys=True, separators=(",", ":"), default=str) |
policy-history --json |
cli/main.py:992 |
json.dumps(rows, default=str) |
No sort_keys, no compact separators.
policy-history is the append-only ledger of policy changes — who weakened or strengthened what, and how it was approved. It's exactly the output someone would diff between two points in time, hash for an audit trail, or cache.
Without sort_keys, key ordering isn't guaranteed stable, so a byte-comparison of two dumps of identical ledger state can report a spurious difference. On an audit surface that's a genuinely unhelpful property.
tests/unit/test_cli_policy_history_json.py also has no determinism test, unlike test_cli_scan_json.py, which asserts a repeated invocation produces byte-identical stdout.
sort_keys=True, separators=(",", ":").test_cli_scan_json.py — invoke twice against the same DB state, assert again.stdout == result.stdout.Two consecutive policy-history --json calls on unchanged state produce byte-identical stdout, proven by a new test, and a populated-ledger case exists.
default=str can stay — harmless, though every ledger column is already a JSON-native type.Comment here to claim it.
🤖 Generated with Claude Code
Originally posted by: AshSgDe29071999
I'd like to make
policy-history --jsonoutput deterministic like the other JSON commands.Ticket changed by: fu351