code-craft

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Code Craft

代码工程实践

A small set of durable, language-agnostic engineering principles, plus a router to the dialect of whatever language you are actually editing. The principles are the same everywhere; only the spelling changes.
这是一套经久耐用、与语言无关的核心工程原则,同时提供了针对你正在使用的编程语言的适配指南。核心原则在所有语言中通用,只是具体实现方式有所不同。

How to use this skill

如何使用该技能

  1. Apply the universal core below. These hold in every language. They are the decisions that survive a rewrite into another language.
  2. Detect the language(s) in scope from the files being touched (see the detection guide), then read
    languages/<lang>.md
    . That file shows how each universal principle is spelled in that language, plus the idioms and tooling unique to it. Load only the language(s) you are working in.
  3. Read
    principles/<name>.md
    for depth
    when a principle is the crux of the change (a boundary redesign, an error-model decision, a test strategy). The core below is the summary; the principle file is the workflow and the nuance.
  4. Run the project's own formatter, type-check, linter, and tests before claiming done. The language file names the concrete commands.
  1. 遵循下方的通用核心原则。这些原则适用于所有编程语言,是即使将代码重写为其他语言也依然成立的决策准则。
  2. 根据待处理文件识别目标语言(参考检测指南),然后阅读
    languages/<lang>.md
    文件
    。该文件展示了每条通用原则在对应语言中的具体实现方式,以及该语言特有的编程范式和工具。只需加载你正在使用的语言相关文件即可。
  3. 当某条原则是变更的核心时(比如边界重构、错误模型决策、测试策略制定),阅读
    principles/<name>.md
    文件获取详细内容。下方的核心部分是摘要,原则文件则包含具体工作流程和细节。
  4. 在完成工作前,运行项目自带的格式化工具、类型检查器、代码检查器和测试用例。语言文件中会列出具体的命令。

Universal core

通用核心原则

Each principle links to a deeper file and maps into every language file.
每条原则都链接到对应的详细文件,并映射到各个语言的适配文件中。

1. Make illegal states unrepresentable

1. 让非法状态无法被表示

Encode invariants in the type system so the bad case cannot be constructed, not in a name, comment, or convention that a caller can ignore. A wrapper that only renames a value buys nothing; a type whose only constructor enforces the invariant buys everything. Prefer enums/unions for mutually exclusive states over flag soup, and structured data over a string that has to be re-parsed. Depth:
principles/illegal-states.md
.
在类型系统中编码不变量,确保错误状态无法被构造,而不是依赖调用者可能忽略的命名、注释或约定。仅重命名值的包装类型毫无意义;只有构造函数能强制保证不变量的类型才真正有用。对于互斥状态,优先使用枚举/联合类型而非多个标记位;优先使用结构化数据而非需要重新解析的字符串。详细内容:
principles/illegal-states.md

2. Parse, don't validate

2. 解析而非验证

At every boundary where weak external data enters (config, JSON/TOML, CLI/env, network, user edits), convert it once into a proof-carrying type and pass that type inward. Do not write
validate(x) -> bool/void
and then keep passing the raw value; return the refined value. If a caller can skip the parse and still type-check, the design is not done. Depth:
principles/parse-dont-validate.md
.
在弱类型外部数据进入的所有边界(配置、JSON/TOML、CLI/环境变量、网络、用户输入),将数据一次性转换为带验证的类型后再向内传递。不要编写
validate(x) -> bool/void
函数后继续传递原始值;应返回经过精炼的有效值。如果调用者可以跳过解析步骤仍能通过类型检查,说明设计尚未完成。详细内容:
principles/parse-dont-validate.md

3. Errors are values; gates fail closed

3. 错误即值;默认失败关闭

