Skip to content

Add default shell timeout policy - #17

Merged
CalvinSturm merged 1 commit into
mainfrom
feat/default-shell-timeout-policy
Jul 1, 2026
Merged

Add default shell timeout policy#17
CalvinSturm merged 1 commit into
mainfrom
feat/default-shell-timeout-policy

Conversation

@CalvinSturm

Copy link
Copy Markdown
Owner

Summary

Adds a safe default shell timeout policy so host shell commands no longer run forever when timeout_ms is omitted.

Host shell commands now default to a 120 second timeout unless the caller explicitly passes timeout_ms: 0 to opt out.

What changed

  • Added DEFAULT_SHELL_TIMEOUT_MS = 120_000

  • Added shell timeout resolution logic in exec_shell

  • Updated shell tool documentation to mention the default

  • Preserved explicit timeout_ms > 0 override behavior

  • Preserved explicit timeout_ms: 0 as the unbounded/back-compatible opt-out

  • Preserved DockerTarget behavior:

    • explicit timeout_ms > 0 still returns a structured unsupported-target error
    • missing timeout_ms maps to unbounded on Docker and is not accidentally rejected

Timeout semantics

Case Host target Docker target
timeout_ms > 0 enforced rejected with structured unsupported error
timeout_ms == 0 unbounded unbounded
timeout_ms missing 120000 ms default unbounded

Why

After PR #15, LocalAgent supported explicit shell timeouts, but commands could still run forever when the model omitted timeout_ms.

This closes that gap for host execution while preserving a deliberate opt-out path.

Validation

  • cargo fmt --check
  • cargo clippy --all-targets -- -D warnings
  • cargo test --lib target::
  • cargo test --lib tools::
  • cargo test --test tool_call_accuracy_ci
  • cargo test --lib repro
  • cargo test --test artifact_golden
  • python scripts/ci_release_readiness.py

All validation passed locally.

Notes

The default is currently a documented compile-time constant, not a CLI/profile setting. That keeps this PR small and avoids profile/golden churn. A future PR can wire this into reliability profiles or a --shell-timeout-ms flag.

Follow-ups

  • Runtime/profile override for shell timeout policy
  • Docker shell timeout enforcement
  • Live shell output streaming / TUI tail events
  • Robust process-tree cleanup
  • Lightweight in-run todo/update_plan tool

Previously an omitted timeout_ms meant unbounded shell execution, so an
autonomous/unattended run could hang forever on a runaway command.

Introduce a target-aware default in resolve_shell_timeout_ms:
- explicit timeout_ms > 0: use it (host enforces; docker still rejects per #15)
- explicit timeout_ms == 0: unbounded opt-out (unchanged)
- missing timeout_ms on host: apply DEFAULT_SHELL_TIMEOUT_MS (120000 ms)
- missing timeout_ms on docker: resolve to 0 (unbounded), NOT a rejection

The docker branch is deliberate: DockerTarget cannot enforce timeouts and
rejects timeout_ms > 0, so a *missing* timeout must stay unbounded there rather
than silently becoming a rejection. Explicit docker requests are unchanged.

The default lives as a documented module constant in tools/exec_shell.rs (easy
to adjust; no reliability-profile/RunArgs/golden churn) and is reflected in the
shell tool description.

Tests: resolver covers missing->host-default, explicit>0 override, explicit 0
unbounded, and missing-on-docker stays unbounded; a behavioral execute_tool test
confirms a fast host command with no timeout still succeeds under the default.
@CalvinSturm
CalvinSturm merged commit 719ae60 into main Jul 1, 2026
1 check passed
@CalvinSturm
CalvinSturm deleted the feat/default-shell-timeout-policy branch July 1, 2026 00:57
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.

1 participant