Skip to content

ToolRejectScope

ToolRejectScope = "once" | "session" | "always"

Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/types.ts:399

§6 — persistence scope for a reject decision, the always reject half of the escalation menu:

  • once — refuse this single invocation; remember nothing (the default).
  • session — additionally record a deny entry for this call, in the one entry grammar, for the life of this runner instance. The matcher consults it before anything else, so the next identical call is refused without reaching a person at all.
  • always — additionally persist that entry to the project store (ToolApprovalScope’s mirror: .gsloth/.gsloth-settings/shell-denylist.json) so the refusal survives a restart. This is what every escalation menu’s always reject control sends.

The two scopes stay different types even now that they list the same three values. They are different questions with different bounds — a reject has no catastrophic clamp and no unresolvable-command exclusion, since refusing more is safe in every direction — and collapsing them would let a future value added for one side become answerable on the other by accident.

A caller may still ask for session, and the runner honours it rather than upgrading it: the lifetime that lands is reported back through the /approvals display, so a refusal held only for this session is never shown as a saved one. It is also where an always refusal lands when the project file cannot be opened. That is NOT merely “a re-prompt next session”: the refusal is held for this run only, the unreadable file is left as it is, and next session nothing in it applies — so the same call is left to the rest of the gate, which may refuse it under another rule, prompt for it, or run it without asking (bypass, or a matching saved allow). The user is told at load time; see PersistedApprovalGrants.