pi-subagent-timeout-safety
Mutation-safe timeout policy for pi-subagents launches
Package details
Install pi-subagent-timeout-safety from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-subagent-timeout-safety- Package
pi-subagent-timeout-safety- Version
0.3.0- Published
- Jul 29, 2026
- Downloads
- 135/mo · 135/wk
- Author
- aloneio
- License
- MIT
- Types
- extension
- Size
- 40.9 KB
- Dependencies
- 0 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./extensions/subagent-timeout-safety/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-subagent-timeout-safety
A reusable Pi package that prevents a
pi-subagents writer from being killed by a caller-supplied wall-clock timeout
or turn budget while it may be in the middle of a file mutation.
It was originally designed against Pi 0.82.0 and pi-subagents 0.35.1.
The current deployed compatibility matrix has also been verified with:
- Pi
0.82.1 pi-subagents0.37.0- Node.js
24+
This is currently version 0.3.0 of the package.
Why
pi-subagents treats timeoutMs / maxRuntimeMs as a hard elapsed deadline.
When it expires, its runner terminates the child process and then escalates to
SIGKILL. A hard turnBudget can also terminate a child. Neither is a safe
boundary for an active edit, write, or mutating bash command.
This package changes only the LLM-issued subagent tool-call path:
- For a possibly mutating run it removes run-level
timeoutMs,maxRuntimeMs, andturnBudgetbefore the tool executes. - It appends a checkpoint instruction to concrete writer tasks.
- It leaves limits intact only when the resolved agent is tool-restricted and cannot mutate; prompt wording alone cannot revoke an agent's tools.
- Unknown agent names fail closed: they are treated as capable of mutation.
- Agent discovery mirrors local user/project scope, configured extra user-agent directories, and nested agent directories before classifying a custom role; package-provided agent definitions are treated as unresolved and fail closed.
- It emits a durable
subagent-timeout-safetyaudit message whenever it removes a limit.
It does not patch pi-subagents files.
Install
Review the source before installing—Pi packages execute with your user account's full permissions.
Install from npm (recommended)
pi install npm:pi-subagent-timeout-safety
Update or remove the npm installation:
pi update npm:pi-subagent-timeout-safety
pi remove npm:pi-subagent-timeout-safety
For a project-local installation recorded in .pi/settings.json, add -l:
pi install -l npm:pi-subagent-timeout-safety
Use pi update npm:pi-subagent-timeout-safety to update the package; use
pi remove -l npm:pi-subagent-timeout-safety to remove that project-local installation.
Test or develop from a local checkout
pi -e /absolute/path/to/pi-subagent-timeout-safety
Install globally from a local checkout
pi install /absolute/path/to/pi-subagent-timeout-safety
Git sources remain an option when you need a specific repository revision for development or debugging:
pi install git:gitlab.com/aloneio/pi-subagent-timeout-safety
Restart Pi or run /reload after changing the source/configuration.
To remove a globally installed local checkout:
pi remove /absolute/path/to/pi-subagent-timeout-safety
Configuration
The package default is stored next to the extension entrypoint. In this source checkout, the path is:
extensions/subagent-timeout-safety/config.json
When this whole package directory is auto-discovered under
~/.pi/agent/extensions/subagent-timeout-safety/, the resulting live path is:
~/.pi/agent/extensions/subagent-timeout-safety/extensions/subagent-timeout-safety/config.json
{
"version": 1,
"enabled": true,
"allowExplicitMutationTimeout": false,
"unknownAgentMayMutate": true
}
Keep allowExplicitMutationTimeout set to false. Setting it to true
disables the protection for caller-supplied writer limits and reintroduces the
risk of a child being killed during mutation. Also leave turnBudget unset in
the pi-subagents global extension configuration: it is a downstream fallback
outside this package's interception boundary.
Use /subagent-timeout-safety in Pi to see the active policy and scan local
agent definitions for unsafe frontmatter defaults.
Operational model
For long writer work, detach the run and bound only the parent's wait:
subagent({
agent: "worker",
async: true,
task: "Implement the requested change and report checkpoints."
});
subagent_wait({ id: "run-id", all: true, timeoutMs: 1_200_000 });
subagent_wait timing out stops waiting; it does not terminate the child. Use
status, steer, interrupt, or stop when the supervising agent decides
what should happen next.
Classification
The policy is intentionally capability-based rather than prompt-trust-based. A
custom agent whose resolved declared tools are all read-only can retain caller
limits. An agent that has write, edit, bash, or another unrecognized tool
is mutation-capable even if its task says read-only or its acceptance role is
read-only: text does not remove tool permissions. Built-in pi-subagents
roles are conservatively considered mutation-capable because their shipped tool
sets include bash, write, or edit. Unknown agent names fail closed.
Important limitations
This is a supported Pi tool_call interception, not a full replacement for
pi-subagents timeout architecture.
- Covered: normal model-issued
subagent(...)calls, includingaction: "schedule"at creation time. - Not covered: direct internal invocation paths that do not execute the Pi
subagenttool—currently slash-command bridges, extension-to-extension delegation, RPCspawn, a scheduled job firing later, and an authorized fanout child. These paths must not be given writer hard limits until the upstream plugin offers a checkpoint-safe policy at its executor boundary. - Global defaults:
pi-subagentsfalls back to a configured globalturnBudgetafter this hook. Do not configure a globalturnBudgetwhile mutation-capable agents are enabled; this package cannot distinguish those downstream fallback limits. Similarly, do not set per-agent timeout or turn-budget defaults on mutation-capable roles. - Agent defaults:
pi-subagentsresolves custom-agenttimeoutMsandturnBudgetfrontmatter after Pi'stool_callhook. The command reports detected local frontmatter defaults, but package-supplied agent defaults are treated as unresolved/fail-closed. - Other termination causes remain: explicit
stop, parent/session abort, protocol-output safety limits, provider failure, OS failure, and system shutdown can still end a child.
Development and verification
npm test
npm run check
The tests use no network and do not launch an LLM. They cover policy classification, limit removal, local agent discovery/scope, package loading, child exclusion, and the extension handler's mutation of Pi's validated tool input.
Security and distribution
The package contains no credentials, provider settings, models, user agent
profiles, session state, or unrelated global extensions. package.json marks
@earendil-works/pi-coding-agent as a peer dependency, per Pi package guidance.
License
MIT. See LICENSE.