ds-principles
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseEngineering principles
工程原则
If a trigger matches, apply the rule. Name principles that changed a decision.
如果某个触发条件匹配,就应用对应规则。说明哪些原则改变了决策。
Design
设计
- Subtract, then add little. Remove dead code and stale checks first, then make the shortest diff that works. No abstraction with one user. Apply when sizing a diff or tempted to add a layer.
- Data shape first. Choose the core types and structures before logic. Apply before writing new logic.
- Model the domain. Put states in one structure, such as a typed union, state machine, or lookup table, not scattered conditionals. Apply when code branches a lot or repeats a shape across files.
- Redesign for the new need. Fit a new requirement as if it existed from day one. Apply when an addition strains the design.
- Low reader load. Inline one-caller wrappers and shrink mutable scope. Apply when code is hard to trace.
- Guards at boundaries. Validate where input enters: CLI, config, network, files, external APIs. Trust types inside and keep core logic pure. Apply when adding validation or error handling.
- Idempotent steps. Rerunning a step, even after a crash, reaches the same state. Apply to commands, setup, and retries.
- No shared writers. Give each concurrent actor its own file, branch, or key before using locks. Apply when parallel work touches shared state.
- Migrate, then delete. Move every caller and delete the old API in one change. No shims. Apply when replacing an API or rewriting in phases.
- Compare options. For an unprecedented design, sketch two or three. Prefer fewer, polished features. Apply to novel architecture, UX, or scope choices.
- 先做减法,再少量添加。 先移除 dead code 和 stale checks,再编写能够奏效的最小 diff。不要为只有一个调用方创建 abstraction。在评估 diff 规模或想增加一层抽象时应用。
- 先确定 data shape。 编写新逻辑之前,先选择核心 types 和 structures。
- 对领域建模。 将状态集中在一个结构中,例如 typed union、state machine 或 lookup table,而不是散落在多个条件分支中。当代码分支很多,或多个文件重复同一种结构时应用。
- 针对新需求重新设计。 让新需求仿佛从第一天起就存在一样自然契合设计。当新增内容让设计变得吃力时应用。
- 降低读者负担。 直接内联仅有一个调用方的 wrapper,并缩小 mutable scope。当代码难以追踪时应用。
- 在边界处设防。 在输入进入系统之处进行验证:CLI、config、network、files、external APIs。信任内部 types,并让核心逻辑保持纯粹。在添加 validation 或 error handling 时应用。
- 确保步骤幂等。 重复执行某一步时,即使中途崩溃,最终也应到达相同状态。适用于 commands、setup 和 retries。
- 不要共享写入方。 在使用 locks 之前,先让每个并发执行方独占自己的 file、branch 或 key。当并行工作会触及共享状态时应用。
- 先迁移,再删除。 在一次变更中迁移所有调用方并删除旧 API。不保留 shim。适用于替换 API 或分阶段重写。
- 比较方案。 对于没有先例的设计,先勾勒两三种方案。优先选择功能更少但打磨更完善的方案。适用于全新的 architecture、UX 或 scope 选择。
Debugging and verification
调试与验证
- Fix root causes. Fix where state first went wrong. A guard fixes only legitimate states. Apply when debugging.
- Attack the premise. After two failed fixes that share an assumption, write it down and test it directly. Apply before a third attempt.
- Prove it works. Run the real thing and read the actual output, not a proxy. Apply before claiming done.
- Verifiable units. Split work into steps that each end in a passing check. Apply to sweeps, migrations, and stacked commits.
- Test behavior. Assert what callers can observe, so tests survive refactors. Apply when writing or keeping a test.
- Explain the number. Find what limits a measurement and confirm it measured the right work. Apply to benchmarks and eval scores.
- Build the tool. Script bulk or repeated work so it can be rerun. Apply to large edit sets or checks.
- 修复根因。 在状态首次出错的位置进行修复。Guard 只能处理合法状态。调试时应用。
- 质疑前提。 两次失败的修复若共享同一假设,就将其写下来并直接验证。在尝试第三次修复前应用。
- 证明它能正常工作。 运行真实系统并读取实际输出,而不是 proxy。在声称完成前应用。
- 创建可验证的单元。 将工作拆分为若干步骤,每一步都以通过检查结束。适用于批量修改、migrations 和 stacked commits。
- 测试行为。 断言调用方可观察到的行为,使测试在重构后仍能保留。编写或维护 test 时应用。
- 解释数字。 找出限制测量结果的因素,并确认测量对象确实是正确的工作。适用于 benchmarks 和 eval scores。
- 构建工具。 将批量或重复性工作编写成 script,以便重新运行。适用于大规模 edit sets 或 checks。
Process
流程
- Guard the context. Keep summaries, not dumps. Send bulk reading to subagents. Apply when outputs or files are large.
- Do not block on the human. On reversible work, proceed and show the result. Apply when tempted to ask "should I?".
- Encode repeated lessons. A correction given twice becomes a lint, test, or script. Apply when a mistake recurs.
- Comments explain why. Keep a comment only for a reason the code cannot show, such as an external constraint or a public API contract. Delete narration and dead code. Fix code whose surprise needs a comment. Apply when writing or reviewing code.
- 控制上下文。 保留摘要,而不是原始内容转储。将批量阅读任务交给子 Agent。当输出或文件过大时应用。
- 不要等待人类。 对于可逆工作,继续执行并展示结果。当你想询问“should I?”时应用。
- 沉淀重复经验。 同一纠正若出现两次,就将其转化为 lint、test 或 script。当同类错误反复发生时应用。
- 注释解释原因。 只保留代码本身无法表达的原因注释,例如外部约束或 public API contract。删除叙述性注释和 dead code。对于因意外行为而需要注释的代码,应直接修正。编写或审查代码时应用。
Types
类型
- Make illegal states unrepresentable. Use discriminated unions, not optional-field bags.
- Parse external data once at the boundary into a named type. Trust it inside.
- Use for untrusted input. Never
unknown. Noanycasts before validation.as - Derive types from a schema, not hand-written guards.
- Add a check in default branches so new variants fail the build.
never - Brand primitives that must not mix, such as user IDs and order IDs.
- 让非法状态无法表示。使用 discriminated unions,而不是 optional-field bags。
- 在边界处一次性解析 external data,并将其转换为 named type;进入内部后信任该类型。
- 对不可信输入使用 ,绝不使用
unknown。验证之前不要使用anycasts。as - 从 schema 派生 types,而不是手写 guards。
- 在 default branches 中加入 check,使新增 variants 在构建时失败。
never - 使用 brand 区分不可混用的 primitives,例如 user IDs 和 order IDs。