Merge latest master into Codex subagent provider
This commit is contained in:
41
examples/acp-agent/tests/fixtures/partial-landlock-sandbox.ts
vendored
Normal file
41
examples/acp-agent/tests/fixtures/partial-landlock-sandbox.ts
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
import { join } from 'node:path'
|
||||
import type { ConfinedArgv, SandboxPolicy } from '@deepseek-ai/dsh-sandbox'
|
||||
import { SandboxProvider } from '@deepseek-ai/dsh-sandbox'
|
||||
|
||||
const NOTICE = 'landlock-run: partial enforcement (older Landlock ABI)'
|
||||
const MISSING_RUNNER_ENV = 'DSH_SNAPSHOT_MISSING_SANDBOX_RUNNER'
|
||||
|
||||
/**
|
||||
* Snapshot-only provider for deterministic runner classification. Its default
|
||||
* launch reproduces older-ABI Landlock; an explicit scenario flag selects a
|
||||
* missing executable under the valid workspace cwd. Keep the Landlock tuple
|
||||
* aligned with `RUNNER_FAILURE_RULES` in `packages/sandbox/sandbox-local/src/index.ts`.
|
||||
*/
|
||||
export default class PartialLandlockSandboxProvider extends SandboxProvider {
|
||||
confine(argv: readonly string[], policy: SandboxPolicy): ConfinedArgv {
|
||||
if (process.env[MISSING_RUNNER_ENV] === '1') {
|
||||
return {
|
||||
argv: [join(policy.workspaceRoot, '.dsh-missing-sandbox-runner'), ...argv],
|
||||
enforcement: 'full',
|
||||
denialSignatures: ['permission denied'],
|
||||
runnerFailureRules: [{ fatalSignatures: ['snapshot-runner: '] }],
|
||||
}
|
||||
}
|
||||
return {
|
||||
argv: [
|
||||
'bash',
|
||||
'-c',
|
||||
`printf '%s\\n' '${NOTICE}' >&2; exec "$@"`,
|
||||
'partial-landlock-run',
|
||||
...argv,
|
||||
],
|
||||
enforcement: 'partial',
|
||||
denialSignatures: ['permission denied'],
|
||||
runnerFailureRules: [{
|
||||
allowedExitCodes: [125],
|
||||
fatalSignatures: ['landlock-run: '],
|
||||
informationalLines: [NOTICE],
|
||||
}],
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,12 +84,16 @@ export function apply(ctx: Context): void {
|
||||
// runs, so the queued FIFO order is what the transcript records. The first
|
||||
// child enqueue is the initial delegation, which also pins the real child id.
|
||||
let accepted = 0
|
||||
ctx.on('agent/inbox/enqueue', (agent) => {
|
||||
ctx.on('agent/inbox/inserted', ({ agent }) => {
|
||||
if (agent.session.header.parentSession === undefined) return
|
||||
if (realChildId === undefined) realChildId = agent.session.header.id
|
||||
accepted += 1
|
||||
if (accepted >= 3) followupsAccepted.resolve(undefined)
|
||||
})
|
||||
ctx.on('agent/pre-step', async ({ agent }, next) => {
|
||||
if (agent.session.header.parentSession !== undefined) await followupsAccepted.promise
|
||||
return next()
|
||||
})
|
||||
|
||||
// The child's ordinary per-turn flushes succeed; only the final continuation
|
||||
// turn's durability checkpoint fails, turning that turn/end into a durable
|
||||
|
||||
Reference in New Issue
Block a user