Resolve the task sandbox from config.toml and add task --read-only#508
Open
cubicj wants to merge 1 commit into
Open
Resolve the task sandbox from config.toml and add task --read-only#508cubicj wants to merge 1 commit into
cubicj wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The plugin always overrides the user's configured
sandbox_modewith hardcoded sandbox values (#482).buildThreadParams/buildResumeParamsfall back to"read-only"whenever the caller passes nothing, and the task path hardcodes the--writeternary to"workspace-write"/"read-only", so asandbox_modein~/.codex/config.tomlnever reaches any job. Users who want config-driven sandboxes (e.g.danger-full-accessfor trusted delegation setups) end up patching the installed plugin by hand.Change
Task paths now send
sandbox: nullwhen the caller does not ask for a specific sandbox, letting the app-server resolve it fromconfig.toml— the same mechanism the plugin already relies on formodel(model: options.model ?? nullfalls back to the configured model today). An explicit--writestill forcesworkspace-write, and both review paths (native and adversarial) deliberately keep their pinnedread-onlysandbox.lib/codex.mjs:buildThreadParamsandbuildResumeParamschangeoptions.sandbox ?? "read-only"tooptions.sandbox ?? null.ThreadStartParams.sandboxis declaredSandboxMode | null, so this is type-clean.codex-companion.mjs: the task path changesrequest.write ? "workspace-write" : "read-only"torequest.write ? "workspace-write" : request.readOnly ? "read-only" : null.Because omitting
--writenow defers to config instead of guaranteeing read-only, the same change adds atask --read-onlyflag as the per-run way to pin the read-only sandbox: it is mutually exclusive with--write(a combined call fails with a clear error), survives the background request round trip into the detached worker, and applies to resumed threads. The rescue command/agent/skill texts are updated one line each so that read-only intent means passing--read-onlyrather than merely omitting--write. The stop-review-gate hook's internal task now passes--read-onlyexplicitly, so every review-shaped run — native review, adversarial review, and the stop-time gate task — keeps a pinned read-only sandbox regardless of config.Behavior only changes for users who set
sandbox_modeinconfig.toml: when it is absent, the app-server's own default for an unset sandbox remains read-only, so stock installations keep today's behavior. Inheriting a permissive mode from config is a deliberate user choice made in their own Codex configuration, and #506 (resolved model/effort/sandbox capture, from #481) makes the inherited value visible on every job record. An explicit per-run escalation flag (#145, PR #147) is complementary to this config-driven default and intentionally out of scope here.Verification
thread/startwithsandbox: nullandconfig.tomlsandbox_mode = "danger-full-access"returned the config-resolved{"type":"dangerFullAccess"}sandbox in the response echo; explicit values still override.npm test: 94/94 passing. The fake-codex fixture now recordsthread/start/thread/resumeparams, with assertions covering every path: a plain task sendssandbox: null,--writesendsworkspace-write,--read-onlypinsread-onlyon fresh, resumed, and background-worker threads,--write --read-onlyis rejected, and native review, adversarial review, and the stop-review-gate hook's task all still sendread-only.npm run build(typecheck viatsconfig.app-server.json): clean.git diff --checkagainst the base commit: clean.Related Issues
Fixes #482