Skip to content

fix: honor approvals.timeout across CLI and ACP - #13088

Open
tomgreeEn wants to merge 1 commit into
NousResearch:mainfrom
tomgreeEn:fix/approval-timeout-config
Open

tomgreeEn wants to merge 1 commit into
NousResearch:mainfrom
tomgreeEn:fix/approval-timeout-config

Conversation

@tomgreeEn

Copy link
Copy Markdown

Summary

  • make ACP approvals inherit approvals.timeout from config when no explicit timeout is provided
  • allow non-positive ACP timeout values to wait indefinitely
  • make the main terminal CLI approval UI also honor approvals.timeout instead of a hardcoded 60s limit
  • add regression tests for both ACP and terminal CLI approval flows

Problem

Hermes had two separate 60-second approval timeouts:

  • the ACP approval bridge defaulted to 60 seconds
  • the main terminal CLI approval UI also hardcoded 60 seconds

This meant approvals.timeout in config.yaml was not fully honored, and users could still hit 1-minute expiry in regular terminal sessions even after fixing the ACP path.

Test Plan

  • run ./venv/bin/python -m pytest tests/acp/test_permissions.py tests/cli/test_cli_approval_ui.py -q -o 'addopts='
  • run ./venv/bin/python -m py_compile cli.py acp_adapter/permissions.py tests/cli/test_cli_approval_ui.py tests/acp/test_permissions.py
  • manually verify that dangerous-command approval prompts no longer expire after 60 seconds when approvals.timeout is set higher

Fixes #3765.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard comp/acp Agent Communication Protocol adapter area/config Config system, migrations, profiles labels Apr 22, 2026
- make ACP approvals inherit approvals.timeout when no explicit timeout is provided
- allow non-positive ACP timeout values to wait indefinitely
- make terminal CLI approval UI honor approvals.timeout instead of a hardcoded 60s limit
- add focused regression tests for ACP and terminal CLI approval flows

Fixes NousResearch#3765.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for tracing the configuration gap across CLI and ACP. The CLI portion is already present on current main in 8ae65d5c8 (cli.py:11695), but the ACP work is still useful after a focused port.

Problems

  • The change covers only ACP command approvals. Current main also creates an ACP edit approval requester at acp_adapter/server.py:1425; that requester still defaults to 60 seconds in acp_adapter/edit_approval.py:290 and waits with it at :327.
  • The proposed timeout <= 0 behavior blocks ACP command approvals indefinitely, while the CLI deadline expires immediately for that value (cli.py:11705, :11733). This also differs from the documented fail-closed timeout contract (website/docs/user-guide/security.md:141-147).
  • Current ACP bridging now schedules through safe_schedule_threadsafe (acp_adapter/permissions.py:134-150), so the PR's direct scheduler call and scheduler patch in its tests need porting.

Suggested changes

  • Salvage the ACP configuration resolution against the current helper, cover both command and edit approval bridges, and define one shared non-positive timeout policy.

Automated hermes-sweeper review.

loop: asyncio.AbstractEventLoop,
session_id: str,
timeout: float = 60.0,
timeout: float | None = None,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please extend the configured timeout to the ACP edit approval requester as well. Current main constructs that independent bridge in acp_adapter/server.py:1425; it still defaults to 60 seconds in acp_adapter/edit_approval.py:290, so edits would retain the reported bug.

try:
future = asyncio.run_coroutine_threadsafe(coro, loop)
response = future.result(timeout=timeout)
if timeout is not None and timeout <= 0:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

An indefinite wait for timeout <= 0 conflicts with the current CLI, which immediately expires a non-positive deadline (cli.py:11705, :11733), and with the documented fail-closed timeout behavior. Define one shared policy before making ACP special-case this value.

@teknium1 teknium1 added sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/acp Agent Communication Protocol adapter comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: make dangerous command approval timeout configurable

3 participants