---
url: >-
  https://adk.nht.io/api/@nhtio/adk/batteries/sandbox/interfaces/RunShellCommandCompletion.md
description: What one `run_shell_command` invocation actually did.
---

# Interface: RunShellCommandCompletion

Defined in: [src/batteries/sandbox/tool.ts:57](https://github.com/NHTIO/ADK/blob/v1.20261003.0/src/src/batteries/sandbox/tool.ts#L57)

What one `run_shell_command` invocation actually did.

## Remarks

The structured completion for [createRunShellCommandTool](../functions/createRunShellCommandTool.md)'s `onCompletion` callback.
Deliberately issued once per invocation, on EVERY terminal outcome — a clean exit, a non-zero
exit, a timeout, a kill, a gate/approval denial, and an enforcer throw all settle this — because
the audit seam exists precisely so a denied or killed command is not indistinguishable from a
successful one.

Field rules:

* `exitCode` is the child's real exit status, or `null` when the command never ran (a gate
  denial, a path refusal, a spawn failure) or its exit status is unknowable.
* `failed` is `true` for every outcome that is not a successful zero exit, INCLUDING denials,
  timeouts, killed children, enforcer errors, and a per-call `policy` function that failed.
  `exitCode !== 0` implies `failed`, and so do outcomes with `exitCode: null`.
* `timedOut` marks the `timeout_seconds` deadline firing (`exitCode` is then `null` or the killed
  child's status, depending on whether `completed` settled).
* `killedBy` names the signal that ACTUALLY terminated the child instead of letting it exit,
  read from the real child settlement (Node's `signalCode`), e.g. `'SIGKILL'` when the enforcer
  kills the process group on a timeout. Absent when the child exited on its own (a clean exit, a
  non-zero exit, or a timeout it won by exiting before the kill landed).
* `denied` marks a refusal BEFORE the command ran (a gate denial, a path/gate/allow-list
  refusal) — no child was spawned.
* `diagnostics` carries everything the enforcer reported (`diagnosticsFor`, the `[sandbox]
  denied: …` lines) plus, for a handler failure, the thrown value's message — including a per-call
  `policy` function that threw or rejected, which fires this completion before the error surfaces.
  Empty usually.
* `artifactRef` names the returned [SpooledArtifact](../../../spooled_artifact/classes/SpooledArtifact.md)'s correlation id — the same id the
  spool store keyed the stream under — so an audit sink can join the completion to the artifact.
  It is present whenever the run reached the enforcer, including an enforcer throw (its id still
  keys any diagnostics recorded for that run). It is absent for the very first refusals (those
  throw before any stream exists) and a throwing per-call `policy` (it fails before a stream is
  opened).

The tool's own return type is UNCHANGED: it still resolves to the artifact. This type travels
only through the callback, so existing consumers keep compiling.

## Properties

| Property                                         | Modifier   | Type                | Description                                                                                           | Defined in                                                                                                                |
| ------------------------------------------------ | ---------- | ------------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|  `artifactRef?` | `readonly` | `string`            | The spool store correlation id backing the invocation's returned artifact, when one exists.           | [src/batteries/sandbox/tool.ts:71](https://github.com/NHTIO/ADK/blob/v1.20261003.0/src/src/batteries/sandbox/tool.ts#L71) |
|  `denied?`           | `readonly` | `boolean`           | Whether the command was refused before spawning (gate denial, path refusal, allow-list).              | [src/batteries/sandbox/tool.ts:67](https://github.com/NHTIO/ADK/blob/v1.20261003.0/src/src/batteries/sandbox/tool.ts#L67) |
|  `diagnostics`  | `readonly` | readonly `string`\[] | Enforcer diagnostics (`[sandbox] denied: …` lines) and, on a handler failure, its message.            | [src/batteries/sandbox/tool.ts:69](https://github.com/NHTIO/ADK/blob/v1.20261003.0/src/src/batteries/sandbox/tool.ts#L69) |
|  `exitCode`        | `readonly` | `number` | `null`  | The child's real exit status; `null` when the command never ran or never reported one.                | [src/batteries/sandbox/tool.ts:59](https://github.com/NHTIO/ADK/blob/v1.20261003.0/src/src/batteries/sandbox/tool.ts#L59) |
|  `failed`            | `readonly` | `boolean`           | `true` for every non-success outcome, including denials, timeouts, kills, and enforcer throws.        | [src/batteries/sandbox/tool.ts:61](https://github.com/NHTIO/ADK/blob/v1.20261003.0/src/src/batteries/sandbox/tool.ts#L61) |
|  `killedBy?`       | `readonly` | `string`            | The signal that actually killed the child instead of letting it exit, when one did, e.g. `'SIGKILL'`. | [src/batteries/sandbox/tool.ts:65](https://github.com/NHTIO/ADK/blob/v1.20261003.0/src/src/batteries/sandbox/tool.ts#L65) |
|  `timedOut`        | `readonly` | `boolean`           | Whether the `timeout_seconds` deadline fired and terminated the command.                              | [src/batteries/sandbox/tool.ts:63](https://github.com/NHTIO/ADK/blob/v1.20261003.0/src/src/batteries/sandbox/tool.ts#L63) |
