feat(bash): the sandboxed executor — per-call policy carrier, denial facts, runner-failure classification
dsh-bash grows the per-call policy carrier: BashExecRequest.sandboxMode (request-optional, spec required-but-nullable — the owner pattern; resolve() is the one explicit defaulting step) and the BashExecutor.sandboxMode capability fact (undefined in the base class — composition truth the tool layer can read). dsh-bash-local carries the field verbatim and confines nothing. dsh-bash-sandbox extends LocalBashExecutor and hands ctx.sandbox the exact argv it is about to spawn. A denial is a RESULT FACT (the command RAN; result.sandbox.denied is orthogonal to exitCode/signal), classified conservatively against the wrap own dialect; a RUNNER failure outranks denial — foreground re-throws the structured SANDBOX_UNAVAILABLE, a settled background task stamps sandbox.runnerFailed — so a broken sandbox never reads as a failing command and the command never runs unconfined. dsh-tool-bash renders the markers and teaches the model not to retry around a policy denial; escalation and per-session switching are staged follow-ups.
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import { Context, Service } from 'cordis'
|
||||
import type { SandboxMode } from '@deepseek-ai/dsh-sandbox'
|
||||
import type { BashExecRequest, BashExecSpec, BashRunResult, BashTask, BashTaskId, BashTaskListener, BashTaskRead, OwnerToken } from './types.ts'
|
||||
|
||||
export { BashTaskId, OwnerToken } from './types.ts'
|
||||
@@ -22,6 +23,7 @@ export type {
|
||||
BashExecRequest,
|
||||
BashExecSpec,
|
||||
BashRunResult,
|
||||
BashSandboxInfo,
|
||||
BashTask,
|
||||
BashTaskListener,
|
||||
BashTaskRead,
|
||||
@@ -70,6 +72,21 @@ export abstract class BashExecutor extends Service {
|
||||
}, 'bash listener teardown')
|
||||
}
|
||||
|
||||
/**
|
||||
* The sandbox mode this executor confines commands under BY DEFAULT, or
|
||||
* `undefined` when it does not sandbox at all — the capability fact the
|
||||
* tool layer reads to advertise escalation honestly (a mode-widening lever
|
||||
* is only offered when a sandboxing executor is mounted to honor it, and
|
||||
* only for modes strictly wider than this one). Composition truth, not
|
||||
* configuration: the base class reports `undefined`; a sandboxing
|
||||
* implementation overrides the getter with its configured mode.
|
||||
* @returns the configured default mode of a sandboxing executor;
|
||||
* `undefined` for an executor that never confines.
|
||||
*/
|
||||
get sandboxMode(): SandboxMode | undefined {
|
||||
return undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a caller's {@link BashExecRequest} into a fully-specified
|
||||
* {@link BashExecSpec}, applying this implementation's config defaults and
|
||||
|
||||
Reference in New Issue
Block a user