ARCH-24 governed process capability
This reference decision record implements the generic governed process capability anticipated by ARCH-23 native runtime and governed CLI tools. Tyrum's native runtime remains the only turn executor.
Quick orientation
- Read this if: you are changing
process.run, process policy, environment projection, output evidence, or child-process lifecycle handling. - Skip this if: you only need the general tool pipeline; use Tools.
- Go deeper: use ARCH-23, Sandbox and policy, Approvals, and Gateway plugins.
Decision snapshot
Public contract and exposure
process.run is the canonical public ID for the process family. It is in the environment group, has the advanced tier, and is state-changing. It accepts an executable, a direct argv array, an optional lexical workspace cwd, an explicit environment overlay, a timeout, and a per-stream output budget. On Windows, the executable must have an explicit extension: bare names are rejected to prevent PATHEXT from resolving a command script, .cmd and .bat are rejected case-insensitively, and trailing-dot or trailing-space forms are rejected conservatively.
Exposure is deliberately stricter than the advanced tier:
- local state mode only; shared state mode fails closed
- exact
tools.allowopt-in with the literalprocess.run default_mode: allow, wildcard selectors, compatibility selectors, and authoring bundles do not enable it- current execution profiles keep it disabled until a profile explicitly adds the exact ID
The existing bash tool remains a compatibility surface for shell text. It is not an alias for process.run, and process.run never shell-joins arguments. The launcher uses spawn(executable, argv, { shell: false }).
Policy and namespace integrity
bash, the legacy tool.exec alias, and process.run are one canonical shell-like policy set for untrusted_shell_requires_approval. Untrusted driving provenance can therefore raise a broad tool-domain allow decision to require_approval.
Process match targets serialize executable, argv, cwd, and a code-point-sorted explicit environment overlay in a fixed order with explicit JSON escaping. Oversized targets retain a readable prefix and a deterministic SHA-256 suffix. Malformed inputs produce no target and no suggested override. Exact generated overrides preserve argv boundaries and process identity; manually authored * patterns are still broad because wildcard matching crosses structural separators.
Plugins cannot register canonical built-in IDs or reserved platform prefixes, including process.. The loader rejects those contributions before plugin code is imported, and execution routing repeats the check so an in-memory or stale registration cannot shadow a built-in.
Environment and ambient authority
The child receives a minimal baseline containing process-startup, home, locale, and temporary-directory variables, followed by the invocation's validated explicit environment overlay. Unrelated gateway variables are not inherited.
Inheriting HOME deliberately delegates ambient authority for credentials and configuration readable by the gateway OS identity, including files under home configuration directories. This is comparable to interactive shell access for that identity; it is not per-invocation credential projection. Environment keys and values are excluded from process output, result metadata, and errors. The unresolved explicit overlay is included in the policy match target and approval audit context so an override cannot authorize a later invocation with a different execution environment; resolved secret values are never placed there.
Lifecycle and evidence
The runner captures stdout and stderr separately in bounded memory. Non-zero exit and timeout are completed results so their output remains visible. Validation and spawn failures use the tool error field.
On POSIX, the root starts as a detached process-group leader. Timeout sends SIGTERM, waits a bounded grace period, then sends SIGKILL only while the root has not emitted exit. A final hard deadline destroys local streams and settles exactly once. If the root exits before escalation, a descendant keeps stdio open, or a descendant may have escaped the group, evidence conservatively reports unconfirmed_or_escaped. On Windows, only direct-child termination is supported and evidence reports unsupported.
The executor produces one bounded, valid UTF-8 JSON object containing redacted invocation identity, workspace-relative cwd, status, timings, separate output streams, capture counters, truncation flags, and descendant-termination state. Before model injection, the runtime wraps that JSON in the standard untrusted <data source="tool"> boundary. The JSON fields are sanitized for the model while raw process evidence is retained only as secret-redacted, bounded untrusted provenance so prompt-injection detection can report neutralization. Non-sensitive process status and counters are also consumed by context reporting. The existing durable tool-call lifecycle remains the attributable record.
Exact approval-override targets include executable, argv boundaries, cwd, and the complete sorted explicit environment overlay. Changing PATH, loader/runtime options, cwd, or any other explicit environment value therefore requires a distinct approval rather than reusing an override for a different process identity.
Security boundary and explicit limitations
process.run is a governed launcher, not a hard sandbox.
- It does not provide filesystem confinement. The cwd check is lexical, and a workspace symlink may point outside the workspace.
- It does not provide network confinement.
- There is no CPU, memory, or syscall limit.
- Inheriting
HOMEexposes ambient gateway-user credentials and configuration. - Same-user child processes can access resources available to that OS identity.
- Deliberately detached descendants can escape the POSIX process group.
- Windows does not provide process-tree termination through this runner.
Process-group signalling improves timeout settlement but does not prove containment or descendant termination. Deployments needing stronger guarantees must supply OS, container, or node boundaries outside this capability.
Non-goals
- no alternate turn executor or external continuity owner
- no specialist- or vendor-specific core tool IDs, runtime adapters, or configuration branches
- no PTY, background or durable process handle, or node dispatch
- no implicit source-control, deployment, release, or publication authority
- no change to
bashor playbookCLIcompatibility behavior