Back to Oh My Openagent

Isolation — QA ONLY our plugin, never the user's real Codex

.agents/skills/codex-qa/references/isolation.md

4.11.02.5 KB
Original Source

Isolation — QA ONLY our plugin, never the user's real Codex

The whole point of this skill: exercise the omo plugin in a real Codex without reading or writing the user's ~/.codex, and without a real model API call. Two levers do all the work.

Lever 1 — an isolated CODEX_HOME

CODEX_HOME is Codex's master state root: config.toml, auth.json, sessions, the state SQLite, plugins, and logs all hang off it (utils/home-dir/src/lib.rs). Point it at a fresh temp dir and Codex reads/writes nothing else.

Gotcha: when CODEX_HOME is set it must already exist or Codex hard-errors. cqa_mk_isolated_home creates it first.

cqa_mk_isolated_home also exports:

  • OMO_CODEX_PROJECT + QA_CWD → a sandbox project dir, so the installer's project-local cleanup and the TUI's cwd never touch your real tree.
  • CODEX_LOCAL_BIN_DIR=$CODEX_HOME/bin → component bins land in the sandbox. (Even without this, a non-default CODEX_HOME already routes bins to $CODEX_HOME/bin; with the DEFAULT home they would leak to ~/.local/bin.)
  • OMO_DISABLE_POSTHOG=1 + OMO_CODEX_DISABLE_POSTHOG=1 → no install/telemetry network call.

Proof it stayed clean: cqa_guard_real_home shasums ~/.codex/config.toml before, cqa_assert_real_home_unchanged re-checks after. Every script runs it.

Lever 2 — a local mock model (no real API)

Codex must reach a model to run a turn. Instead of OpenAI, we run scripts/lib/mock-model.mjs (OpenAI Responses SSE) on localhost and point a custom provider at it via -c overrides:

-c model="mock-model"
-c model_provider="mock_provider"
-c model_providers.mock_provider.name="codex-qa mock"   # REQUIRED: empty name fails config load
-c model_providers.mock_provider.base_url="http://127.0.0.1:<PORT>/v1"
-c model_providers.mock_provider.wire_api="responses"
-c approval_policy="never"
-c sandbox_mode="read-only"

A non-OpenAI provider needs no key/auth, so there is no real egress. -c overrides beat any value in config.toml, so even a misconfigured isolated home still lands on the mock.

The codex shell-function trap

The interactive shell here wraps codex in a function that injects --profile quotio (sparkshell). That breaks non-runtime subcommands like generate-json-schema and would point a turn at the quotio provider. Bash scripts do not inherit that function, so codex inside a #!/usr/bin/env bash script is the real binary on PATH. cqa_codex_bin resolves it explicitly; never rely on the interactive alias. Combined with the isolated CODEX_HOME, the real quotio config is never read.