diff --git a/src/cli.codex_smoke.test.ts b/src/cli.codex_smoke.test.ts index 78e8b07a..cf5aa7c0 100644 --- a/src/cli.codex_smoke.test.ts +++ b/src/cli.codex_smoke.test.ts @@ -391,6 +391,20 @@ Deno.test({ defaultRun.requestLog.includes('"method":"thread/start"'), true, ); + assertEquals( + defaultRun.requestLog.includes('"sandbox":"workspace-write"'), + true, + ); + assertEquals( + defaultRun.requestLog.includes( + '"sandboxPolicy":{"type":"workspaceWrite","writableRoots":[', + ), + true, + ); + assertEquals( + defaultRun.requestLog.includes('"networkAccess":true'), + true, + ); assertEquals(defaultRun.requestLog.includes('"model":null'), true); assertEquals( defaultRun.requestLog.includes( @@ -455,6 +469,40 @@ Deno.test({ projectDocRun.argsLog.includes("project_doc_max_bytes=0"), true, ); + + await Deno.remove(mock.requestLogPath).catch((err) => { + if (err instanceof Deno.errors.NotFound) return; + throw err; + }); + const yoloDeck = await writeDeck( + dir, + "codex-cli/default", + undefined, + "Smoke deck.", + "additionalParams = { gambitYolo = true }", + ); + const yoloRun = await runDeck({ + deckPath: yoloDeck, + codexBinPath: mock.binPath, + argsLogPath: mock.argsLogPath, + requestLogPath: mock.requestLogPath, + cwd: dir, + }); + assertEquals( + yoloRun.code, + 0, + formatCommandDiagnostics("run codex-cli/default yolo", yoloRun), + ); + assertEquals( + yoloRun.requestLog.includes('"sandbox":"danger-full-access"'), + true, + ); + assertEquals( + yoloRun.requestLog.includes( + '"sandboxPolicy":{"type":"dangerFullAccess"}', + ), + true, + ); } finally { await Deno.remove(dir, { recursive: true }).catch((err) => { if (err instanceof Deno.errors.NotFound) return; diff --git a/src/decks/actions/policy_read/PROMPT.md b/src/decks/actions/policy_read/PROMPT.md index 5bf9745d..5675d80f 100644 --- a/src/decks/actions/policy_read/PROMPT.md +++ b/src/decks/actions/policy_read/PROMPT.md @@ -3,4 +3,4 @@ label = "policy_read" execute = "../policy_read.deck.ts" +++ -Compute-only deck for loading policy docs under `workloops/policy/`. +Compute-only deck for loading policy docs under `memos/vault/policies/`. diff --git a/src/decks/actions/policy_search/PROMPT.md b/src/decks/actions/policy_search/PROMPT.md index 5aa2a95d..b22d5f8a 100644 --- a/src/decks/actions/policy_search/PROMPT.md +++ b/src/decks/actions/policy_search/PROMPT.md @@ -16,7 +16,7 @@ Your job: read and summarize the most relevant policies for an upcoming change. Discovery flow: -1. Call `policy_read` with `path="workloops/policy/README.md"` first. +1. Call `policy_read` with `path="memos/vault/policies/README.md"` first. 2. Discover candidate policy file paths from the README markdown links. 3. Select the most relevant policy paths for the requested change. 4. Call `policy_read` for each selected policy path. @@ -29,7 +29,7 @@ Selection rules: - Prefer 2-3 docs by default unless a broader set is clearly needed. - Always include `policy/deck-format-1.0.md` when frontmatter, schema, or deck structure may change. -- If uncertain, include `workloops/policy/README.md` first. +- If uncertain, include `memos/vault/policies/README.md` first. Response requirements: diff --git a/src/decks/gambit-bot/INTENT.md b/src/decks/gambit-bot/INTENT.md index d13e721b..9922247e 100644 --- a/src/decks/gambit-bot/INTENT.md +++ b/src/decks/gambit-bot/INTENT.md @@ -30,11 +30,11 @@ `INTENT.md` first, then make deck/file changes that implement that intent. - `INTENT.md` and `policy/*.md` are guidance-only and must not be treated as executable prompts. -- Treat `workloops/policy/` as a discovery mechanism for long-term behavior, +- Treat `memos/vault/policies/` as a discovery mechanism for long-term behavior, edge cases, and documented preferences that should shape assistant behavior over time. - The assistant being built should be able to understand its purpose thoroughly - by relying on the guidance in `workloops/policy/` plus the current + by relying on the guidance in `memos/vault/policies/` plus the current `INTENT.md`. - Do not distract users with internal processes or jargon. Focus on helping them, and avoid details that do not directly improve their understanding of @@ -75,7 +75,7 @@ `packages/gambit/src/decks/gambit-bot/scenarios/`. - Ensure guidance remains consistent with `packages/gambit/src/decks/gambit-bot/policy/` and - `workloops/policy/templates/INTENT.md`. + `memos/vault/policies/templates/INTENT.md`. ## Activation / revalidation @@ -90,12 +90,12 @@ ### Inputs -- `workloops/policy/templates/INTENT.md` +- `memos/vault/policies/templates/INTENT.md` - `packages/gambit/src/decks/gambit-bot/PROMPT.md` -- `packages/gambit/src/decks/gambit-bot/workloops/policy/product-command.md` +- `packages/gambit/src/decks/gambit-bot/memos/vault/policies/product-command.md` - `packages/gambit/src/decks/gambit-bot/policy/deck-format-1.0.md` ### Related -- `packages/gambit/src/decks/gambit-bot/workloops/policy/README.md` -- `workloops/initiatives/gambit-product-command-launch/INTENT.md` +- `packages/gambit/src/decks/gambit-bot/memos/vault/policies/README.md` +- `memos/vault/vault/gambit-product-command-launch/INTENT.md` diff --git a/src/decks/gambit-bot/policy/deck-format-1.0.md b/src/decks/gambit-bot/policy/deck-format-1.0.md index 4ea16600..d7b24d80 100644 --- a/src/decks/gambit-bot/policy/deck-format-1.0.md +++ b/src/decks/gambit-bot/policy/deck-format-1.0.md @@ -183,13 +183,13 @@ Every deck folder MUST include: Deck folders SHOULD include: - `INTENT.md` -- `workloops/policy/` +- `memos/vault/policies/` Notes (recommended behavior): - Gambit tooling looks for `INTENT.md` and MAY scaffold it if missing. - `INTENT.md` SHOULD follow the canonical intent headings from - `workloops/policy/templates/INTENT.md`. + `memos/vault/policies/templates/INTENT.md`. - `INTENT.md` explains **what** the deck should accomplish and why: goals, non-goals, constraints, tradeoffs, and escalation conditions. It is the source of truth for human alignment and for Gambit Build Assistant decisions about @@ -209,7 +209,7 @@ Deck folders MAY include: - `README.md` (recommended) - `samples/` (recommended) - `snippets/` (recommended) -- `workloops/policy/` (optional policy docs) +- `memos/vault/policies/` (optional policy docs) - `reviews/` (optional AARs / retros) - `actions/`, `scenarios/`, `graders/` (recommended organization only) diff --git a/src/decks/guides/gambit-bot-review.md b/src/decks/guides/gambit-bot-review.md index ecb4f2f9..e15fbfc6 100644 --- a/src/decks/guides/gambit-bot-review.md +++ b/src/decks/guides/gambit-bot-review.md @@ -6,7 +6,7 @@ bot creation and updates. Required behavior - First step for new builds: draft `INTENT.md` using the Product Command - headings from `workloops/policy/templates/INTENT.md`. + headings from `memos/vault/policies/templates/INTENT.md`. - Ask for the minimum kickoff inputs needed to complete intent: purpose, 2-3 example user prompts, success criteria, and data sources. - Use Deck Format v1.0 by default: `PROMPT.md` as the single entrypoint with diff --git a/src/providers/codex.ts b/src/providers/codex.ts index 12962243..e5d4c0bb 100644 --- a/src/providers/codex.ts +++ b/src/providers/codex.ts @@ -629,17 +629,14 @@ async function prepareCodexMcpRootDeck(input: { }; } -function appServerThreadSandboxPolicy(input: { +function appServerSandboxMode(input: { cwd: string; params?: Record; -}): Record { +}): "danger-full-access" | "workspace-write" { if (shouldSkipCodexSandboxConfig(input.params)) { - return { type: "dangerFullAccess" }; + return "danger-full-access"; } - return { - type: "workspaceWrite", - writableRoots: [input.cwd], - }; + return "workspace-write"; } function appServerTurnSandboxPolicy(input: { @@ -652,6 +649,9 @@ function appServerTurnSandboxPolicy(input: { return { type: "workspaceWrite", writableRoots: [input.cwd], + networkAccess: true, + excludeTmpdirEnvVar: false, + excludeSlashTmp: false, }; } @@ -1444,7 +1444,7 @@ async function defaultAppServerTurnRunner( model: model && model !== "default" ? model : null, cwd: input.cwd, approvalPolicy: "never", - sandboxPolicy: appServerThreadSandboxPolicy({ + sandbox: appServerSandboxMode({ cwd: input.cwd, params: input.params, }), @@ -1454,7 +1454,7 @@ async function defaultAppServerTurnRunner( model: model && model !== "default" ? model : null, cwd: input.cwd, approvalPolicy: "never", - sandboxPolicy: appServerThreadSandboxPolicy({ + sandbox: appServerSandboxMode({ cwd: input.cwd, params: input.params, }),