Files
deepseek-harness/docs/defensive-patterns.zh.md
Ziya ec47f2e40f docs(i18n): core-docs batch — five bilingual pairs via the committed pipeline
architecture / cordis-primer / defensive-patterns / glossary / testing
五篇核心文档配对,译文由进仓流水线产出(committed renderer + 金标
few-shot + 严格 XML 协议),并经二遍校验(逐句对照原文复述核查 +
注入 architecture/glossary 仓库上下文的一致性修复)。五篇生成文档
(agent-lifecycle、capability-seams、event-producer-consumer、
graph-atlas、tool-execution-pipeline 均为 gen-doc-graphs 产物)列入
排除清单——手写译文会在再生成时失效,与既有生成目录排除策略一致。
2026-07-15 23:03:13 -07:00

30 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 防御性模式
[English](defensive-patterns.md) | 中文
来之不易的缺陷类别规则以下每条模式都是本项目中实际发布或险些发布的一类缺陷以防止其复发的规则形式陈述。在编写生命周期、并发、子进程或清理代码之前请先阅读本文。测试层面的对应规则真实入口路径、world 验证、资源归属)见 [testing.md](testing.md)。
## 正交结果独立上报
一个结果可以同时具有多重性质:进程可能既超时又以 exit 0 退出,因为它捕获了信号。每个独立事实(`timedOut``signal``exitCode`)都应独立暴露;永远不要把一个 flag 的上报嵌套在另一个 flag 的分支内,否则调用方会把一次被截断的运行误读为正常成功。
## 在接口两侧都遵守跨 seam 契约
当接口文档记录了两种有效的信号方式时——例如适配器可以通过从 `stream()` 抛出异常来报告失败,也可以通过以 `finish {kind:'error'|'aborted'}` 分片结束流来报告——消费方必须两种都处理,而不只是第一个实现碰巧使用的那种。基于库的适配器在流中途无法抛出异常,只能依赖带内路径;如果 agent loop 只捕获 throw就会把提供方的 401 变成一个正常完成的轮次。请在类型定义处记录契约;通过真实消费方测试每个分支。
## 异步状态不是同步状态
`agent.send()` 不会在返回前翻转状态;后台任务的完成与轮次边界存在竞态;`reader.close()` 在 EOF 和 dispose资源释放两种情况下都会触发。永远不要基于一个你刚刚请求的状态来控制流程——应当基于实际触发的事件/promise 来驱动生命周期(`agent/status``task.done`),并观察状态转换(先看到 `running` 再看到 `idle`),而不是假设你发出的动作与轮次 1:1 对应循环会批量处理排队的消息。这条守则是双向的如果等待的转换永远不会发生EOF 且没有提交过工作 → 永远不会进入 `running`),等待就会挂起——请显式处理「无需等待」的分支。
## dispose 必须达到静止,而非仅仅请求停止
一个只发出 kill/abort 就返回的清理逻辑会留下孤儿进程。请让清理逻辑异步化并 await 子进程退出kill → await `done`),并在 kill 之前关闭监听器/通知注册表,使迟到的完成事件保持静默。测试应证明 dispose 确实等到了进程退出(`await fiber.dispose()` 之后 pid 已不存在),而非仅仅证明进程最终会死。
## 在边界处包容回调异常
用户提供的监听器抛出异常时,不得导致它所在的 promise 被 reject也不得饿死排在它之后的监听器。请在分发循环中用 try/catch 包裹并记录日志;一个有问题的订阅者永远不能破坏核心生命周期。
## 永远不要把环境变量或可预测路径暴露给不可信输出
spawn 的命令应获得一个经过清洗的 env移除 `*KEY*`/`*SECRET*`/`*TOKEN*`),确保 harness 凭证不会泄漏到输出、`env` 或溢出文件中。临时/溢出文件应使用私有0700目录、随机文件名和排他的仅所有者可打开模式`'wx'``0o600`)——可预测的全局可读路径会招致符号链接竞态和信息泄露。