fix(subprocess): clarify provider failures and scope polling

This commit is contained in:
pku-xht
2026-08-31 19:26:08 +08:00
parent 6d49ac2ef6
commit fc19a0a3fa
51 changed files with 232 additions and 146 deletions
+12 -10
View File
@@ -1,10 +1,11 @@
/**
* Sandbox-consuming bash executor. It wraps the exact local bash argv through
* `ctx.sandbox`, inherits local process mechanics, and reports the selected
* mode, enforcement, and denial facts. Positive runner-launch evidence means
* the command never ran: foreground calls throw `SANDBOX_UNAVAILABLE`, while
* background processes carry `runnerFailed`; other spawn rejections retain
* local-executor semantics. The tool owns approval and passes a complete per-call policy.
* mode, enforcement, and denial facts. Positive runner-executable evidence
* identifies a broken confinement runner: foreground calls throw
* `SANDBOX_UNAVAILABLE`, while background processes carry `runnerFailed`;
* other provider rejections retain stage-neutral local-executor semantics. The
* tool owns approval and passes a complete per-call policy.
* @module @deepseek-ai/dsh-bash-sandbox
*/
@@ -147,14 +148,15 @@ export class SandboxBashExecutor extends LocalBashExecutor {
* Stamp per-process sandbox facts before `done` settles. Full-access processes
* have no facts; signal deaths are not denials.
*/
protected override onProcessDone(proc: ShellProcess, stderr: string, spawnFailed: boolean, spawnError?: unknown): void {
protected override onProcessDone(proc: ShellProcess, stderr: string, providerRejected: boolean, providerError?: unknown): void {
const facts = this.processFacts.get(proc)
if (facts !== undefined) {
this.processFacts.delete(proc)
// A rejected spawn never started the confined launch. Otherwise runner
// failure outranks denial because its diagnostics may contain denial terms.
const runnerFailed = spawnFailed
? isRunnerSpawnFailure(spawnError, facts.runnerProgram, facts.workdir)
// A provider rejection exposes no public failure stage. Attribute it to
// the confinement runner only when the error independently names argv[0].
// Otherwise settled runner failure outranks denial-like diagnostics.
const runnerFailed = providerRejected
? isRunnerSpawnFailure(providerError, facts.runnerProgram, facts.workdir)
: classifyRunnerFailure(proc.exitCode, stderr, facts.runnerFailureRules) !== undefined
proc.sandbox = {
mode: facts.mode,
@@ -163,7 +165,7 @@ export class SandboxBashExecutor extends LocalBashExecutor {
...(runnerFailed ? { runnerFailed } : {}),
}
}
super.onProcessDone(proc, stderr, spawnFailed, spawnError)
super.onProcessDone(proc, stderr, providerRejected, providerError)
}
/**