Handle expected failure through the language's value channel (Result, error return, typed exception), not by crashing on recoverable conditions. Add context as the error propagates so the message is a chain, not a single line. Never silently swallow an error. A gate or check that cannot produce a valid answer is a block, never a quiet pass. Depth:
principles/errors-as-values.md
.
通过语言的值通道(Result、错误返回值、类型化异常)处理预期内的失败,而非在可恢复条件下直接崩溃。在错误传播过程中添加上下文信息,使错误信息形成链式而非单一语句。绝不能静默忽略错误。若某个检查或网关无法生成有效结果,应直接阻断而非静默放行。详细内容:
principles/errors-as-values.md

4. No stringly-typed data; newtypes over primitives

4. 避免字符串类型滥用;为原始类型创建新类型

A
String
/
string
/
str
that is really an email, a user id, a path, or a state is a bug waiting to happen. Wrap distinct domain values in distinct types so the compiler stops you from passing a
UserId
where an
OrderId
belongs, and so parsing happens once. This is the everyday form of principle 1. Depth:
principles/illegal-states.md
.
将实际代表邮箱、用户ID、路径或状态的
String
/
string
/
str
类型视为潜在bug。将不同领域的值包装在不同类型中,这样编译器就能阻止你将
UserId
传递给需要
OrderId
的地方,同时解析只需执行一次。这是原则1的日常应用形式。详细内容:
principles/illegal-states.md

5. Mind ownership and copies, but clarity first

5. 关注所有权与拷贝,但以清晰度为先

Avoid copying or allocating when borrowing or referencing is correct and clear, especially in loops and hot paths. Accept the most general input type (a view, not an owned container). This matters most in Rust and C-family code and least in GC'd languages, but unnecessary deep copies and re-allocations are a smell everywhere. Do not contort readable code for a copy you have not measured.
当借用或引用更合理且清晰时,避免不必要的拷贝或内存分配,尤其是在循环和热点路径中。接受最通用的输入类型(视图而非拥有所有权的容器)。这一点在Rust和C系语言中最为重要,在GC语言中影响较小,但不必要的深拷贝和重复分配在任何语言中都是不良代码的信号。不要为了一个未经测量的拷贝而牺牲代码的可读性。

6. Test behavior, not implementation; avoid mocks

6. 测试行为而非实现;避免使用Mock

Test at real boundaries with real data. Prefer pure functions, real temp files, and throwaway fixtures over mocking frameworks that assert on internal calls. Name tests for the behavior they pin. Use property-based tests where the input space is large. Keep tests deterministic: no sleeps for synchronization, expose a join/observe channel instead. Depth:
principles/testing.md
.
在真实边界使用真实数据进行测试。优先使用纯函数、真实临时文件和一次性测试夹具,而非依赖断言内部调用的Mock框架。为测试命名时应体现其验证的行为。在输入空间较大时使用基于属性的测试。确保测试具有确定性:不要通过睡眠来同步,而是暴露join/observe通道。详细内容:
principles/testing.md

7. Architecture docs are a stable map

7. 架构文档是稳定的地图

Keep a short, durable description of module boundaries, invariants, and cross-cutting concerns. Name the important modules and the deliberate absences ("X stays out of layer Y"). When code moves, update the map rather than adding a migration note. Keep churny detail in code comments, not the map. Depth:
principles/architecture-docs.md
.
保持一份简洁、持久的文档,描述模块边界、不变量和横切关注点。列出重要模块,并明确说明刻意排除的内容(如“X模块不得进入Y层”)。当代码迁移时,更新这份文档而非添加迁移说明。将易变的细节放在代码注释中,而非架构文档里。详细内容:
principles/architecture-docs.md

8. Earn your abstractions; profile before optimizing

8. 按需抽象;先分析再优化

