openai-codex-rust-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOpenAI Codex Rust Best Practices
OpenAI Codex Rust 最佳实践
Distilled from — a 72-crate, 1,418-file Rust workspace that ships the Codex CLI coding agent. Contains 60 rules across 10 categories, each citing the exact file in codex-rs where the pattern lives, so you can write Rust the way its top contributors (Michael Bolin, jif-oai, Ahmed Ibrahim, Eric Traut, Pavel Krymets) actually ship it.
openai/codexcodex-rs/内容提炼自的工作区——这是一个包含72个crate、1418个文件的Rust工作区,用于交付Codex CLI编码Agent。涵盖10个类别共60条规则,每条规则均引用了codex-rs中对应模式所在的具体文件,让你能够以其核心贡献者(Michael Bolin、jif-oai、Ahmed Ibrahim、Eric Traut、Pavel Krymets)实际交付代码的方式编写Rust。
openai/codexcodex-rs/When to Apply
适用场景
Reference these guidelines when:
- Writing or reviewing async Rust code that spawns tokio tasks, owns cancellation tokens, or manages long-lived background workers.
- Designing error enums, flows, retry loops, or layer boundaries in a library or service.
Result - Building a CLI tool that spawns subprocesses, enforces sandboxing, or runs LLM-generated code safely.
- Architecting a Cargo workspace with more than ~5 crates, deciding what to split out, and how to manage shared dependencies.
- Adding tests to a Rust codebase where existing tests are inline blocks and scaling is becoming painful.
mod tests { ... } - Implementing a JSON-RPC or custom wire protocol with serde — especially one that must evolve without breaking clients.
- Wiring OpenTelemetry traces, logs, or metrics into a service that has privacy constraints around PII.
- Building a Ratatui-based TUI that streams LLM output, handles paste bursts, or manages raw-mode terminal state.
- Hardening a binary against debugger attach, LD_PRELOAD, or environment-variable tampering.
- Any time you find yourself reaching for ,
.unwrap(), oranyhow::Result<()>— this skill explains what codex does instead.#[cfg(feature = "test")]
在以下场景中可参考本指南:
- 编写或审查用于生成tokio任务、持有取消令牌或管理长期后台工作线程的异步Rust代码时。
- 在库或服务中设计错误枚举、流程、重试循环或层级边界时。
Result - 构建可生成子进程、强制沙箱隔离或安全运行LLM生成代码的CLI工具时。
- 架构包含约5个以上crate的Cargo工作区,决定拆分内容及管理共享依赖时。
- 为Rust代码库添加测试,而现有测试为内联块且扩展难度渐增时。
mod tests { ... } - 使用serde实现JSON-RPC或自定义有线协议——尤其是需要在不中断客户端的情况下演进的协议时。
- 为存在PII隐私约束的服务接入OpenTelemetry追踪、日志或指标时。
- 构建基于Ratatui的TUI,用于流式传输LLM输出、处理粘贴批量输入或管理原始模式终端状态时。
- 加固二进制文件以抵御调试器附加、LD_PRELOAD或环境变量篡改时。
- 每当你需要使用、
.unwrap()或anyhow::Result<()>时——本技能会解释codex采用的替代方案。#[cfg(feature = "test")]
Rule Categories by Priority
规则优先级
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | Defensive Coding & Panic Discipline | CRITICAL | |
| 2 | Error Handling & Result Discipline | CRITICAL | |
| 3 | Async, Concurrency & Cancellation | HIGH | |
| 4 | Sandboxing & Process Isolation | HIGH | |
| 5 | Type Design & Invariants | HIGH | |
| 6 | Testing Architecture | MEDIUM-HIGH | |
| 7 | Protocol & Serde Design | MEDIUM-HIGH | |
| 8 | Workspace & Crate Organization | MEDIUM | |
| 9 | Observability & Tracing | MEDIUM | |
| 10 | TUI (Ratatui) Rendering | MEDIUM | |
| 优先级 | 类别 | 影响级别 | 前缀 |
|---|---|---|---|
| 1 | 防御性编程与Panic规范 | CRITICAL | |
| 2 | 错误处理与Result规范 | CRITICAL | |
| 3 | 异步、并发与取消 | HIGH | |
| 4 | 沙箱与进程隔离 | HIGH | |
| 5 | 类型设计与不变量 | HIGH | |
| 6 | 测试架构 | MEDIUM-HIGH | |
| 7 | 协议与Serde设计 | MEDIUM-HIGH | |
| 8 | 工作区与Crate组织 | MEDIUM | |
| 9 | 可观测性与追踪 | MEDIUM | |
| 10 | TUI(Ratatui)渲染 | MEDIUM | |
Quick Reference
快速参考
1. Defensive Coding & Panic Discipline (CRITICAL)
1. 防御性编程与Panic规范(CRITICAL)
- — Deny unwrap and expect at the workspace level, opt in locally.
defensive-deny-unwrap-workspace-wide - — Use debug_assert(false) with a safe fallback on unreachable branches.
defensive-debug-assert-with-early-return - — Avoid learning allowlist rules for general-purpose interpreters.
defensive-banned-interpreter-prefixes - — Cap subprocess output with a head-and-tail ring buffer.
defensive-head-tail-output-buffer - — Time out the I/O drain task separately from the child process.
defensive-io-drain-timeout-grandchildren - — Canonicalize shell wrappers before hashing approval keys.
defensive-canonicalize-approval-cache-key - — Refuse to run when the sandbox cannot enforce the requested policy.
defensive-refuse-to-run-unsandboxed
- — 在工作区级别禁用unwrap和expect,仅在局部场景启用。
defensive-deny-unwrap-workspace-wide - — 在不可达分支使用debug_assert(false)并搭配安全的提前返回逻辑。
defensive-debug-assert-with-early-return - — 避免为通用解释器设置允许列表规则。
defensive-banned-interpreter-prefixes - — 使用首尾环形缓冲区限制子进程输出大小。
defensive-head-tail-output-buffer - — 为I/O排空任务单独设置超时时间,与子进程超时分离。
defensive-io-drain-timeout-grandchildren - — 在对审批密钥哈希前先规范化shell包装器。
defensive-canonicalize-approval-cache-key - — 当沙箱无法执行请求的策略时,拒绝运行。
defensive-refuse-to-run-unsandboxed
2. Error Handling & Result Discipline (CRITICAL)
2. 错误处理与Result规范(CRITICAL)
- — Classify retryable errors with an exhaustive match on every variant.
errors-exhaustive-retryable-match - — Encode transient vs permanent outcomes as two enum variants.
errors-transient-permanent-type-split - — Carry the server-requested retry delay inside the error variant.
errors-carry-retry-delay-in-variant - — Translate errors at the layer boundary in a single function.
errors-boundary-error-translator - — Put display-relevant error state in a struct, not a preformatted string.
errors-struct-display-payload - — Split tool errors into respond-to-model and fatal variants.
errors-tool-call-respond-vs-fatal - — Wrap io::Error in a struct with a context field instead of anyhow.
errors-io-error-with-context-struct
- — 通过对每个变体的穷举匹配对可重试错误进行分类。
errors-exhaustive-retryable-match - — 将临时与永久结果编码为两个枚举变体。
errors-transient-permanent-type-split - — 在错误变体中携带服务器要求的重试延迟。
errors-carry-retry-delay-in-variant - — 在层级边界的单个函数中统一转换错误。
errors-boundary-error-translator - — 将与显示相关的错误状态存入结构体,而非预格式化字符串。
errors-struct-display-payload - — 将工具错误分为响应模型和致命错误两类变体。
errors-tool-call-respond-vs-fatal - — 将io::Error包装到带有上下文字段的结构体中,而非使用anyhow。
errors-io-error-with-context-struct
3. Async, Concurrency & Cancellation (HIGH)
3. 异步、并发与取消(HIGH)
- — Use Arc<AbortOnDropHandle> so dropped owners auto-cancel tasks.
async-abort-on-drop-handle - — Cancel cooperatively first, then abort after a grace deadline.
async-graceful-then-forceful-cancel - — Use biased select to make cancellation always win race ties.
async-biased-select-for-cancellation - — Bound the submission channel but leave the event channel unbounded.
async-bounded-vs-unbounded-channel-split - — Give spawned sub-tasks child tokens, not clones of the parent.
async-child-cancellation-tokens - — Wrap a background JoinHandle in Shared<BoxFuture> for multi-waiter joins.
async-shared-boxfuture-joinhandle
- — 使用Arc<AbortOnDropHandle>,让被丢弃的所有者自动取消任务。
async-abort-on-drop-handle - — 首先尝试协作式取消,超过宽限期后再强制终止。
async-graceful-then-forceful-cancel - — 使用偏向选择,让取消操作在竞争中始终优先。
async-biased-select-for-cancellation - — 对提交通道设置边界,而事件通道保持无边界。
async-bounded-vs-unbounded-channel-split - — 为生成的子任务分配子令牌,而非父令牌的克隆。
async-child-cancellation-tokens - — 将后台JoinHandle包装在Shared<BoxFuture>中,支持多等待者连接。
async-shared-boxfuture-joinhandle
4. Sandboxing & Process Isolation (HIGH)
4. 沙箱与进程隔离(HIGH)
- — Keep sandbox policy as shared data, not per-platform code.
sandbox-shared-policy-data-model - — Stage incompatible restrictions by re-executing the same binary.
sandbox-staged-restrictions-re-exec - — Multiplex helper binaries via argv[0] and symlinks.
sandbox-argv0-multiplex-binary - — Mount /dev/null over the first missing path to block mkdir escapes.
sandbox-dev-null-first-missing-mount - — Stack env vars, seccomp, and namespaces for network isolation.
sandbox-three-layer-network-isolation - — Clear the env and tether children via pre_exec before every spawn.
sandbox-env-clear-pre-exec
- — 将沙箱策略作为共享数据存储,而非按平台拆分代码。
sandbox-shared-policy-data-model - — 通过重新执行同一二进制文件来分阶段应用不兼容的限制。
sandbox-staged-restrictions-re-exec - — 通过argv[0]和符号链接复用辅助二进制文件。
sandbox-argv0-multiplex-binary - — 在第一个缺失路径上挂载/dev/null,以阻止mkdir逃逸。
sandbox-dev-null-first-missing-mount - — 叠加环境变量、seccomp和命名空间实现网络隔离。
sandbox-three-layer-network-isolation - — 在每次生成子进程前,通过pre_exec清理环境并绑定子进程。
sandbox-env-clear-pre-exec
5. Type Design & Invariants (HIGH)
5. 类型设计与不变量(HIGH)
- — Pass deserializer context via a thread-local RAII guard.
types-thread-local-raii-serde - — Pair an ergonomic trait with a private dyn-safe adapter trait.
types-dyn-safe-adapter-trait - — Use serde try_from on a newtype to run validation on every parse.
types-try-from-newtype-validation - — Implement Borrow, AsRef, and Deref on every public ID newtype.
types-full-reference-hierarchy - — Mark every public wire-level enum non_exhaustive from the start.
types-non-exhaustive-public-enums - — Preserve unrecognized values in an Unknown variant.
types-unknown-variant-forward-compat
- — 通过线程本地RAII guard传递反序列化上下文。
types-thread-local-raii-serde - — 将易用性 trait 与私有dyn-safe适配trait配对使用。
types-dyn-safe-adapter-trait - — 在newtype上使用serde try_from,在每次解析时运行验证逻辑。
types-try-from-newtype-validation - — 在每个公开ID newtype上实现Borrow、AsRef和Deref。
types-full-reference-hierarchy - — 从一开始就将每个公开有线级枚举标记为non_exhaustive。
types-non-exhaustive-public-enums - — 在Unknown变体中保留未识别的值。
types-unknown-variant-forward-compat
6. Testing Architecture (MEDIUM-HIGH)
6. 测试架构(MEDIUM-HIGH)
- — Attach tests as sibling files via #[path] instead of inline mod tests.
testing-path-attribute-sibling-tests - — Fake the network with wiremock and small SSE event constructors.
testing-wiremock-sse-fakes - — Gate test-only behavior with an AtomicBool, not a cargo feature.
testing-atomic-bool-test-opt-in - — Configure test fixtures with a closure builder.
testing-config-closure-builder - — Snapshot terminal rendering with insta for stable UI diffs.
testing-insta-snapshot-tui-rendering - — Use start_paused and advance to make timing-dependent tests deterministic.
testing-paused-runtime-advance
- — 通过#[path]将测试作为同级文件附加,而非内联mod tests。
testing-path-attribute-sibling-tests - — 使用wiremock和小型SSE事件构造函数模拟网络。
testing-wiremock-sse-fakes - — 使用AtomicBool而非cargo特性来控制仅测试用的行为。
testing-atomic-bool-test-opt-in - — 使用闭包构建器配置测试夹具。
testing-config-closure-builder - — 使用insta对终端渲染进行快照,实现稳定的UI差异对比。
testing-insta-snapshot-tui-rendering - — 使用start_paused和advance使依赖时序的测试具有确定性。
testing-paused-runtime-advance
7. Protocol & Serde Design (MEDIUM-HIGH)
7. 协议与Serde设计(MEDIUM-HIGH)
- — Dispatch JSON-RPC by an internally tagged enum with a macro.
proto-internally-tagged-rpc-dispatch - — Use Option<Option<T>> to distinguish absent, null, and set.
proto-double-option-tri-state - — Pair rename and alias to migrate wire names without breaking clients.
proto-rename-alias-wire-migration - — Gate experimental fields by runtime presence, not capability flags.
proto-experimental-runtime-gate - — Treat SSE streams as idle-timeout with required terminator.
proto-sse-idle-timeout-terminator - — Split internal error enums from wire error enums.
proto-internal-vs-wire-error-split
- — 通过带内部标签的枚举和宏实现JSON-RPC分发。
proto-internally-tagged-rpc-dispatch - — 使用Option<Option<T>>区分缺失、空值和已设置状态。
proto-double-option-tri-state - — 将rename和alias配对使用,在不中断客户端的情况下迁移有线名称。
proto-rename-alias-wire-migration - — 通过运行时存在性而非能力标志来控制实验性字段。
proto-experimental-runtime-gate - — 将SSE流视为带超时的空闲连接,并要求终止符。
proto-sse-idle-timeout-terminator - — 将内部错误枚举与有线错误枚举分离。
proto-internal-vs-wire-error-split
8. Workspace & Crate Organization (MEDIUM)
8. 工作区与Crate组织(MEDIUM)
- — Avoid per-crate features; use target-cfg or separate crates instead.
workspace-ban-per-crate-features - — Declare every dependency version once in workspace.dependencies.
workspace-single-source-dependencies - — Stack HTTP layers as transport, api, and core crates.
workspace-layered-transport-api-core - — Register shared test helpers as workspace member crates.
workspace-test-support-as-member-crates - — Place shared utilities in single-purpose microcrates under utils/.
workspace-utils-microcrate-fanout - — Encode policy in workspace.lints and clippy.toml.
workspace-lint-config-package
- — 避免使用每个crate单独的特性;改用target-cfg或独立crate。
workspace-ban-per-crate-features - — 在workspace.dependencies中统一声明每个依赖的版本。
workspace-single-source-dependencies - — 将HTTP层分为transport、api和core三个crate。
workspace-layered-transport-api-core - — 将共享测试助手注册为工作区成员crate。
workspace-test-support-as-member-crates - — 将共享工具放入utils/下的单用途微crate中。
workspace-utils-microcrate-fanout - — 在workspace.lints和clippy.toml中编码策略。
workspace-lint-config-package
9. Observability & Tracing (MEDIUM)
9. 可观测性与追踪(MEDIUM)
- — Route PII to log-only targets and keep traces cardinality-safe.
otel-log-only-vs-trace-safe-targets - — Declare span fields as field::Empty, then record them when known.
otel-field-empty-then-record - — Build per-layer EnvFilter instances with boxed fmt layers.
otel-layered-subscribers-env-filter - — Propagate W3C traceparent via env vars, JSON-RPC, and HTTP headers.
otel-w3c-traceparent-propagation - — Default #[instrument] to trace level, reserve info for network calls.
otel-instrument-at-trace-level
- — 将PII路由至仅日志目标,保持追踪的基数安全。
otel-log-only-vs-trace-safe-targets - — 将span字段声明为field::Empty,在已知值时再记录。
otel-field-empty-then-record - — 使用boxed fmt层构建每层的EnvFilter实例。
otel-layered-subscribers-env-filter - — 通过环境变量、JSON-RPC和HTTP头传播W3C traceparent。
otel-w3c-traceparent-propagation - — 将#[instrument]默认设置为trace级别,仅为网络调用保留info级别。
otel-instrument-at-trace-level
10. TUI (Ratatui) Rendering (MEDIUM)
10. TUI(Ratatui)渲染(MEDIUM)
- — Replace fixed throttles with hysteresis-gated smooth and catch-up modes.
tui-two-gear-hysteresis-chunking - — Coalesce redraws through a FrameRequester actor and rate limiter.
tui-schedule-frame-coalescer - — Restore terminal state via a Drop guard and a chained panic hook.
tui-drop-guard-panic-hook-chain - — Detect unbracketed paste bursts via a character timing state machine.
tui-paste-burst-state-machine - — Pause the event stream by dropping it before a subprocess handoff.
tui-event-broker-pause-resume
- — 用带迟滞的平滑和追赶模式替代固定节流。
tui-two-gear-hysteresis-chunking - — 通过FrameRequester actor和速率限制器合并重绘请求。
tui-schedule-frame-coalescer - — 通过Drop guard和链式panic钩子恢复终端状态。
tui-drop-guard-panic-hook-chain - — 通过字符时序状态机检测无括号的粘贴批量输入。
tui-paste-burst-state-machine - — 在子进程切换前通过丢弃事件流来暂停事件流。
tui-event-broker-pause-resume
How to Use
使用方法
Read individual reference files for detailed explanations and code examples cited from :
codex-rs/- Section definitions — Category structure, impact levels, and prefixes
- AGENTS.md — Auto-generated navigation document compiling every rule
Each rule file contains:
- Imperative title matching its frontmatter
- 2–4 sentence explanation of the WHY
- Incorrect example showing the naive approach
- Correct example from codex-rs with the file path cited
阅读单个参考文件获取详细说明及引用自的代码示例:
codex-rs/- 章节定义 — 类别结构、影响级别及前缀说明
- AGENTS.md — 自动生成的导航文档,汇总所有规则
每条规则文件包含:
- 与前置内容匹配的命令式标题
- 2-4句关于WHY的解释
- 错误示例:展示朴素实现方式
- 正确示例:来自codex-rs的代码,并标注文件路径
Reference Files
参考文件
| File | Description |
|---|---|
| AGENTS.md | Auto-built TOC document compiling every rule |
| README.md | Skill repository docs — contribution, structure, commands |
| references/_sections.md | Category definitions and ordering |
| gotchas.md | Failure points discovered while applying these rules |
| metadata.json | Version, discipline, references to codex-rs |
| 文件 | 描述 |
|---|---|
| AGENTS.md | 自动构建的目录文档,汇总所有规则 |
| README.md | 技能仓库文档——贡献指南、结构说明、命令 |
| references/_sections.md | 类别定义与排序 |
| gotchas.md | 应用这些规则时发现的失败点 |
| metadata.json | 版本、规范、codex-rs相关引用 |