Overview

I run Claude Code and Codex side by side, and I split my work between them on purpose. Each subscription has usage limits, and leaning on one until it hits its usage limit means stopping mid-task. Alternating spreads the load across both, so I keep working. That only pays off if switching between them is cheap, which is the whole point of what follows: one copy of the workflows both can read, separate configuration where the products genuinely differ, and a way to catch the two drifting apart.

This document is the Codex half. The Claude Code half covers that side’s rules, agents, permission gates, and hooks, and has its own write-up. Each stands alone; read both if you want the parallel setup.

Goals for Codex in this setup:

  • the same reusable build, test, release, UI, and repository workflows;
  • similar planning, implementation, review, and Git approval boundaries;
  • separate provider-specific configuration where Claude and Codex work differently;
  • private Git tracking for both global configurations;
  • a read-only parity audit that detects drift without synchronizing anything automatically;
  • normal editor tabs and a usable local chat history inside VS Code.

Architecture

%USERPROFILE%\.claude
├── CLAUDE.md
├── agents\
├── settings.json
├── skills\                         Canonical shared skills
├── config-parity\                  Parity manifest
└── private Git repo: claude-config

%USERPROFILE%\.codex
├── AGENTS.md
├── config.toml
├── agents\
├── rules\
└── private Git repo: codex-config

%USERPROFILE%\.agents\skills
├── myapps-build-ship    -> %USERPROFILE%\.claude\skills\myapps-build-ship
├── myapps-fleet-rollout -> %USERPROFILE%\.claude\skills\myapps-fleet-rollout
├── myapps-new-project   -> %USERPROFILE%\.claude\skills\myapps-new-project
├── myapps-repo-setup    -> %USERPROFILE%\.claude\skills\myapps-repo-setup
├── myapps-server        -> %USERPROFILE%\.claude\skills\myapps-server
├── myapps-test-session  -> %USERPROFILE%\.claude\skills\myapps-test-session
├── myapps-theme-ui      -> %USERPROFILE%\.claude\skills\myapps-theme-ui
└── agent-config-parity  -> %USERPROFILE%\.claude\skills\agent-config-parity

myapps- is a stand-in for whatever shared prefix you pick. A common prefix keeps a family of skills sorted together; substitute your own throughout the examples below.

The design choices that matter:

  1. .claude and .codex are separate private repositories.
  2. .agents is only a symlink layer and is not its own repository.
  3. Shared skills have one canonical copy under .claude\skills.
  4. Claude-specific instructions, hooks, and settings remain under .claude.
  5. Codex-specific instructions, sandbox settings, custom agents, and rules remain under .codex.
  6. A parity audit tracks translated behavior and intentional provider differences.

VS Code Extensions

Installed

  • Claude Code
  • Codex - OpenAI’s coding agent
    • Extension ID: OpenAI.chatgpt
  • Codex Extras
    • Extension ID: netroforge.codex-extras

Install from the command line:

code --install-extension OpenAI.chatgpt
code --install-extension netroforge.codex-extras

Why Codex Extras

The official Codex extension works, but I wanted a more normal editor-tab workflow. Codex Extras adds:

  • a Codex Chats panel in the Activity Bar;
  • current-workspace chats grouped separately from other workspaces;
  • pinned Codex editor tabs when opening existing chats;
  • a visible New Codex Agent toolbar button;
  • automatic refresh when chats are created or renamed.

It reads the local Codex session index and does not parse or copy transcript contents. The extension is unofficial and independent from OpenAI.


Codex Global Configuration

The Codex home directory is:

%USERPROFILE%\.codex

My tracked configuration currently includes:

.codex\
├── .gitignore
├── AGENTS.md
├── config.toml
├── agents\
│   ├── correctness_reviewer.toml
│   ├── explorer.toml
│   ├── plan_implementer.toml
│   └── plan_reviewer.toml
└── rules\
    └── default.rules

Runtime files such as authentication, sessions, logs, caches, databases, and sandbox state are excluded from Git.

Example config.toml

This is the general shape of my current configuration. Model names are account- and time-dependent, so replace them with models available to you.

model = "gpt-5.6-sol"
model_reasoning_effort = "medium"
review_model = "gpt-5.6-terra"
personality = "pragmatic"

approval_policy = "on-request"
sandbox_mode = "workspace-write"

[windows]
sandbox = "elevated"

[sandbox_workspace_write]
network_access = false

[memories]
generate_memories = false
use_memories = false

[analytics]
enabled = false

