openai-codex-rust-patterns

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

OpenAI Codex Rust Best Practices

OpenAI Codex Rust 最佳实践

Distilled from
openai/codex
codex-rs/
— 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/codex
codex-rs/
工作区——这是一个包含72个crate、1418个文件的Rust工作区,用于交付Codex CLI编码Agent。涵盖10个类别共60条规则,每条规则均引用了codex-rs中对应模式所在的具体文件,让你能够以其核心贡献者(Michael Bolin、jif-oai、Ahmed Ibrahim、Eric Traut、Pavel Krymets)实际交付代码的方式编写Rust。

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,
    Result
    flows, retry loops, or layer boundaries in a library or service.
  • 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
    mod tests { ... }
    blocks and scaling is becoming painful.
  • 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()
    ,
    anyhow::Result<()>
    , or
    #[cfg(feature = "test")]
    — this skill explains what codex does instead.
在以下场景中可参考本指南:
  • 编写或审查用于生成tokio任务、持有取消令牌或管理长期后台工作线程的异步Rust代码时。
  • 在库或服务中设计错误枚举、
    Result
    流程、重试循环或层级边界时。
  • 构建可生成子进程、强制沙箱隔离或安全运行LLM生成代码的CLI工具时。
  • 架构包含约5个以上crate的Cargo工作区,决定拆分内容及管理共享依赖时。
  • 为Rust代码库添加测试,而现有测试为内联
    mod tests { ... }
    块且扩展难度渐增时。
  • 使用serde实现JSON-RPC或自定义有线协议——尤其是需要在不中断客户端的情况下演进的协议时。
  • 为存在PII隐私约束的服务接入OpenTelemetry追踪、日志或指标时。
  • 构建基于Ratatui的TUI,用于流式传输LLM输出、处理粘贴批量输入或管理原始模式终端状态时。
  • 加固二进制文件以抵御调试器附加、LD_PRELOAD或环境变量篡改时。
  • 每当你需要使用
    .unwrap()
    anyhow::Result<()>
    #[cfg(feature = "test")]
    时——本技能会解释codex采用的替代方案。

Rule Categories by Priority

规则优先级

PriorityCategoryImpactPrefix
1Defensive Coding & Panic DisciplineCRITICAL
defensive-
2Error Handling & Result DisciplineCRITICAL
errors-
3Async, Concurrency & CancellationHIGH
async-
4Sandboxing & Process IsolationHIGH
sandbox-
5Type Design & InvariantsHIGH
types-
6Testing ArchitectureMEDIUM-HIGH
testing-
7Protocol & Serde DesignMEDIUM-HIGH
proto-
8Workspace & Crate OrganizationMEDIUM
workspace-
9Observability & TracingMEDIUM
otel-
10TUI (Ratatui) RenderingMEDIUM
tui-
优先级类别影响级别前缀
1防御性编程与Panic规范CRITICAL
defensive-
2错误处理与Result规范CRITICAL
errors-
3异步、并发与取消HIGH
async-
4沙箱与进程隔离HIGH
sandbox-
5类型设计与不变量HIGH
types-
6测试架构MEDIUM-HIGH
testing-
7协议与Serde设计MEDIUM-HIGH
proto-
8工作区与Crate组织MEDIUM
workspace-
9可观测性与追踪MEDIUM
otel-
10TUI(Ratatui)渲染MEDIUM
tui-

Quick Reference

快速参考

1. Defensive Coding & Panic Discipline (CRITICAL)

1. 防御性编程与Panic规范(CRITICAL)

  • defensive-deny-unwrap-workspace-wide
    — Deny unwrap and expect at the workspace level, opt in locally.
  • defensive-debug-assert-with-early-return
    — Use debug_assert(false) with a safe fallback on unreachable branches.
  • defensive-banned-interpreter-prefixes
    — Avoid learning allowlist rules for general-purpose interpreters.
  • defensive-head-tail-output-buffer
    — Cap subprocess output with a head-and-tail ring buffer.
  • defensive-io-drain-timeout-grandchildren
    — Time out the I/O drain task separately from the child process.
  • defensive-canonicalize-approval-cache-key
    — Canonicalize shell wrappers before hashing approval keys.
  • defensive-refuse-to-run-unsandboxed
    — Refuse to run when the sandbox cannot enforce the requested policy.
  • defensive-deny-unwrap-workspace-wide
    — 在工作区级别禁用unwrap和expect,仅在局部场景启用。
  • defensive-debug-assert-with-early-return
    — 在不可达分支使用debug_assert(false)并搭配安全的提前返回逻辑。
  • defensive-banned-interpreter-prefixes
    — 避免为通用解释器设置允许列表规则。
  • defensive-head-tail-output-buffer
    — 使用首尾环形缓冲区限制子进程输出大小。
  • defensive-io-drain-timeout-grandchildren
    — 为I/O排空任务单独设置超时时间,与子进程超时分离。
  • defensive-canonicalize-approval-cache-key
    — 在对审批密钥哈希前先规范化shell包装器。
  • defensive-refuse-to-run-unsandboxed
    — 当沙箱无法执行请求的策略时,拒绝运行。

