Skip to content

feat(cli): add --quiet to doberman demo (#441) - #447

Open
blackcoderx wants to merge 2 commits into
DobermanCore:mainfrom
blackcoderx:feat/cli/demo-quiet-flag
Open

feat(cli): add --quiet to doberman demo (#441)#447
blackcoderx wants to merge 2 commits into
DobermanCore:mainfrom
blackcoderx:feat/cli/demo-quiet-flag

Conversation

@blackcoderx

Copy link
Copy Markdown
Contributor

Slice

What this PR does

Adds a --quiet / -q flag to doberman demo, mirroring scan --quiet. When
set, it suppresses the opening banner, the per-scenario narration line, and the
closing "Run doberman dash" hint — keeping only the summary (silent on a full
match, loud with details on a mismatch) and the exit code. This lets demo run
as a CI smoke test ("is the engine alive") without polluting build logs.
Display-only: the scenarios and the engine decision path are untouched.

Tests added (run in CI)

  • tests/unit/test_cli_demo_quiet.pydemo --fast --quiet produces far
    fewer stdout lines than demo --fast (banner/narration/hint gone), exit
    codes match between quiet and loud runs, and the quiet run still reports the
    summary line.

Public-release safety (doberman-core only)

  • Contains nothing from the "not allowed" list: no enterprise/hosted code, no proprietary detection, no customer data, no secrets, no commercial-license code
  • Core still builds/tests/runs with NO enterprise package installed

Security checklist

  • Fails closed on error / uncertainty
  • No secret, full file, or unredacted prompt logged or committed
  • Any guardrail/learning change is raise-only (no silent loosening)
  • Every BLOCK/AUTH carries reason codes + a human explanation
  • doberman-core does not import doberman_enterprise

Edge cases covered / Deviations from plan / Risks introduced

  • Covered: quiet mode still surfaces the mismatch summary (loud, with per-scenario detail) if a scenario disagrees with its expected verdict — only the narration is suppressed, not failure visibility.
  • No deviations from the issue's proposed approach.
  • No risks: purely a CLI display change, no engine/rule/decision-path changes.

Written with Claude Code assistance.

Closes #441

Mirrors scan --quiet: suppresses the banner, per-scenario narration,
and the closing 'doberman dash' hint, keeping only the summary
line/table and the exit code. Lets 'doberman demo' run as a CI smoke
test without polluting build logs. Display-only; scenarios and the
engine path are untouched.

Closes DobermanCore#441
@blackcoderx

blackcoderx commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

@fu351 — flagging this for you.

CI: 5/6 checks are green (secret-scan, package-smoke-test, test (ubuntu-latest, 3.12), test (ubuntu-latest, 3.13), test (windows-latest, 3.12)). Only test (ubuntu-latest, 3.11) fails, and it's unrelated to this PR's diff.

Root cause: test collection dies with the same error in ~230 unrelated modules:

TypeError: type 'DictReader' is not subscriptable

traced through doberman/subjective/baseline.pyriverriver/stream/iter_csv.py:21:

class DictReader(csv.DictReader["FeatureName"]):

csv.DictReader isn't subscriptable at runtime on Python 3.11 — only on newer Python, which is exactly why 3.12/3.13/Windows-3.12 all passed and only the 3.11 leg died.

It's a fresh regression, not a pre-existing bug in this repo's code: the failing job's pip resolve pulled river==0.26.0 (pyproject.toml has an unpinned floor, river>=0.21). The previously-resolved river==0.25.0 has the unsubscripted form (class DictReader(csv.DictReader):, no ["FeatureName"]), so 0.26.0 is the version that introduced the runtime subscript. main's last CI run this morning was green only because its pip cache still held the older wheel — the next cache miss on main will hit this too, independent of any change here.

Confirmed this reproduces against a clean main checkout as well, before any of this PR's changes existed, so it's not something introduced by this slice. Leaving the call on whether/how to pin river to you rather than bundling an unrelated dependency fix into this PR.

@fu351

fu351 commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Thanks @blackcoderx, and thank you for the river diagnosis, tracing it to the 0.25→0.26 DictReader subscript and reproducing against a clean main saved me the whole investigation. The pin is merged as #452. Two small things on the PR itself: the one behavior this flag exists for, a mismatch still failing loudly with a nonzero exit under --quiet, has no direct test, and test_demo.py already has the mismatch-forcing pattern, so one test combining the two closes that. And docs/CLI.md's flag table borrows scan's no-output wording, but demo --quiet keeps the summary line, your CHANGELOG entry says it right and the table doesn't. Don't worry about the merge conflict the pin created, that one's mine, I'll land the branch from here once the test is in.

Adds the one direct test the flag was missing: a scenario mismatch
under --quiet still exits nonzero and still prints the MISMATCH
detail -- narration is suppressed, the failure signal never is. Uses
the same mismatch-forcing technique as test_demo.py's existing
mismatch tests.

Also fixes docs/CLI.md's machine-readable-flags table, which copied
scan's fully-silent --quiet wording onto demo. demo --quiet keeps the
summary line/table (CHANGELOG.md already described this correctly);
the table now says so instead of claiming demo goes fully silent.

Addresses review feedback on PR DobermanCore#447.
@blackcoderx

Copy link
Copy Markdown
Contributor Author

@fu351 Both addressed, pushed as cbf31be:

  • Added test_mismatch_still_reported_loudly_under_quiet to test_cli_demo_quiet.py, combining test_demo.py's mismatch-forcing pattern with --quiet — asserts nonzero exit, MISMATCH, and the actual/expected detail still print under --quiet.
  • Fixed docs/CLI.md's flag table: it no longer claims demo --quiet is fully silent like scan --quiet — now says it keeps the banner/narration/hint suppressed but the summary line/table still prints, matching what the CHANGELOG entry already said.

Left the CHANGELOG.md conflict from #452 alone as you asked — branch is otherwise a straight fast-forward push, no rebase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cli: add --quiet to doberman demo so it can run as a CI smoke test

2 participants