[agents]
enabled = true
max_concurrent_threads_per_session = 3
default_subagent_model = "gpt-5.6-terra"
default_subagent_reasoning_effort = "medium"

I also have trusted-project entries in config.toml. Those are machine-specific and should not be copied blindly.

Windows sandbox choice

I use the native Windows elevated sandbox rather than WSL. This fits my Windows-native repositories, PowerShell tooling, Python environments, and desktop application testing.

The Codex elevated sandbox is a stronger native Windows sandbox implementation. It does not mean every action is automatically approved or that ordinary commands run as an unrestricted administrator.


Adapting Claude Code Behavior into AGENTS.md

Codex does not import Claude Code’s memory or configuration automatically. I had Codex perform a read-only audit of my Claude setup and translate the provider-neutral intent into:

%USERPROFILE%\.codex\AGENTS.md

I did not copy CLAUDE.md verbatim. The two products have different instruction formats, permission systems, hooks, models, and sandbox behavior.

The translated Codex guidance covers:

  • my role as requirements owner and acceptance tester rather than the coder;
  • trust-but-verify behavior;
  • request scope and authority boundaries;
  • planning, implementation, and review responsibilities;
  • separate commit, merge, push, tag, build, and release approvals;
  • branch hygiene and status reporting;
  • testing and manual smoke-test expectations;
  • temporary-file cleanup;
  • no ownership, ACL, inheritance, or permission repair without approval;
  • no repository-local test temp fallback merely to bypass sandbox restrictions;
  • mixed CRLF/LF endings treated as cosmetic unless they violate policy or cause a real problem;
  • security and secret-handling rules;
  • provider-parity checks after global configuration changes.

A typical high-level structure is:

Global Codex Rules
===================

## About Me
## Authority and Request Scope
## Coding Roles
## Planning and Implementation
## Reviews
## Git Workflow
## Files, Systems, and Remote Access
## Security
## Shared Configuration and Provider Parity

Codex reads global AGENTS.md at session startup, so start a new Codex chat after changing it.


Custom Codex Agents

I created four Codex agent definitions:

%USERPROFILE%\.codex\agents\correctness_reviewer.toml
%USERPROFILE%\.codex\agents\explorer.toml
%USERPROFILE%\.codex\agents\plan_implementer.toml
%USERPROFILE%\.codex\agents\plan_reviewer.toml
Agent Purpose Read-only?
Explorer Locates evidence, inspects repository structure, and identifies relevant files and symbols. Avoids acting as a code reviewer. Yes
Correctness Reviewer Independently reviews the actual diff for bugs and regressions, checks security, privacy, and failure handling, and identifies missing tests for changed non-UI behavior. Verifies findings before reporting them. Yes
Plan Implementer Implements an approved plan, validates the expected branch and scope, runs appropriate tests, and avoids unrelated changes. Stops before Git operations unless separately approved. No
Plan Reviewer Reviews the implementation against the user’s actual request, identifies missing scope, added scope, or a wrong interpretation, and reports findings without rewriting the implementation automatically. No

The senior developer gives the implementer a small work order containing the desired outcome, owned files or edit surface, acceptance criteria, relevant source paths, required validation, and protected or out-of-scope areas.

Correctness and intent remain separate reviews, the same split covered on the site’s review model page. The correctness reviewer checks whether the change is technically sound. The plan reviewer checks whether it is the change the user actually requested.

The Claude and Codex agent files are separate translations. They are not symlinked because their syntax, model declarations, tool controls, and sandbox settings are provider-specific.


Codex Rules and Git Approval Behavior

Codex uses both:

  1. the Windows sandbox, which enforces filesystem and network boundaries; and
  2. prefix_rule entries under .codex\rules, which control matching commands that request execution outside the sandbox.

My final Git rules are deliberately narrower than the first draft, since a broad git remote, config, and tag rule prompted for approval even on read-only commands like git remote -v. Splitting the rules keeps normal reads quiet while mutations still gate.

Prompts for approval Runs without a prompt
git commit git status
git merge git log
git push git branch --all
git reset git remote -v
git checkout git remote get-url
git restore git config --get
every form of git clean git config --list
mutating git remote subcommands git tag --list
destructive or forced git tag forms git stash list
destructive git config options
git stash drop
git stash clear

git clean stays intentionally broad because it can delete ordinary untracked files inside the writable workspace, including when options are reordered or combined.

Example:

prefix_rule(
    pattern = ["git", ["commit", "merge", "push", "reset", "checkout", "restore"]],
    decision = "prompt",
    justification = "Git state-changing operations require explicit approval.",
)

