Skip to content

fix(policy): Restructure policy evaluation for per-violation callbacks#27

Merged
anormang1992 merged 1 commit intomainfrom
fix/ensures-multiple-policy-evaluation
Mar 19, 2026
Merged

fix(policy): Restructure policy evaluation for per-violation callbacks#27
anormang1992 merged 1 commit intomainfrom
fix/ensures-multiple-policy-evaluation

Conversation

@anormang1992
Copy link
Owner

@anormang1992 anormang1992 commented Mar 19, 2026

Summary

  • PolicyGate.evaluate() now returns list[PolicyViolation] instead of PolicyResult — the gate collects violations, orchestration lives in VRE.check_policy()
  • Hard blocks (requires_confirmation=False) are immediate and non-overridable — on_policy is never consulted
  • Confirmation-required violations are the only ones routed to on_policy, which now receives list[PolicyViolation] instead of a single message string
  • PolicyCallbackResult model for structured callback returns — passed=True means the action passes the policy (no violation), passed=False means it fails (violation fires)
  • PENDING enum value removedPolicyAction is now PASS or BLOCK only
  • Claude Code hook combines all confirmation violations into a single bulleted TUI prompt
  • Demo ProtectedFileDeletePolicy callback that inspects rm commands for protected files via literal match, glob expansion against the filesystem, and recursive directory inspection
  • parse_bash_primitives returns the base command name for unrecognized commands instead of an empty list, giving visibility into why unknown commands are blocked

Test plan

  • All 205 existing tests pass
  • Ruff lint clean
  • New tests for PolicyCallbackResult semantics, mixed violation orchestration, and on_policy passthrough
  • Demo tested with protected file deletion scenarios (literal, glob, directory)
  • Verify Claude Code hook TUI renders bulleted violations correctly

🤖 Generated with Claude Code

…allbacks and correct orchestration

PolicyGate.evaluate() now returns list[PolicyViolation] instead of PolicyResult,
moving decision orchestration into VRE.check_policy(). Hard blocks (requires_confirmation=False)
are immediate and non-overridable; only confirmation-required violations are routed to on_policy.

Key changes:
- PolicyCallbackResult model for structured callback returns (passed=True means action passes)
- on_policy signature: Callable[[list[PolicyViolation]], bool] — receives only pending violations
- PENDING enum value removed — only PASS and BLOCK remain
- PolicyViolation.requires_confirmation delegates to policy, carries callback_result
- Claude Code hook combines confirmation violations into single bulleted TUI prompt
- Demo ProtectedFileDeletePolicy callback with filesystem inspection
- parse_bash_primitives returns base command for unrecognized commands (visibility into blocks)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@anormang1992 anormang1992 merged commit 0a4f501 into main Mar 19, 2026
2 checks passed
@anormang1992 anormang1992 deleted the fix/ensures-multiple-policy-evaluation branch March 19, 2026 02:25
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.

Refactor policy system to support multiple policy evaluation with callback results

1 participant