Prefer the smallest correct thing. Do not add generics, traits/interfaces, layers, or indirection before there are two real callers that need them. Do not optimize on a hunch: measure first, then optimize the proven hot path, then measure again. Premature abstraction and premature optimization are the same mistake (acting on a future that has not arrived). Depth:
principles/simplicity.md
.
优先选择最小且正确的实现方案。在有两个真实调用者确实需要之前,不要添加泛型、 trait/接口、层级或间接层。不要凭直觉优化:先测量,再针对已证实的热点路径进行优化,然后再次测量。过早抽象和过早优化本质上是同一个错误(基于尚未到来的未来做出决策)。详细内容:
principles/simplicity.md

9. New projects: take the defaults

9. 新项目:遵循默认规范

When starting a new project (or hardening a young one), do not re-litigate tooling. Lock in one opinionated auto-formatter and one linter per language and run the full check suite from one recipe in both CI and a pre-commit hook (so they never drift), add a deterministic agent-rules layer that also gates in CI and an agentic review gate over each changeset, ship CLI binaries via tag-triggered releases with checksummed install scripts, and scaffold the community/governance files. License is the one decision the agent must ask about: AGPL-3.0-or-later or Apache-2.0, nothing else. The picks and the full checklist are in
principles/new-project-defaults.md
.
启动新项目(或加固年轻项目)时,不要在工具选择上反复纠结。为每种语言锁定一个风格统一的自动格式化工具和一个代码检查器,在CI和预提交钩子中通过同一个脚本运行完整的检查套件(确保两者不会脱节),添加一个确定性的Agent规则层并在CI中设置网关,为每个变更集添加Agent评审网关,通过标签触发发布并提供带校验和的安装脚本发布CLI二进制文件,同时搭建社区/治理相关文件。许可证是唯一需要Agent询问的决策:只能选择AGPL-3.0-or-later或Apache-2.0,不允许其他选项。具体选择和完整清单见
principles/new-project-defaults.md

Language router

语言适配指南

Detect the language, then read its file. Each maps the principles into the dialect and adds what is unique to that language (tooling, concurrency model, naming, project layout, idioms to reach for, anti-patterns to refuse).
LanguageFileDetect by
Rust
languages/rust.md
*.rs
,
Cargo.toml
TypeScript / JavaScript
languages/typescript.md
*.ts
,
*.tsx
,
*.js
,
tsconfig.json
,
package.json
Go
languages/go.md
*.go
,
go.mod
Python
languages/python.md
*.py
,
pyproject.toml
,
requirements.txt
For a language not listed, apply the universal core directly and follow the project's existing conventions; the principles are designed to transfer.
识别目标语言后,阅读对应的适配文件。每个文件都会将通用原则转换为该语言的方言,并添加该语言特有的内容(工具、并发模型、命名规范、项目布局、推荐范式、需避免的反模式)。
语言文件检测方式
Rust
languages/rust.md
*.rs
,
Cargo.toml
TypeScript / JavaScript
languages/typescript.md
*.ts
,
*.tsx
,
*.js
,
tsconfig.json
,
package.json
Go
languages/go.md
*.go
,
go.mod
Python
languages/python.md
*.py
,
pyproject.toml
,
requirements.txt
对于未列出的语言,直接应用通用核心原则并遵循项目现有约定;这些原则设计为具有可迁移性。

Precedence

优先级

Project instructions and existing code conventions win over this skill. If a repo's
AGENTS.md
/
CLAUDE.md
or its established patterns conflict with a principle here, follow the repo and say so. This skill is the default, not an override.
项目说明和现有代码约定优先于本技能。如果仓库的
AGENTS.md
/
CLAUDE.md
或已确立的模式与本技能中的原则冲突,请遵循仓库的规定并说明原因。本技能是默认准则,而非强制覆盖规则。

Provenance

来源

Distilled from
leonardomso/rust-skills
(MIT), Matklad's Rust100k series, and Alexis King's "Parse, don't validate" and "Names are not type safety", then generalized beyond Rust.
提炼自
leonardomso/rust-skills
(MIT许可证)、Matklad的Rust100k系列、Alexis King的《Parse, don't validate》和《Names are not type safety》,然后推广到Rust以外的语言。