Merge remote-tracking branch 'origin/master' into cross-family-fs-sandbox

# Conflicts:
#	docs/config-catalog.md
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/event-producer-consumer.md
#	docs/persistence-catalog.md
#	examples/acp-agent/cordis.yml
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl
#	examples/acp-agent/tests/snapshots/both-mode-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/permission-switching/session.jsonl
#	examples/acp-agent/tests/snapshots/skill-load/session.jsonl
#	examples/acp-agent/tests/snapshots/text-turn/session.jsonl
#	packages/bash/bash-sandbox/src/index.ts
#	packages/bash/bash/src/types.ts
#	packages/bash/tool-bash/src/index.ts
#	packages/fs/fs/src/index.ts
#	packages/sandbox/sandbox-policy/src/session-mode.ts
#	packages/ui/permission/src/index.ts
#	packages/ui/permission/tests/permission.spec.ts
#	scripts/doc-budgets.manifest.json
This commit is contained in:
kingwl
2026-07-14 21:25:36 +08:00
608 changed files with 7195 additions and 12508 deletions
@@ -1,11 +1,8 @@
/**
* SandboxBashExecutor tests: the CONSUMER side of the sandbox seam. A fake
* `ctx.sandbox` provider (injected as a real cordis service) makes wrapping,
* policy hand-off, fail-closed propagation, classification, and fact
* stamping all deterministic without any real runner; the real-provider
* integration proof lives in `tests/landlock.e2e.ts`. Denials are produced
* with plain unix permissions (a 0555 directory), which exercises the same
* stderr signature the classifier keys on.
* Consumer-side `SandboxBashExecutor` tests. A fake Cordis sandbox service makes wrapping,
* policy hand-off, fail-closed propagation, classification, and fact stamping deterministic;
* real-provider integration lives in `tests/landlock.e2e.ts`. A mode-0555 directory supplies
* the Unix denial signature used by the classifier without requiring a real sandbox runner.
*/
import { chmodSync, mkdirSync, mkdtempSync } from 'node:fs'
@@ -297,10 +294,9 @@ describe('background sandbox facts', () => {
})
it('overlapping background tasks keep their OWN wrap facts (per-task, not latest-wrap)', async () => {
// The seam returns facts PER WRAP — a legal provider may vary them
// between calls. The slow task settles AFTER the quick one started, so a
// latest-wrap field would classify its denial against the quick task's
// dialect (missing it) and stamp the wrong enforcement.
// Facts belong to each wrap and may vary between calls. The slow task settles after the
// quick task starts; a shared latest-wrap field would classify and stamp it with the wrong
// task's dialect and enforcement.
const wraps: Array<Pick<ConfinedArgv, 'enforcement' | 'denialSignatures'>> = [
{ enforcement: 'partial', denialSignatures: ['permission denied'] },
{ enforcement: 'full', denialSignatures: ['read-only file system'] },