prefix_rule(
    pattern = ["git", "clean"],
    decision = "prompt",
    justification = "Git clean can delete untracked workspace files and requires explicit approval.",
)

prefix_rule(
    pattern = [
        "git",
        "remote",
        ["add", "rename", "remove", "rm", "set-head", "set-branches", "set-url", "update", "prune"],
    ],
    decision = "prompt",
    justification = "Changing Git remote configuration or remote-tracking state requires explicit approval.",
)

Use match and not_match examples as inline rule tests, and validate rules with:

codex execpolicy check --pretty `
  --rules "$HOME\.codex\rules\default.rules" `
  -- git remote -v

Rules are loaded at startup. Restart Codex after changing them.


Sharing Skills Between Claude Code and Codex

Canonical location

My provider-neutral skills live under:

%USERPROFILE%\.claude\skills

Codex user-skill location

Codex discovers user skills under:

%USERPROFILE%\.agents\skills

Codex supports symlinked skill directories, so each Codex-facing skill is a directory symbolic link to the canonical Claude-owned directory.

A whole-directory link exposes all current and future skill content: SKILL.md, references\, templates\, scripts\, assets\, and any tests and supporting files. There is no copy job, synchronization script, or second source of truth.

Enable Windows Developer Mode or run an appropriately elevated shell.

Create the parent directory:

New-Item -ItemType Directory -Force "$HOME\.agents\skills"

Example using native mklink:

mklink /D "%USERPROFILE%\.agents\skills\myapps-build-ship" "%USERPROFILE%\.claude\skills\myapps-build-ship"

Repeat for each shared skill.

My shared skills are:

myapps-build-ship
myapps-fleet-rollout
myapps-new-project
myapps-repo-setup
myapps-server
myapps-test-session
myapps-theme-ui
agent-config-parity

Validation

Get-Item -Force "$HOME\.agents\skills\myapps-build-ship" |
    Select-Object FullName, LinkType, Target, Attributes

Require:

  • LinkType is SymbolicLink;
  • the target is the expected canonical directory;
  • the linked and source inventories match;
  • deleting the link never deletes the canonical target.

Provider-neutral skill wording

Shared skills should describe the actor as the coding agent when the workflow applies to both products.

Do not neutralize genuinely provider-specific behavior. Examples:

  • Claude model metadata stays Claude-specific.
  • Codex sandbox behavior stays Codex-specific.
  • Claude notification hooks stay Claude-specific.
  • Shared testing, release, UI, and Git workflows can usually be provider-neutral.

Private Git Repositories

I track two private repositories:

%USERPROFILE%\.claude   -> claude-config
%USERPROFILE%\.codex    -> codex-config

I do not make %USERPROFILE%\.agents a repository. It contains only the symlink layer.

Codex allowlist-style .gitignore

The Codex directory also contains credentials, sessions, logs, databases, caches, and sandbox state. Use an ignore-everything, include-only-known- config approach.

Example:

