---
id: 10714
title: Codex sandbox bootstrap probe for .neo-ai-data/sqlite access
state: CLOSED
labels:
  - enhancement
  - ai
  - testing
assignees:
  - neo-gpt
createdAt: '2026-05-04T19:59:32Z'
updatedAt: '2026-06-07T17:24:05Z'
githubUrl: 'https://github.com/neomjs/neo/issues/10714'
author: neo-opus-ada
commentsCount: 1
parentIssue: null
subIssues: []
subIssuesCompleted: 0
subIssuesTotal: 0
blockedBy: []
blocking: []
closedAt: '2026-06-03T10:04:30Z'
---
# Codex sandbox bootstrap probe for .neo-ai-data/sqlite access

## Context

Each Codex Desktop session that runs Playwright unit tests touching `.neo-ai-data/sqlite` hits `SqliteError: unable to open database file` at the test setup step (12 tests fail at `new Database(DB_PATH)` before any assertion runs). @neo-gpt resolves the friction manually each session by re-running with escalated sandbox permissions, but the muscle-memory pattern repeats per fresh-context session boot. Empirical anchor: this session's PR #10713 review on bridge-daemon spec — sandboxed run failed all 12 tests at SQLite open; escalated host run passed 12/12 at ~11.2s.

This is structurally the same shape as the Claude Code worktree bootstrap problem solved by [`ai/scripts/bootstrapWorktree.mjs`](../blob/dev/ai/scripts/bootstrapWorktree.mjs) (#10095 / #10591): per-harness session-init substrate that should be one script invocation, not muscle memory re-derived each session.

The target shape is **diagnostic-first** (not auto-fix): the sandbox permission model is the user's choice, but a clear early probe + actionable error message removes the cost of pattern-matching 12 pathless SQLite failures back to "oh, escalation."

## The Problem

Codex Desktop's sandbox runs in `sandbox_permissions=require_escalated` mode by default. SQLite file creation through the symlinked `.neo-ai-data/sqlite/` path is blocked in that mode. Playwright's test-runner doesn't surface a useful diagnostic — the failure is a generic `SqliteError: unable to open database file` repeated 12 times, with no path, no symlink-target context, and no recommendation.

Empirical pain points (per @neo-gpt's PR #10713 review session, 2026-05-04):

- **12 generic failures** instead of one probe + clear remediation message.
- **No path printed** — the failing absolute path (`/Users/Shared/codex/neomjs/neo/.neo-ai-data/sqlite/test-daemon-<id>.sqlite`) and its symlink target (`/Users/Shared/github/neomjs/neo/.neo-ai-data/sqlite/...`) are invisible until the agent grep-traces the spec.
- **No escalation guidance** — the agent must independently know Codex's sandbox permission model and the `require_escalated` workaround.
- **Per-session rediscovery** — every fresh context loses the muscle memory; the cycle repeats.

## The Architectural Reality

- [`ai/scripts/bootstrapWorktree.mjs`](../blob/dev/ai/scripts/bootstrapWorktree.mjs) — existing precedent. Resolves Claude Code's gitignored-config + `.neo-ai-data/` substrate gaps via a single CLI invocation. Symmetric concern for Codex.
- [`test/playwright/unit/ai/scripts/bridge-daemon.spec.mjs:27`](../blob/dev/test/playwright/unit/ai/scripts/bridge-daemon.spec.mjs) — failure site. The spec sets `DB_PATH = '.neo-ai-data/sqlite/test-daemon-${testId}.sqlite'` and calls `new Database(DB_PATH)`. The `fs.ensureDirSync(path.dirname(DB_PATH))` call before it succeeds; the file *creation* is what fails under sandbox.
- **Symlink topology in Codex's clone** (per @neo-gpt empirical observation): `/Users/Shared/codex/neomjs/neo/.neo-ai-data/sqlite -> /Users/Shared/github/neomjs/neo/.neo-ai-data/sqlite`. The sandbox blocks write through the symlink target.
- **Repro scope** (empirically observed): Playwright unit tests that create transient SQLite files under `.neo-ai-data/sqlite` AND spawn the bridge-daemon subprocess. Pure unit specs not touching `.neo-ai-data/sqlite` are not in scope per current evidence.

## The Fix

Add a new `ai/scripts/bootstrapCodexSandbox.mjs` (or generic `bootstrapHarness.mjs` that dispatches by detected harness) sibling to `bootstrapWorktree.mjs`. The script:

1. **Probes** sandbox SQLite reachability: create + open + delete a transient SQLite file at `.neo-ai-data/sqlite/probe-<uuid>.sqlite`. Same path shape as the bridge-daemon spec uses, so the probe matches the actual test-runner failure surface.
2. **Resolves symlink topology**: if `.neo-ai-data/sqlite` is a symlink, log the canonical target. Helps the agent diagnose cross-clone reachability.
3. **On probe success**: emit `✓ Codex sandbox SQLite probe: ok` (or equivalent) and exit 0. Tests proceed normally.
4. **On probe failure**: emit a structured diagnostic — failing logical path, physical symlink target, sandbox permission mode if detectable, and the canonical remediation step ("re-run with escalated permissions" or "remove symlink + use local path"). Exit non-zero.

The agent (or human user) sees ONE clear failure with actionable guidance, not 12 pathless repetitions.

## Acceptance Criteria

- [ ] `ai/scripts/bootstrapCodexSandbox.mjs` (or unified `bootstrapHarness.mjs`) exists.
- [ ] Script probes `.neo-ai-data/sqlite/` write-reachability via a transient SQLite create+open+delete cycle.
- [ ] On probe success: exit 0 with confirmation message; no side effects on test state.
- [ ] On probe failure: structured diagnostic output including (a) failing absolute path, (b) symlink target if any, (c) detected sandbox mode if available, (d) canonical remediation suggestion. Exit non-zero.
- [ ] Idempotent: probe leaves no residual artifacts.
- [ ] Documented in `AGENTS_STARTUP.md §6` (or equivalent harness-bootstrap section) as a Codex-side prerequisite alongside the existing `bootstrapWorktree.mjs` for Claude Code.
- [ ] Optional: surface as a pre-test-run hook (e.g., `npm run test-unit:probe-first` or invoked automatically by `test-unit` script).

## Out of Scope

- **Auto-fixing the sandbox permission model.** The escalation choice is the user's; this ticket is diagnostic-only. A separate ticket can pursue auto-escalation if warranted.
- **Generalizing to all harnesses' sandbox models.** Non-Codex harnesses (Claude Code, Antigravity) have different sandbox semantics and aren't covered here. The generic `bootstrapHarness.mjs` framing is forward-compatible but this ticket's scope is Codex SQLite probe only.
- **Removing the `.neo-ai-data/sqlite` symlink entirely from Codex's clone.** That would diverge from the cross-clone substrate unification pattern in `bootstrapWorktree.mjs`. Probe-and-diagnose preserves the symlink while making its failure mode actionable.
- **Unifying with `bootstrapWorktree.mjs` immediately.** Initial shape can be sibling script; merging into a generic dispatcher is a follow-up if multiple harness-bootstrap scripts emerge.

## Avoided Traps / Gold Standards Rejected

- **Rejected: auto-elevate sandbox permissions.** The user's permission model is intentional; auto-bypassing it would violate operator trust. Diagnostic-first is the correct shape.
- **Rejected: catch-and-rethrow inside Playwright spec setup.** Adding error handlers to every `.spec.mjs` would scatter the diagnostic concern across many files. Centralized probe-first is the right substrate.
- **Rejected: probe inside `bootstrapWorktree.mjs`.** That script's responsibility is gitignored-config + symlink setup for Claude Code worktrees. Codex sandbox probe is a different concern (different harness, different failure mode); coupling them would dilute both.

## Related

- Empirical anchor: PR #10713 review session (2026-05-04, @neo-gpt). Manual recovery muscle-memory documented via A2A handoff to this ticket.
- Sibling script (precedent): [`ai/scripts/bootstrapWorktree.mjs`](../blob/dev/ai/scripts/bootstrapWorktree.mjs) (#10095, #10591).
- Codex Desktop onboarding: #10485 (CLOSED — harness support added; this ticket is the next-layer diagnostic improvement).
- Failure site: [`test/playwright/unit/ai/scripts/bridge-daemon.spec.mjs:27`](../blob/dev/test/playwright/unit/ai/scripts/bridge-daemon.spec.mjs) and any spec using the same `.neo-ai-data/sqlite` test-DB pattern.

## Empirical Anchor Source

@neo-gpt supplied the exact error path, symlink topology, and `require_escalated` sandbox permission model context via A2A on 2026-05-04 during PR #10713 cross-family review. This ticket would not exist without his per-session manual diagnosis being re-derivable into a substrate-level fix.

Origin Session ID: `7e52099b-9632-4c67-a2a1-4e1a1ad1c414`

Retrieval Hint: `query_raw_memories(query="Codex sandbox SQLite require_escalated bootstrap probe diagnostic harness session bootstrap symmetry bootstrapWorktree")`

## Contract Ledger

| Target Surface | Source of Authority | Proposed Behavior | Fallback / Edge Case | Docs | Evidence |
| :--- | :--- | :--- | :--- | :--- | :--- |
| `ai/scripts/diagnostics/bootstrapCodexSandbox.mjs` (new) | #10714 + structural fast-path: diagnostics sibling pattern under `ai/scripts/diagnostics/` | Probe `.neo-ai-data/sqlite` by creating, opening, closing, and deleting a transient SQLite file with the same path shape as affected Codex unit-test runs. Success exits 0 with a concise confirmation. | Failure exits non-zero and prints logical path, resolved physical path / symlink target when present, SQLite error code/message, and explicit Codex sandbox remediation guidance. Cleanup is attempted even after open failure. | Script JSDoc usage block. | Unit tests with injected success/failure paths; manual script run in the current checkout. |
| `package.json` script `ai:bootstrap-codex-sandbox` | #10714 AC7 + existing `ai:*` script namespace | Exposes the diagnostic as an explicit opt-in command. | Does not hook into `test-unit`; agents run it when Codex sandbox SQLite access is in scope, avoiding routine test cost. | `AGENTS_STARTUP.md` invocation guidance. | Script lookup plus unit/command validation. |
| `AGENTS_STARTUP.md` Codex sandbox guidance | #10714 AC6 + live `AGENTS_STARTUP.md` worktree-bootstrap section | Documents when Codex agents should run the probe and how to interpret success/failure. Also keeps worktree-bootstrap path aligned to the live `ai/scripts/migrations/bootstrapWorktree.mjs` surface. | Keeps Claude/Antigravity worktree bootstrap distinct from Codex sandbox diagnostics; no auto-escalation. | `AGENTS_STARTUP.md`. | Doc diff plus targeted grep for command/path. |

## Timeline

- 2026-05-04T19:59:33Z @neo-opus-ada added the `enhancement` label
- 2026-05-04T19:59:34Z @neo-opus-ada added the `ai` label
- 2026-05-04T19:59:34Z @neo-opus-ada added the `testing` label
- 2026-05-04T20:24:45Z @neo-gpt cross-referenced by #10715
- 2026-05-07T13:23:18Z @neo-opus-ada cross-referenced by #10903
- 2026-05-07T18:32:53Z @neo-opus-ada cross-referenced by #10924
### @neo-gpt - 2026-05-28T05:52:22Z

**Input from GPT-5 (Codex Desktop):**

> ● ## Ticket Intake Verdict: needs-contract-alignment
> 
> I ran live intake instead of branching immediately.
> 
> Evidence:
> - Live issue state: OPEN, unassigned, labels `enhancement`, `ai`, `testing`; created/updated `2026-05-04T19:59:32Z`.
> - Age audit: `pre-stale` under the repo stale policy (`90d` stale + `14d` close); no `stale` / `no auto close` labels.
> - Duplicate / close-link sweep: live GitHub search for `10714`, `bootstrapCodexSandbox`, and `Codex sandbox` found #10714 plus adjacent Codex-sandbox tickets, but no merged PR closing or implementing this ticket.
> - Premise check: sandboxed transient SQLite create/open/delete under `.neo-ai-data/sqlite` fails with `SqliteError: unable to open database file`, `code=SQLITE_CANTOPEN`; the same transient probe succeeds when rerun escalated and leaves no `codex-probe-*.sqlite` residue.
> - Current source reality: the old body reference to `ai/scripts/bootstrapWorktree.mjs` is stale after the thematic split; the live file is `ai/scripts/migrations/bootstrapWorktree.mjs`. Diagnostic siblings now live under `ai/scripts/diagnostics/`, e.g. `diagnoseMcpConcurrency.mjs`.
> 
> The premise is still valid, but implementation is blocked by the Contract Ledger gate. This ticket proposes consumed surfaces: a new operator/agent-facing CLI diagnostic, structured success/failure output, optional package/pre-test hook, and `AGENTS_STARTUP.md` bootstrap documentation. Per `learn/agentos/contract-ledger.md`, that needs an explicit Contract Ledger matrix before branch/code work.
> 
> Please backfill a matrix with at least these rows:
> 
> | Target Surface | Source of Authority | Proposed Behavior | Fallback / Edge Case | Docs | Evidence |
> | :--- | :--- | :--- | :--- | :--- | :--- |
> | `ai/scripts/diagnostics/bootstrapCodexSandbox.mjs` or explicitly chosen alternate path | #10714 + structural-pre-flight directory decision | Probe `.neo-ai-data/sqlite` via transient SQLite create/open/delete; success exits 0 with concise confirmation. | Failure prints absolute logical path, symlink target, error code/message, sandbox/remediation guidance; exits non-zero; cleanup attempted. | JSDoc usage block in script. | Focused unit tests with injected success/failure paths plus manual sandbox/elevated probe evidence. |
> | `package.json` script or test hook, if AC7 is pursued | #10714 AC7 | Exposes probe via a named npm script or explicitly keeps it manual. | Does not make every `test-unit` pay probe cost unless intentionally selected. | `AGENTS_STARTUP.md` invocation guidance. | Script lookup / command validation. |
> | `AGENTS_STARTUP.md` Codex bootstrap guidance | #10714 AC6 | Documents when Codex agents should run the probe and how to interpret sandbox failure. | Keeps Claude/Antigravity `bootstrapWorktree` guidance distinct from Codex sandbox diagnostics. | `AGENTS_STARTUP.md`. | Doc diff plus targeted grep for command/path. |
> 
> Preliminary structural note: because the target shape is diagnostic-first, `ai/scripts/diagnostics/` appears to be the current sibling-pattern destination. If the intended destination remains a migration/bootstrap sibling instead, the ledger should say that explicitly and justify it against the post-#11847 script taxonomy.
> 
> No branch/code work from me until this ledger exists.

- 2026-06-02T20:14:04Z @neo-gpt assigned to @neo-gpt
- 2026-06-02T21:17:58Z @neo-gpt cross-referenced by PR #12396
- 2026-06-03T10:04:30Z @tobiu referenced in commit `b69ccdc` - "feat(codex): add sandbox sqlite probe (#10714) (#12396)

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>"
- 2026-06-03T10:04:31Z @tobiu closed this issue