2. Error Handling & Result Discipline (CRITICAL)

2. 错误处理与Result规范(CRITICAL)

  • errors-exhaustive-retryable-match
    — Classify retryable errors with an exhaustive match on every variant.
  • errors-transient-permanent-type-split
    — Encode transient vs permanent outcomes as two enum variants.
  • errors-carry-retry-delay-in-variant
    — Carry the server-requested retry delay inside the error variant.
  • errors-boundary-error-translator
    — Translate errors at the layer boundary in a single function.
  • errors-struct-display-payload
    — Put display-relevant error state in a struct, not a preformatted string.
  • errors-tool-call-respond-vs-fatal
    — Split tool errors into respond-to-model and fatal variants.
  • errors-io-error-with-context-struct
    — Wrap io::Error in a struct with a context field instead of anyhow.
  • 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
    — 将工具错误分为响应模型和致命错误两类变体。
  • errors-io-error-with-context-struct
    — 将io::Error包装到带有上下文字段的结构体中,而非使用anyhow。

3. Async, Concurrency & Cancellation (HIGH)

3. 异步、并发与取消(HIGH)

  • async-abort-on-drop-handle
    — Use Arc<AbortOnDropHandle> so dropped owners auto-cancel tasks.
  • async-graceful-then-forceful-cancel
    — Cancel cooperatively first, then abort after a grace deadline.
  • async-biased-select-for-cancellation
    — Use biased select to make cancellation always win race ties.
  • async-bounded-vs-unbounded-channel-split
    — Bound the submission channel but leave the event channel unbounded.
  • async-child-cancellation-tokens
    — Give spawned sub-tasks child tokens, not clones of the parent.
  • async-shared-boxfuture-joinhandle
    — Wrap a background JoinHandle in Shared<BoxFuture> for multi-waiter joins.
  • async-abort-on-drop-handle
    — 使用Arc<AbortOnDropHandle>,让被丢弃的所有者自动取消任务。
  • async-graceful-then-forceful-cancel
    — 首先尝试协作式取消,超过宽限期后再强制终止。
  • async-biased-select-for-cancellation
    — 使用偏向选择,让取消操作在竞争中始终优先。
  • async-bounded-vs-unbounded-channel-split
    — 对提交通道设置边界,而事件通道保持无边界。
  • async-child-cancellation-tokens
    — 为生成的子任务分配子令牌,而非父令牌的克隆。
  • async-shared-boxfuture-joinhandle
    — 将后台JoinHandle包装在Shared<BoxFuture>中,支持多等待者连接。

4. Sandboxing & Process Isolation (HIGH)

4. 沙箱与进程隔离(HIGH)

  • sandbox-shared-policy-data-model
    — Keep sandbox policy as shared data, not per-platform code.
  • sandbox-staged-restrictions-re-exec
    — Stage incompatible restrictions by re-executing the same binary.
  • sandbox-argv0-multiplex-binary
    — Multiplex helper binaries via argv[0] and symlinks.
  • sandbox-dev-null-first-missing-mount
    — Mount /dev/null over the first missing path to block mkdir escapes.
  • sandbox-three-layer-network-isolation
    — Stack env vars, seccomp, and namespaces for network isolation.
  • sandbox-env-clear-pre-exec
    — Clear the env and tether children via pre_exec before every spawn.
  • sandbox-shared-policy-data-model
    — 将沙箱策略作为共享数据存储,而非按平台拆分代码。
  • sandbox-staged-restrictions-re-exec
    — 通过重新执行同一二进制文件来分阶段应用不兼容的限制。
  • sandbox-argv0-multiplex-binary
    — 通过argv[0]和符号链接复用辅助二进制文件。
  • sandbox-dev-null-first-missing-mount
    — 在第一个缺失路径上挂载/dev/null,以阻止mkdir逃逸。
  • sandbox-three-layer-network-isolation
    — 叠加环境变量、seccomp和命名空间实现网络隔离。
  • sandbox-env-clear-pre-exec
    — 在每次生成子进程前,通过pre_exec清理环境并绑定子进程。

