@bjoernrochel/sevro 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +34 -4
- package/README.md +7 -6
- package/dist/examples/basic/graded.json +13 -0
- package/dist/examples/basic/host.js +9 -0
- package/dist/examples/basic/host.js.map +1 -0
- package/dist/examples/basic/prompt-only.json +7 -0
- package/dist/examples/recipes/candidate.js +23 -0
- package/dist/examples/recipes/candidate.js.map +1 -0
- package/dist/examples/recipes/cases/coding-change.json +21 -0
- package/dist/examples/recipes/cases/host-tools.json +21 -0
- package/dist/examples/recipes/cases/mise.json +21 -0
- package/dist/examples/recipes/cases/node.json +21 -0
- package/dist/examples/recipes/cases/python-uv.json +21 -0
- package/dist/examples/recipes/cases/semantic.json +17 -0
- package/dist/examples/recipes/coding-change/check.js +16 -0
- package/dist/examples/recipes/coding-change/check.js.map +1 -0
- package/dist/examples/recipes/executable.js +20 -0
- package/dist/examples/recipes/executable.js.map +1 -0
- package/dist/examples/recipes/extension-artifacts.js +56 -0
- package/dist/examples/recipes/extension-artifacts.js.map +1 -0
- package/dist/examples/recipes/extension-methods.js +167 -0
- package/dist/examples/recipes/extension-methods.js.map +1 -0
- package/dist/examples/recipes/extension.js +28 -0
- package/dist/examples/recipes/extension.js.map +1 -0
- package/dist/examples/recipes/modules.js +9 -0
- package/dist/examples/recipes/modules.js.map +1 -0
- package/dist/examples/recipes/repository-skill/.agents/skills/startup-guide/SKILL.md +7 -0
- package/dist/examples/recipes/repository-skill/.claude/skills/startup-guide/SKILL.md +7 -0
- package/dist/examples/recipes/repository-skill/README.md +3 -0
- package/dist/examples/recipes/run-inputs.js +144 -0
- package/dist/examples/recipes/run-inputs.js.map +1 -0
- package/dist/examples/recipes/run-options.js +103 -0
- package/dist/examples/recipes/run-options.js.map +1 -0
- package/dist/examples/recipes/run.js +62 -0
- package/dist/examples/recipes/run.js.map +1 -0
- package/dist/examples/recipes/runtime/empty.json +1 -0
- package/dist/examples/recipes/runtime/goals.json +1 -0
- package/dist/examples/recipes/runtime/mise.json +6 -0
- package/dist/examples/recipes/runtime/path.json +1 -0
- package/dist/examples/recipes/runtime/plugins.json +4 -0
- package/dist/examples/recipes/runtime/python-uv.json +10 -0
- package/dist/examples/recipes/semantic-judge.js +27 -0
- package/dist/examples/recipes/semantic-judge.js.map +1 -0
- package/dist/examples/templates/coding/adapter.js +14 -0
- package/dist/examples/templates/coding/adapter.js.map +1 -0
- package/dist/examples/templates/coding/case.json +15 -0
- package/dist/examples/templates/repository-skill/.agents/skills/startup-guide/SKILL.md +6 -0
- package/dist/examples/templates/repository-skill/extension-data.js +61 -0
- package/dist/examples/templates/repository-skill/extension-data.js.map +1 -0
- package/dist/examples/templates/repository-skill/extension.js +29 -0
- package/dist/examples/templates/repository-skill/extension.js.map +1 -0
- package/dist/examples/templates/response/adapter.js +13 -0
- package/dist/examples/templates/response/adapter.js.map +1 -0
- package/dist/examples/templates/response/case.json +13 -0
- package/dist/src/advisory.js +86 -0
- package/dist/src/advisory.js.map +1 -0
- package/dist/src/candidate-artifacts.js +139 -0
- package/dist/src/candidate-artifacts.js.map +1 -0
- package/dist/src/candidate-codex-state.js +110 -0
- package/dist/src/candidate-codex-state.js.map +1 -0
- package/dist/src/case-validation.js +92 -0
- package/dist/src/case-validation.js.map +1 -0
- package/dist/src/cli/cancellation.js +21 -0
- package/dist/src/cli/cancellation.js.map +1 -0
- package/dist/src/cli/command.js +60 -0
- package/dist/src/cli/command.js.map +1 -0
- package/dist/src/cli/completion.js +14 -0
- package/dist/src/cli/completion.js.map +1 -0
- package/dist/src/cli/demo.js +45 -0
- package/dist/src/cli/demo.js.map +1 -0
- package/dist/src/cli/evaluation.js +40 -0
- package/dist/src/cli/evaluation.js.map +1 -0
- package/dist/src/cli/extension.js +54 -0
- package/dist/src/cli/extension.js.map +1 -0
- package/dist/src/cli/help.js +190 -0
- package/dist/src/cli/help.js.map +1 -0
- package/dist/src/cli/hosts.js +33 -0
- package/dist/src/cli/hosts.js.map +1 -0
- package/dist/src/cli/init-settings.js +29 -0
- package/dist/src/cli/init-settings.js.map +1 -0
- package/dist/src/cli/init.js +82 -0
- package/dist/src/cli/init.js.map +1 -0
- package/dist/src/cli/invocation.js +431 -0
- package/dist/src/cli/invocation.js.map +1 -0
- package/dist/src/cli/loading.js +110 -0
- package/dist/src/cli/loading.js.map +1 -0
- package/dist/src/cli/preparation.js +88 -0
- package/dist/src/cli/preparation.js.map +1 -0
- package/dist/src/cli/presentation.js +61 -0
- package/dist/src/cli/presentation.js.map +1 -0
- package/dist/src/cli/progress.js +5 -0
- package/dist/src/cli/progress.js.map +1 -0
- package/dist/src/cli/run-manifest.js +108 -0
- package/dist/src/cli/run-manifest.js.map +1 -0
- package/dist/src/cli/run-options.js +367 -0
- package/dist/src/cli/run-options.js.map +1 -0
- package/dist/src/cli/run-overrides.js +51 -0
- package/dist/src/cli/run-overrides.js.map +1 -0
- package/dist/src/cli/settings.js +127 -0
- package/dist/src/cli/settings.js.map +1 -0
- package/dist/src/cli/summary.js +28 -0
- package/dist/src/cli/summary.js.map +1 -0
- package/dist/src/cli.js +20 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/contract-types.js +2 -0
- package/dist/src/contract-types.js.map +1 -0
- package/dist/src/engine.js +4 -0
- package/dist/src/engine.js.map +1 -0
- package/dist/src/evaluation/advisory.js +85 -0
- package/dist/src/evaluation/advisory.js.map +1 -0
- package/dist/src/evaluation/check-plan.js +292 -0
- package/dist/src/evaluation/check-plan.js.map +1 -0
- package/dist/src/evaluation/collection.js +61 -0
- package/dist/src/evaluation/collection.js.map +1 -0
- package/dist/src/evaluation/context.js +2 -0
- package/dist/src/evaluation/context.js.map +1 -0
- package/dist/src/evaluation/grading-host.js +28 -0
- package/dist/src/evaluation/grading-host.js.map +1 -0
- package/dist/src/evaluation/grading.js +154 -0
- package/dist/src/evaluation/grading.js.map +1 -0
- package/dist/src/evaluation/invocation-plan.js +312 -0
- package/dist/src/evaluation/invocation-plan.js.map +1 -0
- package/dist/src/evaluation/plan.js +376 -0
- package/dist/src/evaluation/plan.js.map +1 -0
- package/dist/src/evaluation/progress.js +14 -0
- package/dist/src/evaluation/progress.js.map +1 -0
- package/dist/src/evaluation/resources.js +159 -0
- package/dist/src/evaluation/resources.js.map +1 -0
- package/dist/src/evaluation/run.js +148 -0
- package/dist/src/evaluation/run.js.map +1 -0
- package/dist/src/evaluation/scheduler.js +27 -0
- package/dist/src/evaluation/scheduler.js.map +1 -0
- package/dist/src/evaluation/semantic.js +183 -0
- package/dist/src/evaluation/semantic.js.map +1 -0
- package/dist/src/evaluation/trial.js +593 -0
- package/dist/src/evaluation/trial.js.map +1 -0
- package/dist/src/evaluation/types.js +20 -0
- package/dist/src/evaluation/types.js.map +1 -0
- package/dist/src/evidence/host-results.js +67 -0
- package/dist/src/evidence/host-results.js.map +1 -0
- package/dist/src/evidence/retained-artifacts.js +17 -0
- package/dist/src/evidence/retained-artifacts.js.map +1 -0
- package/dist/src/evidence/trial-writer.js +131 -0
- package/dist/src/evidence/trial-writer.js.map +1 -0
- package/dist/src/evidence/usage.js +14 -0
- package/dist/src/evidence/usage.js.map +1 -0
- package/dist/src/executable.js +20 -0
- package/dist/src/executable.js.map +1 -0
- package/dist/src/extension-client.js +212 -0
- package/dist/src/extension-client.js.map +1 -0
- package/dist/src/extension-session.js +236 -0
- package/dist/src/extension-session.js.map +1 -0
- package/dist/src/fixtures/advisory.js +206 -0
- package/dist/src/fixtures/advisory.js.map +1 -0
- package/dist/src/fixtures/bin.js +41 -0
- package/dist/src/fixtures/bin.js.map +1 -0
- package/dist/src/fixtures/cleanup.js +43 -0
- package/dist/src/fixtures/cleanup.js.map +1 -0
- package/dist/src/fixtures/create.js +94 -0
- package/dist/src/fixtures/create.js.map +1 -0
- package/dist/src/fixtures/generated.js +181 -0
- package/dist/src/fixtures/generated.js.map +1 -0
- package/dist/src/fixtures/git-hooks.js +16 -0
- package/dist/src/fixtures/git-hooks.js.map +1 -0
- package/dist/src/fixtures/preparation.js +201 -0
- package/dist/src/fixtures/preparation.js.map +1 -0
- package/dist/src/fixtures/repository.js +255 -0
- package/dist/src/fixtures/repository.js.map +1 -0
- package/dist/src/fixtures/setup.js +175 -0
- package/dist/src/fixtures/setup.js.map +1 -0
- package/dist/src/fixtures/tools.js +57 -0
- package/dist/src/fixtures/tools.js.map +1 -0
- package/dist/src/fixtures/workspace-state.js +155 -0
- package/dist/src/fixtures/workspace-state.js.map +1 -0
- package/dist/src/generated/cli-result.cjs +2 -0
- package/dist/src/generated/extension.cjs +2 -0
- package/dist/src/generated/report.cjs +2 -0
- package/dist/src/generated/run-evidence.cjs +2 -0
- package/dist/src/generated/runtime.cjs +2 -0
- package/dist/src/git.js +72 -0
- package/dist/src/git.js.map +1 -0
- package/dist/src/graders/artifact.js +68 -0
- package/dist/src/graders/artifact.js.map +1 -0
- package/dist/src/graders/git-head.js +112 -0
- package/dist/src/graders/git-head.js.map +1 -0
- package/dist/src/graders/output.js +345 -0
- package/dist/src/graders/output.js.map +1 -0
- package/dist/src/graders/semantic.js +132 -0
- package/dist/src/graders/semantic.js.map +1 -0
- package/dist/src/graders/shell.js +321 -0
- package/dist/src/graders/shell.js.map +1 -0
- package/dist/src/host-diagnostic-redaction.js +52 -0
- package/dist/src/host-diagnostic-redaction.js.map +1 -0
- package/dist/src/host-diagnostics.js +248 -0
- package/dist/src/host-diagnostics.js.map +1 -0
- package/dist/src/hosts/claude-continuation.js +89 -0
- package/dist/src/hosts/claude-continuation.js.map +1 -0
- package/dist/src/hosts/claude-credential.js +121 -0
- package/dist/src/hosts/claude-credential.js.map +1 -0
- package/dist/src/hosts/claude-events.js +136 -0
- package/dist/src/hosts/claude-events.js.map +1 -0
- package/dist/src/hosts/claude-keychain.js +100 -0
- package/dist/src/hosts/claude-keychain.js.map +1 -0
- package/dist/src/hosts/claude-login-recovery.js +67 -0
- package/dist/src/hosts/claude-login-recovery.js.map +1 -0
- package/dist/src/hosts/claude-login-refresh.js +146 -0
- package/dist/src/hosts/claude-login-refresh.js.map +1 -0
- package/dist/src/hosts/claude-login-store.js +124 -0
- package/dist/src/hosts/claude-login-store.js.map +1 -0
- package/dist/src/hosts/claude-login.js +74 -0
- package/dist/src/hosts/claude-login.js.map +1 -0
- package/dist/src/hosts/claude-native-goal.js +138 -0
- package/dist/src/hosts/claude-native-goal.js.map +1 -0
- package/dist/src/hosts/claude-process.js +10 -0
- package/dist/src/hosts/claude-process.js.map +1 -0
- package/dist/src/hosts/claude-refresh-lock.js +76 -0
- package/dist/src/hosts/claude-refresh-lock.js.map +1 -0
- package/dist/src/hosts/claude-repository-invocation.js +229 -0
- package/dist/src/hosts/claude-repository-invocation.js.map +1 -0
- package/dist/src/hosts/claude-settings.js +156 -0
- package/dist/src/hosts/claude-settings.js.map +1 -0
- package/dist/src/hosts/claude-skill-activations.js +131 -0
- package/dist/src/hosts/claude-skill-activations.js.map +1 -0
- package/dist/src/hosts/claude-state.js +237 -0
- package/dist/src/hosts/claude-state.js.map +1 -0
- package/dist/src/hosts/claude-tool-calls.js +150 -0
- package/dist/src/hosts/claude-tool-calls.js.map +1 -0
- package/dist/src/hosts/claude.js +373 -0
- package/dist/src/hosts/claude.js.map +1 -0
- package/dist/src/hosts/codex-app-server.js +764 -0
- package/dist/src/hosts/codex-app-server.js.map +1 -0
- package/dist/src/hosts/codex-configuration.js +91 -0
- package/dist/src/hosts/codex-configuration.js.map +1 -0
- package/dist/src/hosts/codex-events.js +104 -0
- package/dist/src/hosts/codex-events.js.map +1 -0
- package/dist/src/hosts/codex-exec-controls.js +434 -0
- package/dist/src/hosts/codex-exec-controls.js.map +1 -0
- package/dist/src/hosts/codex-invocation.js +54 -0
- package/dist/src/hosts/codex-invocation.js.map +1 -0
- package/dist/src/hosts/codex-marketplace.js +185 -0
- package/dist/src/hosts/codex-marketplace.js.map +1 -0
- package/dist/src/hosts/codex-native-calls.js +516 -0
- package/dist/src/hosts/codex-native-calls.js.map +1 -0
- package/dist/src/hosts/codex-process.js +10 -0
- package/dist/src/hosts/codex-process.js.map +1 -0
- package/dist/src/hosts/codex-profile.js +206 -0
- package/dist/src/hosts/codex-profile.js.map +1 -0
- package/dist/src/hosts/codex-session-files.js +89 -0
- package/dist/src/hosts/codex-session-files.js.map +1 -0
- package/dist/src/hosts/codex-state.js +310 -0
- package/dist/src/hosts/codex-state.js.map +1 -0
- package/dist/src/hosts/codex.js +527 -0
- package/dist/src/hosts/codex.js.map +1 -0
- package/dist/src/hosts/isolation-common.js +43 -0
- package/dist/src/hosts/isolation-common.js.map +1 -0
- package/dist/src/hosts/isolation-roots.js +64 -0
- package/dist/src/hosts/isolation-roots.js.map +1 -0
- package/dist/src/hosts/isolation.js +12 -0
- package/dist/src/hosts/isolation.js.map +1 -0
- package/dist/src/hosts/linux-sandbox.js +127 -0
- package/dist/src/hosts/linux-sandbox.js.map +1 -0
- package/dist/src/hosts/mac-sandbox.js +137 -0
- package/dist/src/hosts/mac-sandbox.js.map +1 -0
- package/dist/src/hosts/native-controls.js +151 -0
- package/dist/src/hosts/native-controls.js.map +1 -0
- package/dist/src/hosts/native-request.js +33 -0
- package/dist/src/hosts/native-request.js.map +1 -0
- package/dist/src/hosts/process-lifecycle.js +167 -0
- package/dist/src/hosts/process-lifecycle.js.map +1 -0
- package/dist/src/hosts/protected-worktrees.js +81 -0
- package/dist/src/hosts/protected-worktrees.js.map +1 -0
- package/dist/src/hosts/skill-hook-catalog.js +100 -0
- package/dist/src/hosts/skill-hook-catalog.js.map +1 -0
- package/dist/src/hosts/skill-hook-handler.js +228 -0
- package/dist/src/hosts/skill-hook-handler.js.map +1 -0
- package/dist/src/hosts/skill-hooks.js +423 -0
- package/dist/src/hosts/skill-hooks.js.map +1 -0
- package/dist/src/hosts/workspace-fingerprint.js +72 -0
- package/dist/src/hosts/workspace-fingerprint.js.map +1 -0
- package/dist/src/identity.js +167 -0
- package/dist/src/identity.js.map +1 -0
- package/dist/src/instrumentation.js +83 -0
- package/dist/src/instrumentation.js.map +1 -0
- package/dist/src/native-transcript-state.js +85 -0
- package/dist/src/native-transcript-state.js.map +1 -0
- package/dist/src/native-transcript-view.js +65 -0
- package/dist/src/native-transcript-view.js.map +1 -0
- package/dist/src/native-transcripts.js +208 -0
- package/dist/src/native-transcripts.js.map +1 -0
- package/dist/src/paths.js +13 -0
- package/dist/src/paths.js.map +1 -0
- package/dist/src/process-lifecycle.js +101 -0
- package/dist/src/process-lifecycle.js.map +1 -0
- package/dist/src/provenance.js +263 -0
- package/dist/src/provenance.js.map +1 -0
- package/dist/src/prune.js +228 -0
- package/dist/src/prune.js.map +1 -0
- package/dist/src/report.js +276 -0
- package/dist/src/report.js.map +1 -0
- package/dist/src/resolved-case.js +29 -0
- package/dist/src/resolved-case.js.map +1 -0
- package/dist/src/results-lock.js +40 -0
- package/dist/src/results-lock.js.map +1 -0
- package/dist/src/results.js +127 -0
- package/dist/src/results.js.map +1 -0
- package/dist/src/run-owner.js +283 -0
- package/dist/src/run-owner.js.map +1 -0
- package/dist/src/runner-paths.js +11 -0
- package/dist/src/runner-paths.js.map +1 -0
- package/dist/src/runtime/config.js +323 -0
- package/dist/src/runtime/config.js.map +1 -0
- package/dist/src/runtime/discovery-apple.js +65 -0
- package/dist/src/runtime/discovery-apple.js.map +1 -0
- package/dist/src/runtime/discovery-providers.js +37 -0
- package/dist/src/runtime/discovery-providers.js.map +1 -0
- package/dist/src/runtime/discovery.js +40 -0
- package/dist/src/runtime/discovery.js.map +1 -0
- package/dist/src/runtime/hook-processes.js +81 -0
- package/dist/src/runtime/hook-processes.js.map +1 -0
- package/dist/src/runtime/hooks.js +304 -0
- package/dist/src/runtime/hooks.js.map +1 -0
- package/dist/src/runtime/paths.js +244 -0
- package/dist/src/runtime/paths.js.map +1 -0
- package/dist/src/runtime/query.js +76 -0
- package/dist/src/runtime/query.js.map +1 -0
- package/dist/src/runtime/seeds.js +98 -0
- package/dist/src/runtime/seeds.js.map +1 -0
- package/dist/src/runtime/shared-cache.js +81 -0
- package/dist/src/runtime/shared-cache.js.map +1 -0
- package/dist/src/runtime/state.js +106 -0
- package/dist/src/runtime/state.js.map +1 -0
- package/dist/src/runtime-process.js +148 -0
- package/dist/src/runtime-process.js.map +1 -0
- package/dist/src/schema-types.js +2 -0
- package/dist/src/schema-types.js.map +1 -0
- package/dist/src/schema.js +16 -0
- package/dist/src/schema.js.map +1 -0
- package/dist/src/shell.js +5 -0
- package/dist/src/shell.js.map +1 -0
- package/dist/src/sqlite-lock.js +18 -0
- package/dist/src/sqlite-lock.js.map +1 -0
- package/dist/src/storage.js +21 -0
- package/dist/src/storage.js.map +1 -0
- package/dist/src/transcript-retention.js +109 -0
- package/dist/src/transcript-retention.js.map +1 -0
- package/dist/src/value-guards.js +26 -0
- package/dist/src/value-guards.js.map +1 -0
- package/docs/architecture.md +5 -2
- package/docs/creating-cases.md +2 -3
- package/docs/development-cli.md +12 -7
- package/docs/documentation-quality.md +4 -3
- package/docs/evaluation-workflow.md +8 -8
- package/docs/getting-started.md +7 -6
- package/docs/guide-evaluation.md +1 -1
- package/docs/identity-v1.md +4 -1
- package/docs/installing.md +31 -13
- package/docs/licensing.md +2 -2
- package/docs/native-hosts.md +1 -1
- package/docs/recipes.md +41 -40
- package/docs/releases.md +20 -4
- package/docs/run-settings-v1.md +3 -3
- package/docs/specs/repository-guide.md +1 -1
- package/docs/troubleshooting.md +1 -1
- package/docs/typescript-quality.md +18 -1
- package/examples/recipes/executable.ts +19 -0
- package/examples/recipes/extension-artifacts.ts +1 -1
- package/examples/recipes/extension.ts +2 -1
- package/examples/recipes/modules.ts +9 -0
- package/examples/recipes/run-inputs.ts +14 -19
- package/examples/recipes/run-options.ts +9 -8
- package/examples/recipes/run.ts +21 -7
- package/examples/templates/repository-skill/extension-data.ts +1 -1
- package/examples/templates/repository-skill/extension.ts +2 -1
- package/package.json +14 -6
- package/src/cli/demo.ts +3 -2
- package/src/cli/help.ts +4 -3
- package/src/cli/init-settings.ts +5 -4
- package/src/cli/init.ts +9 -8
- package/src/cli/invocation.ts +2 -1
- package/src/cli/preparation.ts +2 -2
- package/src/cli.ts +1 -1
- package/src/executable.ts +19 -0
- package/src/extension-client.ts +6 -12
- package/src/fixtures/setup.ts +3 -2
- package/src/git.ts +2 -1
- package/src/graders/git-head.ts +3 -2
- package/src/graders/shell.ts +4 -3
- package/src/hosts/claude-keychain.ts +3 -2
- package/src/hosts/claude-login-refresh.ts +3 -2
- package/src/hosts/claude-refresh-lock.ts +2 -1
- package/src/hosts/isolation-roots.ts +3 -2
- package/src/hosts/process-lifecycle.ts +4 -6
- package/src/hosts/protected-worktrees.ts +2 -1
- package/src/hosts/skill-hook-handler.ts +1 -1
- package/src/hosts/skill-hooks.ts +10 -2
- package/src/provenance.ts +7 -6
- package/src/results-lock.ts +4 -4
- package/src/run-owner.ts +15 -9
- package/src/runner-paths.ts +21 -0
- package/src/runtime/hook-processes.ts +2 -1
- package/src/runtime/hooks.ts +9 -7
- package/src/runtime-process.ts +194 -0
- package/src/sqlite-lock.ts +25 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["codex.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { candidateCodexStateRetained } from \"../candidate-codex-state\";\nimport { lstat, mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { isAbsolute, join } from \"node:path\";\nimport type { HostAdapter, HostResult } from \"../engine\";\nimport { allocateNativeState } from \"../native-transcript-state\";\nimport {\n failedNativeTranscripts,\n retainEnabledNativeTranscripts,\n} from \"../native-transcripts\";\nimport { runtimeNativeGoalEnabled } from \"../runtime/config\";\nimport {\n releaseRuntimeHooks,\n runtimeHookObservation,\n type HookMounts,\n} from \"../runtime/hooks\";\nimport { runtimeObservations } from \"../runtime/state\";\nimport { validateNativeHostRequest, validHostTimeout } from \"./native-request\";\nimport { runCodexAppServer } from \"./codex-app-server\";\nimport { summarizeCodexEvents, type CodexEventSummary } from \"./codex-events\";\nimport { verifyCodexInvocation } from \"./codex-invocation\";\nimport { installCodexPlugins } from \"./codex-marketplace\";\nimport {\n codexNativeCallObservation,\n codexNativeSessionLastOrdinal,\n} from \"./codex-native-calls\";\nimport { runCodexProcess, CodexProcessFailure } from \"./codex-process\";\nimport {\n codexHookMounts,\n prepareCodexState,\n type CodexHostOptions,\n} from \"./codex-state\";\nimport { codexNativeControls } from \"./native-controls\";\nimport { workspaceFingerprint } from \"./workspace-fingerprint\";\nimport { codexSkillCatalogRoots } from \"./skill-hook-catalog\";\nimport {\n prepareSkillTracking,\n skillTrackingObservation,\n skillActivationClaims,\n skillExposureClaims,\n type SkillTracking,\n} from \"./skill-hooks\";\nimport {\n cleanupNativeState,\n createHostDiagnostics,\n diagnoseHostRequest,\n diagnosticConfiguration,\n type HostDiagnostics,\n} from \"../host-diagnostics\";\nexport type { CodexHostOptions } from \"./codex-state\";\nconst DEFAULT_TIMEOUT_MS = 10 * 60_000;\n\ntype Request = Parameters<HostAdapter[\"run\"]>[0];\ntype ProcessResult = Pick<\n Awaited<ReturnType<typeof runCodexProcess>>,\n \"code\" | \"out\"\n>;\ntype AppServerResult = Awaited<ReturnType<typeof runCodexAppServer>>;\ntype Observation = {\n id: string;\n completeness: \"complete\" | \"partial\";\n data: Record<string, unknown>;\n};\ntype CodexState = Awaited<ReturnType<typeof prepareCodexState>>;\ninterface ExecutionContext {\n options: CodexHostOptions;\n request: Request;\n state: CodexState;\n timeoutMs: number;\n hooks: HookMounts;\n skillTracking: SkillTracking;\n diagnostics: HostDiagnostics;\n}\ninterface TurnResult {\n execution: ProcessResult;\n summary: CodexEventSummary;\n followUp: ProcessResult | null;\n followUpSummary: CodexEventSummary | null;\n appServer: AppServerResult | null;\n continuation: Observation | undefined;\n}\n\nfunction validCodexPaths(options: CodexHostOptions): boolean {\n return (\n [\n options.binary,\n options.authFile,\n options.projectRoot,\n options.resultsRoot,\n ...options.additionalProtectedRoots,\n ].every(isAbsolute) &&\n (options.sandboxBinary === undefined || isAbsolute(options.sandboxBinary))\n );\n}\nfunction validConcurrencyLimit(limit: number | null): boolean {\n return limit === null || (Number.isSafeInteger(limit) && limit >= 1);\n}\nfunction validEntrypoint(entrypoint: CodexHostOptions[\"entrypoint\"]): boolean {\n return (\n entrypoint === undefined || [\"exec\", \"app-server\"].includes(entrypoint)\n );\n}\n\nfunction validCodexIdentity(\n options: CodexHostOptions,\n limit: number | null,\n timeoutMs: number,\n): boolean {\n return (\n !!options.model &&\n !!options.effort &&\n validEntrypoint(options.entrypoint) &&\n validConcurrencyLimit(limit) &&\n validHostTimeout(timeoutMs)\n );\n}\nfunction codexCapabilities(\n entrypoint: CodexHostOptions[\"entrypoint\"],\n): string[] {\n return [\n \"sevro.host.continuation\",\n \"sevro.host.runtime\",\n \"sevro.host.native-transcripts\",\n \"sevro.host.hooks\",\n \"sevro.host.skill-activations\",\n \"sevro.host.skill-activation-claims\",\n \"sevro.host.skill-exposure-claims\",\n ...(entrypoint === \"app-server\" ? [\"sevro.host.native-goal\"] : []),\n \"sevro.codex.plugin-marketplace\",\n \"sevro.codex.explicit-invocation\",\n \"sevro.codex.repository-invocation\",\n \"sevro.codex.native-calls\",\n \"sevro.host.native-controls\",\n ];\n}\nfunction codexConfiguration(\n limit: number | null,\n entrypoint: CodexHostOptions[\"entrypoint\"],\n retainDiagnostics?: boolean,\n) {\n return {\n ...diagnosticConfiguration(retainDiagnostics),\n \"sevro.codex.agent-concurrency-limit\": limit,\n ...(entrypoint === \"app-server\"\n ? { \"sevro.codex.entrypoint\": \"app-server\" }\n : {}),\n };\n}\n\n/** Construct one Codex route without inheriting user settings or credentials. */\nexport function createCodexHost(options: CodexHostOptions): HostAdapter {\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const limit = options.agentConcurrencyLimit ?? null;\n if (\n !validCodexPaths(options) ||\n !validCodexIdentity(options, limit, timeoutMs)\n )\n throw new Error(\"invalid Codex host configuration\");\n return {\n id: \"sevro.host.codex\",\n hostCapabilities: codexCapabilities(options.entrypoint),\n model: options.model,\n effort: options.effort,\n configuration: codexConfiguration(\n limit,\n options.entrypoint,\n options.retainHostDiagnostics,\n ),\n run(request) {\n return runCodexRequest(options, timeoutMs, limit, request);\n },\n };\n}\n\nfunction allocateCodexRequestState(request: Request): Promise<string> {\n return allocateNativeState(\n \"codex-\",\n request.runtimePolicy ? request.workspace : undefined,\n );\n}\n\nasync function runCodexRequest(\n options: CodexHostOptions,\n timeoutMs: number,\n limit: number | null,\n request: Request,\n): Promise<HostResult> {\n const diagnostics = createHostDiagnostics(\n \"codex\",\n options.retainHostDiagnostics,\n request,\n );\n return diagnoseHostRequest(diagnostics, async () => {\n diagnostics.stage = \"request-validation\";\n await diagnostics.readCredentials(options.authFile);\n return executeCodexRequest(options, timeoutMs, limit, request, diagnostics);\n });\n}\n\nasync function executeCodexRequest(\n options: CodexHostOptions,\n timeoutMs: number,\n limit: number | null,\n request: Request,\n diagnostics: HostDiagnostics,\n): Promise<HostResult> {\n await validateCodexRequest(options, request);\n diagnostics.stage = \"state-allocation\";\n const stateRoot = await allocateCodexRequestState(request);\n const helperRoot =\n process.platform === \"linux\"\n ? await mkdtemp(join(tmpdir(), \"sevro-codex-helper-\"))\n : undefined;\n let activeHooks: HookMounts | undefined;\n try {\n diagnostics.stage = \"state-preparation\";\n const state = await prepareCodexState(\n stateRoot,\n options,\n limit,\n request,\n helperRoot,\n );\n const installedPluginRoots = await installCodexPlugins({\n binary: options.binary,\n env: state.env,\n pluginCacheRoot: state.pluginCacheRoot,\n request,\n diagnostics,\n });\n diagnostics.stage = \"hooks-preparation\";\n const hooks = await codexHookMounts(request, state, installedPluginRoots);\n activeHooks = hooks;\n const skillTracking = await prepareCodexSkillTracking(\n state,\n request,\n installedPluginRoots,\n );\n await codexPreflight(options, request, state, diagnostics);\n const context: ExecutionContext = {\n options,\n request,\n state,\n timeoutMs,\n hooks,\n skillTracking,\n diagnostics,\n };\n const turns = await new CodexTurnExecution(context).run();\n if (turns.summary.complete) diagnostics.stage = \"result-processing\";\n return await retainCodexResult(context, turns);\n } catch (cause) {\n return await failedNativeTranscripts(\n cause,\n request.runtimePolicy,\n join(stateRoot, \"codex-home\", \"sessions\"),\n \"codex\",\n request.runtimeRole,\n diagnostics,\n );\n } finally {\n await cleanupNativeState(diagnostics, async () => {\n await releaseRuntimeHooks(activeHooks);\n if (!candidateCodexStateRetained(request.candidateRuntimeRoot, stateRoot))\n await rm(stateRoot, { recursive: true, force: true });\n if (helperRoot) await rm(helperRoot, { recursive: true, force: true });\n });\n }\n}\n\nasync function retainCodexResult(context: ExecutionContext, turns: TurnResult) {\n const result = await codexHostResult(context, turns);\n await context.diagnostics.retainFailure(\n result,\n \"Codex host execution did not complete\",\n );\n await retainEnabledNativeTranscripts(\n result,\n context.request.runtimePolicy,\n join(context.state.codexHome, \"sessions\"),\n \"codex\",\n context.request.runtimeRole,\n turns.summary.threadId,\n );\n return result;\n}\n\nasync function prepareCodexSkillTracking(\n state: CodexState,\n request: Request,\n pluginRoots: string[],\n): Promise<SkillTracking> {\n const roots = await codexSkillCatalogRoots(request.workspace, pluginRoots, [\n { directory: join(state.codexHome, \"skills\"), boundary: state.codexHome },\n {\n directory: join(state.parentHome, \".agents/skills\"),\n boundary: state.parentHome,\n },\n {\n directory: join(state.commandHome, \".agents/skills\"),\n boundary: state.commandHome,\n },\n {\n directory: join(state.commandHome, \".codex/skills\"),\n boundary: state.commandHome,\n },\n ]);\n const tracking = await prepareSkillTracking({\n privateRoot: state.codexHome,\n host: \"codex\",\n roots,\n });\n await writeFile(\n join(state.codexHome, \"hooks.json\"),\n JSON.stringify({ hooks: tracking.hooks }),\n {\n flag: \"wx\",\n mode: 0o600,\n },\n );\n return tracking;\n}\n\nasync function validateCodexRequest(\n options: CodexHostOptions,\n request: Request,\n): Promise<void> {\n await validateNativeHostRequest(request, \"Codex\");\n requireCodexGoalRoute(request, options);\n await verifyCodexInvocation(request);\n await requireCodexFixtureConfiguration(request);\n}\n\nasync function requireCodexFixtureConfiguration(\n request: Request,\n): Promise<void> {\n const path = join(request.workspace, \".codex\");\n if (!existsSync(path)) return;\n if (request.runtimePolicy?.codexState !== true)\n throw new Error(\"fixture Codex configuration is unsupported\");\n if (!(await lstat(path)).isDirectory())\n throw new Error(\"fixture Codex configuration must be a physical directory\");\n}\n\nfunction requireCodexGoalRoute(\n request: Request,\n options: CodexHostOptions,\n): void {\n if (\n runtimeNativeGoalEnabled(request.runtimePolicy) &&\n options.entrypoint !== \"app-server\"\n )\n throw new Error(\"native-goal runtime policy requires Codex app-server\");\n}\nfunction sandboxArgs(\n state: CodexState,\n request: Request,\n command: string[],\n): string[] {\n return [\n state.sandboxBinary,\n \"sandbox\",\n \"-P\",\n state.profileId,\n \"-C\",\n request.workspace,\n ...command,\n ];\n}\nasync function sandboxPreflight(\n state: CodexState,\n request: Request,\n command: string[],\n diagnostics: HostDiagnostics,\n) {\n return runCodexProcess({\n diagnostics,\n argv: sandboxArgs(state, request, command),\n cwd: request.workspace,\n env: state.env,\n timeoutMs: 60_000,\n phase: \"isolation-preflight\",\n signal: request.signal,\n });\n}\nasync function codexPreflight(\n options: CodexHostOptions,\n request: Request,\n state: CodexState,\n diagnostics: HostDiagnostics,\n): Promise<void> {\n diagnostics.stage = \"isolation-preflight\";\n const probe = join(state.commandTemp, \"isolation-probe\");\n await writeFile(probe, \"probe\\n\", { flag: \"wx\", mode: 0o600 });\n const checked = await sandboxPreflight(\n state,\n request,\n [\n \"/bin/sh\",\n \"-c\",\n '/bin/cat \"$1\" >/dev/null && ! /bin/ls \"$2\" >/dev/null 2>&1 && ! /bin/cat \"$3\" >/dev/null 2>&1 && ! /bin/cat \"$4\" >/dev/null 2>&1 || exit 70; \"$5\" --version >/dev/null 2>&1 || exit 71',\n \"sevro-probe\",\n probe,\n options.projectRoot,\n join(state.codexHome, \"auth.json\"),\n // The opt-in config read is tested separately; credentials always stay denied.\n join(\n state.codexHome,\n request.runtimePolicy?.codexState === true\n ? \"auth.json\"\n : \"config.toml\",\n ),\n state.sandboxBinary,\n ],\n diagnostics,\n );\n if (checked.code === 71)\n throw new CodexProcessFailure(\"executable-preflight\", checked);\n if (checked.code !== 0)\n throw new CodexProcessFailure(\"isolation-preflight\", checked);\n await rm(probe);\n}\n\nfunction routeArgs(context: ExecutionContext): string[] {\n return [\n \"-m\",\n context.options.model,\n \"-c\",\n `model_reasoning_effort=${JSON.stringify(context.options.effort)}`,\n \"-c\",\n `default_permissions=${JSON.stringify(context.state.profileId)}`,\n \"-c\",\n 'approval_policy=\"never\"',\n \"-c\",\n \"features.hooks=true\",\n ];\n}\nfunction initialTurnArgs(context: ExecutionContext): string[] {\n return [\n context.options.binary,\n \"exec\",\n \"--json\",\n \"--strict-config\",\n \"--skip-git-repo-check\",\n ...(context.request.followUpPrompt ||\n context.request.runtimePolicy?.nativeTranscripts\n ? []\n : [\"--ephemeral\"]),\n \"--ignore-rules\",\n \"--dangerously-bypass-hook-trust\",\n \"-C\",\n context.request.workspace,\n ...routeArgs(context),\n \"-\",\n ];\n}\nfunction followUpTurnArgs(\n context: ExecutionContext,\n threadId: string,\n): string[] {\n return [\n context.options.binary,\n \"exec\",\n \"resume\",\n \"--json\",\n \"--strict-config\",\n \"--skip-git-repo-check\",\n \"--ignore-rules\",\n \"--dangerously-bypass-hook-trust\",\n ...routeArgs(context),\n threadId,\n \"-\",\n ];\n}\nasync function codexProcessTurn(\n context: ExecutionContext,\n argv: string[],\n input: string,\n): Promise<ProcessResult> {\n context.diagnostics.stage = \"exec\";\n const result = await runCodexProcess({\n diagnostics: context.diagnostics,\n argv,\n cwd: context.request.workspace,\n env: context.state.env,\n input,\n timeoutMs: context.timeoutMs,\n signal: context.request.signal,\n });\n return result;\n}\nasync function initialFingerprint(request: Request): Promise<string | null> {\n return request.followUpPrompt\n ? workspaceFingerprint(request.workspace)\n : null;\n}\nasync function continuationBoundary(\n context: ExecutionContext,\n threadId: string,\n originalFingerprint: string | null,\n goal: Record<string, unknown> = {},\n): Promise<Observation> {\n const boundary = await workspaceFingerprint(context.request.workspace);\n const measured = originalFingerprint !== null && boundary !== null;\n return {\n id: \"sevro.codex.continuation\",\n completeness: measured ? \"complete\" : \"partial\",\n data: {\n method: \"same_thread_resume\",\n ...goal,\n threadId,\n nativeAfterOrdinal: await codexNativeSessionLastOrdinal(\n context.state.codexHome,\n threadId,\n ),\n preFollowUpWorktreeUnchanged: measured\n ? originalFingerprint === boundary\n : null,\n },\n };\n}\nfunction requireInitialCompletion(\n summary: CodexEventSummary,\n appServer: AppServerResult | null,\n): void {\n if (!summary.complete && !appServer)\n throw new Error(\"Codex turn did not complete\");\n}\nfunction requireFollowUpCompletion(\n followUp: CodexEventSummary,\n original: CodexEventSummary,\n): void {\n if (!followUp.complete || followUp.threadId !== original.threadId)\n throw new Error(\n \"Codex follow-up turn did not complete in the original thread\",\n );\n}\nfunction appServerSummary(result: AppServerResult): CodexEventSummary {\n return {\n threadId: result.evidence.threadId ?? \"\",\n complete: result.code === 0,\n finalMessage: result.finalMessage,\n // App-server reports cumulative thread totals, not per-turn usage. Keep\n // usage unknown rather than count continuations or feedback more than once.\n inputTokens: null,\n outputTokens: null,\n usageComplete: false,\n };\n}\nfunction initialSummary(\n appServer: AppServerResult | null,\n execution: ProcessResult,\n): CodexEventSummary {\n return appServer\n ? appServerSummary(appServer)\n : summarizeCodexEvents(execution.out, execution.code);\n}\nclass CodexTurnExecution {\n private appServerContinuation?: Observation;\n constructor(private context: ExecutionContext) {}\n async run(): Promise<TurnResult> {\n const fingerprint = await initialFingerprint(this.context.request);\n const appServer = await this.maybeAppServer(fingerprint);\n const execution =\n appServer ??\n (await codexProcessTurn(\n this.context,\n initialTurnArgs(this.context),\n this.context.request.prompt,\n ));\n const summary = initialSummary(appServer, execution);\n requireInitialCompletion(summary, appServer);\n const follow = await this.maybeFollowUp(summary, appServer, fingerprint);\n return {\n execution,\n summary,\n appServer,\n ...follow,\n };\n }\n\n private async maybeAppServer(\n fingerprint: string | null,\n ): Promise<AppServerResult | null> {\n const { options, request, state, timeoutMs } = this.context;\n if (options.entrypoint !== \"app-server\") return null;\n this.context.diagnostics.stage = \"app-server\";\n return runCodexAppServer({\n diagnostics: this.context.diagnostics,\n argv: [\n options.binary,\n \"app-server\",\n \"--stdio\",\n \"--strict-config\",\n \"-c\",\n `default_permissions=${JSON.stringify(state.profileId)}`,\n \"-c\",\n \"features.hooks=true\",\n ],\n env: state.env,\n permissionProfile: state.profileId,\n vettedHooks: true,\n request: {\n repoDir: request.workspace,\n prompt: request.prompt,\n model: options.model,\n effort: options.effort,\n signal: request.signal,\n control: {\n appServerTimeoutMs: timeoutMs,\n ...(request.followUpPrompt\n ? { followUpPrompt: request.followUpPrompt }\n : {}),\n },\n },\n followUpBoundary: async (threadId, goal) => {\n this.appServerContinuation = await continuationBoundary(\n this.context,\n threadId,\n fingerprint,\n goal,\n );\n return JSON.stringify({\n type: \"sevro.codex.feedback-boundary\",\n ...this.appServerContinuation.data,\n });\n },\n });\n }\n\n private async maybeFollowUp(\n summary: CodexEventSummary,\n appServer: AppServerResult | null,\n fingerprint: string | null,\n ) {\n const prompt = this.context.request.followUpPrompt;\n if (!prompt || appServer)\n return {\n followUp: null,\n followUpSummary: null,\n continuation: this.appServerContinuation,\n };\n const continuation = await continuationBoundary(\n this.context,\n summary.threadId,\n fingerprint,\n );\n const followUp = await codexProcessTurn(\n this.context,\n followUpTurnArgs(this.context, summary.threadId),\n prompt,\n );\n const followUpSummary = summarizeCodexEvents(followUp.out, followUp.code);\n requireFollowUpCompletion(followUpSummary, summary);\n return { followUp, followUpSummary, continuation };\n }\n}\n\nfunction explicitInvocationReceipt(\n selected: Request[\"explicitSkillInvocation\"],\n completed: boolean,\n) {\n if (!selected) return null;\n return {\n id: \"sevro.codex.explicit-invocation\",\n completeness: completed ? (\"complete\" as const) : (\"partial\" as const),\n data: {\n method: \"explicit_invocation\",\n primarySkill: selected.skillName,\n },\n };\n}\nfunction appServerObservation(result: AppServerResult | null): Observation[] {\n return result\n ? [\n {\n id: \"sevro.host.native-goal\",\n completeness: result.code === 0 ? \"complete\" : \"partial\",\n data: { ...result.evidence },\n },\n ]\n : [];\n}\nasync function codexObservations(context: ExecutionContext, turns: TurnResult) {\n const tracking = await skillTrackingObservation(\n context.skillTracking,\n turns.summary.threadId,\n turns.summary.complete,\n );\n const native = await codexNativeCallObservation(\n context.state.codexHome,\n turns.summary.threadId,\n { followUpPrompt: context.request.followUpPrompt },\n );\n const explicit = explicitInvocationReceipt(\n context.request.explicitSkillInvocation,\n turns.summary.complete,\n );\n return [\n ...(await codexHookObservations(context)),\n ...runtimeObservations(\n context.request.runtimePolicy,\n context.request.runtimeRole,\n ),\n ...appServerObservation(turns.appServer),\n native,\n codexNativeControls(native),\n ...(turns.continuation ? [turns.continuation] : []),\n ...(explicit ? [explicit] : []),\n tracking,\n ...skillActivationClaims(tracking),\n ...skillExposureClaims(tracking),\n ];\n}\n\nasync function codexHookObservations(context: ExecutionContext) {\n if (!context.request.runtimePolicy) return [];\n return [await runtimeHookObservation(context.hooks)];\n}\nfunction codexArtifacts(turns: TurnResult) {\n return [\n {\n id: \"sevro.codex.events\",\n bytes: Buffer.from(turns.execution.out, \"utf8\"),\n },\n ...(turns.followUp\n ? [\n {\n id: \"sevro.codex.follow-up-events\",\n bytes: Buffer.from(turns.followUp.out, \"utf8\"),\n },\n ]\n : []),\n ];\n}\nfunction tokenCount(\n initial: number | null,\n followUp: number | null | undefined,\n): number | null {\n if (followUp === undefined) return initial;\n return initial !== null && followUp !== null ? initial + followUp : null;\n}\nfunction codexUsageComplete(\n summary: CodexEventSummary,\n followUp: CodexEventSummary | null,\n): boolean {\n return summary.usageComplete && (followUp?.usageComplete ?? true);\n}\nfunction codexUsage(turns: TurnResult) {\n return {\n inputTokens: tokenCount(\n turns.summary.inputTokens,\n turns.followUpSummary?.inputTokens,\n ),\n outputTokens: tokenCount(\n turns.summary.outputTokens,\n turns.followUpSummary?.outputTokens,\n ),\n usageComplete: codexUsageComplete(turns.summary, turns.followUpSummary),\n costUsd: null,\n };\n}\nasync function codexHostResult(\n context: ExecutionContext,\n turns: TurnResult,\n): Promise<HostResult> {\n const final = turns.followUpSummary ?? turns.summary;\n return {\n finalMessage: final.finalMessage,\n ...(turns.appServer ? { executionFailed: !turns.summary.complete } : {}),\n complete: final.finalMessage !== null,\n observations: await codexObservations(context, turns),\n artifacts: codexArtifacts(turns),\n actualCondition: \"passive\",\n ...codexUsage(turns),\n };\n}\n"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { realpath } from "node:fs/promises";
|
|
2
|
+
import { isAbsolute } from "node:path";
|
|
3
|
+
import { insideRoot as inside } from "../paths.js";
|
|
4
|
+
export { insideRoot as inside } from "../paths.js";
|
|
5
|
+
import { insideRuntimeRoot } from "../runtime/paths.js";
|
|
6
|
+
import { workspaceBoundaryException } from "../fixtures/workspace-state.js";
|
|
7
|
+
export class HostIsolationError extends Error {
|
|
8
|
+
constructor(message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "HostIsolationError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export async function commandRuntimeRoot(stateRoot, path) {
|
|
14
|
+
if (!path)
|
|
15
|
+
return undefined;
|
|
16
|
+
const root = await realpath(path);
|
|
17
|
+
if (root === stateRoot || !insideRuntimeRoot(stateRoot, root))
|
|
18
|
+
throw new HostIsolationError("command runtime must be contained in private state");
|
|
19
|
+
return root;
|
|
20
|
+
}
|
|
21
|
+
export function requireIsolationPaths(options) {
|
|
22
|
+
if (!options.argv.length || options.argv.some((part) => !part))
|
|
23
|
+
throw new HostIsolationError("isolated command must be nonempty");
|
|
24
|
+
if (!options.protectedRoots.length)
|
|
25
|
+
throw new HostIsolationError("isolated command needs protected roots");
|
|
26
|
+
if (!absoluteIsolationPaths(options))
|
|
27
|
+
throw new HostIsolationError("isolation paths must be absolute");
|
|
28
|
+
}
|
|
29
|
+
function absoluteIsolationPaths(options) {
|
|
30
|
+
return (isAbsolute(options.workspace) &&
|
|
31
|
+
isAbsolute(options.privateStateRoot) &&
|
|
32
|
+
(options.writableCacheRoots ?? []).every(isAbsolute) &&
|
|
33
|
+
options.protectedRoots.every(isAbsolute));
|
|
34
|
+
}
|
|
35
|
+
export function requireDisjointState(workspace, roots, stateRoot) {
|
|
36
|
+
if (roots.some((root) => inside(root, workspace) &&
|
|
37
|
+
!workspaceBoundaryException(root, workspace).length) ||
|
|
38
|
+
inside(stateRoot, workspace))
|
|
39
|
+
throw new HostIsolationError("protected root includes the candidate workspace");
|
|
40
|
+
if (inside(workspace, stateRoot))
|
|
41
|
+
throw new HostIsolationError("sandbox state is inside the candidate workspace");
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=isolation-common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isolation-common.js","sourceRoot":"","sources":["isolation-common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,yBAAyB;AAC5C,OAAO,EAAE,UAAU,EAAE,kBAAkB;AACvC,OAAO,EAAE,UAAU,IAAI,MAAM,EAAE,oBAAiB;AAChD,OAAO,EAAE,UAAU,IAAI,MAAM,EAAE,oBAAiB;AAChD,OAAO,EAAE,iBAAiB,EAAE,4BAAyB;AACrD,OAAO,EAAE,0BAA0B,EAAE,uCAAoC;AAGzE,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAuBD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAiB,EACjB,IAAwB;IAExB,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC;QAC3D,MAAM,IAAI,kBAAkB,CAC1B,oDAAoD,CACrD,CAAC;IACJ,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAyB;IAC7D,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC;QAC5D,MAAM,IAAI,kBAAkB,CAAC,mCAAmC,CAAC,CAAC;IACpE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM;QAChC,MAAM,IAAI,kBAAkB,CAAC,wCAAwC,CAAC,CAAC;IACzE,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC;QAClC,MAAM,IAAI,kBAAkB,CAAC,kCAAkC,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,sBAAsB,CAAC,OAAyB;IACvD,OAAO,CACL,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC;QAC7B,UAAU,CAAC,OAAO,CAAC,gBAAgB,CAAC;QACpC,CAAC,OAAO,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC;QACpD,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,CACzC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,SAAiB,EACjB,KAAe,EACf,SAAiB;IAEjB,IACE,KAAK,CAAC,IAAI,CACR,CAAC,IAAI,EAAE,EAAE,CACP,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC;QACvB,CAAC,0BAA0B,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,MAAM,CACtD;QACD,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC;QAE5B,MAAM,IAAI,kBAAkB,CAC1B,iDAAiD,CAClD,CAAC;IACJ,IAAI,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC;QAC9B,MAAM,IAAI,kBAAkB,CAC1B,iDAAiD,CAClD,CAAC;AACN,CAAC","sourcesContent":["import { realpath } from \"node:fs/promises\";\nimport { isAbsolute } from \"node:path\";\nimport { insideRoot as inside } from \"../paths\";\nexport { insideRoot as inside } from \"../paths\";\nimport { insideRuntimeRoot } from \"../runtime/paths\";\nimport { workspaceBoundaryException } from \"../fixtures/workspace-state\";\nimport type { CandidateArtifactRoots } from \"../candidate-artifacts\";\n\nexport class HostIsolationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"HostIsolationError\";\n }\n}\n\nexport interface IsolationOptions {\n argv: string[];\n workspace: string;\n protectedRoots: string[];\n protectedRootsCanonical?: boolean;\n privateStateRoot: string;\n denyNetwork?: boolean;\n localHttp?: boolean;\n readOnlyRoots?: string[];\n transcriptReadRoots?: string[];\n candidateArtifactRoots?: CandidateArtifactRoots;\n hookReadRoots?: string[];\n writableRuntimeRoot?: string;\n writableCacheRoots?: string[];\n}\n\nexport interface IsolatedCommand {\n argv: string[];\n release(): Promise<void>;\n}\n\nexport async function commandRuntimeRoot(\n stateRoot: string,\n path: string | undefined,\n): Promise<string | undefined> {\n if (!path) return undefined;\n const root = await realpath(path);\n if (root === stateRoot || !insideRuntimeRoot(stateRoot, root))\n throw new HostIsolationError(\n \"command runtime must be contained in private state\",\n );\n return root;\n}\n\nexport function requireIsolationPaths(options: IsolationOptions): void {\n if (!options.argv.length || options.argv.some((part) => !part))\n throw new HostIsolationError(\"isolated command must be nonempty\");\n if (!options.protectedRoots.length)\n throw new HostIsolationError(\"isolated command needs protected roots\");\n if (!absoluteIsolationPaths(options))\n throw new HostIsolationError(\"isolation paths must be absolute\");\n}\n\nfunction absoluteIsolationPaths(options: IsolationOptions): boolean {\n return (\n isAbsolute(options.workspace) &&\n isAbsolute(options.privateStateRoot) &&\n (options.writableCacheRoots ?? []).every(isAbsolute) &&\n options.protectedRoots.every(isAbsolute)\n );\n}\n\nexport function requireDisjointState(\n workspace: string,\n roots: string[],\n stateRoot: string,\n): void {\n if (\n roots.some(\n (root) =>\n inside(root, workspace) &&\n !workspaceBoundaryException(root, workspace).length,\n ) ||\n inside(stateRoot, workspace)\n )\n throw new HostIsolationError(\n \"protected root includes the candidate workspace\",\n );\n if (inside(workspace, stateRoot))\n throw new HostIsolationError(\n \"sandbox state is inside the candidate workspace\",\n );\n}\n"]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { runnerRoot } from "../runner-paths.js";
|
|
2
|
+
import { isMissingFile } from "../fixtures/tools.js";
|
|
3
|
+
import { realpath } from "node:fs/promises";
|
|
4
|
+
import { homedir, userInfo } from "node:os";
|
|
5
|
+
import { isAbsolute } from "node:path";
|
|
6
|
+
import { protectedWorktrees } from "./protected-worktrees.js";
|
|
7
|
+
import { nativeStateParent } from "../native-transcript-state.js";
|
|
8
|
+
import { workspaceStateParent } from "../fixtures/workspace-state.js";
|
|
9
|
+
async function protectedRootCandidates(options) {
|
|
10
|
+
const optionalConfigRoots = [
|
|
11
|
+
process.env.CODEX_HOME,
|
|
12
|
+
process.env.CLAUDE_CONFIG_DIR,
|
|
13
|
+
].filter((value) => Boolean(value));
|
|
14
|
+
const candidates = [
|
|
15
|
+
await nativeStateParent(),
|
|
16
|
+
await workspaceStateParent(),
|
|
17
|
+
runnerRoot,
|
|
18
|
+
options.projectRoot,
|
|
19
|
+
options.resultsRoot,
|
|
20
|
+
homedir(),
|
|
21
|
+
userInfo().homedir,
|
|
22
|
+
...options.additionalRoots,
|
|
23
|
+
...optionalConfigRoots,
|
|
24
|
+
];
|
|
25
|
+
if (candidates.some((root) => !isAbsolute(root)))
|
|
26
|
+
throw new Error("evaluation protected roots must be absolute");
|
|
27
|
+
return { candidates, optionalConfigRoots };
|
|
28
|
+
}
|
|
29
|
+
/** Include source, results, host configuration, and every active peer fixture. */
|
|
30
|
+
export async function evaluationProtectedRoots(options) {
|
|
31
|
+
const workspace = await realpath(options.workspace);
|
|
32
|
+
const { candidates, optionalConfigRoots } = await protectedRootCandidates(options);
|
|
33
|
+
const namespace = await workspaceStateParent();
|
|
34
|
+
const nativeNamespace = await nativeStateParent();
|
|
35
|
+
const roots = [];
|
|
36
|
+
for (const candidate of candidates) {
|
|
37
|
+
const canonical = await canonicalProtectedRoot(candidate, [
|
|
38
|
+
...optionalConfigRoots,
|
|
39
|
+
]);
|
|
40
|
+
if (!includedProtectedRoot(canonical, workspace, options.ownedStateRoot))
|
|
41
|
+
continue;
|
|
42
|
+
{
|
|
43
|
+
roots.push(canonical);
|
|
44
|
+
// Private namespaces are boundaries, not Git source trees to traverse.
|
|
45
|
+
if (canonical !== namespace && canonical !== nativeNamespace)
|
|
46
|
+
roots.push(...(await protectedWorktrees(canonical)).filter((root) => root !== workspace));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return [...new Set(roots)];
|
|
50
|
+
}
|
|
51
|
+
function includedProtectedRoot(root, workspace, state) {
|
|
52
|
+
return root !== null && root !== workspace && root !== state;
|
|
53
|
+
}
|
|
54
|
+
async function canonicalProtectedRoot(candidate, optionalRoots) {
|
|
55
|
+
try {
|
|
56
|
+
return await realpath(candidate);
|
|
57
|
+
}
|
|
58
|
+
catch (cause) {
|
|
59
|
+
if (optionalRoots.includes(candidate) && isMissingFile(cause))
|
|
60
|
+
return null;
|
|
61
|
+
throw new Error("evaluation protected root is unreadable", { cause });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=isolation-roots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isolation-roots.js","sourceRoot":"","sources":["isolation-roots.ts"],"names":[],"mappings":"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","sourcesContent":["import { runnerRoot } from \"../runner-paths\";\nimport { isMissingFile } from \"../fixtures/tools\";\nimport { realpath } from \"node:fs/promises\";\nimport { homedir, userInfo } from \"node:os\";\nimport { isAbsolute } from \"node:path\";\nimport { protectedWorktrees } from \"./protected-worktrees\";\nimport { nativeStateParent } from \"../native-transcript-state\";\nimport { workspaceStateParent } from \"../fixtures/workspace-state\";\n\n/** Include source, results, host configuration, and every active peer fixture. */\ninterface ProtectedRootsOptions {\n workspace: string;\n projectRoot: string;\n resultsRoot: string;\n additionalRoots: string[];\n ownedStateRoot?: string;\n}\n\nasync function protectedRootCandidates(options: ProtectedRootsOptions) {\n const optionalConfigRoots = [\n process.env.CODEX_HOME,\n process.env.CLAUDE_CONFIG_DIR,\n ].filter((value): value is string => Boolean(value));\n const candidates = [\n await nativeStateParent(),\n await workspaceStateParent(),\n runnerRoot,\n options.projectRoot,\n options.resultsRoot,\n homedir(),\n userInfo().homedir,\n ...options.additionalRoots,\n ...optionalConfigRoots,\n ];\n if (candidates.some((root) => !isAbsolute(root)))\n throw new Error(\"evaluation protected roots must be absolute\");\n return { candidates, optionalConfigRoots };\n}\n\n/** Include source, results, host configuration, and every active peer fixture. */\nexport async function evaluationProtectedRoots(\n options: ProtectedRootsOptions,\n): Promise<string[]> {\n const workspace = await realpath(options.workspace);\n const { candidates, optionalConfigRoots } =\n await protectedRootCandidates(options);\n const namespace = await workspaceStateParent();\n const nativeNamespace = await nativeStateParent();\n const roots: string[] = [];\n for (const candidate of candidates) {\n const canonical = await canonicalProtectedRoot(candidate, [\n ...optionalConfigRoots,\n ]);\n if (!includedProtectedRoot(canonical, workspace, options.ownedStateRoot))\n continue;\n {\n roots.push(canonical);\n // Private namespaces are boundaries, not Git source trees to traverse.\n if (canonical !== namespace && canonical !== nativeNamespace)\n roots.push(\n ...(await protectedWorktrees(canonical)).filter(\n (root) => root !== workspace,\n ),\n );\n }\n }\n return [...new Set(roots)];\n}\n\nfunction includedProtectedRoot(\n root: string | null,\n workspace: string,\n state: string | undefined,\n): root is string {\n return root !== null && root !== workspace && root !== state;\n}\n\nasync function canonicalProtectedRoot(\n candidate: string,\n optionalRoots: string[],\n): Promise<string | null> {\n try {\n return await realpath(candidate);\n } catch (cause) {\n if (optionalRoots.includes(candidate) && isMissingFile(cause)) return null;\n throw new Error(\"evaluation protected root is unreadable\", { cause });\n }\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { HostIsolationError } from "./isolation-common.js";
|
|
2
|
+
import { prepareMacSandboxCommand } from "./mac-sandbox.js";
|
|
3
|
+
import { prepareLinuxSandboxCommand } from "./linux-sandbox.js";
|
|
4
|
+
/** Select the native filesystem boundary for evaluator-owned commands. */
|
|
5
|
+
export function prepareIsolatedCommand(options) {
|
|
6
|
+
if (process.platform === "darwin")
|
|
7
|
+
return prepareMacSandboxCommand(options);
|
|
8
|
+
if (process.platform === "linux")
|
|
9
|
+
return prepareLinuxSandboxCommand(options);
|
|
10
|
+
throw new HostIsolationError("host isolation is unavailable");
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=isolation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isolation.js","sourceRoot":"","sources":["isolation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAyB,8BAA2B;AAC/E,OAAO,EAAE,wBAAwB,EAAE,yBAAsB;AACzD,OAAO,EAAE,0BAA0B,EAAE,2BAAwB;AAE7D,0EAA0E;AAC1E,MAAM,UAAU,sBAAsB,CAAC,OAAyB;IAC9D,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAC5E,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,0BAA0B,CAAC,OAAO,CAAC,CAAC;IAC7E,MAAM,IAAI,kBAAkB,CAAC,+BAA+B,CAAC,CAAC;AAChE,CAAC","sourcesContent":["import { HostIsolationError, type IsolationOptions } from \"./isolation-common\";\nimport { prepareMacSandboxCommand } from \"./mac-sandbox\";\nimport { prepareLinuxSandboxCommand } from \"./linux-sandbox\";\n\n/** Select the native filesystem boundary for evaluator-owned commands. */\nexport function prepareIsolatedCommand(options: IsolationOptions) {\n if (process.platform === \"darwin\") return prepareMacSandboxCommand(options);\n if (process.platform === \"linux\") return prepareLinuxSandboxCommand(options);\n throw new HostIsolationError(\"host isolation is unavailable\");\n}\n"]}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { mkdir, realpath, rm, stat, writeFile } from "node:fs/promises";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { requireNativeTranscriptViews, requireNativeHookRoots, } from "../native-transcript-state.js";
|
|
6
|
+
import { requireRuntimeReadRoots } from "../runtime/paths.js";
|
|
7
|
+
import { requireWritableCacheRoots } from "../runtime/shared-cache.js";
|
|
8
|
+
import { requireCandidateArtifactRoots } from "../candidate-artifacts.js";
|
|
9
|
+
import { commandRuntimeRoot, HostIsolationError, requireDisjointState, requireIsolationPaths, } from "./isolation-common.js";
|
|
10
|
+
const BWRAP = "/usr/bin/bwrap";
|
|
11
|
+
async function protectedKind(path) {
|
|
12
|
+
try {
|
|
13
|
+
return (await stat(path)).isDirectory() ? "directory" : "file";
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
if (error.code === "ENOENT")
|
|
17
|
+
return "directory";
|
|
18
|
+
throw error;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function requireLinuxSandbox() {
|
|
22
|
+
if (process.platform !== "linux" || !existsSync(BWRAP))
|
|
23
|
+
throw new HostIsolationError("Linux bubblewrap isolation is unavailable");
|
|
24
|
+
}
|
|
25
|
+
function networkArgs(denyNetwork) {
|
|
26
|
+
return denyNetwork ? ["--unshare-net"] : [];
|
|
27
|
+
}
|
|
28
|
+
function mountProtectedRoot(path, kind, blockedFile) {
|
|
29
|
+
return kind === "directory"
|
|
30
|
+
? ["--tmpfs", path, "--chmod", "0111", path]
|
|
31
|
+
: ["--ro-bind", blockedFile, path];
|
|
32
|
+
}
|
|
33
|
+
/** Mask protected inputs before launching an evaluator-owned command. */
|
|
34
|
+
export async function prepareLinuxSandboxCommand(options) {
|
|
35
|
+
requireLinuxSandbox();
|
|
36
|
+
await requireNativeTranscriptViews(options.transcriptReadRoots);
|
|
37
|
+
await requireCandidateArtifactRoots(options.candidateArtifactRoots);
|
|
38
|
+
await requireNativeHookRoots(options.hookReadRoots, options.privateStateRoot);
|
|
39
|
+
requireIsolationPaths(options);
|
|
40
|
+
const workspace = await realpath(options.workspace);
|
|
41
|
+
const roots = options.protectedRootsCanonical
|
|
42
|
+
? options.protectedRoots
|
|
43
|
+
: await Promise.all(options.protectedRoots.map((path) => realpath(path)));
|
|
44
|
+
await mkdir(options.privateStateRoot, { recursive: true, mode: 0o700 });
|
|
45
|
+
const stateRoot = await realpath(options.privateStateRoot);
|
|
46
|
+
const ownedRoot = await commandRuntimeRoot(stateRoot, options.writableRuntimeRoot);
|
|
47
|
+
const readRoots = options.readOnlyRoots ?? [];
|
|
48
|
+
const writableCacheRoots = await cacheMountRoots(options, [
|
|
49
|
+
...roots,
|
|
50
|
+
stateRoot,
|
|
51
|
+
]);
|
|
52
|
+
requireRuntimeReadRoots(readRoots, [...roots, stateRoot]);
|
|
53
|
+
requireDisjointState(workspace, roots, stateRoot);
|
|
54
|
+
const blockedFile = resolve(stateRoot, `blocked-${randomUUID()}`);
|
|
55
|
+
await writeFile(blockedFile, "", { flag: "wx", mode: 0o000 });
|
|
56
|
+
try {
|
|
57
|
+
const protectedRoots = [...new Set([...roots, stateRoot])].sort((left, right) => left.length - right.length);
|
|
58
|
+
const kinds = await Promise.all(protectedRoots.map(protectedKind));
|
|
59
|
+
const masks = protectedRoots.flatMap((path, index) => mountProtectedRoot(path, kinds[index], blockedFile));
|
|
60
|
+
return {
|
|
61
|
+
argv: [
|
|
62
|
+
BWRAP,
|
|
63
|
+
"--die-with-parent",
|
|
64
|
+
"--unshare-user",
|
|
65
|
+
"--unshare-pid",
|
|
66
|
+
...networkArgs(Boolean(options.denyNetwork)),
|
|
67
|
+
"--ro-bind",
|
|
68
|
+
"/",
|
|
69
|
+
"/",
|
|
70
|
+
"--dev-bind",
|
|
71
|
+
"/dev",
|
|
72
|
+
"/dev",
|
|
73
|
+
"--proc",
|
|
74
|
+
"/proc",
|
|
75
|
+
"--bind",
|
|
76
|
+
"/tmp",
|
|
77
|
+
"/tmp",
|
|
78
|
+
...masks,
|
|
79
|
+
"--bind",
|
|
80
|
+
workspace,
|
|
81
|
+
workspace,
|
|
82
|
+
...readRoots.flatMap((path) => ["--ro-bind", path, path]),
|
|
83
|
+
...transcriptMounts(options),
|
|
84
|
+
...candidateArtifactMounts(options),
|
|
85
|
+
...hookMounts(options),
|
|
86
|
+
...(ownedRoot ? ["--bind", ownedRoot, ownedRoot] : []),
|
|
87
|
+
...writableCacheRoots.flatMap((path) => ["--bind", path, path]),
|
|
88
|
+
"--chdir",
|
|
89
|
+
workspace,
|
|
90
|
+
"--",
|
|
91
|
+
...options.argv,
|
|
92
|
+
],
|
|
93
|
+
release: async () => {
|
|
94
|
+
await rm(blockedFile, { force: true });
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
await rm(blockedFile, { force: true });
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function cacheMountRoots(options, protectedRoots) {
|
|
104
|
+
return requireWritableCacheRoots(options.writableCacheRoots ?? [], protectedRoots);
|
|
105
|
+
}
|
|
106
|
+
function transcriptMounts(options) {
|
|
107
|
+
return (options.transcriptReadRoots ?? []).flatMap((path) => [
|
|
108
|
+
"--ro-bind",
|
|
109
|
+
path,
|
|
110
|
+
path,
|
|
111
|
+
]);
|
|
112
|
+
}
|
|
113
|
+
function candidateArtifactMounts(options) {
|
|
114
|
+
return Object.values(options.candidateArtifactRoots ?? {}).flatMap((path) => [
|
|
115
|
+
"--ro-bind",
|
|
116
|
+
path,
|
|
117
|
+
path,
|
|
118
|
+
]);
|
|
119
|
+
}
|
|
120
|
+
function hookMounts(options) {
|
|
121
|
+
return (options.hookReadRoots ?? []).flatMap((path) => [
|
|
122
|
+
"--ro-bind",
|
|
123
|
+
path,
|
|
124
|
+
path,
|
|
125
|
+
]);
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=linux-sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linux-sandbox.js","sourceRoot":"","sources":["linux-sandbox.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, realpath, rm, stat, writeFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport {\n requireNativeTranscriptViews,\n requireNativeHookRoots,\n} from \"../native-transcript-state\";\nimport { requireRuntimeReadRoots } from \"../runtime/paths\";\nimport { requireWritableCacheRoots } from \"../runtime/shared-cache\";\nimport { requireCandidateArtifactRoots } from \"../candidate-artifacts\";\nimport {\n commandRuntimeRoot,\n HostIsolationError,\n requireDisjointState,\n requireIsolationPaths,\n type IsolatedCommand,\n type IsolationOptions,\n} from \"./isolation-common\";\n\nconst BWRAP = \"/usr/bin/bwrap\";\n\nasync function protectedKind(path: string): Promise<\"file\" | \"directory\"> {\n try {\n return (await stat(path)).isDirectory() ? \"directory\" : \"file\";\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return \"directory\";\n throw error;\n }\n}\n\nfunction requireLinuxSandbox(): void {\n if (process.platform !== \"linux\" || !existsSync(BWRAP))\n throw new HostIsolationError(\"Linux bubblewrap isolation is unavailable\");\n}\n\nfunction networkArgs(denyNetwork: boolean): string[] {\n return denyNetwork ? [\"--unshare-net\"] : [];\n}\n\nfunction mountProtectedRoot(\n path: string,\n kind: \"file\" | \"directory\" | undefined,\n blockedFile: string,\n): string[] {\n return kind === \"directory\"\n ? [\"--tmpfs\", path, \"--chmod\", \"0111\", path]\n : [\"--ro-bind\", blockedFile, path];\n}\n\n/** Mask protected inputs before launching an evaluator-owned command. */\nexport async function prepareLinuxSandboxCommand(\n options: IsolationOptions,\n): Promise<IsolatedCommand> {\n requireLinuxSandbox();\n await requireNativeTranscriptViews(options.transcriptReadRoots);\n await requireCandidateArtifactRoots(options.candidateArtifactRoots);\n await requireNativeHookRoots(options.hookReadRoots, options.privateStateRoot);\n requireIsolationPaths(options);\n const workspace = await realpath(options.workspace);\n const roots = options.protectedRootsCanonical\n ? options.protectedRoots\n : await Promise.all(options.protectedRoots.map((path) => realpath(path)));\n await mkdir(options.privateStateRoot, { recursive: true, mode: 0o700 });\n const stateRoot = await realpath(options.privateStateRoot);\n const ownedRoot = await commandRuntimeRoot(\n stateRoot,\n options.writableRuntimeRoot,\n );\n const readRoots = options.readOnlyRoots ?? [];\n const writableCacheRoots = await cacheMountRoots(options, [\n ...roots,\n stateRoot,\n ]);\n requireRuntimeReadRoots(readRoots, [...roots, stateRoot]);\n requireDisjointState(workspace, roots, stateRoot);\n const blockedFile = resolve(stateRoot, `blocked-${randomUUID()}`);\n await writeFile(blockedFile, \"\", { flag: \"wx\", mode: 0o000 });\n try {\n const protectedRoots = [...new Set([...roots, stateRoot])].sort(\n (left, right) => left.length - right.length,\n );\n const kinds = await Promise.all(protectedRoots.map(protectedKind));\n const masks = protectedRoots.flatMap((path, index) =>\n mountProtectedRoot(path, kinds[index], blockedFile),\n );\n return {\n argv: [\n BWRAP,\n \"--die-with-parent\",\n \"--unshare-user\",\n \"--unshare-pid\",\n ...networkArgs(Boolean(options.denyNetwork)),\n \"--ro-bind\",\n \"/\",\n \"/\",\n \"--dev-bind\",\n \"/dev\",\n \"/dev\",\n \"--proc\",\n \"/proc\",\n \"--bind\",\n \"/tmp\",\n \"/tmp\",\n ...masks,\n \"--bind\",\n workspace,\n workspace,\n ...readRoots.flatMap((path) => [\"--ro-bind\", path, path]),\n ...transcriptMounts(options),\n ...candidateArtifactMounts(options),\n ...hookMounts(options),\n ...(ownedRoot ? [\"--bind\", ownedRoot, ownedRoot] : []),\n ...writableCacheRoots.flatMap((path) => [\"--bind\", path, path]),\n \"--chdir\",\n workspace,\n \"--\",\n ...options.argv,\n ],\n release: async () => {\n await rm(blockedFile, { force: true });\n },\n };\n } catch (error) {\n await rm(blockedFile, { force: true });\n throw error;\n }\n}\n\nfunction cacheMountRoots(options: IsolationOptions, protectedRoots: string[]) {\n return requireWritableCacheRoots(\n options.writableCacheRoots ?? [],\n protectedRoots,\n );\n}\n\nfunction transcriptMounts(options: IsolationOptions): string[] {\n return (options.transcriptReadRoots ?? []).flatMap((path) => [\n \"--ro-bind\",\n path,\n path,\n ]);\n}\n\nfunction candidateArtifactMounts(options: IsolationOptions): string[] {\n return Object.values(options.candidateArtifactRoots ?? {}).flatMap((path) => [\n \"--ro-bind\",\n path,\n path,\n ]);\n}\n\nfunction hookMounts(options: IsolationOptions): string[] {\n return (options.hookReadRoots ?? []).flatMap((path) => [\n \"--ro-bind\",\n path,\n path,\n ]);\n}\n"]}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { containsControl } from "../value-guards.js";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { mkdir, realpath, rm, writeFile } from "node:fs/promises";
|
|
5
|
+
import { dirname, resolve } from "node:path";
|
|
6
|
+
import { requireNativeTranscriptViews, requireNativeHookRoots, } from "../native-transcript-state.js";
|
|
7
|
+
import { requireCandidateArtifactRoots } from "../candidate-artifacts.js";
|
|
8
|
+
import { workspaceBoundaryException } from "../fixtures/workspace-state.js";
|
|
9
|
+
import { requireWritableCacheRoots } from "../runtime/shared-cache.js";
|
|
10
|
+
import { insideRuntimeRoot, isRuntimeHomeRoot, requireRuntimeReadRoots, } from "../runtime/paths.js";
|
|
11
|
+
import { commandRuntimeRoot, HostIsolationError, requireDisjointState, requireIsolationPaths, } from "./isolation-common.js";
|
|
12
|
+
export { HostIsolationError } from "./isolation-common.js";
|
|
13
|
+
const SANDBOX_EXEC = "/usr/bin/sandbox-exec";
|
|
14
|
+
function quoted(path) {
|
|
15
|
+
if (containsControl(path))
|
|
16
|
+
throw new HostIsolationError("sandbox path contains a control character");
|
|
17
|
+
return path.replaceAll("\\", "\\\\").replaceAll('"', '\\"');
|
|
18
|
+
}
|
|
19
|
+
/** Protect canonical roots while preserving explicitly granted access. */
|
|
20
|
+
export function macSandboxProfile(deniedRoots, denyNetwork = false, readOnlyRoots = [], writableRuntimeRoot, transcriptReadRoots = [], workspace, localHttp, writableCacheRoots) {
|
|
21
|
+
requireProfileRoots(deniedRoots);
|
|
22
|
+
return [
|
|
23
|
+
"(version 1)",
|
|
24
|
+
"(allow default)",
|
|
25
|
+
...(denyNetwork ? ["(deny network*)"] : []),
|
|
26
|
+
...localHttpRules(localHttp),
|
|
27
|
+
...[...new Set(deniedRoots)]
|
|
28
|
+
.sort()
|
|
29
|
+
.flatMap((path) => [
|
|
30
|
+
`(deny file-read* ${workspaceReadFilter(path, readExceptions(path, readOnlyRoots, writableRuntimeRoot, transcriptReadRoots, workspace, writableCacheRoots), workspace)})`,
|
|
31
|
+
`(deny file-write* ${rootFilter(path, [...writableExceptions(path, writableRuntimeRoot, writableCacheRoots), ...workspaceBoundaryException(path, workspace)])})`,
|
|
32
|
+
]),
|
|
33
|
+
...deniedRoots.flatMap((path) => workspaceBoundaryException(path, workspace).map(() => `(deny file-read-data (literal "${quoted(path)}"))`)),
|
|
34
|
+
...[...readOnlyRoots, ...transcriptReadRoots].map((path) => `(deny file-write* (subpath "${quoted(path)}"))`),
|
|
35
|
+
...deniedRoots.flatMap((root) => ancestorMetadataRules(root, readExceptions(root, readOnlyRoots, writableRuntimeRoot, transcriptReadRoots, workspace, writableCacheRoots))),
|
|
36
|
+
"",
|
|
37
|
+
].join("\n");
|
|
38
|
+
}
|
|
39
|
+
function localHttpRules(enabled) {
|
|
40
|
+
return enabled
|
|
41
|
+
? [
|
|
42
|
+
'(allow network-bind (local ip "*:*"))',
|
|
43
|
+
'(allow network-inbound (local ip "localhost:*"))',
|
|
44
|
+
'(allow network-outbound (remote ip "localhost:*"))',
|
|
45
|
+
]
|
|
46
|
+
: [];
|
|
47
|
+
}
|
|
48
|
+
function ancestorMetadataRules(root, readRoots) {
|
|
49
|
+
const ancestors = new Set();
|
|
50
|
+
for (const readRoot of readRoots) {
|
|
51
|
+
for (let path = dirname(readRoot); insideRuntimeRoot(root, path); path = dirname(path)) {
|
|
52
|
+
ancestors.add(path);
|
|
53
|
+
if (path === resolve(root))
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return [...ancestors]
|
|
58
|
+
.sort()
|
|
59
|
+
.map((path) => `(allow file-read-metadata (literal "${quoted(path)}"))`);
|
|
60
|
+
}
|
|
61
|
+
function requireProfileRoots(roots) {
|
|
62
|
+
if (!roots.length || roots.some((path) => !path.startsWith("/")))
|
|
63
|
+
throw new HostIsolationError("sandbox roots must be absolute and nonempty");
|
|
64
|
+
}
|
|
65
|
+
function readExceptions(root, readRoots, writableRuntimeRoot, transcriptReadRoots, workspace, writableCacheRoots = []) {
|
|
66
|
+
const exceptions = isRuntimeHomeRoot(root)
|
|
67
|
+
? readRoots.filter((path) => insideRuntimeRoot(root, path))
|
|
68
|
+
: [];
|
|
69
|
+
return [
|
|
70
|
+
...transcriptReadRoots.filter((path) => insideRuntimeRoot(root, path)),
|
|
71
|
+
...exceptions,
|
|
72
|
+
...writableExceptions(root, writableRuntimeRoot, writableCacheRoots),
|
|
73
|
+
...workspaceBoundaryException(root, workspace),
|
|
74
|
+
];
|
|
75
|
+
}
|
|
76
|
+
function writableExceptions(root, runtime, caches = []) {
|
|
77
|
+
return [
|
|
78
|
+
...ownedException(root, runtime),
|
|
79
|
+
...caches.flatMap((cache) => ownedException(root, cache)),
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
function rootFilter(root, exceptions) {
|
|
83
|
+
const base = `(subpath "${quoted(root)}")`;
|
|
84
|
+
if (!exceptions.length)
|
|
85
|
+
return base;
|
|
86
|
+
return `(require-all ${base} ${exceptions.map((path) => `(require-not (subpath "${quoted(path)}"))`).join(" ")})`;
|
|
87
|
+
}
|
|
88
|
+
function workspaceReadFilter(root, exceptions, workspace) {
|
|
89
|
+
const filter = rootFilter(root, exceptions);
|
|
90
|
+
return workspaceBoundaryException(root, workspace).length
|
|
91
|
+
? `(require-all ${filter} (require-not (literal "${quoted(root)}")))`
|
|
92
|
+
: filter;
|
|
93
|
+
}
|
|
94
|
+
function ownedException(root, ownedRoot) {
|
|
95
|
+
if (ownedRoot && insideRuntimeRoot(root, ownedRoot))
|
|
96
|
+
return [ownedRoot];
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
/** Build the outer boundary before launching an agent or candidate-controlled code. */
|
|
100
|
+
export async function prepareMacSandboxCommand(options) {
|
|
101
|
+
requireSandboxAvailable();
|
|
102
|
+
await requireNativeTranscriptViews(options.transcriptReadRoots);
|
|
103
|
+
await requireCandidateArtifactRoots(options.candidateArtifactRoots);
|
|
104
|
+
await requireNativeHookRoots(options.hookReadRoots, options.privateStateRoot);
|
|
105
|
+
requireIsolationPaths(options);
|
|
106
|
+
const workspace = await realpath(options.workspace);
|
|
107
|
+
const roots = options.protectedRootsCanonical
|
|
108
|
+
? options.protectedRoots
|
|
109
|
+
: await Promise.all(options.protectedRoots.map((path) => realpath(path)));
|
|
110
|
+
await mkdir(options.privateStateRoot, { recursive: true, mode: 0o700 });
|
|
111
|
+
const stateRoot = await realpath(options.privateStateRoot);
|
|
112
|
+
const ownedRoot = await commandRuntimeRoot(stateRoot, options.writableRuntimeRoot);
|
|
113
|
+
const readRoots = options.readOnlyRoots ?? [];
|
|
114
|
+
const writableCacheRoots = await requireWritableCacheRoots(options.writableCacheRoots ?? [], [...roots, stateRoot]);
|
|
115
|
+
requireRuntimeReadRoots(readRoots, [...roots, stateRoot]);
|
|
116
|
+
requireDisjointState(workspace, roots, stateRoot);
|
|
117
|
+
const profilePath = resolve(stateRoot, `host-${randomUUID()}.sb`);
|
|
118
|
+
await writeFile(profilePath, macSandboxProfile([...roots, stateRoot], options.denyNetwork, readRoots, ownedRoot, curatedReadRoots(options), workspace, options.localHttp, writableCacheRoots), { flag: "wx", mode: 0o600 });
|
|
119
|
+
return {
|
|
120
|
+
argv: [SANDBOX_EXEC, "-f", profilePath, ...options.argv],
|
|
121
|
+
release: async () => {
|
|
122
|
+
await rm(profilePath, { force: true });
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function curatedReadRoots(options) {
|
|
127
|
+
return [
|
|
128
|
+
...(options.transcriptReadRoots ?? []),
|
|
129
|
+
...(options.hookReadRoots ?? []),
|
|
130
|
+
...Object.values(options.candidateArtifactRoots ?? {}),
|
|
131
|
+
];
|
|
132
|
+
}
|
|
133
|
+
function requireSandboxAvailable() {
|
|
134
|
+
if (process.platform !== "darwin" || !existsSync(SANDBOX_EXEC))
|
|
135
|
+
throw new HostIsolationError("macOS sandbox-exec isolation is unavailable");
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=mac-sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mac-sandbox.js","sourceRoot":"","sources":["mac-sandbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,oBAAoB;AACzC,OAAO,EAAE,eAAe,EAAE,2BAAwB;AAClD,OAAO,EAAE,UAAU,EAAE,gBAAgB;AACrC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,yBAAyB;AAClE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB;AAC7C,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,GACvB,sCAAmC;AACpC,OAAO,EAAE,6BAA6B,EAAE,kCAA+B;AACvE,OAAO,EAAE,0BAA0B,EAAE,uCAAoC;AACzE,OAAO,EAAE,yBAAyB,EAAE,mCAAgC;AACpE,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,GACxB,4BAAyB;AAC1B,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,GAGtB,8BAA2B;AAE5B,OAAO,EAAE,kBAAkB,EAAE,8BAA2B;AAGxD,MAAM,YAAY,GAAG,uBAAuB,CAAC;AAE7C,SAAS,MAAM,CAAC,IAAY;IAC1B,IAAI,eAAe,CAAC,IAAI,CAAC;QACvB,MAAM,IAAI,kBAAkB,CAAC,2CAA2C,CAAC,CAAC;IAC5E,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,iBAAiB,CAC/B,WAAqB,EACrB,WAAW,GAAG,KAAK,EACnB,gBAA0B,EAAE,EAC5B,mBAA4B,EAC5B,sBAAgC,EAAE,EAClC,SAAkB,EAClB,SAAmB,EACnB,kBAA6B;IAE7B,mBAAmB,CAAC,WAAW,CAAC,CAAC;IACjC,OAAO;QACL,aAAa;QACb,iBAAiB;QACjB,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,GAAG,cAAc,CAAC,SAAS,CAAC;QAC5B,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;aACzB,IAAI,EAAE;aACN,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACjB,oBAAoB,mBAAmB,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE,aAAa,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,SAAS,EAAE,kBAAkB,CAAC,EAAE,SAAS,CAAC,GAAG;YACzK,qBAAqB,UAAU,CAAC,IAAI,EAAE,CAAC,GAAG,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,EAAE,kBAAkB,CAAC,EAAE,GAAG,0BAA0B,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG;SACjK,CAAC;QACJ,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAC9B,0BAA0B,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,GAAG,CAC7C,GAAG,EAAE,CAAC,kCAAkC,MAAM,CAAC,IAAI,CAAC,KAAK,CAC1D,CACF;QACD,GAAG,CAAC,GAAG,aAAa,EAAE,GAAG,mBAAmB,CAAC,CAAC,GAAG,CAC/C,CAAC,IAAI,EAAE,EAAE,CAAC,+BAA+B,MAAM,CAAC,IAAI,CAAC,KAAK,CAC3D;QACD,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAC9B,qBAAqB,CACnB,IAAI,EACJ,cAAc,CACZ,IAAI,EACJ,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,SAAS,EACT,kBAAkB,CACnB,CACF,CACF;QACD,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,OAA4B;IAClD,OAAO,OAAO;QACZ,CAAC,CAAC;YACE,uCAAuC;YACvC,kDAAkD;YAClD,oDAAoD;SACrD;QACH,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAY,EAAE,SAAmB;IAC9D,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,KACE,IAAI,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,EAC5B,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,EAC7B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EACpB,CAAC;YACD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACpB,IAAI,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC;gBAAE,MAAM;QACpC,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,SAAS,CAAC;SAClB,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,uCAAuC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAe;IAC1C,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC9D,MAAM,IAAI,kBAAkB,CAAC,6CAA6C,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,cAAc,CACrB,IAAY,EACZ,SAAmB,EACnB,mBAAuC,EACvC,mBAA6B,EAC7B,SAAkB,EAClB,qBAA+B,EAAE;IAEjC,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC;QACxC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC3D,CAAC,CAAC,EAAE,CAAC;IACP,OAAO;QACL,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACtE,GAAG,UAAU;QACb,GAAG,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,EAAE,kBAAkB,CAAC;QACpE,GAAG,0BAA0B,CAAC,IAAI,EAAE,SAAS,CAAC;KAC/C,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CACzB,IAAY,EACZ,OAA2B,EAC3B,SAAmB,EAAE;IAErB,OAAO;QACL,GAAG,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC;QAChC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;KAC1D,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,UAAoB;IACpD,MAAM,IAAI,GAAG,aAAa,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;IAC3C,IAAI,CAAC,UAAU,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,gBAAgB,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,0BAA0B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AACpH,CAAC;AAED,SAAS,mBAAmB,CAC1B,IAAY,EACZ,UAAoB,EACpB,SAAkB;IAElB,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC5C,OAAO,0BAA0B,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,MAAM;QACvD,CAAC,CAAC,gBAAgB,MAAM,2BAA2B,MAAM,CAAC,IAAI,CAAC,MAAM;QACrE,CAAC,CAAC,MAAM,CAAC;AACb,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,SAA6B;IACjE,IAAI,SAAS,IAAI,iBAAiB,CAAC,IAAI,EAAE,SAAS,CAAC;QAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACxE,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,uFAAuF;AACvF,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,OAAyB;IAEzB,uBAAuB,EAAE,CAAC;IAC1B,MAAM,4BAA4B,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAChE,MAAM,6BAA6B,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACpE,MAAM,sBAAsB,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC9E,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,OAAO,CAAC,uBAAuB;QAC3C,CAAC,CAAC,OAAO,CAAC,cAAc;QACxB,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5E,MAAM,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxE,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,MAAM,kBAAkB,CACxC,SAAS,EACT,OAAO,CAAC,mBAAmB,CAC5B,CAAC;IACF,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;IAC9C,MAAM,kBAAkB,GAAG,MAAM,yBAAyB,CACxD,OAAO,CAAC,kBAAkB,IAAI,EAAE,EAChC,CAAC,GAAG,KAAK,EAAE,SAAS,CAAC,CACtB,CAAC;IACF,uBAAuB,CAAC,SAAS,EAAE,CAAC,GAAG,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAC1D,oBAAoB,CAAC,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,QAAQ,UAAU,EAAE,KAAK,CAAC,CAAC;IAClE,MAAM,SAAS,CACb,WAAW,EACX,iBAAiB,CACf,CAAC,GAAG,KAAK,EAAE,SAAS,CAAC,EACrB,OAAO,CAAC,WAAW,EACnB,SAAS,EACT,SAAS,EACT,gBAAgB,CAAC,OAAO,CAAC,EACzB,SAAS,EACT,OAAO,CAAC,SAAS,EACjB,kBAAkB,CACnB,EACD,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAC5B,CAAC;IACF,OAAO;QACL,IAAI,EAAE,CAAC,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;QACxD,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAyB;IACjD,OAAO;QACL,GAAG,CAAC,OAAO,CAAC,mBAAmB,IAAI,EAAE,CAAC;QACtC,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;QAChC,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,sBAAsB,IAAI,EAAE,CAAC;KACvD,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB;IAC9B,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;QAC5D,MAAM,IAAI,kBAAkB,CAAC,6CAA6C,CAAC,CAAC;AAChF,CAAC","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { containsControl } from \"../value-guards\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, realpath, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport {\n requireNativeTranscriptViews,\n requireNativeHookRoots,\n} from \"../native-transcript-state\";\nimport { requireCandidateArtifactRoots } from \"../candidate-artifacts\";\nimport { workspaceBoundaryException } from \"../fixtures/workspace-state\";\nimport { requireWritableCacheRoots } from \"../runtime/shared-cache\";\nimport {\n insideRuntimeRoot,\n isRuntimeHomeRoot,\n requireRuntimeReadRoots,\n} from \"../runtime/paths\";\nimport {\n commandRuntimeRoot,\n HostIsolationError,\n requireDisjointState,\n requireIsolationPaths,\n type IsolatedCommand,\n type IsolationOptions,\n} from \"./isolation-common\";\n\nexport { HostIsolationError } from \"./isolation-common\";\nexport type { IsolatedCommand } from \"./isolation-common\";\n\nconst SANDBOX_EXEC = \"/usr/bin/sandbox-exec\";\n\nfunction quoted(path: string): string {\n if (containsControl(path))\n throw new HostIsolationError(\"sandbox path contains a control character\");\n return path.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"');\n}\n\n/** Protect canonical roots while preserving explicitly granted access. */\nexport function macSandboxProfile(\n deniedRoots: string[],\n denyNetwork = false,\n readOnlyRoots: string[] = [],\n writableRuntimeRoot?: string,\n transcriptReadRoots: string[] = [],\n workspace?: string,\n localHttp?: boolean,\n writableCacheRoots?: string[],\n): string {\n requireProfileRoots(deniedRoots);\n return [\n \"(version 1)\",\n \"(allow default)\",\n ...(denyNetwork ? [\"(deny network*)\"] : []),\n ...localHttpRules(localHttp),\n ...[...new Set(deniedRoots)]\n .sort()\n .flatMap((path) => [\n `(deny file-read* ${workspaceReadFilter(path, readExceptions(path, readOnlyRoots, writableRuntimeRoot, transcriptReadRoots, workspace, writableCacheRoots), workspace)})`,\n `(deny file-write* ${rootFilter(path, [...writableExceptions(path, writableRuntimeRoot, writableCacheRoots), ...workspaceBoundaryException(path, workspace)])})`,\n ]),\n ...deniedRoots.flatMap((path) =>\n workspaceBoundaryException(path, workspace).map(\n () => `(deny file-read-data (literal \"${quoted(path)}\"))`,\n ),\n ),\n ...[...readOnlyRoots, ...transcriptReadRoots].map(\n (path) => `(deny file-write* (subpath \"${quoted(path)}\"))`,\n ),\n ...deniedRoots.flatMap((root) =>\n ancestorMetadataRules(\n root,\n readExceptions(\n root,\n readOnlyRoots,\n writableRuntimeRoot,\n transcriptReadRoots,\n workspace,\n writableCacheRoots,\n ),\n ),\n ),\n \"\",\n ].join(\"\\n\");\n}\n\nfunction localHttpRules(enabled: boolean | undefined): string[] {\n return enabled\n ? [\n '(allow network-bind (local ip \"*:*\"))',\n '(allow network-inbound (local ip \"localhost:*\"))',\n '(allow network-outbound (remote ip \"localhost:*\"))',\n ]\n : [];\n}\n\nfunction ancestorMetadataRules(root: string, readRoots: string[]): string[] {\n const ancestors = new Set<string>();\n for (const readRoot of readRoots) {\n for (\n let path = dirname(readRoot);\n insideRuntimeRoot(root, path);\n path = dirname(path)\n ) {\n ancestors.add(path);\n if (path === resolve(root)) break;\n }\n }\n return [...ancestors]\n .sort()\n .map((path) => `(allow file-read-metadata (literal \"${quoted(path)}\"))`);\n}\n\nfunction requireProfileRoots(roots: string[]): void {\n if (!roots.length || roots.some((path) => !path.startsWith(\"/\")))\n throw new HostIsolationError(\"sandbox roots must be absolute and nonempty\");\n}\n\nfunction readExceptions(\n root: string,\n readRoots: string[],\n writableRuntimeRoot: string | undefined,\n transcriptReadRoots: string[],\n workspace?: string,\n writableCacheRoots: string[] = [],\n): string[] {\n const exceptions = isRuntimeHomeRoot(root)\n ? readRoots.filter((path) => insideRuntimeRoot(root, path))\n : [];\n return [\n ...transcriptReadRoots.filter((path) => insideRuntimeRoot(root, path)),\n ...exceptions,\n ...writableExceptions(root, writableRuntimeRoot, writableCacheRoots),\n ...workspaceBoundaryException(root, workspace),\n ];\n}\n\nfunction writableExceptions(\n root: string,\n runtime: string | undefined,\n caches: string[] = [],\n): string[] {\n return [\n ...ownedException(root, runtime),\n ...caches.flatMap((cache) => ownedException(root, cache)),\n ];\n}\n\nfunction rootFilter(root: string, exceptions: string[]): string {\n const base = `(subpath \"${quoted(root)}\")`;\n if (!exceptions.length) return base;\n return `(require-all ${base} ${exceptions.map((path) => `(require-not (subpath \"${quoted(path)}\"))`).join(\" \")})`;\n}\n\nfunction workspaceReadFilter(\n root: string,\n exceptions: string[],\n workspace?: string,\n): string {\n const filter = rootFilter(root, exceptions);\n return workspaceBoundaryException(root, workspace).length\n ? `(require-all ${filter} (require-not (literal \"${quoted(root)}\")))`\n : filter;\n}\n\nfunction ownedException(root: string, ownedRoot: string | undefined): string[] {\n if (ownedRoot && insideRuntimeRoot(root, ownedRoot)) return [ownedRoot];\n return [];\n}\n\n/** Build the outer boundary before launching an agent or candidate-controlled code. */\nexport async function prepareMacSandboxCommand(\n options: IsolationOptions,\n): Promise<IsolatedCommand> {\n requireSandboxAvailable();\n await requireNativeTranscriptViews(options.transcriptReadRoots);\n await requireCandidateArtifactRoots(options.candidateArtifactRoots);\n await requireNativeHookRoots(options.hookReadRoots, options.privateStateRoot);\n requireIsolationPaths(options);\n const workspace = await realpath(options.workspace);\n const roots = options.protectedRootsCanonical\n ? options.protectedRoots\n : await Promise.all(options.protectedRoots.map((path) => realpath(path)));\n await mkdir(options.privateStateRoot, { recursive: true, mode: 0o700 });\n const stateRoot = await realpath(options.privateStateRoot);\n const ownedRoot = await commandRuntimeRoot(\n stateRoot,\n options.writableRuntimeRoot,\n );\n const readRoots = options.readOnlyRoots ?? [];\n const writableCacheRoots = await requireWritableCacheRoots(\n options.writableCacheRoots ?? [],\n [...roots, stateRoot],\n );\n requireRuntimeReadRoots(readRoots, [...roots, stateRoot]);\n requireDisjointState(workspace, roots, stateRoot);\n const profilePath = resolve(stateRoot, `host-${randomUUID()}.sb`);\n await writeFile(\n profilePath,\n macSandboxProfile(\n [...roots, stateRoot],\n options.denyNetwork,\n readRoots,\n ownedRoot,\n curatedReadRoots(options),\n workspace,\n options.localHttp,\n writableCacheRoots,\n ),\n { flag: \"wx\", mode: 0o600 },\n );\n return {\n argv: [SANDBOX_EXEC, \"-f\", profilePath, ...options.argv],\n release: async () => {\n await rm(profilePath, { force: true });\n },\n };\n}\n\nfunction curatedReadRoots(options: IsolationOptions): string[] {\n return [\n ...(options.transcriptReadRoots ?? []),\n ...(options.hookReadRoots ?? []),\n ...Object.values(options.candidateArtifactRoots ?? {}),\n ];\n}\n\nfunction requireSandboxAvailable(): void {\n if (process.platform !== \"darwin\" || !existsSync(SANDBOX_EXEC))\n throw new HostIsolationError(\"macOS sandbox-exec isolation is unavailable\");\n}\n"]}
|