Files
dev/code-rs/MIGRATION_GUIDE.md
T
zeekay 25f1f1da4f vendor: upstream lives under vendor/, so ours is what is left
codex-rs/ is a read-only mirror of openai/codex that just-every refreshes and
we never edit. It sat at the repo root next to code-rs/, the product, and the
only thing separating them was that everyone knew. Nothing checked it.

That knowing is what makes branding endless. There are ~400 upstream-brand
literals in code-rs today and ~224 of ours, hand-placed on the same lines the
sync delta lands on, so every sync re-fights the same 17 files. You cannot fix
that while the line between "theirs" and "ours" is a convention.

vendor/codex/ makes it a boundary. Everything under vendor/ is upstream: never
branded, never edited, replaced wholesale on sync. Everything outside it is
ours and must carry our name — which is now a question a test can ask.

code-rs coupled to the mirror through exactly one line, an include_str! of
models.json, and it still does. The other 17 files are path strings.

Syncing changes by one sed: just-every's delta names codex-rs/, so rewrite the
patch paths to vendor/codex/ before applying it.
2026-08-07 21:22:34 -07:00

12 KiB

Crate Migration Guide: codex-rs to code-rs

This guide documents the process for moving shared crates from codex-rs into code-rs, making them fully independent.

Overview

The code-rs repository currently contains thin wrapper crates that re-export functionality from their codex-rs counterparts. This creates a cross-repository dependency via relative paths (../vendor/codex/...). The migration process moves the implementation into code-rs so that the crate owns its code and no longer depends on codex-rs.

Case Study: linux-sandbox Migration

We successfully migrated code-linux-sandbox as a representative example. This crate had:

  • Multiple source modules (landlock.rs, linux_run_main.rs)
  • A binary entry point (main.rs)
  • Integration tests
  • Platform-specific dependencies (Linux only)
  • Dependencies on codex-core (which had already been migrated to code-core)

Migration Pattern

1. Pre-Migration Analysis

Before starting, understand:

  • Source crate location: /home/azureuser/code/vendor/codex/<crate-name>/
  • Destination crate location: /home/azureuser/code/code-rs/<crate-name>/
  • Current wrapper structure: Usually just pub use codex_<crate>::*;
  • Dependencies: What other crates does this depend on?
  • Consumers: What crates in code-rs depend on this wrapper?

2. File Structure Migration

Copy all implementation files from codex-rs to code-rs:

# Source modules (excluding lib.rs which needs special handling)
cp vendor/codex/<crate>/src/*.rs code-rs/<crate>/src/
# Exception: main.rs will need modification

# Tests (if they exist)
cp -r vendor/codex/<crate>/tests/ code-rs/<crate>/tests/

Files to copy:

  • All source modules: src/*.rs (except lib.rs - see below)
  • Test files: tests/**/*.rs
  • Integration test structure: tests/all.rs, tests/suite/

3. Update Cargo.toml

Replace the wrapper dependency with actual implementation dependencies.

Before (wrapper):

[dependencies]
codex-linux-sandbox = { workspace = true }

After (independent):

[target.'cfg(target_os = "linux")'.dependencies]
clap = { workspace = true, features = ["derive"] }
code-core = { workspace = true }  # Note: codex-core → code-core
landlock = { workspace = true }
libc = { workspace = true }
seccompiler = { workspace = true }

[target.'cfg(target_os = "linux")'.dev-dependencies]
tempfile = { workspace = true }
tokio = { workspace = true, features = ["io-std", "macros", "process", "rt-multi-thread", "signal"] }

Key considerations:

  • Copy ALL dependency sections from codex-rs Cargo.toml
  • Replace codex-* dependencies with code-* equivalents where they exist
  • Keep the same features and version constraints
  • Include both [dependencies] and [dev-dependencies]
  • Handle platform-specific dependencies (e.g., [target.'cfg(target_os = "linux")'.dependencies])

4. Update lib.rs

Replace the wrapper re-export with the actual module structure.

Before (wrapper):

//! Thin wrapper around the upstream `codex-linux-sandbox` crate.
pub use codex_linux_sandbox::*;

After (independent):

#[cfg(target_os = "linux")]
mod landlock;
#[cfg(target_os = "linux")]
mod linux_run_main;

#[cfg(target_os = "linux")]
pub fn run_main() -> ! {
    linux_run_main::run_main();
}

