test(snapshot): pin the parent-only override through the assembled headless app

Review fix (ds-review-bot on #623): the ACP scenario runs at deployment
strength (the automation protocol has no session-scoped switch), so the
assembled-app path could not detect the delegation bypass itself. The new
keyless subagent-inheritance headless scenario closes that on the
semantic-checkpoint precedent: a seeded parent log carrying a real
sandbox/mode: read-only switch under a workspace-write deployment default
is resumed through the Loader-booted cli-demo app via a resume fixture
plugin and delegates through the real subagent tool; the child's real
write is denied by the real dsh-fs-sandbox fence (physical ENOENT
assertion), its persisted header carries the inherited baseline, and both
logs pin as expected outputs. Verified red: disabling the driver's capture
makes the scenario fail on the disk assertion (the child writes under the
deployment default).
This commit is contained in:
kingwl
2026-07-27 12:54:54 +08:00
parent 50d759c888
commit 68d59a5414
10 changed files with 300 additions and 5 deletions
@@ -34,5 +34,5 @@ A confined child that hits the wall gets the ordinary denial marker; an escalati
- A parent's tightened sandbox mode and `'never'` approval stance now bind spawn children, fork children (regardless of seed timing), and grandchildren; the delegation bypass is closed at every depth, with no first-turn timing window (veto, injection, crash). Pinned by the real-wall suite in `packages/subagent/subagent-inprocess/tests/inheritance.spec.ts` (a scripted-model child hitting the real `dsh-fs-sandbox` fence through the real `write` tool, asserted on disk state and denial markers — including the delegation-vs-late-switch race, a veto-capable prompt-submit listener, and header durability before any child turn) and the `overrideOf` contract tests in the two service suites (baseline read, seed-boundary precedence, closed-vocabulary rejection).
- The baseline rides `SessionHeader` through both persistence backends (a JSONL header-line field; SQLite `sessions` columns with `SCHEMA_VERSION` bumped to 11 — pre-release, no migration), so resume restores it like `delegationDepth`; the child may later be switched independently, its own post-seed events outranking the baseline.
- Accepted limits: a parent switch made while a child is already running does not propagate (snapshot semantics); out-of-process backends (`subagent-acp`, subprocess children) inherit nothing here — their policy belongs to the child harness's own deployment, the sandbox Agent Note's deferred phase.
- Snapshot coverage runs at deployment strength only: the recorded `subagent-sandbox-inheritance` scenario proves a delegated child confined under a read-only DEPLOYMENT policy through the assembled ACP app, but the automation-only protocol has no session-scoped switch, so a parent-ONLY override (wider default, tightened parent, denied child) is not expressible there. When picked up, the shape is the headless suite's semantic-checkpoint precedent: seed a persisted parent log carrying a real `sandbox/mode` switch, resume it through the Loader-booted cli-demo app via a resume fixture plugin, and let it delegate — a scenario-harness addition (the headless suite has no subagent+sandbox overlay yet), not a new mechanism.
- Assembled-app snapshots pin both strengths. The recorded `subagent-sandbox-inheritance` ACP scenario proves a delegated child confined under a read-only DEPLOYMENT policy (the automation-only protocol has no session-scoped switch). The keyless `subagent-inheritance` headless scenario pins the parent-ONLY override on the semantic-checkpoint precedent: a seeded parent log carrying a real `sandbox/mode: read-only` switch under a workspace-write deployment default is resumed through the Loader-booted cli-demo app via a resume fixture plugin and delegates; the child's real write is denied by the real fence, its persisted header carries the inherited baseline, and disabling the driver's capture makes the scenario fail on the physical disk assertion — the assembled-app red/green anchor for the delegation bypass.
- `dsh-subagent-inprocess` declares `dsh-sandbox-policy` and `dsh-user-approval` as peers for the `ctx.get` typing; both remain runtime-optional. `SessionHeader` gains two neutral optional string fields; `SESSION_FORMAT_VERSION` stays 0 (additive, pre-release).