Skip to content

fix(runtime): surface blocks suppressed by an observe downgrade - #261

Open
Ar9av wants to merge 1 commit into
mainfrom
fix/256-surface-suppressed-enforcement
Open

Ar9av wants to merge 1 commit into
mainfrom
fix/256-surface-suppressed-enforcement

Conversation

@Ar9av

@Ar9av Ar9av commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Closes #256.

The bug

A per-agent mode: observe control silently discarded blocking findings, and no surface said so. This is what an operator saw while the guardrail enforced nothing:

surface reported actual
audit record verdict: warned a block was dropped
stderr [prismor] [HIGH] ... (ordinary advisory) a block was dropped
prismor agents show <agent> mode: enforce effective mode was observe

agents show resolved the agent without org controls (agents list already 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.

  • Decision carries suppressed / suppressed_by
  • audit verdict is suppressed, not warned; the reason names the rule and the suppressor
  • one stderr line: would block: [HIGH] ... (rule: X) — SUPPRESSED by org-agent-control observe mode
  • agents show resolves 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 means

Tests

tests/test_suppressed_enforcement.py, 9 tests:

  • suppressed vs warned vs blocked vs allowed, and that a real block still wins over a suppression note
  • reason text names rule + suppressor
  • end-to-end reproduction: org observe pin + a curl | bash payload → call allowed, suppressed_by == "org-agent-control", rule recorded, stderr says SUPPRESSED
  • same payload without the pin → blocks, nothing suppressed
  • benign call under a pin → no phantom suppression

Full suite: 24 failed / 1738 passed, against a clean-main baseline 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_denies and 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 for codex/Bash from another test is agent-control category and blocks regardless of observe.

https://claude.ai/code/session_01YU9bdvnpgAc6XyWTAoL12M

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
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.

Per-agent mode override silently suppresses blocks with no signal in CLI, audit trail, or stderr

1 participant