5. Type Design & Invariants (HIGH)

5. 类型设计与不变量(HIGH)

  • types-thread-local-raii-serde
    — Pass deserializer context via a thread-local RAII guard.
  • types-dyn-safe-adapter-trait
    — Pair an ergonomic trait with a private dyn-safe adapter trait.
  • types-try-from-newtype-validation
    — Use serde try_from on a newtype to run validation on every parse.
  • types-full-reference-hierarchy
    — Implement Borrow, AsRef, and Deref on every public ID newtype.
  • types-non-exhaustive-public-enums
    — Mark every public wire-level enum non_exhaustive from the start.
  • types-unknown-variant-forward-compat
    — Preserve unrecognized values in an Unknown variant.
  • types-thread-local-raii-serde
    — 通过线程本地RAII guard传递反序列化上下文。
  • types-dyn-safe-adapter-trait
    — 将易用性 trait 与私有dyn-safe适配trait配对使用。
  • types-try-from-newtype-validation
    — 在newtype上使用serde try_from,在每次解析时运行验证逻辑。
  • types-full-reference-hierarchy
    — 在每个公开ID newtype上实现Borrow、AsRef和Deref。
  • types-non-exhaustive-public-enums
    — 从一开始就将每个公开有线级枚举标记为non_exhaustive。
  • types-unknown-variant-forward-compat
    — 在Unknown变体中保留未识别的值。

6. Testing Architecture (MEDIUM-HIGH)

6. 测试架构(MEDIUM-HIGH)

  • testing-path-attribute-sibling-tests
    — Attach tests as sibling files via #[path] instead of inline mod tests.
  • testing-wiremock-sse-fakes
    — Fake the network with wiremock and small SSE event constructors.
  • testing-atomic-bool-test-opt-in
    — Gate test-only behavior with an AtomicBool, not a cargo feature.
  • testing-config-closure-builder
    — Configure test fixtures with a closure builder.
  • testing-insta-snapshot-tui-rendering
    — Snapshot terminal rendering with insta for stable UI diffs.
  • testing-paused-runtime-advance
    — Use start_paused and advance to make timing-dependent tests deterministic.
  • testing-path-attribute-sibling-tests
    — 通过#[path]将测试作为同级文件附加,而非内联mod tests。
  • testing-wiremock-sse-fakes
    — 使用wiremock和小型SSE事件构造函数模拟网络。
  • testing-atomic-bool-test-opt-in
    — 使用AtomicBool而非cargo特性来控制仅测试用的行为。
  • testing-config-closure-builder
    — 使用闭包构建器配置测试夹具。
  • testing-insta-snapshot-tui-rendering
    — 使用insta对终端渲染进行快照,实现稳定的UI差异对比。
  • testing-paused-runtime-advance
    — 使用start_paused和advance使依赖时序的测试具有确定性。

7. Protocol & Serde Design (MEDIUM-HIGH)

7. 协议与Serde设计(MEDIUM-HIGH)

  • proto-internally-tagged-rpc-dispatch
    — Dispatch JSON-RPC by an internally tagged enum with a macro.
  • proto-double-option-tri-state
    — Use Option<Option<T>> to distinguish absent, null, and set.
  • proto-rename-alias-wire-migration
    — Pair rename and alias to migrate wire names without breaking clients.
  • proto-experimental-runtime-gate
    — Gate experimental fields by runtime presence, not capability flags.
  • proto-sse-idle-timeout-terminator
    — Treat SSE streams as idle-timeout with required terminator.
  • proto-internal-vs-wire-error-split
    — Split internal error enums from wire error enums.
  • proto-internally-tagged-rpc-dispatch
    — 通过带内部标签的枚举和宏实现JSON-RPC分发。
  • proto-double-option-tri-state
    — 使用Option<Option<T>>区分缺失、空值和已设置状态。
  • proto-rename-alias-wire-migration
    — 将rename和alias配对使用,在不中断客户端的情况下迁移有线名称。
  • proto-experimental-runtime-gate
    — 通过运行时存在性而非能力标志来控制实验性字段。
  • proto-sse-idle-timeout-terminator
    — 将SSE流视为带超时的空闲连接,并要求终止符。
  • proto-internal-vs-wire-error-split
    — 将内部错误枚举与有线错误枚举分离。

