This guide documents the process for moving shared crates from codex-rs into code-rs, making them fully independent.
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 (../codex-rs/...). The migration process moves the implementation into code-rs so that the crate owns its code and no longer depends on codex-rs.
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 tocode-core)
Before starting, understand:
- Source crate location:
/home/azureuser/code/codex-rs/<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?
Copy all implementation files from codex-rs to code-rs:
# Source modules (excluding lib.rs which needs special handling)
cp codex-rs/<crate>/src/*.rs code-rs/<crate>/src/
# Exception: main.rs will need modification
# Tests (if they exist)
cp -r codex-rs/<crate>/tests/ code-rs/<crate>/tests/Files to copy:
- All source modules:
src/*.rs(exceptlib.rs- see below) - Test files:
tests/**/*.rs - Integration test structure:
tests/all.rs,tests/suite/
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 withcode-*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])
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
codex-rs/<crate>/src/lib.rs - Keep platform-specific conditional compilation (
#[cfg(...)]) - Preserve all public exports
- Update any codex-specific naming to code-specific
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()
}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::Resultcodex_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
Remove the cross-repository dependency reference.
Location: /home/azureuser/code/code-rs/Cargo.toml
Before:
[workspace.dependencies]
# ...
codex-linux-sandbox = { path = "../codex-rs/linux-sandbox" }
# ...After:
[workspace.dependencies]
# ... (line removed)# 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
Use the provided script for initial file copying:
cd /home/azureuser/code/code-rs
./migrate-crate.sh <crate-name>The script will:
- Copy source files from codex-rs to code-rs
- Copy test files
- Display the dependencies you need to add
- 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
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 }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:
usestatements- Type annotations
- Function calls
- Comments and documentation (optional but recommended)
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");
}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 modulestests/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;Symptom: Cargo complains about duplicate dependencies or conflicting versions.
Solution:
- Remove the
codex-<crate>dependency from workspace Cargo.toml - Ensure
code-<crate>is already defined in workspace dependencies - If dependents break, they may need to be updated to use the new independent crate
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).
Crates should be migrated in dependency order. Dependencies must be migrated before their dependents.
Already migrated:
- ✅
code-core(wascodex-core) - ✅
code-linux-sandbox(wascodex-linux-sandbox)
Remaining wrappers (identified order):
-
Low-level utilities (no codex dependencies):
ansi-escape(identical implementation, trivial)git-apply(minimal dependencies)
-
Process/system level:
process-hardening(may depend on core)execpolicy(depends on core, process-hardening)
-
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.
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)
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
The migration process transforms a thin wrapper crate into a fully independent implementation by:
- Copying implementation files from codex-rs to code-rs
- Updating Cargo.toml with actual dependencies (replacing codex-* with code-*)
- Replacing wrapper re-exports with actual module structure in lib.rs
- Renaming namespaces from codex_* to code_* throughout the code
- Removing the codex- dependency from workspace Cargo.toml
- 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.
The code-linux-sandbox crate was successfully migrated:
- Build status: ✅ Success (
cargo build -p code-linux-sandboxin 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.
