You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(guardrails): reorder PolicyDecision by severity; block-before-redact
Addresses initializ-mk's review on #221.
## Enum ordinal now maps to severity (was: latent aggregate bug)
Pre-fix constant order was Allow=0, Deny=1, Modify=2, so
`partA.Decision > partB.Decision` in CheckOutbound's aggregate
escalation was actually treating Modify as MORE severe than Deny —
opposite of the "Allow < Modify < Deny" comment. Worked only
because Deny short-circuits via the error return path.
Reordered to Allow < Modify < StepUp < Defer < Deny so the
ordinal comparison encodes restrictiveness. String() output and
audit-wire strings are unchanged (SIEM-stable). CheckOutbound's
aggregate escalation now correctly ranks any decision.
New TestPolicyDecision_SeverityOrdering pins the contract so a
future refactor can't silently break it. Also pins DecisionAllow
as the zero value so `PolicyResult{}` still implicitly means Allow.
## Block-before-redact in applyOutputPolicy (was: silent Deny→Modify)
Pre-fix, block detection ran against the progressively-redacted
string. A `redact` rule listed before a `block` rule could rewrite
the substring the block pattern would have caught, silently
downgrading Deny to Modify.
Post-fix, two-pass evaluation: pass 1 checks every block pattern
against the ORIGINAL content and short-circuits on match; pass 2
applies redacts cumulatively. Regression test
TestApplyOutputPolicy_RedactDoesNotHideEarlierBlock proves the
downgrade is closed.
## Docs + CHANGELOG (was: undocumented behavior change)
Dropping the cli_execute short-circuit is backward-incompatible:
existing deny_commands patterns now evaluate against the raw JSON
of every tool call. Added:
- CHANGELOG.md "Changed (potentially breaking)" section under
Unreleased with migration guidance.
- docs/security/policy-decisions.md — new "Behavior change: match
target asymmetry" table (cli_execute → reconstructed command
line; other tools → raw JSON) and a "Block/redact ordering"
section documenting the two-pass evaluation.
## Aggregate comment correction
CheckOutbound's docstring said aggregate.Modified "reflects the
last modified part" but strict `>` keeps the FIRST modified part
at each severity level. Docstring updated to match code.
## Dead code cleanup
Six pre-existing `result = nil` lines on gate-error paths where
the function immediately returns — carried over from an earlier
refactor. Removed while I'm here.
0 commit comments