Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions acp_adapter/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ def _callback(command: str, description: str) -> str:
logger.warning("Permission request timed out or failed: %s", exc)
return "deny"

if response is None:
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

response is None is handled by returning "deny", but it fails silently. If None represents an unexpected/invalid ACP reply, consider logging (at least debug/warning) or adding a short comment explaining why None is an expected value, so diagnosing permission-bridge issues is easier in production.

Suggested change
if response is None:
if response is None:
logger.warning(
"Permission request returned no response; denying by default "
"(session_id=%s, command=%r)",
session_id,
command,
)

Copilot uses AI. Check for mistakes.
return "deny"
Comment on lines +66 to +67
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description still contains template placeholders (e.g., Fixes #, empty Changes Made / How to Test). Please fill these in so reviewers and release notes can trace the bug report and verify the reproduction + fix steps.

Copilot uses AI. Check for mistakes.

outcome = response.outcome
if isinstance(outcome, AllowedOutcome):
option_id = outcome.option_id
Expand Down
14 changes: 14 additions & 0 deletions tests/acp/test_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,17 @@ def test_approval_timeout_returns_deny(self):
result = cb("rm -rf /", "dangerous")

assert result == "deny"

def test_approval_none_response_returns_deny(self):
"""When request_permission resolves to None, the callback should return 'deny'."""
loop = MagicMock(spec=asyncio.AbstractEventLoop)
mock_rp = MagicMock(name="request_permission")

future = MagicMock(spec=Future)
future.result.return_value = None

with patch("acp_adapter.permissions.asyncio.run_coroutine_threadsafe", return_value=future):
cb = make_approval_callback(mock_rp, loop, session_id="s1", timeout=1.0)
result = cb("echo hi", "demo")

assert result == "deny"
Loading