fix(tools): bound execute_code's lifecycle probe and keep the terminal guard answerable to /stop

execute_code ran the same unbounded _is_supervised_gateway_process() probe
ahead of every cell, so the wedge #111922 bounds in terminal_tool still hung
an execute_code call (and its cron slot) forever: share the cell's deadline
and fail closed with a retryable error when the probe renders no verdict.

Moving the terminal pre-exec guard onto a deadline worker made it blind to
/stop, which keys on the tool thread's ident: record the acting-for tid in a
contextvar (copied into the worker by run_bounded_sync) so is_interrupted()
on the worker honours the tool thread's bit too.

Floor the guard's share of the deadline at 30s so a short command timeout
does not turn the guard's own cold-start cost (imports, git probes under
load) into a refusal — tests/tools/test_terminal_error_redaction.py was red
on the branch for exactly that.
This commit is contained in:
teknium1
2026-09-15 15:46:44 -07:00
committed by Teknium
parent c832920275
commit 30b22b54ae
5 changed files with 95 additions and 10 deletions
+14 -1
View File
@@ -694,8 +694,21 @@ def execute_code(
# execute_code is a straight bypass — the terminal() path refuses `launchctl bootout ai.hermes.gateway`,
# but the identical command inside `os.system(...)` / `subprocess.run([...])` here sailed through and
# SIGTERM'd the gateway mid-task.
# The identity probe ends in a kernel process query that has wedged on macOS
# (#111922); share the cell's own deadline and fail CLOSED when it renders no verdict.
from agent.deadline import run_bounded_sync
from tools.process_registry import _is_supervised_gateway_process
if _is_supervised_gateway_process():
from tools.terminal_tool import _PRE_EXEC_GUARD_MIN_TIMEOUT_S
_probe_timeout = max(_load_config().get("timeout", DEFAULT_TIMEOUT), _PRE_EXEC_GUARD_MIN_TIMEOUT_S)
_probe = run_bounded_sync(
_is_supervised_gateway_process, _probe_timeout, label="execute_code.lifecycle-guard",
)
if _probe.timed_out:
return tool_error(
f"execute_code lifecycle guard did not finish within {_probe_timeout}s "
"(process-identity probe wedged); the code was not run. Retry the call."
)
if _probe.value:
from cron.lifecycle_guard import contains_gateway_lifecycle_command
if contains_gateway_lifecycle_command(code):
return tool_error(