feat(cli): status --json and sectioned text output
Your AI's guard dog to stop it from going rogue.
Brought to you by:
doberman
Originally created by: AshSgDe29071999
Implements doberman status --json and blank-line sectioned text so status matches the machine-readable surface of scan / doctor / log / policy-history.
--jsonsort_keys=True, compact separators), same style as scan --json._status_payload() so text and JSON cannot diverge on redaction.version, path, doberman_version, role, mode, prefs, prefs_preset, policy, twofa, password, elevations, taint, hooks, recent_decisions, missed_challenges_24h.test_status_json_parses_with_expected_keys — parses and has the full key set; deterministic across two runs.test_status_text_has_blank_line_section_breaks — section separators present.test_status_never_leaks_enrolled_secret_in_either_view — seeds a TOTP secret; asserts it never appears in text or JSON.
:::bash
pytest tests/unit/test_cli_status.py -q
ruff check src/doberman/cli/main.py tests/unit/test_cli_status.py
ruff format --check src/doberman/cli/main.py tests/unit/test_cli_status.py
Fixes [#258]
Originally posted by: fu351
Clean, and the redaction is the part that matters here. Text and JSON both render from the same
_status_payload(), so the two views can't drift on what they expose: enrollment is boolean straight fromis_enrolled()with no path to the raw secret; elevations whitelistid/scope_glob/expires_at/single_use; decisions carry onlyts/final_verdict/reason_codes; taint is keyed by fingerprint, never the raw path. The guard test actually bites — flippingtwofato leak the real TOTP secret turnstest_status_never_leaks_enrolled_secret_in_either_viewred. Andsort_keys=Trueplus oneechogives a single deterministic document, matching thescan --jsonprecedent.One honest NIT, not a blocker:
hooks[].pathprints the local filesystem path tosettings.json(often a full home path) in both views. It's unchanged from the old text output and it isn't secret material, so it's fine to ship — just the one field that isn't purely abstract, if you ever want to class it.Merge-ready from my side. This is the third of your PRs I've read today and they've all been tidy — thanks for the steady stream.
Ticket changed by: fu351
Originally posted by: fu351
Merged — thanks! Airtight redaction and a single shared payload, exactly right; [#258] is now closed. As I flagged on [#298], #192 (a shared JSON-output contract across the CLI's JSON commands) is the natural next step from this
--jsonwork — it's yours if you want it.Related
Tickets:
#258Tickets:
#298