fix(sandbox): harden the per-session record and the ACL runner failure paths (review round v6)

Durable record: bound to the owning session id and validated at the fold (orphan-SID shape, temp path inside the host temp root) — a fork's copied parent record no longer provisions the child, and a tampered record fails loud. Private temp dir: random unguessable name persisted in the record, created exclusively (pre-existing entries and reparse points fail EEXIST). Persistence: a fresh provision kicks an immediate flush (no write-behind debounce), narrowing the crash window to the flush latency — documented as the one self-healing gap. Runner-failure rules: exit-gated on 127 so a confined command that prints the signature on a non-127 exit is never misclassified. Spawn: AssignProcessToJobObject failure terminates the suspended child (no hanging orphans). SandboxExecutionPolicy.sessionId is the branded SessionId. Boundary docs: qualifying clause on the absolutist sentences, NULL-DACL Known Limitation, 'full' scoped to the supported NTFS surface, CLM gate comment.
This commit is contained in:
Huanqi Cao
2026-08-08 23:23:38 +08:00
parent 441927c526
commit 6478da61e3
27 changed files with 472 additions and 278 deletions

View File

@@ -27,11 +27,13 @@
"peerDependencies": {
"@deepseek-ai/dsh-invariants": "^0.0.1",
"@deepseek-ai/dsh-llm": "^0.0.1",
"@deepseek-ai/dsh-session": "^0.0.1",
"cordis": "^4.0.0-rc.7"
},
"devDependencies": {
"@deepseek-ai/dsh-invariants": "workspace:^",
"@deepseek-ai/dsh-llm": "workspace:^",
"@deepseek-ai/dsh-session": "workspace:^",
"cordis": "^4.0.0-rc.7"
}
}

View File

@@ -7,6 +7,7 @@
import { Context, Service } from 'cordis'
import { HarnessError } from '@deepseek-ai/dsh-llm'
import type { SessionId } from '@deepseek-ai/dsh-session'
export {
ESCALATION_TARGETS,
@@ -41,12 +42,12 @@ export interface SandboxExecutionPolicy {
/** Absolute root directory `workspace-write` may write under. */
workspaceRoot: string
/**
* Opaque identity of the calling session (the `dsh-session` SessionId in
* string form). Backends key per-session state off it (e.g. the windows-acl
* Opaque identity of the calling session (the branded `dsh-session`
* SessionId). Backends key per-session state off it (e.g. the windows-acl
* per-session write grant and private temp subdirectory); absent for
* agentless calls, which fall back to per-call backend state.
*/
sessionId?: string
sessionId?: SessionId
}
/**

View File

@@ -17,6 +17,9 @@
{
"path": "../../llm/llm"
},
{
"path": "../../core/session"
},
{
"path": "../../support/invariants"
}