Originally created by: Maqbool61
apply_egress_velocity_change (added in [#446]) had no caller. A user could
hand-edit .doberman/policies.yaml to loosen burst, volume-bytes, or
fanout without ever crossing the possession-factor gate — silently bypassing
the raise-only invariant the gate exists to enforce.
Closes [#457]
Add doberman egress-velocity to the CLI, mirroring doberman prefs exactly:
gate first, save only on outcome.approved. Every loosening now has to
cross the same TOTP-or-password weaken path as every other policy weakening.
Hand-editing the YAML still works mechanically, but the sanctioned path is
the CLI, and operators who care about the audit trail will use it.
doberman egress-velocity # show current thresholds + built-in defaults
doberman egress-velocity burst 10 # tighten (frictionless, no prompt)
doberman egress-velocity burst 30 # loosen (TOTP if enrolled, else password)
doberman egress-velocity volume-bytes 10485760 # same gate for volume
doberman egress-velocity fanout 5 # same gate for fanout
Tightening (lower value than currently stored) → method=auto, prompter
never invoked, recorded in ledger, persisted immediately.
Loosening (higher value than currently stored) → confirmation prompt, then
TOTP if enrolled, else password. Denied on wrong factor, declined confirm, or
no factor enrolled. Denial recorded in ledger; nothing written to disk.
doberman prefsload_policy → gate → save_policy skeletonoutcome.approved guard before any writeprefs in the Policy panel| File | What |
|---|---|
src/doberman/cli/main.py |
New egress-velocity command + apply_egress_velocity_change / VelocityThresholds imports |
tests/unit/test_cli_egress_velocity.py |
17 new tests mirroring test_cli_lowering_gate.py |
tests/unit/test_cli_help.py |
("egress-velocity",) added to CLI_HELP_TARGETS |
_Boom guard)approved=0burst=25,burst=22 is a strengthen relative to the current stored value —method=auto — even though 22 > 20 (built-in default)ruff check — 0 errorsruff format --check — 383 files already formattedlint-imports — 3 contracts kept, 0 brokenpython scripts/check_markdown_links.py — no broken links
Tickets: #446
Tickets: #457
Tickets: #494
Tickets: #497
Tickets: #509
Originally posted by: Maqbool61
The secret-scan failure is unrelated to this PR. Gitleaks recently required a paid license key for organizations — the error is:
[DobermanCore] is an organization. License key is required.
Error: missing gitleaks license.
This fails in 7 seconds before scanning any code, and would affect every PR opened against this repo. All 5 test jobs (Ubuntu 3.11/3.12/3.13, Windows 3.12, package-smoke-test) pass. The PR is ready to merge.
Ticket changed by: fu351
Ticket changed by: fu351
Ticket changed by: fu351
Ticket changed by: fu351
Ticket changed by: fu351
Originally posted by: fu351
Merged, thanks @Maqbool61! The walkback test is the one I care about most, a gate-approved loosening to burst 25 followed by a move to 22 applies with no prompt even though 22 is still above the built-in 20, which is the tighten-only rule written down as a test. Two things I did on the landing. Your branch and [#472] both added an import at the same spot in cli/main.py, so I merged main into a copy of your branch in our repo (land/pr459, [#494]) and resolved that line, and I added the
egress-velocityrows to the command and exit-code tables in docs/CLI.md next toprefs. Nothing else touched. If you want the next one, [#442] (level-6) is a second plugin tutorial built around a minimaldoberman.audit_sinkssink, and since you wrote both built-in sinks nobody is better placed for it.Related
Tickets:
#442Tickets:
#472Tickets:
#494