ds-principles

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Engineering principles

工程原则

If a trigger matches, apply the rule. Name principles that changed a decision.
如果某个触发条件匹配,就应用对应规则。说明哪些原则改变了决策。

Design

设计

  1. 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.
  2. Data shape first. Choose the core types and structures before logic. Apply before writing new logic.
  3. 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.
  4. Redesign for the new need. Fit a new requirement as if it existed from day one. Apply when an addition strains the design.
  5. Low reader load. Inline one-caller wrappers and shrink mutable scope. Apply when code is hard to trace.
  6. 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.
  7. Idempotent steps. Rerunning a step, even after a crash, reaches the same state. Apply to commands, setup, and retries.
  8. No shared writers. Give each concurrent actor its own file, branch, or key before using locks. Apply when parallel work touches shared state.
  9. 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.
  10. Compare options. For an unprecedented design, sketch two or three. Prefer fewer, polished features. Apply to novel architecture, UX, or scope choices.
  1. 先做减法,再少量添加。 先移除 dead code 和 stale checks,再编写能够奏效的最小 diff。不要为只有一个调用方创建 abstraction。在评估 diff 规模或想增加一层抽象时应用。
  2. 先确定 data shape。 编写新逻辑之前,先选择核心 types 和 structures。
  3. 对领域建模。 将状态集中在一个结构中,例如 typed union、state machine 或 lookup table,而不是散落在多个条件分支中。当代码分支很多,或多个文件重复同一种结构时应用。
  4. 针对新需求重新设计。 让新需求仿佛从第一天起就存在一样自然契合设计。当新增内容让设计变得吃力时应用。
  5. 降低读者负担。 直接内联仅有一个调用方的 wrapper,并缩小 mutable scope。当代码难以追踪时应用。
  6. 在边界处设防。 在输入进入系统之处进行验证:CLI、config、network、files、external APIs。信任内部 types,并让核心逻辑保持纯粹。在添加 validation 或 error handling 时应用。
  7. 确保步骤幂等。 重复执行某一步时,即使中途崩溃,最终也应到达相同状态。适用于 commands、setup 和 retries。
  8. 不要共享写入方。 在使用 locks 之前,先让每个并发执行方独占自己的 file、branch 或 key。当并行工作会触及共享状态时应用。
  9. 先迁移,再删除。 在一次变更中迁移所有调用方并删除旧 API。不保留 shim。适用于替换 API 或分阶段重写。
  10. 比较方案。 对于没有先例的设计,先勾勒两三种方案。优先选择功能更少但打磨更完善的方案。适用于全新的 architecture、UX 或 scope 选择。

Debugging and verification

调试与验证

  1. Fix root causes. Fix where state first went wrong. A guard fixes only legitimate states. Apply when debugging.
  2. Attack the premise. After two failed fixes that share an assumption, write it down and test it directly. Apply before a third attempt.
  3. Prove it works. Run the real thing and read the actual output, not a proxy. Apply before claiming done.
  4. Verifiable units. Split work into steps that each end in a passing check. Apply to sweeps, migrations, and stacked commits.
  5. Test behavior. Assert what callers can observe, so tests survive refactors. Apply when writing or keeping a test.
  6. Explain the number. Find what limits a measurement and confirm it measured the right work. Apply to benchmarks and eval scores.
  7. Build the tool. Script bulk or repeated work so it can be rerun. Apply to large edit sets or checks.
  1. 修复根因。 在状态首次出错的位置进行修复。Guard 只能处理合法状态。调试时应用。
  2. 质疑前提。 两次失败的修复若共享同一假设,就将其写下来并直接验证。在尝试第三次修复前应用。
  3. 证明它能正常工作。 运行真实系统并读取实际输出,而不是 proxy。在声称完成前应用。
  4. 创建可验证的单元。 将工作拆分为若干步骤,每一步都以通过检查结束。适用于批量修改、migrations 和 stacked commits。
  5. 测试行为。 断言调用方可观察到的行为,使测试在重构后仍能保留。编写或维护 test 时应用。
  6. 解释数字。 找出限制测量结果的因素,并确认测量对象确实是正确的工作。适用于 benchmarks 和 eval scores。
  7. 构建工具。 将批量或重复性工作编写成 script,以便重新运行。适用于大规模 edit sets 或 checks。

Process

流程

  1. Guard the context. Keep summaries, not dumps. Send bulk reading to subagents. Apply when outputs or files are large.
  2. Do not block on the human. On reversible work, proceed and show the result. Apply when tempted to ask "should I?".
  3. Encode repeated lessons. A correction given twice becomes a lint, test, or script. Apply when a mistake recurs.
  4. 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.
  1. 控制上下文。 保留摘要,而不是原始内容转储。将批量阅读任务交给子 Agent。当输出或文件过大时应用。
  2. 不要等待人类。 对于可逆工作,继续执行并展示结果。当你想询问“should I?”时应用。
  3. 沉淀重复经验。 同一纠正若出现两次,就将其转化为 lint、test 或 script。当同类错误反复发生时应用。
  4. 注释解释原因。 只保留代码本身无法表达的原因注释,例如外部约束或 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
    unknown
    for untrusted input. Never
    any
    . No
    as
    casts before validation.
  • Derive types from a schema, not hand-written guards.
  • Add a
    never
    check in default branches so new variants fail the build.
  • Brand primitives that must not mix, such as user IDs and order IDs.
  • 让非法状态无法表示。使用 discriminated unions,而不是 optional-field bags。
  • 在边界处一次性解析 external data,并将其转换为 named type;进入内部后信任该类型。
  • 对不可信输入使用
    unknown
    ,绝不使用
    any
    。验证之前不要使用
    as
    casts。
  • 从 schema 派生 types,而不是手写 guards。
  • 在 default branches 中加入
    never
    check,使新增 variants 在构建时失败。
  • 使用 brand 区分不可混用的 primitives,例如 user IDs 和 order IDs。