resolveShellApprovalGate
resolveShellApprovalGate(
config,command):ShellApprovalGateDecision
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/config/shell-policy.ts:1577
EXT-52 — the ONE shell approval-gate policy every agent backend resolves
(GthLangChainAgent = lean/default). It decides whether the opt-in run_shell_command tool is
gated behind the per-command approval interrupt, and which status notice (if any) the backend
should surface. A backend contributes only HOW it installs the interrupt; the policy and its
user-facing copy live here so no two can drift (and so a later rename of this config surface has
one place to change).
CFG-27 — the tool is gated whenever it is enabled, at every rung including bypass. CFG-26
used to leave it UNGATED under bypass outside interactive code, which the ladder cannot
afford: §2.5 makes the declared deny list the one check bypass keeps, and a deny entry can
only fire if the call reaches GthAgentRunner.decideToolApproval — an ungated call never does.
Gating unconditionally also keeps the rung switchable mid-session (/approvals <rung>), since a
tool wired without the interrupt cannot be re-gated without rebuilding the agent.
What each rung then does is decided in decideToolApproval, not here:
• bypass — deny list, then approve without prompting or rating.
• manual/write — deny list, allow-list, else escalate to the human.
• assisted/auto — deny list, allow-list, then the rater.
This decides the SHELL’s gating only, and it is not the whole gated set. With the shell tool
disabled — or on a non-dev-tools command (chat/api/…) — nothing about the shell is gated and
nothing is announced, but at manual and write resolveGatedToolNames still gates
every bound tool the rung does not auto-grant, so an MCP call in a plain chat session is
escalated there. Read gateShell as “does the shell need the interrupt”, never as “is the
interrupt needed at all”.
Shell enablement itself is resolved through getEffectiveDevToolsConfig +
isShellToolEnabled, so the gate stays in lockstep with where GthDevToolkit actually
emits the tool; the posture comes from resolveApprovals, so this and the runner can
never disagree about which rung is in force.
Parameters
Section titled “Parameters”config
Section titled “config”Pick<GthConfig, "commands" | "builtInTools" | "approvals" | "askWriteMode"> | undefined
command
Section titled “command”GthCommand | undefined