/*

!/.gitignore
!/AGENTS.md
!/codex-setup.md
!/config.toml

!/agents/
!/agents/**

!/rules/
!/rules/**

!/hooks.json
!/hooks/
!/hooks/**

Before the first commit:

Set-Location "$HOME\.codex"
git status --short --ignored
git add --dry-run .

Do not commit: authentication files, session JSONL files, local conversation indexes, logs, caches, SQLite databases, sandbox state, temporary files, or secret material.

The two config repositories are committed, merged, and pushed independently. Approval for one repository never authorizes changes in the other.


Preventing Claude and Codex Configuration Drift

See provider-parity for why this exists and what it deliberately does not do. The script itself is not published here, and it does not need to be: it’s a few hundred lines of standard-library Python, and the design matters more than the code. Hand this section to your own coding agent and have it build the script and its tests with you; the rest of this section is the specification.

Layout

%USERPROFILE%\.claude\
├── config-parity\
│   ├── parity-manifest.json
│   └── known-differences.md
└── skills\
    └── agent-config-parity\
        ├── SKILL.md
        ├── scripts\
        │   └── audit_config_parity.py
        └── tests\
            └── test_audit_config_parity.py

%USERPROFILE%\.agents\skills\agent-config-parity
    -> %USERPROFILE%\.claude\skills\agent-config-parity

The audit lives in a shared skill, so both providers can run it through the same symlink.

Both CLAUDE.md and Codex AGENTS.md contain standing instructions to run the read-only parity audit after changes to:

  • global instructions;
  • agent definitions;
  • approval or permission behavior;
  • testing or cleanup policy;
  • Git or release policy;
  • shared cross-provider workflow behavior.

Ordinary application-repository work does not require a parity audit.

Mapping types

The manifest classifies relationships as:

  • shared canonical content through a symlink;
  • translated intent represented differently;
  • provider-specific intentional differences;
  • unmapped behavior;
  • manual review required.

It records:

  • source and target paths;
  • relevant sections;
  • reviewed hashes;
  • repository commits;
  • source-of-truth classification;
  • parity status;
  • provider-specific notes.

known-differences.md

This file holds the results of the human comparison pass the audit cannot do itself: direct conflicts, and rules one provider has that the other does not. It holds open questions only. An entry is deleted once the difference is closed, either by making both sides match or by recording it in the manifest as intentional, so the file never becomes a history of settled arguments.

Audit command

python "$HOME\.claude\skills\agent-config-parity\scripts\audit_config_parity.py" `
  --manifest "$HOME\.claude\config-parity\parity-manifest.json"

Exit codes

0  Reviewed state unchanged or intentionally different
1  Drift, dirty repository, or manual review required
2  Structural failure, invalid manifest, missing file, or broken link
3  Unsafe path resolution

Safety properties

The audit:

  • uses Python’s standard library only;
  • resolves roots through Path.home();
  • rejects paths outside .claude, .codex, and .agents\skills;
  • reads only explicitly mapped artifacts;
  • does not fetch;
  • does not edit;
  • does not stage, commit, merge, push, tag, or publish;
  • does not automatically copy configuration between providers;
  • requires separate human approval for any proposed counterpart change.

Text hashes normalize LF, CRLF, bare CR, and mixed endings so ordinary Windows line-ending conversion does not create false drift. Binary or non-UTF-8 data remains byte-exact.


Normal Day-to-Day Workflow

  1. Open a repository in VS Code.
  2. Use either Claude Code or Codex.
  3. Both agents can invoke the same provider-neutral myapps-* skills.
  4. Provider-specific global instructions and permission systems remain separate.
  5. The agent implements and validates changes on an appropriate branch.
  6. Commit, merge, push, tag, build, and release remain separate approval steps.
  7. A global configuration change triggers the read-only parity audit.
  8. The audit explains whether the counterpart already shares the same canonical content, needs a translated change, should remain provider-specific, or requires human judgment.
  9. Changes to .claude and .codex are reviewed, committed, merged, and pushed separately.

Validation Checklist

After setting up a similar environment, verify:

Codex global setup

  • A fresh Codex chat can summarize the loaded AGENTS.md.
  • config.toml parses and the intended models and sandbox are active.
  • All custom agent TOML files load.
  • The correctness reviewer remains read-only and separate from intent review.
  • Memories and analytics match your intended privacy settings.

Rules

  • git status, git log, git remote -v, and file listing run without an unnecessary approval prompt.
  • git commit, git merge, git push, git clean, and destructive operations still prompt.
  • codex execpolicy check passes all inline tests.

Shared skills

  • Every .agents\skills entry is a directory symbolic link.
  • Every target resolves to the intended .claude\skills directory.
  • Source and linked inventories match.
  • A new Codex session discovers all expected skills.

Git repositories

  • .claude and .codex are clean.
  • Both private remotes are synchronized.
  • .agents is not a third repository.
  • No runtime, session, authentication, cache, database, or sandbox files are tracked.

Parity audit

  • The audit runs twice with stable output.
  • Exit code is 0 at the reviewed baseline.
  • Tests pass.
  • All shared-skill links report healthy.
  • A deliberate global instruction change is detected and explained without being synchronized automatically.

VS Code UX

  • Codex Extras shows the local chat list.
  • Existing chats open in pinned editor tabs.
  • New agents can be started from the toolbar.
  • Claude Code remains available and unaffected.

What Not to Do

  • Do not symlink all of .claude into .codex.
  • Do not copy Claude hooks directly into Codex without translating the behavior.
  • Do not force Claude and Codex to use identical provider-specific settings.
  • Do not auto-sync global configuration based only on file hashes.
  • Do not treat wording or syntax differences as drift when intent is equivalent.
  • Do not permanently patch an installed VS Code extension unless you accept that updates may overwrite the change.
  • Do not let either provider modify the other provider’s repository without separate approval.

References


Closing Notes

This is a deliberate separation of concerns, not a one-click Claude-to-Codex import. That balance lets me use Claude Code and Codex side by side in VS Code without maintaining two independent copies of every workflow or pretending the products have identical capabilities.