Fix: the tool substituted the deployment sandbox default for the session's

dsh-bash-sandbox is the composed ctx.shell, and its resolve() stamps
`request.sandboxPolicy ?? ctx.sandboxPolicy.resolve()`. Omitting the policy
therefore does NOT mean "unconfined" -- it silently substitutes the DEPLOYMENT
default (`DSH_PERMISSION_MODE ?? 'workspace-write'`) for the session's preset.
On a host with no sandbox runner that confines a danger-full-access session and
fails with SandboxUnavailableError before slopo is ever reached, which is
exactly what happened: the tool was unusable while bash worked.

Resolve the calling session's policy the way dsh-tool-bash does, and pass it on
every call. A confining executor with no ctx.sandboxPolicy is now refused
outright rather than guessed at.

That fix exposes a second problem worth naming. Slopo's state lives under
$DSH_HOME, which is outside the workspace root a workspace-write sandbox permits
writing to, so under that preset nothing would work. The tool now refuses before
running and names both ways out -- run under danger-full-access, or set stateDir
to a directory inside the workspace -- instead of letting a write fail halfway
through an embed.

Five tests pin this: the session's policy is resolved exactly once and travels
with the session, a missing policy service is refused, state outside the sandbox
is refused before any execution, state inside it proceeds, and status/configure
never touch the shell at all.
This commit is contained in:
dsh-slopo agent committed 2026-09-22 07:12:03 +01:00
1 parent a8e577ae38
commit e758a723e2
3 files changed
+177 -4

No files matched your search

+15
View File
@@ -190,6 +190,21 @@ embedding failure — onto a message and a next step.
**`--config-version 1` is an alarm, not boilerplate.** It makes slopo fail if its
agent-facing contract has moved on, which is the signal that the skill text in
`skills/` needs re-porting from upstream.
**The sandbox can block slopo's state.** Slopo's index, config and log live
under `$DSH_HOME`, which is outside the workspace that a `workspace-write`
sandbox permits writing to. The tool detects that and refuses *before* running,
naming both ways out, rather than letting a write fail halfway through an embed:
run the session under the `danger-full-access` preset, or set `stateDir` to a
directory inside the workspace.
**What the tool does with the sandbox policy, and why it matters.** The mounted
`ctx.shell` on a confined deployment is `dsh-bash-sandbox`, whose `resolve()`
stamps `request.sandboxPolicy ?? ctx.sandboxPolicy.resolve()`. Omitting the
policy therefore does *not* mean "unconfined" — it silently substitutes the
**deployment** default (`DSH_PERMISSION_MODE ?? 'workspace-write'`), which is not
the session's preset. That is what makes a `danger-full-access` session fail with
`SandboxUnavailableError` on a host with no sandbox runner. The tool resolves the
session's policy the way `dsh-tool-bash` does and passes it per call.
## Slopo is an external process, not a library