关于 openai-codex-rust-patterns
这是一套提炼自 OpenAI Codex 的 codex-rs 工作区的 Rust 工程实践技能,面向 Rust 开发者,涵盖异步系统、CLI、协议和大型工作区,并为规则提供源码引用。
主要功能
- 01涵盖 11 类的 63 条规则
- 02引用 codex-rs 源码文件
- 03异步与取消机制指南
- 04沙箱和密钥处理模式
- 05协议、测试与工作区设计
- 06Ratatui TUI 与追踪实践
适用场景
- 01审查异步 Rust 任务与取消设计
- 02强化 CLI 子进程与沙箱策略
- 03设计可演进的 serde 协议
- 04组织多 crate Cargo 工作区
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill openai-codex-rust-patterns安装后在 Claude Code 中输入/openai-codex-rust-patterns确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
AGENTS.mdgotchas.mdmetadata.jsonREADME.mdreferences/_sections.mdasync-abort-on-drop-handle.mdasync-biased-select-for-cancellation.mdasync-bounded-vs-unbounded-channel-split.mdasync-child-cancellation-tokens.mdasync-graceful-then-forceful-cancel.mdasync-shared-boxfuture-joinhandle.mddefensive-banned-interpreter-prefixes.mddefensive-canonicalize-approval-cache-key.mddefensive-debug-assert-with-early-return.mddefensive-deny-unwrap-workspace-wide.mddefensive-fault-isolate-plugin-load.mddefensive-head-tail-output-buffer.mddefensive-io-drain-timeout-grandchildren.mddefensive-recover-poisoned-lock.mddefensive-refuse-to-run-unsandboxed.mderrors-boundary-error-translator.mderrors-carry-retry-delay-in-variant.mderrors-exhaustive-retryable-match.mderrors-io-error-with-context-struct.mderrors-struct-display-payload.mderrors-tool-call-respond-vs-fatal.mderrors-transient-permanent-type-split.mdotel-field-empty-then-record.mdotel-instrument-at-trace-level.mdotel-layered-subscribers-env-filter.md详细介绍
OpenAI Codex Rust 最佳实践
摘编自 openai/codex codex-rs/ —— 一个包含 119 个 crate、2,008 个文件的 Rust 工作区,用于发布 Codex CLI 编码 Agent。涵盖 11 个类别中的 63 条规则,每条规则都引用了 codex-rs 中对应模式所在的确切文件,帮助你按照顶尖贡献者(Michael Bolin、jif-oai、Ahmed Ibrahim、Eric Traut、Pavel Krymets)的实际方式编写 Rust。引用已根据 main 分支的提交 8a94430(2026-05-25)更新。
何时应用
遇到以下情况时,可参考这些指南:
- 编写或审查会启动 tokio 任务、拥有取消令牌或管理长期运行后台工作线程的异步 Rust 代码。
- 在库或服务中设计错误枚举、
Result流程、重试循环或分层边界。 - 构建会启动子进程、强制执行沙箱隔离或安全运行大模型生成代码的 CLI 工具。
- 构建包含约 5 个以上 crate 的 Cargo 工作区,决定如何拆分,以及如何管理共享依赖项。
- 为 Rust 代码库添加测试,而现有测试采用内联
mod tests { ... }块,且扩展起来正变得愈发困难。 - 使用 serde 实现 JSON-RPC 或自定义线协议,尤其是协议必须演进且不能破坏客户端的情况。
- 将 API 密钥或其他机密读入内存,或加固处理凭据的二进制程序,以防止核心转储、调试器附加和
LD_PRELOAD。 - 强制执行必须能够抵御 DNS 重绑定的网络出口白名单,或加载不可信的插件/扩展。
- 在对 PII 有隐私限制的服务中接入 OpenTelemetry 跟踪、日志或指标。
- 构建基于 Ratatui 的 TUI,以流式方式输出大模型内容、处理粘贴突发输入或管理终端原始模式状态。
- 每当你想使用
.unwrap()、.lock().unwrap()、anyhow::Result<()>或#[cfg(feature = "test")]时——本技能会说明 codex 的替代做法。
按优先级划分的规则类别
| 优先级 | 类别 | 影响 | 前缀 |
|---|---|---|---|
| 1 | 防御性编码与 Panic 规范 | 严重 | defensive- |
| 2 | 错误处理与 Result 规范 | 严重 | errors- |
| 3 | 异步、并发与取消 | 高 | async- |
| 4 | 沙箱隔离与进程隔离 | 高 | sandbox- |
| 5 | 机密与进程加固 | 高 | secrets- |
| 6 | 类型设计与不变量 | 高 | types- |
| 7 | 测试架构 | 中高 | testing- |
| 8 | 协议与 Serde 设计 | 中高 | proto- |
| 9 | 工作区与 Crate 组织 | 中 | workspace- |
| 10 | 可观测性与跟踪 | 中 | otel- |
| 11 | TUI(Ratatui)渲染 | 中 | tui- |
快速参考
1. 防御式编码与 panic 纪律(严重)
defensive-deny-unwrap-workspace-wide— 在工作区级别禁止使用 unwrap 和 expect,在本地选择性启用。defensive-debug-assert-with-early-return— 在不可达分支中使用 debug_assert(false),并提供安全的回退方案。defensive-recover-poisoned-lock— 使用 into_inner 恢复中毒的锁,而不是对其调用 unwrap。defensive-banned-interpreter-prefixes— 避免为通用解释器编写允许列表规则。defensive-head-tail-output-buffer— 使用首尾环形缓冲区限制子进程输出。defensive-io-drain-timeout-grandchildren— 为 I/O 排空任务单独设置超时,不与子进程共用超时。defensive-refuse-to-run-unsandboxed— 如果沙箱无法强制执行所请求的策略,就拒绝运行。defensive-canonicalize-approval-cache-key— 对 shell 包装器进行规范化,然后再对审批密钥进行哈希处理。defensive-fault-isolate-plugin-load— 隔离插件加载失败,并在模型看到清单文本前对其进行清理。
2. 错误处理与 Result 纪律(严重)
errors-exhaustive-retryable-match— 使用穷尽式 match 检查所有变体,判断哪些错误可以重试。errors-transient-permanent-type-split— 将临时结果与永久结果编码为两个枚举变体。errors-boundary-error-translator— 在层边界处通过单个函数转换错误。errors-carry-retry-delay-in-variant— 在错误变体中携带服务端请求的重试延迟。errors-struct-display-payload— 将与显示相关的错误状态放在结构体中,而不是预先格式化的字符串中。errors-tool-call-respond-vs-fatal— 将工具错误拆分为返回给模型的错误和致命错误两种变体。errors-io-error-with-context-struct— 使用带有上下文字段的结构体包装 io::Error,而不是使用 anyhow。
3. 异步、并发与取消(高)
async-abort-on-drop-handle— 将 JoinHandle 存储为 AbortOnDropHandle,以便在 Drop 时取消任务。async-graceful-then-forceful-cancel— 先协作式取消,再在宽限期限后中止。async-biased-select-for-cancellation— 使用 biased select,确保发生竞争平局时始终优先取消。async-bounded-vs-unbounded-channel-split— 限制提交通道的容量,但让事件通道保持无界。async-child-cancellation-tokens— 为生成的子任务提供子令牌,而不是父令牌的克隆。async-shared-boxfuture-joinhandle— 使用 Shared 包装后台 JoinHandle,以支持多个等待者加入。
4. 沙箱与进程隔离(HIGH)
sandbox-shared-policy-data-model— 将沙箱策略保留为共享数据,而不是针对各个平台编写代码。sandbox-staged-restrictions-re-exec— 通过重新执行同一个二进制文件,分阶段应用不兼容的限制。sandbox-resolve-before-allow-dns-rebinding— 解析主机名并拒绝私有 IP,以抵御 DNS 重绑定攻击。sandbox-dev-null-first-missing-mount— 在第一个缺失路径上挂载 /dev/null,以阻止 mkdir 越界。sandbox-three-layer-network-isolation— 组合使用环境变量、seccomp 和命名空间来隔离网络。sandbox-env-clear-pre-exec— 在每次启动前,通过 pre_exec 清除环境变量并约束子进程。sandbox-argv0-multiplex-binary— 通过 argv[0] 和符号链接复用辅助二进制文件。
5. 密钥与进程加固(HIGH)
secrets-read-into-locked-buffer— 将密钥读入经清零的栈缓冲区,然后对其调用 mlock — 绝不要通过 stdin() 读取。secrets-ctor-pre-main-hardening— 在 main() 运行前加固处理密钥的进程,并在失败时采取拒绝策略。secrets-manual-debug-elide— 手动编写 Debug 实现以隐藏凭据,而不是通过派生生成。
6. 类型设计与不变量(HIGH)
types-thread-local-raii-serde— 通过线程本地 RAII 守卫传递反序列化器上下文。types-try-from-newtype-validation— 在 newtype 上使用 serde try_from,以便在每次解析时运行验证。types-non-exhaustive-public-enums— 从一开始就将每个公开的线级枚举标记为 non_exhaustive。types-unknown-variant-forward-compat— 在 Unknown 变体中保留无法识别的值。
7. 测试架构(MEDIUM-HIGH)
testing-path-attribute-sibling-tests— 使用 #[path] 将测试作为同级文件附加,而不是内联编写 mod tests。testing-wiremock-sse-fakes— 使用 wiremock 和简洁的 SSE 事件构造器模拟网络。testing-atomic-bool-test-opt-in— 使用 AtomicBool 而不是 cargo feature 来控制仅用于测试的行为。testing-insta-snapshot-tui-rendering— 使用 insta 对终端渲染进行快照测试,以生成稳定的 UI 差异。testing-paused-runtime-advance— 使用 start_paused 和 advance,让依赖时序的测试具有确定性。
8. 协议与 Serde 设计(中高)
proto-internally-tagged-rpc-dispatch— 使用内部标记的枚举和宏分发 JSON-RPC。proto-double-option-tri-state— 使用 Option<Option> 区分未提供、null 和已设置。proto-rename-alias-wire-migration— 配合使用 rename 和 alias,在不中断客户端的情况下迁移线缆名称。proto-experimental-runtime-gate— 根据运行时是否存在来门控实验性字段,而非使用能力标志。proto-sse-idle-timeout-terminator— 将 SSE 流视为带空闲超时且必须包含终止符的流。proto-internal-vs-wire-error-split— 将内部错误枚举与线缆错误枚举分开。proto-removed-feature-tombstone— 将已移除的功能标志保留为可解析的空操作墓碑。
9. 工作区与 Crate 组织(中)
workspace-layered-transport-api-core— 将 HTTP 分层为 transport、api 和 core crate。workspace-lint-config-package— 在 workspace.lints 和 clippy.toml 中编码策略。workspace-utils-microcrate-fanout— 将共享工具放入 utils/ 下用途单一的微型 crate。workspace-test-support-as-member-crates— 将共享测试辅助工具注册为工作区成员 crate。workspace-ban-per-crate-features— 避免按 crate 设置功能;改用 target-cfg 或独立 crate。
10. 可观测性与追踪(中)
otel-log-only-vs-trace-safe-targets— 将 PII 路由到仅记录日志的目标,并确保追踪的基数安全。otel-field-empty-then-record— 将 span 字段声明为 field::Empty,并在获知其值后再记录。otel-layered-subscribers-env-filter— 使用装箱的 fmt 层,为每一层构建 EnvFilter 实例。otel-w3c-traceparent-propagation— 通过环境变量、JSON-RPC 和 HTTP 标头传播 W3C traceparent。otel-instrument-at-trace-level— 默认将 #[instrument] 设为 trace 级别,并将 info 保留给网络调用。
11. TUI(Ratatui)渲染(中)
tui-two-gear-hysteresis-chunking— 用滞回控制的平滑模式和追赶模式取代固定节流。tui-schedule-frame-coalescer— 通过 FrameRequester actor 和速率限制器合并重绘请求。tui-drop-guard-panic-hook-chain— 通过 Drop 守卫和链式 panic hook 恢复终端状态。tui-paste-burst-state-machine— 通过字符计时状态机检测未加括号的粘贴突发。tui-event-broker-pause-resume— 在切换到子进程前丢弃事件流,以暂停该流。
使用方法
阅读各参考文件,了解对 codex-rs/ 中引用的详细说明和代码示例:
每个规则文件都包含:
- 与其 frontmatter 匹配的祈使式标题
- 2–4 句解释 WHY 的说明
- 错误示例,展示最直接的做法
- 来自 codex-rs 的正确示例,并注明文件路径
参考文件
| 文件 | 说明 |
|---|---|
| AGENTS.md | 自动构建的 TOC 文档,汇总所有规则 |
| README.md | 技能仓库文档 — 贡献、结构、命令 |
| references/_sections.md | 类别定义和排序 |
| gotchas.md | 应用这些规则时发现的问题 |
| metadata.json | 版本、规范领域、对 codex-rs 的引用 |
评论
支持 Markdown