Skip to content

fix(approval): a reviewer DENY needs its own human answer (RIG-8544) - #44

Merged
mattwilkinsonn merged 4 commits into
rigel-releasefrom
nemo-guard/rig-8544-a-reviewer-deny-needs-its-own-human
Nov 9, 2026
Merged

mattwilkinsonn merged 4 commits into
rigel-releasefrom
nemo-guard/rig-8544-a-reviewer-deny-needs-its-own-human

Conversation

@rigel-mintaka

@rigel-mintaka rigel-mintaka commented Nov 9, 2026 •

Copy link
Copy Markdown
Collaborator

What does this PR do?

After #43, a smart-reviewer DENY goes to a human. Review found ways it could still run without a human answering it. Now a DENY runs only after a person answers "once" to that request; otherwise it is blocked.

Related Issue

RIG-8544. Follows #43.

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • A DENY is never grouped with another request. Subagent auto-approve and bulk approve skip it.
  • A session or always reply to a DENY counts as once.
  • A reply must name a DENY by its ID to release it. A reply without an ID resolves nothing while a DENY is first in the queue, so cards that send no ID can't release or skip past it. /approve says to answer DENY requests on their own card.
  • With review_first, the reviewer runs first; a cached grant then applies only to a non-DENY verdict.
  • The CLI gets the DENY flag and always shows the warning and a command row, down to 11 terminal rows.
  • A human deny or timeout adds the denial-breaker text; "once" resets the count.

How to Test

  1. Focused approval, gateway, CLI, Telegram, relay and plugin-origin suites: 305 passed.
  2. The new or changed tests fail on cb0ca31c.
  3. ruff check passes on touched files.
  4. Three gateway tests (test_automation_retry, test_hosted_mux_runtime, test_hosted_group_members) also fail on 99ffc621.

Checklist

Code

  • My commit messages follow Conventional Commits
  • My PR contains only changes related to this fix
  • I've added tests for my changes

Documentation & Housekeeping

  • I've updated relevant documentation — N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A

For New Skills

N/A

Screenshots / Logs

N/A: test runs above.

Refs RIG-8544

Co-authored-by: Matt Wilkinson matt@rigel.build

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@linear-code

linear-code Bot commented Nov 9, 2026

Copy link
Copy Markdown

RIG-8544

@rigel-mintaka

Copy link
Copy Markdown
Collaborator Author

Review round 1 (head cb0ca31c)

Full lens fan-out (correctness, security, design, style). The direct fixes hold: bulk approve skips DENY, session and always become once, DENY doesn't coalesce, and subagent auto-approve refuses DENY. The invariant still breaks in three ways, so this PR is not ready.

Severity Finding Disposition
High Card taps and /approve resolve the oldest request in the session, not the one shown. A tap on an ordinary card can release a queued DENY. Fixing: the resolver never releases a DENY unless its own request_id names it. The Telegram and relay cards will carry request_id.
High Same root cause, through parallel tool calls and plain /approve Fixing with the above
High The interactive CLI hardcodes smart_denied=False, so the reviewer warning is never shown Fixing: carry smart_denied through PendingControls and GatewayAgent
Medium A cached session grant skips the reviewer Fixing: skip the cache when review_first is set
Medium The CLI panel can drop every command row, and it miscounts rows Fixing: keep at least one command row; correct the count
Medium Subagent auto-approve also matches display text; its docstring is wrong Fixing: use the kwarg only; correct the docstring
Medium Reviewer note string is duplicated; an over-length comment Fixing
Medium No end-to-end test for DENY queued ahead of an ordinary card Adding it
Low Assorted style and test nits Cheap ones fixed; rest noted

Next: fixes with tests that fail first, then round 2.

…ewer DENY cannot be released by another (RIG-8544)
@rigel-mintaka

Copy link
Copy Markdown
Collaborator Author

Round 1 fixes (head 6d66927e)

All round 1 high and medium findings are addressed in 6d66927e:

  • Oldest-request resolution: a reply that doesn't name a DENY by its ID never releases it. Telegram and relay cards carry their request ID.
  • CLI warning: smart_denied now reaches the interactive CLI.
  • Cached grant: with review_first, the reviewer always runs.
  • Panel: at least one command row stays visible, and the row count is fixed.
  • Subagent check: it uses the kwarg only, and its docstring is corrected.
  • Cleanup: one shared note constant; the long comment is shortened; the end-to-end mixed-queue case is added.

All 9 new or changed tests fail on cb0ca31c. Focused suites pass. Round 2, with every lens, is running on this head.

rigel-mintaka and others added 2 commits November 8, 2026 20:55
A reply with no request ID resolves nothing while a DENY heads the queue.
review_first honours cached grants for non-DENY verdicts. The CLI panel keeps
the warning and a command row at 11 rows.

Refs RIG-8544

Co-authored-by: Matt Wilkinson <matt@rigel.build>
An empty request ID no longer resolves the head of the queue, and the managed
worker rejects empty prompt IDs.

Refs RIG-8544

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@mattwilkinsonn
mattwilkinsonn marked this pull request as ready for review November 9, 2026 02:21
@mattwilkinsonn
mattwilkinsonn merged commit 624e2ef into rigel-release Nov 9, 2026
1 check passed
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.

2 participants