mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
docs(i18n): normalize seam consumer terminology
This commit is contained in:
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-06-19-acp-snapshot-tests.md: 43900632c4e5e3904c2d0e3b75f2a3fe3b3a50cc
|
||||
2026-06-19-acp-snapshot-tests.zh.md: 58e9c10bfe5d02179eb31e510d63691b99a0c1da
|
||||
2026-06-19-acp-snapshot-tests.zh.md: c3a926dfe6ed2c0228cc99a5258cbb35798591f8
|
||||
|
||||
@@ -61,7 +61,7 @@ Status: implemented
|
||||
|
||||
### 隔离:当前靠归一化,后续可加沙箱
|
||||
|
||||
工具确定性来自生成的 cwd、清理后的环境、全新的非登录 shell、受限命令和规范化。cwd 默认为平台临时目录;当临时目录是始终可写的策略根,而行为需要独立项目位置时,场景可以改为提供其父目录。并发重放运行各自拥有独立 cwd、持久化目录和由定长场景键区分的 spill 根目录,因此一个场景的拆除无法删除另一个场景仍在进行的完整输出恢复,同时真实路径预览预算保持稳定。该层不声称提供 OS 级隔离。如果需要更强层级,sandbox executor 可以通过现有[能力接缝](../architecture/2026-06-13-capability-seams.md)替换本地后端。
|
||||
工具确定性来自生成的 cwd、清理后的环境、全新的非登录 shell、受限命令和规范化。cwd 默认为平台临时目录;当临时目录是始终可写的策略根,而行为需要独立项目位置时,场景可以改为提供其父目录。并发重放运行各自拥有独立 cwd、持久化目录和由定长场景键区分的 spill 根目录,因此一个场景的拆除无法删除另一个场景仍在进行的完整输出恢复,同时真实路径预览预算保持稳定。该层不声称提供 OS 级隔离。如果需要更强层级,sandbox executor 可以通过现有[能力 seam](../architecture/2026-06-13-capability-seams.md)替换本地后端。
|
||||
|
||||
### 回放插件是独立的包
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-06-22-subagent-snapshot-replay.md: 4aad8b6ddd3e4f8b8ad5565e10b263953d81ea31
|
||||
2026-06-22-subagent-snapshot-replay.zh.md: 77a4302fe3aa529972195f87306b24493bbcdd06
|
||||
2026-06-22-subagent-snapshot-replay.zh.md: 2dfcee22463c8bb31e68bfb078915475e2bd7f78
|
||||
|
||||
@@ -13,7 +13,7 @@ Status: implemented
|
||||
- **`dsh-llm-replay` 没有做任何键控。** 它用一个全局游标,将第 N 次 `llm/stream` 调用对应到单一录制序列的第 N 条。当父 agent(智能体)和一个进程内 subagent 在同一个上下文上同时流式输出时,调用交错,单一游标会把子 agent 的脚本发给父 agent(反之亦然)。
|
||||
- **harness 只收集一份日志。** `findSessionLog` 遍历 sessions 根目录,返回找到的第一个 `.jsonl`。subagent 作为第二个 `Session` 运行,在同一个 cwd bucket 下有自己的日志,因此子 agent 的 transcript 被静默丢弃。
|
||||
|
||||
这就是 [subagent 接缝 Agent Note(agent 决策记录)](../feature/2026-06-21-subagent-capability-seam.md)中通过 `TODO(subagent-snapshots)` 推迟的工作:进程内后端(PR2)落地时已有单元 + e2e 覆盖,但在这套基础设施落地前,完整 transcript 快照层无法表达嵌套 agent 形状。本 Agent Note 就是该堆叠式后续工作。
|
||||
这就是 [subagent seam Agent Note(agent 决策记录)](../feature/2026-06-21-subagent-capability-seam.md)中通过 `TODO(subagent-snapshots)` 推迟的工作:进程内后端(PR2)落地时已有单元 + e2e 覆盖,但在这套基础设施落地前,完整 transcript 快照层无法表达嵌套 agent 形状。本 Agent Note 就是该堆叠式后续工作。
|
||||
|
||||
## 决策
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-07-04-hook-snapshot-matrix.md: ceb91a70e1f9582cf2a7cb4cec0ba8aaf5699b8e
|
||||
2026-07-04-hook-snapshot-matrix.zh.md: 649d2dd4b3149a9c78ff47cdaf16d7d38fc24fe3
|
||||
2026-07-04-hook-snapshot-matrix.zh.md: 61c0c06569db17e7daec8d75d4af8150a1f9dd52
|
||||
|
||||
@@ -6,7 +6,7 @@ Status: implemented
|
||||
|
||||
## 问题
|
||||
|
||||
hook bridge——[`dsh-hooks-claude`](../../../../packages/hooks/hooks-claude)(7 个 Claude Code hook 点)和 [`dsh-hooks-codex`](../../../../packages/hooks/hooks-codex)(5 个 Codex 点)——把外部 hook 命令映射到 harness 拦截接缝。它们有深入的单元与覆盖率规格覆盖(每个决策分支、每种 payload dialect,针对 mock 接缝驱动),外加一个受密钥门控的 e2e(`hooks.e2e.ts`,实时 `PreToolUse` 阻止)。但完整 transcript(文本记录)快照层——会启动真实 `acp-agent` 子进程、无需密钥重放已记录 session,并将规范化 ACP(Agent Client Protocol)stdout + 重新持久化日志与已提交预期输出进行 diff 的那张网——只覆盖了一个 hook:Claude `UserPromptSubmit` 阻止(`hook-cc-promptsubmit-block`)。
|
||||
hook bridge——[`dsh-hooks-claude`](../../../../packages/hooks/hooks-claude)(7 个 Claude Code hook 点)和 [`dsh-hooks-codex`](../../../../packages/hooks/hooks-codex)(5 个 Codex 点)——把外部 hook 命令映射到 harness 拦截 seam。它们有深入的单元与覆盖率规格覆盖(每个决策分支、每种 payload dialect,针对 mock seam 驱动),外加一个受密钥门控的 e2e(`hooks.e2e.ts`,实时 `PreToolUse` 阻止)。但完整 transcript(文本记录)快照层——会启动真实 `acp-agent` 子进程、无需密钥重放已记录 session,并将规范化 ACP(Agent Client Protocol)stdout + 重新持久化日志与已提交预期输出进行 diff 的那张网——只覆盖了一个 hook:Claude `UserPromptSubmit` 阻止(`hook-cc-promptsubmit-block`)。
|
||||
|
||||
这正是 mock 单元测试在结构上无法替代的层级:它验证的是真实 bridge 将真实 hook 进程的结果翻译到真实 seam 决策,再到真实 agent loop(智能体循环)的反应,渲染结果与编辑器看到的完全一致。一个 bridge 翻译或 loop 结构的回归,即使让所有单元测试保持绿色,也会在除那一个 hook 点之外的所有点上逃逸;而对于 Codex bridge,ACP 示例甚至没有加载它,因此没有任何 Codex hook 能端到端触发。
|
||||
|
||||
@@ -37,16 +37,16 @@ hook bridge——[`dsh-hooks-claude`](../../../../packages/hooks/hooks-claude)
|
||||
|
||||
在构建矩阵过程中发现,记录于此是因为这些遗漏是决策而非疏忽:
|
||||
|
||||
- **`SessionStart` 和 `SubagentStart`** 通过脱离且尽力而为的 `void runPoint(...).then(agent.inject())` 注入上下文,没有轮次绑定。由此产生的 `context/message` 会与它应先于的工作(首次模型请求 / 子项的第一个轮次)竞速,并落在不确定的日志位置。记录的预期输出甚至无法在自己的重放中复现——对两者执行 10 次重放稳定性检查,结果均为 10/10 次失败。它们继续留在 bridge 的单元覆盖率中,那里会直接驱动接缝而不存在时序竞速。(如果注入未来改为绑定轮次且具备确定性——`TODO(session-start-gating)` 所指方向——它们就能接受快照测试。)
|
||||
- **`SessionStart` 和 `SubagentStart`** 通过脱离且尽力而为的 `void runPoint(...).then(agent.inject())` 注入上下文,没有轮次绑定。由此产生的 `context/message` 会与它应先于的工作(首次模型请求 / 子项的第一个轮次)竞速,并落在不确定的日志位置。记录的预期输出甚至无法在自己的重放中复现——对两者执行 10 次重放稳定性检查,结果均为 10/10 次失败。它们继续留在 bridge 的单元覆盖率中,那里会直接驱动 seam 而不存在时序竞速。(如果注入未来改为绑定轮次且具备确定性——`TODO(session-start-gating)` 所指方向——它们就能接受快照测试。)
|
||||
- **`SubagentStop`** 只观察:其 `subagent/end` handler 不传递轮次(因此没有 `hook/*` 日志事件),也不执行注入。它不会向 transcript 写入任何内容,因此预期输出会与无 hook 运行逐字节相同,永远无法证明失败——一道咬不住问题的守卫。它继续由单元覆盖率负责(`bridge.spec.ts` 已断言仅观察调用)。
|
||||
|
||||
因此,该矩阵覆盖了所有具有确定性、可观测 transcript 足迹的 hook 点,涵盖两种方言。
|
||||
|
||||
## 后果
|
||||
|
||||
- 现在,两种 dialect 中每个具有可观察 transcript 的 bridge 接缝映射,都在真实应用的完整 transcript 层受到守护——包括此前完全没有端到端覆盖的 Codex bridge。记录的预期输出捕获模型对遭拒绝/遭阻止/强制继续轮次的真实反应,而手工编写的 transcript 只能猜测这种反应。
|
||||
- 现在,两种 dialect 中每个具有可观察 transcript 的 bridge seam 映射,都在真实应用的完整 transcript 层受到守护——包括此前完全没有端到端覆盖的 Codex bridge。记录的预期输出捕获模型对遭拒绝/遭阻止/强制继续轮次的真实反应,而手工编写的 transcript 只能猜测这种反应。
|
||||
- `UserPromptSubmit` 阻止场景无需密钥即可编写(没有模型轮次);其余场景从已记录 fixture(测试前置数据)无需密钥重放。`pnpm run test:snapshot:record` 从实时 API 重新生成记录式 fixture,并像所有记录场景一样在缺少密钥时自行跳过。
|
||||
- 证明会变红的准则仍成立:篡改 hook 配置输出(例如改变拒绝理由)会让相应场景在重放时变红——hook 进程在重放期间真实运行(只有模型被重放),因此预期输出守护的是实际 hook→接缝→循环路径,而非其 mock。
|
||||
- 证明会变红的准则仍成立:篡改 hook 配置输出(例如改变拒绝理由)会让相应场景在重放时变红——hook 进程在重放期间真实运行(只有模型被重放),因此预期输出守护的是实际 hook→seam→循环路径,而非其 mock。
|
||||
- `acp-agent` 演示现在加载了一个通常会无操作的 Codex bridge(典型项目中没有 `codex-hooks.json`),这正是预期的柔性失败行为,而非代价。
|
||||
|
||||
<!-- agent-note-format: alternatives-not-recorded (pre-format Agent Note) -->
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-07-08-shared-acp-snapshot-package.md: 3e5a2b12114d535490a17361128862f6d1c09a73
|
||||
2026-07-08-shared-acp-snapshot-package.zh.md: 86b3e65c76a1bde593c30d0d1c20010ec7e4d6d5
|
||||
2026-07-08-shared-acp-snapshot-package.zh.md: c6b943d93e58c714b52d05d1c9b352e7fb8e2205
|
||||
|
||||
@@ -8,7 +8,7 @@ Status: implemented
|
||||
|
||||
ACP(Agent Client Protocol)快照层([快照 Agent Note(agent 决策记录)](2026-06-19-acp-snapshot-tests.md))由位于一个示例测试目录内的三个模块构建:`snapshot-harness.ts`(启动真实 bin 子进程,通过 ACP JSON-RPC 驱动它,采集持久化日志)、`snapshot-normalize.ts`(纯预期输出规范化器),以及 `acp.snapshot.ts` 中约 150 行的场景主体与 fixture(测试前置数据)守卫(记录/重放模式、stdout 预期输出与日志比较、固定请求头一致性守卫、孤立项/必需文件/单一固定项元测试)。
|
||||
|
||||
第二个希望获得快照覆盖的 ACP 示例——直接消费者是 sandbox/approval 组合——只能复制这些模块,恰好分叉了绝不能漂移的逻辑:记录写回、请求头清理、子 session 采集顺序。spawn/client 胶水也在 `acp.e2e.ts`、`hooks.e2e.ts` 和 harness 中重复三份。文件位置决定了测试严格度:逐文件 100% 覆盖率门禁只测量 `packages/*/*/src`,因此这些机制完全未被测量——正是同一种缺口,曾推动 `dsh-llm-replay` 从 `examples/` 移入 [packages/support](../../../../packages/support/README.md)。此外,harness 的 ACP client 硬编码 `requestPermission → cancelled`,因此 approval 往返——sandbox 组合的主打行为——完全无法在快照层表达。
|
||||
第二个希望获得快照覆盖的 ACP 示例——直接消费方是 sandbox/approval 组合——只能复制这些模块,恰好分叉了绝不能漂移的逻辑:记录写回、请求头清理、子 session 采集顺序。spawn/client 胶水也在 `acp.e2e.ts`、`hooks.e2e.ts` 和 harness 中重复三份。文件位置决定了测试严格度:逐文件 100% 覆盖率门禁只测量 `packages/*/*/src`,因此这些机制完全未被测量——正是同一种缺口,曾推动 `dsh-llm-replay` 从 `examples/` 移入 [packages/support](../../../../packages/support/README.md)。此外,harness 的 ACP client 硬编码 `requestPermission → cancelled`,因此 approval 往返——sandbox 组合的主打行为——完全无法在快照层表达。
|
||||
|
||||
## 决策
|
||||
|
||||
@@ -28,7 +28,7 @@ ACP(Agent Client Protocol)快照层([快照 Agent Note(agent 决策记
|
||||
- **在 `examples/` 下建共享模块目录**:代码仍在覆盖率门禁之外,且需要跨示例边界的相对导入,违反包名导入约定;`examples/` 的叶子节点按设计应保持轻薄。
|
||||
- **`dsh-acp-demo` 的 `/testing` 子路径导出**:将测试基础设施耦合到产品包的对外服务接口与依赖集中;`packages/support/` 的存在正是为了真实但兼容性承诺较低的开发/测试包,`dsh-llm-replay` 是先例,本包与之配套。
|
||||
- **导出原始测试体函数而非套件工厂**:每个示例将重新拥有 `describe`/`it` 骨架(每套件约 80 行注册样板),却无灵活性收益;工厂使消费方只需一张场景表加一次调用,而导出的纯辅助函数在工厂设计内保留了可单元测试性。
|
||||
- **使用可注入 ACP `Client` factory 代替声明式 `permissionAnswers`**——灵活性最大,但会把 SDK client 构造泄漏给每个消费者,并恰好在正在统一的层重新引入逐示例漂移;声明式队列让 `input.json` 保持为唯一脚本表面,并与预期输出规范化兼容。
|
||||
- **使用可注入 ACP `Client` factory 代替声明式 `permissionAnswers`**——灵活性最大,但会把 SDK client 构造泄漏给每个消费方,并恰好在正在统一的层重新引入逐示例漂移;声明式队列让 `input.json` 保持为唯一脚本表面,并与预期输出规范化兼容。
|
||||
- **泛化到 ACP 之外(传输无关的快照 harness)**:不存在第二种传输方式;harness 端到端都是 ACP 形态(SDK 客户端、JSON-RPC 帧、`session/update` 等待器),推测性的抽象将是一个超前于任何消费方的 seam 拆分。
|
||||
|
||||
## 测试
|
||||
|
||||
Reference in New Issue
Block a user