DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-sandbox-arg-guard

d

dsh-sandbox-arg-guard

Manifest valid

Keeps a redundant sandbox-escalation argument from failing a tool call. Escalating tools (pwsh, bash, write, edit) advertise the full sandbox_permissions enum, but DSH only accepts a level strictly wi

hasBundlePatch

dsh-sandbox-arg-guard

Keeps a redundant sandbox-escalation argument from failing a tool call.

When an escalating tool (pwsh, bash, write, edit) is rejected because the model requested a sandbox level it cannot ask for, this plugin re-issues the same call once without that argument — so the call the model actually intended just runs.

⚠️ Scope narrowed by an upstream fix (2026-09-19)

The same-level case is fixed in DSH 0.1.6-alpha.2 and no longer needs this plugin. Commit 61c548e2 (fix(sandbox): accept repeated effective permission modes, PR #4326) added if (mode === effectiveMode) return effectiveMode at packages/sandbox/sandbox/src/escalation.ts:155 — verified first-hand on master. Repeating the level already in effect is now accepted silently.

What remains, and what this plugin is for now: narrower or unsupported targets still throw at :159-160 (sandbox escalation to "…" is not strictly wider than this call's current "…" mode). The plugin still removes the argument in that case, so the call runs. The retry is safe for the same reason as before: the throw still precedes any execution.

The sections below document the original 0.1.2-rc.1 reproduction, including its same-level A/B. They are kept as an accurate record of that version rather than rewritten to look current — see EVIDENCE.md for the update note and the verified upstream lines. The narrower-target case has not yet been re-measured on 0.1.6-alpha.2.

The failure it prevents

Every escalating tool advertises the full sandbox_permissions enum, but DSH only accepts a request for a level strictly wider than the one already in effect. From packages/sandbox/sandbox/src/escalation.ts:159-164:

// Strict widening is an EXECUTION check against the call's effective mode —
// deliberately not a schema constraint (the enum is the closed target
// vocabulary; the effective mode is per-call truth).
if (!(WIDER_MODES[effectiveMode] ?? []).includes(mode as SandboxMode)) {
  throw new Error(`sandbox escalation to "${mode}" is not strictly wider than this call's current "${effectiveMode}" mode`)
}

The schema therefore cannot tell the model which values are legal for this call, and a model that reflexively passes the argument — a very common habit — picks the level it is already at. The result:

Error: sandbox escalation to "workspace-write" is not strictly wider than this call's current "workspace-write" mode

Nothing runs. The model gets an error for a call that was perfectly reasonable apart from one redundant field, and for some models that is a whole turn spent retrying. This is item 1 of the community-verified unfixed-issue list in discussion #6520 — the most-reported entry there, with eight directly related discussions and three more in the same family.

What the plugin does

Registers exactly one tools/execute waterfall listener. It calls next() exactly once and returns what it produced. Only when the settled result is that one documented rejection and the arguments actually carried an escalation field does it re-issue the identical call with sandbox_permissions and justification removed.

Why retrying is safe. escalation.ts:143-152 states the ordering:

Resolve a sandbox-escalation request BEFORE anything executes … the tool registry turns the throw into the call's isError result, and nothing has run. A non-widening request never prompts a human.

Because the rejection precedes any work, re-issuing the same call minus the redundant field cannot double-apply a side effect. The retry is also loop-free by construction: the corrected arguments no longer contain an escalation field, so they cannot match the rejection pattern again.

Why this seam and no other. tools/pre-execute and agent/pre-step are waterfall hooks that return a decision (allow / ask / deny) — neither can rewrite arguments. tools/execute is the one hook whose return value is the execution result, and ToolRuntime.execute(input) is public with a constructible input, so a listener may re-issue a corrected call.

Verified

BEFORE and AFTER on real session logs, same stub, same tool call — raw output in EVIDENCE.md:

guard absentguard installed
tool/resultError: sandbox escalation to "workspace-write" is not strictly wider …PROBE-EXECUTED
isErrortruefalse
did the command runnoyes

The session contains exactly one tool/call and one tool/result in both cases: the retry is not visible as a second call, and the command did not run twice.

Install

dsh plugin --profile web add github:apex-mochen/dsh-sandbox-arg-guard

Restart the profile afterwards.

Configuration

- id: dsh-sandbox-arg-guard
  config:
    verbose: false   # log every repair
    enabled: true    # set false to keep it installed but inert
OptionTypeDefaultMeaning
verbosebooleanfalseLog each repair on the diagnostic channel
enabledbooleantrueTurn the guard off without uninstalling

What it deliberately does not do

  • Only that one rejection. An approval refusal, a genuine permission failure, or a tool's own error is passed through untouched — see the isError check in test/smoke.mjs.
  • Never twice. A second retry is unreachable; a check asserts it.
  • Fails open. If the corrected call cannot be issued at all, DSH's original and accurate error is what the caller sees.
  • No dependencies. One implementation file, Node built-ins only. It never spawns, reads, writes, or fetches.

This is a workaround, not a core fix

The real fix belongs in DSH: either make the advertised enum relative to the effective mode, or treat a non-widening request as a no-op instead of an error. The source comment shows the current shape is deliberate, so this plugin narrows the gap in user-visible behaviour without changing core. DSH does not accept external pull requests today (CONTRIBUTING.md), so a plugin is the reachable seam.

Compatibility

  • DSH 0.1.x (peer: @deepseek-ai/cordis ^4.0.1)
  • Node.js 20+
  • Registers exactly one waterfall listener (tools/execute) and contributes no tools

License

MIT

Comments

Loading…

Similar plugins

dsh-jev-guard

Pre-execution safety valve for DSH that judges with TypeSafe Jev: it hooks tools/pre-execute and decides every bash/pwsh call by first applying offline static rules, then by asking the Jev model — the

Security & AuditTools & CapabilitiesManifest valid

★ 0

MIT

JavaScript

dsh plugin --profile web add dsh-jev-guard

Keeps one reasoning-only turn from making an entire session unusable. When a turn produces no visible text and no tool call, the assistant message is persisted empty, the gateway then rejects every la

Sessions & MessagesManifest valid

★ 0

dsh plugin --profile web add dsh-reasoning-only-guard

by tancheng33

Runtime security gate on the tool pipeline: denies calls naming hosts outside an egress allowlist, redacts credentials from results at the canonical value rather than only the rendered content, and ap

Security & AuditDevelopment & InfrastructureManifest valid

★ 1

↓ 95/wk

MIT

TypeScript

Sep 22, 2026

dsh plugin --profile web add dsh-egress-guard

by yamingmou

Recall, edit-and-resend and regenerate, plus in-conversation versioning: a timeline of every rewind, artifact rollback (git-first, snapshot fallback), a fork map of explored paths, session lineage, an

Sessions & MessagesDevelopment & InfrastructureSecurity & AuditManifest valid

★ 4

↓ 1.1k/wk

MIT

JavaScript

Sep 19, 2026

dsh plugin --profile web add dsh-retrace

Stages exact DSH tool calls without dispatch, presents complete canonical arguments in a durable Batch Review Inbox, invalidates approvals after edits or restarts, and commits only a matching SHA-256

Security & AuditManifest valid

★ 0

dsh plugin --profile web add dsh-action-outbox

by MrWeiCodes

Fine-grained permission gateway: per-category tool-call review (outside-workspace directories, commands, file read/write, subagents, repeated actions) with global & per-project allow/deny exceptions,

Security & AuditWorkflow & AutomationTools & CapabilitiesManifest valid

★ 9

↓ 881/wk

MIT

JavaScript

Sep 25, 2026

dsh plugin --profile web add @mrweicodes/dsh-permgate