#[cfg(not(target_os = "linux"))]
pub fn run_main() -> ! {
    panic!("code-linux-sandbox is only supported on Linux");
}

Key considerations:

  • Copy the exact module structure from vendor/codex/<crate>/src/lib.rs
  • Keep platform-specific conditional compilation (#[cfg(...)])
  • Preserve all public exports
  • Update any codex-specific naming to code-specific

5. Update main.rs (if binary)

Change the namespace from codex_* to code_*.

Before:

fn main() -> ! {
    codex_linux_sandbox::run_main()
}

After:

/// Note that the cwd, env, and command args are preserved in the ultimate call
/// to `execv`, so the caller is responsible for ensuring those values are
/// correct.
fn main() -> ! {
    code_linux_sandbox::run_main()
}

6. Update Source Files: Replace Namespace References

Replace all codex_* module references with code_* equivalents:

# Example: Update codex_core to code_core
find code-rs/<crate>/src -name '*.rs' -exec sed -i 's/codex_core/code_core/g' {} +

# Update codex_<crate> to code_<crate> (with underscores)
find code-rs/<crate>/src -name '*.rs' -exec sed -i 's/codex_linux_sandbox/code_linux_sandbox/g' {} +

Common replacements:

  • use codex_core:: → use code_core::
  • codex_core::error::Result → code_core::error::Result
  • codex_core::protocol::SandboxPolicy → code_core::protocol::SandboxPolicy

Files that commonly need updates:

  • Module implementation files (e.g., landlock.rs, linux_run_main.rs)
  • Any file that imports from other crates
  • Test files that reference the crate's types

7. Update Workspace Cargo.toml

Remove the cross-repository dependency reference.

Location: /home/azureuser/code/code-rs/Cargo.toml

Before:

[workspace.dependencies]
# ...
codex-linux-sandbox = { path = "../vendor/codex/linux-sandbox" }
# ...

After:

[workspace.dependencies]
# ... (line removed)

8. Build and Verify

# Build the migrated crate
cd /home/azureuser/code/code-rs
cargo build -p code-<crate-name>

# Run tests
cargo test -p code-<crate-name>

# Build dependent crates (e.g., code-arg0 depends on code-linux-sandbox)
cargo build -p <dependent-crate>

Success criteria:

  • cargo build -p code-<crate> compiles without errors
  • Tests pass (if applicable)
  • Dependent crates still build correctly
  • No references to codex-<crate> remain in the migrated crate

Automated Migration Script

Use the provided script for initial file copying:

cd /home/azureuser/code/code-rs
./migrate-crate.sh <crate-name>

The script will:

  1. Copy source files from codex-rs to code-rs
  2. Copy test files
  3. Display the dependencies you need to add
  4. Provide a checklist of manual steps

Note: The script handles the tedious file copying but requires manual steps for:

  • Updating Cargo.toml dependencies
  • Modifying lib.rs and main.rs
  • Replacing namespace references
  • Updating workspace configuration

Common Pitfalls and Solutions

Pitfall 1: Missing Dependencies

Symptom: Build fails with "cannot find crate" errors.

Solution: Ensure ALL dependencies from the codex-rs Cargo.toml are copied to code-rs Cargo.toml, including:

  • Platform-specific dependencies ([target.'cfg(...)'.dependencies])
  • Dev dependencies for tests
  • Feature flags on dependencies

Example:

# Don't forget platform-specific dependencies!
[target.'cfg(target_os = "linux")'.dependencies]
libc = { workspace = true }

Pitfall 2: Incomplete Namespace Replacement

Symptom: Build fails with "use of undeclared crate or module codex_*" errors.

Solution: Search for ALL occurrences of codex_ in the migrated crate:

grep -r "codex_" code-rs/<crate>/src/
grep -r "codex_" code-rs/<crate>/tests/

Replace with the appropriate code_* variant. Common locations:

  • use statements
  • Type annotations
  • Function calls
  • Comments and documentation (optional but recommended)

Pitfall 3: Forgetting Platform-Specific Compilation

Symptom: Build succeeds but runtime behavior is incorrect, or code compiles on wrong platforms.

Solution: Preserve ALL #[cfg(...)] attributes from the original:

#[cfg(target_os = "linux")]  // Don't forget these!
mod landlock;

#[cfg(not(target_os = "linux"))]
pub fn run_main() -> ! {
    panic!("code-linux-sandbox is only supported on Linux");
}

Pitfall 4: Test Directory Structure

Symptom: Tests don't compile or can't find test modules.

Solution: Copy the ENTIRE test directory structure, including:

  • tests/all.rs (integration test entry point)
  • tests/suite/ directory with all modules
  • tests/suite/mod.rs (module aggregation)

The pattern in codex-rs uses a single integration test binary:

// tests/all.rs
mod suite;

// tests/suite/mod.rs
mod landlock;
mod other_test_modules;

Pitfall 5: Workspace Dependency Conflicts

Symptom: Cargo complains about duplicate dependencies or conflicting versions.

Solution:

  1. Remove the codex-<crate> dependency from workspace Cargo.toml
  2. Ensure code-<crate> is already defined in workspace dependencies
  3. If dependents break, they may need to be updated to use the new independent crate

Pitfall 6: Binary Crates with Libraries

Symptom: Binary doesn't link or can't find library functions.

Solution: Ensure BOTH lib and bin are defined in Cargo.toml:

[lib]
name = "code_linux_sandbox"  # Note: underscores
path = "src/lib.rs"

[[bin]]
name = "code-linux-sandbox"  # Note: hyphens
path = "src/main.rs"

The binary name uses hyphens, the library name uses underscores (Rust convention).

Dependency Migration Order

Crates should be migrated in dependency order. Dependencies must be migrated before their dependents.

Already migrated:

  • ✅ code-core (was codex-core)
  • ✅ code-linux-sandbox (was codex-linux-sandbox)

Remaining wrappers (identified order):

  1. Low-level utilities (no codex dependencies):

    • ansi-escape (identical implementation, trivial)
    • git-apply (minimal dependencies)
  2. Process/system level:

    • process-hardening (may depend on core)
    • execpolicy (depends on core, process-hardening)
  3. Networking/client:

    • backend-client (depends on core)
    • cloud-tasks-client (depends on backend-client)
    • responses-api-proxy (depends on backend-client)

Note: Run grep -r "codex-" code-rs/*/Cargo.toml to see current wrapper dependencies.

Verification Checklist

After migration, verify:

  • cargo build -p code-<crate> succeeds
  • cargo test -p code-<crate> succeeds (if tests exist)
  • No codex-<crate> dependency remains in workspace Cargo.toml
  • No use codex_* imports remain in src/ (except for unavoidable upstream deps)
  • All dependent crates still build: cargo build -p <dependent>
  • Binary crates (if any) execute correctly
  • Tests copied from codex-rs still pass
  • Platform-specific behavior preserved (if applicable)

File Checklist for Migration

For each crate, ensure you handle:

  • Cargo.toml - Dependencies, features, and metadata
  • src/lib.rs - Main library module structure
  • src/main.rs - Binary entry point (if applicable)
  • src/*.rs - All implementation modules
  • tests/all.rs - Integration test entry point (if exists)
  • tests/suite/*.rs - Individual test modules (if exists)
  • Workspace Cargo.toml - Remove codex-* reference
  • Dependent crates - Verify they still build

Summary

The migration process transforms a thin wrapper crate into a fully independent implementation by:

  1. Copying implementation files from codex-rs to code-rs
  2. Updating Cargo.toml with actual dependencies (replacing codex-* with code-*)
  3. Replacing wrapper re-exports with actual module structure in lib.rs
  4. Renaming namespaces from codex_* to code_* throughout the code
  5. Removing the codex- dependency from workspace Cargo.toml
  6. Building and verifying the migrated crate and its dependents

The result is a crate that owns its implementation and no longer depends on ../codex-rs, making code-rs more independent and easier to maintain.

linux-sandbox Migration Results

The code-linux-sandbox crate was successfully migrated:

  • Build status: ✅ Success (cargo build -p code-linux-sandbox in 1m 50s)
  • Files migrated: 7 files (lib.rs, main.rs, landlock.rs, linux_run_main.rs, + 3 test files)
  • Dependencies: 5 external + 1 internal (code-core)
  • Namespace changes: 4 occurrences (codex_core → code_core, codex_linux_sandbox → code_linux_sandbox)
  • Workspace change: Removed 1 line from workspace Cargo.toml

The crate now compiles independently without any reference to codex-rs.