Conversation
A per-agent `mode: observe` control silently discarded blocking findings, and nothing said so. The audit record read `verdict: warned` — identical to an ordinary warn-level rule — stderr printed the usual advisory line, and `prismor agents show` resolved the agent WITHOUT org controls, so it reported the local mode as if it were effective. The combination is what makes this dangerous: a guardrail pinned to observe a month earlier reported detection and enforced nothing, and every surface an operator would check agreed that enforcement was on. Observed in a benchmark lane as 91 findings across 11 rules and 0 blocks, including floor rules that hard-block on another agent path. Behaviour is unchanged — observe still allows the call. What changes is that the drop is now visible: - Decision carries `suppressed` / `suppressed_by` - audit records the verdict as `suppressed`, not `warned`, and the reason names the rule and the suppressor - one stderr line: "would block ... SUPPRESSED by <source> observe mode" - `agents show` resolves org controls and prints the mode with its origin, flagging a local value that the org overrides Closes #256 Claude-Session: https://claude.ai/code/session_01YU9bdvnpgAc6XyWTAoL12M
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #256.
The bug
A per-agent
mode: observecontrol silently discarded blocking findings, and no surface said so. This is what an operator saw while the guardrail enforced nothing:verdict: warned[prismor] [HIGH] ...(ordinary advisory)prismor agents show <agent>mode: enforceobserveagents showresolved the agent without org controls (agents listalready passed them), so it printed the local value as if it were effective.Found in a benchmark lane that recorded 91 findings across 11 rules and 0 blocks, including floor rules (
remote-execution,destructive-command,secret-exfiltration,rce-canary) that hard-block on another agent path. The pin had been set a month earlier and forgotten. It also outranks a device-wide force-enforce, so the obvious remedy doesn't help.What changes
Enforcement behaviour is unchanged — observe still allows the call. Only visibility changes.
Decisioncarriessuppressed/suppressed_bysuppressed, notwarned; the reason names the rule and the suppressorwould block: [HIGH] ... (rule: X) — SUPPRESSED by org-agent-control observe modeagents showresolves org controls, prints the mode with its origin (org/local/default), warns when a local value is overridden by the org, and spells out what observe meansTests
tests/test_suppressed_enforcement.py, 9 tests:suppressedvswarnedvsblockedvsallowed, and that a real block still wins over a suppression notecurl | bashpayload → call allowed,suppressed_by == "org-agent-control", rule recorded, stderr says SUPPRESSEDFull suite: 24 failed / 1738 passed, against a clean-
mainbaseline of 24 failed / 1729 passed — same failures, +9 new tests, no regressions. (The 24 are pre-existing and unrelated; 4 adapter test files were excluded in both runs because their namespace packages aren't installed in a bare clone.)One note for reviewers: the end-to-end tests neutralise
tool_deniesand use a unique agent name in their engine fixture. Without that they pass alone and fail in the full suite, because a leaked org tool-deny forcodex/Bashfrom another test is agent-control category and blocks regardless of observe.https://claude.ai/code/session_01YU9bdvnpgAc6XyWTAoL12M