Originally created by: slegarraga
Fixes [#430]
Every --last flag flows into a storage reader whose LIMIT clause was guarded by truthiness:
query = _SELECT_DECISIONS + (f" LIMIT {int(limit)}" if limit else "")
limit=0 is falsy, so the clause was dropped and "show me zero rows" returned every row. The signature already documents the intended contract (limit: int | None = None, None = unlimited), so the guard now reads if limit is not None.
src/doberman/storage/log.py: read_decisions and read_decisions_since use limit is not None.src/doberman/policy/drift.py: read_policy_changes had the same pattern; fixed there too, which covers policy-history --last 0.tests/unit/test_storage_last_zero.py (new): pins the 0/None/1 contract for all three readers against a real seeded DB. These tests fail on main without the fix.tests/unit/test_cli_log_jsonl.py: log --jsonl --last 0 must print nothing (fails on main without the fix).No field or schema changes; behavior only changes for limit=0, which previously returned data nobody asked for.
Reproduced before fixing: doberman demo --fast --path <tmp>, then log --last 0 printed all 8 rows, byte-identical to log --last 100.
With the fix, on this machine:
pytest tests/unit/test_storage_last_zero.py tests/unit/test_cli_log_jsonl.py: 10 passed.pytest tests/unit -k "log or decisions or drift or policy or tune": 212 passed, 1 skipped.pytest tests/unit = 2713 passed, 3 skipped, excluding test_hosthook_codex.py and test_hosthook_taint_floor.py, which abort natively on this Mac even on a clean checkout of main; CI arbitrates those two.ruff check and ruff format --check clean on all touched files.doberman log --last 0 --path <seeded tmp> now prints (no decisions recorded yet).
Ticket changed by: fu351
Originally posted by: fu351
Merged, thanks @slegarraga! Fixing the truthiness guard in all three readers instead of just the log path the issue named is what I was hoping to see,
policy-history --last 0had the same bug and your storage-level contract test now pins the 0/None/1 semantics for all three at once. If you want to stay in storage, [#213] (level-5) adds a configurable prune policy for the decision log and builds directly on the readers you just fixed.Related
Tickets:
#213Originally posted by: slegarraga
Thank you for the thoughtful review and merge, @fu351! I really enjoyed tightening those semantics across all three readers — that contract test felt like the right way to make the fix durable. I'll take a look at [#213] next and follow up with questions or a focused PR soon. :)
Related
Tickets:
#213