8. Workspace & Crate Organization (MEDIUM)

8. 工作区与Crate组织(MEDIUM)

  • workspace-ban-per-crate-features
    — Avoid per-crate features; use target-cfg or separate crates instead.
  • workspace-single-source-dependencies
    — Declare every dependency version once in workspace.dependencies.
  • workspace-layered-transport-api-core
    — Stack HTTP layers as transport, api, and core crates.
  • workspace-test-support-as-member-crates
    — Register shared test helpers as workspace member crates.
  • workspace-utils-microcrate-fanout
    — Place shared utilities in single-purpose microcrates under utils/.
  • workspace-lint-config-package
    — Encode policy in workspace.lints and clippy.toml.
  • workspace-ban-per-crate-features
    — 避免使用每个crate单独的特性;改用target-cfg或独立crate。
  • workspace-single-source-dependencies
    — 在workspace.dependencies中统一声明每个依赖的版本。
  • workspace-layered-transport-api-core
    — 将HTTP层分为transport、api和core三个crate。
  • workspace-test-support-as-member-crates
    — 将共享测试助手注册为工作区成员crate。
  • workspace-utils-microcrate-fanout
    — 将共享工具放入utils/下的单用途微crate中。
  • workspace-lint-config-package
    — 在workspace.lints和clippy.toml中编码策略。

9. Observability & Tracing (MEDIUM)

9. 可观测性与追踪(MEDIUM)

  • otel-log-only-vs-trace-safe-targets
    — Route PII to log-only targets and keep traces cardinality-safe.
  • otel-field-empty-then-record
    — Declare span fields as field::Empty, then record them when known.
  • otel-layered-subscribers-env-filter
    — Build per-layer EnvFilter instances with boxed fmt layers.
  • otel-w3c-traceparent-propagation
    — Propagate W3C traceparent via env vars, JSON-RPC, and HTTP headers.
  • otel-instrument-at-trace-level
    — Default #[instrument] to trace level, reserve info for network calls.
  • otel-log-only-vs-trace-safe-targets
    — 将PII路由至仅日志目标,保持追踪的基数安全。
  • otel-field-empty-then-record
    — 将span字段声明为field::Empty,在已知值时再记录。
  • otel-layered-subscribers-env-filter
    — 使用boxed fmt层构建每层的EnvFilter实例。
  • otel-w3c-traceparent-propagation
    — 通过环境变量、JSON-RPC和HTTP头传播W3C traceparent。
  • otel-instrument-at-trace-level
    — 将#[instrument]默认设置为trace级别,仅为网络调用保留info级别。

10. TUI (Ratatui) Rendering (MEDIUM)

10. TUI(Ratatui)渲染(MEDIUM)

  • tui-two-gear-hysteresis-chunking
    — Replace fixed throttles with hysteresis-gated smooth and catch-up modes.
  • tui-schedule-frame-coalescer
    — Coalesce redraws through a FrameRequester actor and rate limiter.
  • tui-drop-guard-panic-hook-chain
    — Restore terminal state via a Drop guard and a chained panic hook.
  • tui-paste-burst-state-machine
    — Detect unbracketed paste bursts via a character timing state machine.
  • tui-event-broker-pause-resume
    — Pause the event stream by dropping it before a subprocess handoff.
  • tui-two-gear-hysteresis-chunking
    — 用带迟滞的平滑和追赶模式替代固定节流。
  • tui-schedule-frame-coalescer
    — 通过FrameRequester actor和速率限制器合并重绘请求。
  • tui-drop-guard-panic-hook-chain
    — 通过Drop guard和链式panic钩子恢复终端状态。
  • 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

参考文件

FileDescription
AGENTS.mdAuto-built TOC document compiling every rule
README.mdSkill repository docs — contribution, structure, commands
references/_sections.mdCategory definitions and ordering
gotchas.mdFailure points discovered while applying these rules
metadata.jsonVersion, discipline, references to codex-rs
文件描述
AGENTS.md自动构建的目录文档,汇总所有规则
README.md技能仓库文档——贡献指南、结构说明、命令
references/_sections.md类别定义与排序
gotchas.md应用这些规则时发现的失败点
metadata.json版本、规范、codex-rs相关引用