fix(inbox): a negated allow word is a refusal, not an approval - #445
Open
ishita199615 wants to merge 1 commit into
Open
fix(inbox): a negated allow word is a refusal, not an approval#445ishita199615 wants to merge 1 commit into
ishita199615 wants to merge 1 commit into
Conversation
resolve_from_reply tested the allow list before the deny list, so the first branch won on any reply containing an allow keyword and the deny branch was never reached. Word boundaries (andrewyng#161) stopped "disallow" matching allow, but they cannot see the word in front: "not approved" contains "approved", so a refusal typed into Slack or Telegram resolved the item as allow and the parked action went ahead. Reproduced on main against InboxStore - "not approved", "I don't approve", "no, do not approve this", "please don't allow that" and "never approve this one" all resolved to allow, as did "denied - do not allow" (both intents present, allow tested first). Deny is now tested before allow, so a reply carrying both intents lands closed, and a new _NEGATED_ALLOW pattern catches an allow keyword behind an adjacent negator - the case with no deny keyword at all to fall through to. The window is bounded to two intervening words so it reads adjacency rather than a negator appearing anywhere in the message; prose like "did not surface anything new, so approve" still resolves as allow. Emoji checks, plain approvals and the free-text answer path are unchanged. As andrewyng#161 put it, a false allow is the worst-case direction - this path gates parked unattended actions.
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.
The problem
Reply "not approved" to an approval request in Slack and OpenWorker approves it — the email goes out.
resolve_from_reply(coworker/inbox_routing.py:137) checks allow before deny and stops at the first hit:_ALLOW_WORDSis\b(?:approve|approved|allow|allowed|yes)\b."not approved"matchesapproved, so the first branch wins and theelifnever runs. Thenotis never read.#161 added those word boundaries so
"disallow"stopped matchingallow. Boundaries fix matching inside a word, not the word in front of it.On
mainat01b6f83, against a realInboxStore:Short answers (
no,deny) work. Full-sentence refusals flip.Why it matters
This is the live path for Slack/Telegram approval replies —
manager.py:2830_resolve_inbox_replyroutes inbound messages here forkind="approval"items, which gate sends, shell commands and file writes. The ownership check above it decides who may answer; nothing checked what they meant.It fails in the wrong direction. A misread approval costs a second click. A misread refusal has already sent the email.
The fix
Deny is tested first, so a reply with both intents (
"denied - do not allow") lands closed. And a new pattern catches the case with no deny word at all:The
{0,2}window is deliberate.ask_userquestions reuse this parser, so a broader rule would start swallowing free-text answers."did not surface anything new, so approve"still resolves as allow — there's a test pinning it.Emoji reactions, plain approvals and the free-text path are unchanged.
Tests
6 new cases in
tests/test_inbox_routing.py, plus 3 pinning what must not change, alongside the ones #161 added.git checkout main -- coworker/inbox_routing.py): 6 failed, 15 passed