Explorar o código

Merge origin/master into codex/remove-knip

Turtle hai 2 semanas
pai
achega
7e92ed8213
Modificáronse 100 ficheiros con 977 adicións e 56 borrados
  1. 1 1
      .agents/notes/README.i18n.yaml
  2. 7 5
      .agents/notes/README.zh.md
  3. 6 0
      .agents/notes/archived/architecture/2026-07-19-gui-layering-and-rpc-protocol.i18n.yaml
  4. 2 1
      .agents/notes/archived/architecture/2026-07-19-gui-layering-and-rpc-protocol.md
  5. 9 8
      .agents/notes/archived/architecture/2026-07-19-gui-layering-and-rpc-protocol.zh.md
  6. 6 0
      .agents/notes/archived/architecture/2026-08-04-websocket-downlink-carrier.i18n.yaml
  7. 2 1
      .agents/notes/archived/architecture/2026-08-04-websocket-downlink-carrier.md
  8. 2 1
      .agents/notes/archived/architecture/2026-08-04-websocket-downlink-carrier.zh.md
  9. 6 0
      .agents/notes/archived/architecture/2026-08-11-plugin-settings-tabs.i18n.yaml
  10. 1 0
      .agents/notes/archived/architecture/2026-08-11-plugin-settings-tabs.md
  11. 1 0
      .agents/notes/archived/architecture/2026-08-11-plugin-settings-tabs.zh.md
  12. 6 0
      .agents/notes/archived/bug-fix/2026-07-31-composer-text-layers-share-one-scrollport.i18n.yaml
  13. 1 0
      .agents/notes/archived/bug-fix/2026-07-31-composer-text-layers-share-one-scrollport.md
  14. 2 1
      .agents/notes/archived/bug-fix/2026-07-31-composer-text-layers-share-one-scrollport.zh.md
  15. 6 0
      .agents/notes/archived/bug-fix/2026-08-04-large-history-pagination-call-stack.i18n.yaml
  16. 1 0
      .agents/notes/archived/bug-fix/2026-08-04-large-history-pagination-call-stack.md
  17. 1 0
      .agents/notes/archived/bug-fix/2026-08-04-large-history-pagination-call-stack.zh.md
  18. 6 0
      .agents/notes/archived/bug-fix/2026-08-06-plan-narrow-viewport-regression.i18n.yaml
  19. 1 0
      .agents/notes/archived/bug-fix/2026-08-06-plan-narrow-viewport-regression.md
  20. 2 1
      .agents/notes/archived/bug-fix/2026-08-06-plan-narrow-viewport-regression.zh.md
  21. 6 0
      .agents/notes/archived/bug-fix/2026-08-11-preset-card-description-clamp.i18n.yaml
  22. 1 0
      .agents/notes/archived/bug-fix/2026-08-11-preset-card-description-clamp.md
  23. 1 0
      .agents/notes/archived/bug-fix/2026-08-11-preset-card-description-clamp.zh.md
  24. 6 0
      .agents/notes/archived/bug-fix/2026-08-13-safari-textarea-soft-wrap-reflow.i18n.yaml
  25. 1 0
      .agents/notes/archived/bug-fix/2026-08-13-safari-textarea-soft-wrap-reflow.md
  26. 2 1
      .agents/notes/archived/bug-fix/2026-08-13-safari-textarea-soft-wrap-reflow.zh.md
  27. 6 0
      .agents/notes/archived/bug-fix/2026-08-20-composer-edit-range-from-selection.i18n.yaml
  28. 48 0
      .agents/notes/archived/bug-fix/2026-08-20-composer-edit-range-from-selection.md
  29. 48 0
      .agents/notes/archived/bug-fix/2026-08-20-composer-edit-range-from-selection.zh.md
  30. 6 0
      .agents/notes/archived/bug-fix/2026-08-20-composer-reference-decoration-keys.i18n.yaml
  31. 40 0
      .agents/notes/archived/bug-fix/2026-08-20-composer-reference-decoration-keys.md
  32. 40 0
      .agents/notes/archived/bug-fix/2026-08-20-composer-reference-decoration-keys.zh.md
  33. 6 0
      .agents/notes/archived/bug-fix/2026-08-24-system-prompt-section-order-ties.i18n.yaml
  34. 28 0
      .agents/notes/archived/bug-fix/2026-08-24-system-prompt-section-order-ties.md
  35. 28 0
      .agents/notes/archived/bug-fix/2026-08-24-system-prompt-section-order-ties.zh.md
  36. 6 0
      .agents/notes/archived/feature/2026-07-30-versioned-gui-welcome-onboarding.i18n.yaml
  37. 1 0
      .agents/notes/archived/feature/2026-07-30-versioned-gui-welcome-onboarding.md
  38. 3 2
      .agents/notes/archived/feature/2026-07-30-versioned-gui-welcome-onboarding.zh.md
  39. 6 0
      .agents/notes/archived/feature/2026-08-06-bundled-dsh-badge-skill.i18n.yaml
  40. 1 0
      .agents/notes/archived/feature/2026-08-06-bundled-dsh-badge-skill.md
  41. 2 1
      .agents/notes/archived/feature/2026-08-06-bundled-dsh-badge-skill.zh.md
  42. 6 0
      .agents/notes/archived/feature/2026-08-07-workspace-picker-composer-entry.i18n.yaml
  43. 1 0
      .agents/notes/archived/feature/2026-08-07-workspace-picker-composer-entry.md
  44. 2 1
      .agents/notes/archived/feature/2026-08-07-workspace-picker-composer-entry.zh.md
  45. 6 0
      .agents/notes/archived/feature/2026-08-10-creator-guidance-introduce-cue.i18n.yaml
  46. 1 0
      .agents/notes/archived/feature/2026-08-10-creator-guidance-introduce-cue.md
  47. 1 0
      .agents/notes/archived/feature/2026-08-10-creator-guidance-introduce-cue.zh.md
  48. 6 0
      .agents/notes/archived/feature/2026-08-11-collapsible-ask-user-question-card.i18n.yaml
  49. 1 0
      .agents/notes/archived/feature/2026-08-11-collapsible-ask-user-question-card.md
  50. 1 0
      .agents/notes/archived/feature/2026-08-11-collapsible-ask-user-question-card.zh.md
  51. 6 0
      .agents/notes/archived/feature/2026-08-11-web-export-command-and-dialog.i18n.yaml
  52. 1 0
      .agents/notes/archived/feature/2026-08-11-web-export-command-and-dialog.md
  53. 1 0
      .agents/notes/archived/feature/2026-08-11-web-export-command-and-dialog.zh.md
  54. 6 0
      .agents/notes/archived/feature/2026-08-18-product-subagent-failure-facts.i18n.yaml
  55. 81 0
      .agents/notes/archived/feature/2026-08-18-product-subagent-failure-facts.md
  56. 81 0
      .agents/notes/archived/feature/2026-08-18-product-subagent-failure-facts.zh.md
  57. 6 0
      .agents/notes/archived/feature/2026-08-18-web-home-path-tilde.i18n.yaml
  58. 38 0
      .agents/notes/archived/feature/2026-08-18-web-home-path-tilde.md
  59. 38 0
      .agents/notes/archived/feature/2026-08-18-web-home-path-tilde.zh.md
  60. 6 0
      .agents/notes/archived/feature/2026-08-19-high-cache-hit-decimal-display.i18n.yaml
  61. 51 0
      .agents/notes/archived/feature/2026-08-19-high-cache-hit-decimal-display.md
  62. 51 0
      .agents/notes/archived/feature/2026-08-19-high-cache-hit-decimal-display.zh.md
  63. 82 1
      .agents/notes/archived/manifest.json
  64. 6 0
      .agents/notes/archived/process/2026-08-12-documentation-site-navigation-and-chrome.i18n.yaml
  65. 1 0
      .agents/notes/archived/process/2026-08-12-documentation-site-navigation-and-chrome.md
  66. 1 0
      .agents/notes/archived/process/2026-08-12-documentation-site-navigation-and-chrome.zh.md
  67. 6 0
      .agents/notes/archived/simplification/2026-07-04-drop-image-content-block.i18n.yaml
  68. 1 0
      .agents/notes/archived/simplification/2026-07-04-drop-image-content-block.md
  69. 1 0
      .agents/notes/archived/simplification/2026-07-04-drop-image-content-block.zh.md
  70. 6 0
      .agents/notes/archived/simplification/2026-08-11-cmdline-program-action.i18n.yaml
  71. 1 0
      .agents/notes/archived/simplification/2026-08-11-cmdline-program-action.md
  72. 2 1
      .agents/notes/archived/simplification/2026-08-11-cmdline-program-action.zh.md
  73. 6 0
      .agents/notes/archived/simplification/2026-08-11-quickstart-documentation-home.i18n.yaml
  74. 1 0
      .agents/notes/archived/simplification/2026-08-11-quickstart-documentation-home.md
  75. 2 1
      .agents/notes/archived/simplification/2026-08-11-quickstart-documentation-home.zh.md
  76. 6 0
      .agents/notes/archived/simplification/2026-08-13-remove-first-run-beta-notice.i18n.yaml
  77. 1 0
      .agents/notes/archived/simplification/2026-08-13-remove-first-run-beta-notice.md
  78. 3 2
      .agents/notes/archived/simplification/2026-08-13-remove-first-run-beta-notice.zh.md
  79. 6 0
      .agents/notes/archived/simplification/2026-08-19-knip-config-cleanup.i18n.yaml
  80. 32 0
      .agents/notes/archived/simplification/2026-08-19-knip-config-cleanup.md
  81. 32 0
      .agents/notes/archived/simplification/2026-08-19-knip-config-cleanup.zh.md
  82. 6 0
      .agents/notes/archived/testing/2026-08-12-required-python-runtime-pull-request-ci.i18n.yaml
  83. 1 0
      .agents/notes/archived/testing/2026-08-12-required-python-runtime-pull-request-ci.md
  84. 3 2
      .agents/notes/archived/testing/2026-08-12-required-python-runtime-pull-request-ci.zh.md
  85. 2 2
      .agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.i18n.yaml
  86. 2 2
      .agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.md
  87. 3 3
      .agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.zh.md
  88. 1 1
      .agents/notes/implemented/architecture/2026-06-11-dev-invariants-over-deep-readonly.i18n.yaml
  89. 1 1
      .agents/notes/implemented/architecture/2026-06-11-dev-invariants-over-deep-readonly.zh.md
  90. 1 1
      .agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.i18n.yaml
  91. 1 1
      .agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.zh.md
  92. 1 1
      .agents/notes/implemented/architecture/2026-06-11-microkernel-event-taxonomy.i18n.yaml
  93. 1 1
      .agents/notes/implemented/architecture/2026-06-11-microkernel-event-taxonomy.zh.md
  94. 1 1
      .agents/notes/implemented/architecture/2026-06-11-runtime-arg-validation.i18n.yaml
  95. 3 3
      .agents/notes/implemented/architecture/2026-06-11-runtime-arg-validation.zh.md
  96. 2 2
      .agents/notes/implemented/architecture/2026-06-13-capability-seams.i18n.yaml
  97. 1 1
      .agents/notes/implemented/architecture/2026-06-13-capability-seams.md
  98. 3 3
      .agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md
  99. 1 1
      .agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.i18n.yaml
  100. 1 1
      .agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.zh.md

+ 1 - 1
.agents/notes/README.i18n.yaml

@@ -3,4 +3,4 @@
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/README.md
 README.md: ae8e4724d610c97d74910d7dec5c95af69e93281
-README.zh.md: a16403ae87cd16d758b8303f42f60ad34b9c1eb3
+README.zh.md: 8cecc7068d9efc5e2ebb78d2301d03633f70f137

+ 7 - 5
.agents/notes/README.zh.md

@@ -16,13 +16,13 @@
 
 文件名中的日期是该主题**首次提出**的时间(以 git 历史为准)。Agent Note 之间的交叉引用使用相对 Markdown 链接(`[topic](../../implemented/architecture/2026-…-….md)`),从不使用纯文字或编号,这样既可机械检查,也能在文件夹间移动时保持有效。
 
-活跃生命周期目录树就是工作清单:浏览其生命周期/类别文件夹,或搜索仓库即可。请勿添加集中式 `INDEX.md`;设计理由见[不设索引的 Agent Note](implemented/process/2026-07-19-remove-generated-agent-note-index.md)。未来指导价值较低的已实施记录会移至下文所述、单独冻结的 [`archived/`](archived/AGENTS.md) 目录树。
+活跃生命周期目录树就是工作清单:浏览其生命周期/类别文件夹,或搜索仓库即可。请勿添加集中式 `INDEX.md`;设计理由见[不设索引的 Agent Note](implemented/process/2026-07-19-remove-generated-agent-note-index.zh.md)。未来指导价值较低的已实施记录会移至下文所述、单独冻结的 [`archived/`](archived/AGENTS.md) 目录树。
 
 <a id="classification"></a>
 
 ## 分类
 
-每份 Agent Note 属于 `scripts/agent-note-tree.ts` 中封闭集合里的一个路径编码类别;分类门禁拒绝其他文件夹。新增类别需要同时更新规范集合与本节。见[分类 Agent Note](implemented/process/2026-06-20-agent-note-classification.md)。
+每份 Agent Note 属于 `scripts/agent-note-tree.ts` 中封闭集合里的一个路径编码类别;分类门禁拒绝其他文件夹。新增类别需要同时更新规范集合与本节。见[分类 Agent Note](implemented/process/2026-06-20-agent-note-classification.zh.md)。
 
 | 类别 | 覆盖范围 |
 |---|---|
@@ -41,7 +41,9 @@
 
 归档路径编码为 `archived/{class}/yyyy-mm-dd-topic-title.md`;其中有意省略 `implemented`,因为只有 implemented Agent Note 可以进入归档。归档变更会移动完整的英文、中文和伴随记录三个文件,保留 `Status: implemented`,在两种语言的文件中紧接该状态行插入相同的 `Archived: YYYY-MM-DD` 行,重新记录伴随记录,并修复或删除入站链接。归档时只允许对内容做这些更改。
 
-封存后,每组归档文件都永久冻结。禁止编辑、翻译、重新格式化、更新、移动或删除,也不得将其视为当前行为的权威依据。文档门禁会跳过归档源文件,包括其中的出站链接;当活跃文档有意引用历史时,仍可链接到归档 Agent Note。[`verify-archived-agent-notes`](../../scripts/verify-archived-agent-notes.ts) 强制执行封闭的类别目录树、完整的三文件配对、归档元数据、伴随记录 hash,以及仅追加的冻结内容 manifest(元数据清单)。[归档政策 Agent Note](implemented/process/2026-07-26-frozen-agent-note-archive.md) 记录了设计依据。
+封存后,每组归档文件都永久冻结。禁止编辑、翻译、重新格式化、更新、移动或删除,也不得将其视为当前行为的权威依据。文档门禁会跳过归档源文件,包括其中的出站链接;当活跃文档有意引用历史时,仍可链接到归档 Agent Note。[`verify-archived-agent-notes`](../../scripts/verify-archived-agent-notes.ts) 强制执行封闭的类别目录树、完整的三文件配对、归档元数据、伴随记录 hash,以及仅追加的冻结内容 manifest(元数据清单)。[归档政策 Agent Note](implemented/process/2026-07-26-frozen-agent-note-archive.zh.md) 记录了设计依据。
+
+<a id="when-to-write-one"></a>
 
 ## 何时需要写一份
 
@@ -57,7 +59,7 @@
 
 ## 文件格式
 
-每份活跃 Agent Note 遵循统一的文件内格式,由 `pnpm run verify-agent-note-format`([scripts/verify-agent-note-format.ts](../../scripts/verify-agent-note-format.ts),`doc-sync`(文档同步门禁)的一环)强制执行;该格式的设计动机及其否决的替代方案见[统一格式 Agent Note](implemented/process/2026-07-05-uniform-agent-note-format.md)。归档记录保留封存时的格式,并增加上述归档日期行。
+每份活跃 Agent Note 遵循统一的文件内格式,由 `pnpm run verify-agent-note-format`([scripts/verify-agent-note-format.ts](../../scripts/verify-agent-note-format.ts),`doc-sync`(文档同步门禁)的一环)强制执行;该格式的设计动机及其否决的替代方案见[统一格式 Agent Note](implemented/process/2026-07-05-uniform-agent-note-format.zh.md)。归档记录保留封存时的格式,并增加上述归档日期行。
 
 ### 头部块
 
@@ -126,4 +128,4 @@ Status: <status>
 
 ### 中文对侧文件
 
-`.zh.md` 对侧文件按 [i18n 约定](../../docs/i18n/README.md)逐章节与其英文对侧文件保持相同结构;机器检查的头部标记(`# Agent Note: ` 和 `Status:` 行)保持英文原样不翻译。格式门禁跳过 `.zh.md` 文件;配对门禁检查它们的一致性。
+`.zh.md` 对侧文件按 [i18n 约定](../../docs/i18n/README.zh.md)逐章节与其英文对侧文件保持相同结构;机器检查的头部标记(`# Agent Note: ` 和 `Status:` 行)保持英文原样不翻译。格式门禁跳过 `.zh.md` 文件;配对门禁检查它们的一致性。

+ 6 - 0
.agents/notes/archived/architecture/2026-07-19-gui-layering-and-rpc-protocol.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write .agents/notes/archived/architecture/2026-07-19-gui-layering-and-rpc-protocol.md
+2026-07-19-gui-layering-and-rpc-protocol.md: b27d8d024612d890819bfca9b43c0c81464dfdd3
+2026-07-19-gui-layering-and-rpc-protocol.zh.md: 3cf4ba6421c7332c1f8cebb61656a1546f3ad45f

+ 2 - 1
.agents/notes/implemented/architecture/2026-07-19-gui-layering-and-rpc-protocol.md → .agents/notes/archived/architecture/2026-07-19-gui-layering-and-rpc-protocol.md

@@ -1,6 +1,7 @@
 # Agent Note: GUI layering and the RPC protocol — host/client layering by capability provider, the four-quadrant message model, and the fetch carrier
 
 Status: implemented
+Archived: 2026-08-27
 
 English | [中文](2026-07-19-gui-layering-and-rpc-protocol.zh.md)
 
@@ -209,7 +210,7 @@ The same domain tree as `ApiProxy`, but unary methods **take the business payloa
 
 ### The instance-level envelope observation aspect
 
-All four quadrant full forms pass through `onEnvelope`; the base implementation is an **instance-owned microtask-batched buffer** (frame storms must not disturb consumers per frame; module-level state would leak across instances/tests, hence instance-owned). Observers subscribe via `subscribeEnvelopes(listener)` (receiving whole batches as `readonly RpcMessage[]`, returning an unsubscribe function); a listener throw is isolated (observation must never bite the carrier). With no subscribers the buffering costs nothing. No shipped consumer subscribes today — the aspect is the designated seat for wire diagnostics (the retired RPC debug panel was its first consumer, and a future one plugs in without touching the carrier).
+All four quadrant full forms pass through `onEnvelope`; the base implementation is an **instance-owned microtask-batched buffer** (frame storms must not disturb consumers per frame; module-level state would leak across instances/tests, hence instance-owned). Observers subscribe via `subscribeEnvelopes(listener)` (receiving whole batches as `readonly RpcMessage[]`, returning an unsubscribe function); a listener throw is isolated (observation must never bite the carrier). With no subscribers the buffering costs nothing. No shipped consumer subscribes — the aspect is the designated seat for wire diagnostics (the retired RPC debug panel was its first consumer, and a future one plugs in without touching the carrier).
 
 ### The subclass table (transport carriage)
 

+ 9 - 8
.agents/notes/implemented/architecture/2026-07-19-gui-layering-and-rpc-protocol.zh.md → .agents/notes/archived/architecture/2026-07-19-gui-layering-and-rpc-protocol.zh.md

@@ -1,10 +1,11 @@
 # Agent Note: GUI 分层与 RPC 协议——host/client 按能力提供方分层、四象限消息模型与 fetch 载体
 
 Status: implemented
+Archived: 2026-08-27
 
 [English](2026-07-19-gui-layering-and-rpc-protocol.md) | 中文
 
-> 分工线:本篇 = 分层模型 + 通道无关的 RPC 协议;协议的 Web 实现由 HTTP 上行加 [WebSocket 下行载体](2026-08-04-websocket-downlink-carrier.md)组成,浏览器对象层见 [Web 客户端架构笔记](2026-07-19-gui-web-client-architecture.md)。
+> 分工线:本篇 = 分层模型 + 通道无关的 RPC 协议;协议的 Web 实现由 HTTP 上行加 [WebSocket 下行载体](2026-08-04-websocket-downlink-carrier.zh.md)组成,浏览器对象层见 [Web 客户端架构笔记](2026-07-19-gui-web-client-architecture.zh.md)。
 
 ## Problem
 
@@ -23,13 +24,13 @@ Status: implemented
 目录按照如下分层:
 - `packages/host/*`:包只提供 Host 侧能力(代表了以现在 Harness 实体插件系统为主体的 Node.js 代码核心工程),除此之外,还包含
     - 统一后端协议(fetch、HTTP、流式接口等)定义和支持,见本篇「消息协议」起各节
-- `packages/client/*`:包只提供 Client 侧能力,每包单边不混。这里住三类包(两条轴归 [client 插件装载笔记](2026-07-23-client-plugin-loading-model.md) 所有):
+- `packages/client/*`:包只提供 Client 侧能力,每包单边不混。这里住三类包(两条轴归 [client 插件装载笔记](2026-07-23-client-plugin-loading-model.zh.md) 所有):
     - **纯库**(`ui-slots`、`ui-primitives`,外加内核包 `loader`):普通根入口包,静态打包进壳;两个客户端库播种进模块表。
     - **静态到达 entry 包**(`connection`、`runtime`、`ui-theme`、`i18n`、`hmr`):无 `dsh.client` 键、无浏览器 bundle——壳把它们的 `src/client/` 半边打进自己的 bundle 并向 `ctx.modules` 登记;它们与其余单元一样,作为 host 独家撰写的图里的 entry 受治理。
     - **fetch 到达插件包**(`ui-layout`、`ui-sidebar`、`ui-conversation`、`ui-trajectory`):双入口——根入口是 node 半边(空 `apply`,其存在是为了让 host Loader 管辖生命周期、让 web 插件注册表发现 package.json 的 `dsh.client` 声明);实现住在 `src/client/` 下,经 `./client` 子路径发布(tsdown 闭包工厂 bundle)。跨插件消费 `/client` 只限类型;值层面的协作走 cordis 服务。
 - `apps/` 作为对外导出的应用入口,可以由 Client / Host 混合组装。
     - `apps/web`(`dsh-web-frontend`)是 vite 应用:`dsh-client-web` 导出的壳 API 之上的一层薄 `main.ts`。
-    - `apps/cli`(`@deepseek-ai/dsh`)分发命令:`dsh web` = Host + webserver + 构建出的 `dsh-web-frontend` dist;`dsh --profile headless` = [直接使用核心 Agent/Session 的入口](2026-08-09-headless-direct-core-entry-point.md),不含 Host、HTTP 或浏览器层。
+    - `apps/cli`(`@deepseek-ai/dsh`)分发命令:`dsh web` = Host + webserver + 构建出的 `dsh-web-frontend` dist;`dsh --profile headless` = [直接使用核心 Agent/Session 的入口](2026-08-09-headless-direct-core-entry-point.zh.md),不含 Host、HTTP 或浏览器层。
     - 将来的 Electron 应用经由 IPC fetch 载体复用同一套 web client 包。
 
 ```
@@ -50,9 +51,9 @@ harness core packages ──────────────────┘
 - `runtime → apiproxy` 单向;apiproxy 仅依赖类型定义。
 - client 侧包**永不 import** host 侧包的运行时(只吃 `/api`、`/client` 两个浏览器安全子路径)。
 - `webserver` 不依赖 `runtime`:它提供 `{ fetch }` 特定实现 ——「webserver ← runtime」只是运行时注入关系,不是包依赖。
-- client 侧跨包 import 插件包一律走 `/client` 子路径,且插件包之间只限类型 import——跨插件值 import 在 tsdown 纯度门禁处即构建错误(值层面的协作走 cordis 服务;边规则归 [client 插件装载笔记](2026-07-23-client-plugin-loading-model.md) 所有)。
+- client 侧跨包 import 插件包一律走 `/client` 子路径,且插件包之间只限类型 import——跨插件值 import 在 tsdown 纯度门禁处即构建错误(值层面的协作走 cordis 服务;边规则归 [client 插件装载笔记](2026-07-23-client-plugin-loading-model.zh.md) 所有)。
 
-TypeScript 以 solution 根引用的**两个聚合 program** 检查(`tsconfig.json` = solution;`tsconfig.host.json` = host 侧 + 测试,排除 `packages/client`;`tsconfig.client.json` = client 各包及其测试):两侧在相同键(`sessions`、`loader`)下以不同服务合并 cordis `Context` 接口,单一 program 会同时看到两份声明合并而报冲突。共享叶子包(session/llm/tools/apiproxy 等)只构建一次,由两个 program 共同引用([拓扑](../process/2026-07-22-tsconfig-solution-root-two-aggregates.md))。
+TypeScript 以 solution 根引用的**两个聚合 program** 检查(`tsconfig.json` = solution;`tsconfig.host.json` = host 侧 + 测试,排除 `packages/client`;`tsconfig.client.json` = client 各包及其测试):两侧在相同键(`sessions`、`loader`)下以不同服务合并 cordis `Context` 接口,单一 program 会同时看到两份声明合并而报冲突。共享叶子包(session/llm/tools/apiproxy 等)只构建一次,由两个 program 共同引用([拓扑](../process/2026-07-22-tsconfig-solution-root-two-aggregates.zh.md))。
 
 协议侧:TS interface(`packages/host/apiproxy/src/api/`,零 Node 依赖,浏览器可 import);wire 消息统一为**双向模型**——每条逻辑消息按「谁发起 × request/response」分类(两轴四格,后文称四象限),与物理通道解耦;客户端统一继承 `AbstractApiClient`(协议不变量全在基类,平台差异只是 `doFetch` 传输切面)。
 
@@ -167,7 +168,7 @@ export type ResponseValue<K> =
 
 ### 帧(server→client,具名 union)
 
-两条逻辑流:mux 流(`/api/events.mux`,全 session 聚合)与 host 流(`/api/events.host`,host 级事件)。浏览器通过每流一条下行 WebSocket 消费,进程内 fetch 载体以 SSE 保持同构;物理边界见 [WebSocket 下行载体](2026-08-04-websocket-downlink-carrier.md)。帧示例一行:
+两条逻辑流:mux 流(`/api/events.mux`,全 session 聚合)与 host 流(`/api/events.host`,host 级事件)。浏览器通过每流一条下行 WebSocket 消费,进程内 fetch 载体以 SSE 保持同构;物理边界见 [WebSocket 下行载体](2026-08-04-websocket-downlink-carrier.zh.md)。帧示例一行:
 
 | 帧 type | 载荷 | 何时发 |
 |---|---|---|
@@ -207,14 +208,14 @@ export type ResponseValue<K> =
 
 ### 实例级 envelope 观测切面
 
-四象限全形均过 `onEnvelope`;基类实现是**实例持有的微任务合批缓冲**(帧风暴不逐帧惊扰消费方;模块级状态会跨实例/测试泄漏,故实例持有)。观测者经 `subscribeEnvelopes(listener)` 订阅(收整批 `readonly RpcMessage[]`,返回退订函数);listener 抛异常被隔离(观测不得反噬载体)。无订阅者时零缓冲成本。当前没有任何现役消费方订阅——该切面是 wire 诊断的预留位(已退役的 RPC 调试面板是它的首个消费方,将来的诊断消费方接入时不动载体)。
+四象限全形均过 `onEnvelope`;基类实现是**实例持有的微任务合批缓冲**(帧风暴不逐帧惊扰消费方;模块级状态会跨实例/测试泄漏,故实例持有)。观测者经 `subscribeEnvelopes(listener)` 订阅(收整批 `readonly RpcMessage[]`,返回退订函数);listener 抛异常被隔离(观测不得反噬载体)。无订阅者时零缓冲成本。没有任何已交付消费方订阅——该切面是 wire 诊断的预留位(已退役的 RPC 调试面板是它的首个消费方,将来的诊断消费方接入时不动载体)。
 
 ### 子类表(传输承载)
 
 | 子类 | 所在包 | doFetch | 用途 |
 |---|---|---|---|
 | `InProcessApiClient` | apiproxy 本包 | 注入的 `{ fetch }` handler | **同构点**:`new InProcessApiClient(toFetchHandler(api))` 全程不过网络但真跑 wire 序列化/zod/SSE 帧;载体测试与调用方可以在不打开端口的情况下运行这套协议,而产品 `dsh --profile headless` 直接驱动 core |
-| `WebApiClient` | dsh-client-connection | `globalThis.fetch` 上行 + 每逻辑流一条同源 WebSocket 下行 | 浏览器客户端;物理边界见 [WebSocket 下行载体](2026-08-04-websocket-downlink-carrier.md) |
+| `WebApiClient` | dsh-client-connection | `globalThis.fetch` 上行 + 每逻辑流一条同源 WebSocket 下行 | 浏览器客户端;物理边界见 [WebSocket 下行载体](2026-08-04-websocket-downlink-carrier.zh.md) |
 | `FixtureApiClient` | dsh-client-connection | 不用(协议层覆写) | 无 server 的 UI 开发(`?fixture`):覆写 `callUnary`/`openMux`/`openHost`/`respond` 虚方法,自己就是假 server(帧 rpcId 由它 mint,语义自洽) |
 | IPC 桥子类(假想示例——尚无此形态) | Electron 壳 | IPC 序列化往返 | 只需换 doFetch,约定/基类零改 |
 

+ 6 - 0
.agents/notes/archived/architecture/2026-08-04-websocket-downlink-carrier.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write .agents/notes/archived/architecture/2026-08-04-websocket-downlink-carrier.md
+2026-08-04-websocket-downlink-carrier.md: 5edcdd95cf2845d455a61930a9fc00e7e57e72eb
+2026-08-04-websocket-downlink-carrier.zh.md: 213697effb8655583e7c420e58acfd171261a8d8

+ 2 - 1
.agents/notes/implemented/architecture/2026-08-04-websocket-downlink-carrier.md → .agents/notes/archived/architecture/2026-08-04-websocket-downlink-carrier.md

@@ -1,6 +1,7 @@
 # Agent Note: WebSocket carrier for browser downlinks
 
 Status: implemented
+Archived: 2026-08-27
 
 English | [中文](2026-08-04-websocket-downlink-carrier.zh.md)
 
@@ -16,7 +17,7 @@ WebSocket carries only the host→browser downlink. All client→host unary call
 
 ## Upgrade and lifecycle boundaries
 
-`dsh-host-webserver` provides an exact upgrade-route registration point alongside ordinary routes, dispatches Node upgrade sockets by pathname only, contains raw-socket errors, and waits for surviving upgraded connections to close during server teardown; it knows nothing about Harness frames or WebSocket messages. `dsh-client-connection` owns the WebSocket handshake, frame output, and stream cancellation, and reuses the `/api` Host/Origin trust fence before upgrade. An untrusted authority or cross-origin Origin is rejected before `ctx.apiProxy.events.*` starts.
+`dsh-host-webserver` provides an exact upgrade-route registration point alongside ordinary routes, dispatches Node upgrade sockets by pathname only, contains raw-socket errors, and waits for surviving upgraded connections to close during server teardown; it knows nothing about Harness frames or WebSocket messages. `dsh-client-connection` owns the WebSocket handshake, frame output, and stream cancellation. Before upgrade it applies the `/api` Host/Origin checks followed by the same signed browser-cookie authentication as unary HTTP. An untrusted authority or cross-origin Origin receives 403; a trusted but unauthenticated request receives 401; neither starts a Remote stream.
 
 A browser abort or socket close cancels the corresponding host stream; plugin teardown also waits for that source iterator's cleanup. If a host stream throws midway, the carrier sends one existing `stream/error` frame and then closes the socket; the client treats that frame as connection loss rather than delivering it to a business sink. Each WebSocket reports open independently, and the existing readiness handshake still waits until mux and host are both open and the `host.describe` HTTP call has succeeded before publishing connected.
 

+ 2 - 1
.agents/notes/implemented/architecture/2026-08-04-websocket-downlink-carrier.zh.md → .agents/notes/archived/architecture/2026-08-04-websocket-downlink-carrier.zh.md

@@ -1,6 +1,7 @@
 # Agent Note: 浏览器下行 WebSocket 载体
 
 Status: implemented
+Archived: 2026-08-27
 
 [English](2026-08-04-websocket-downlink-carrier.md) | 中文
 
@@ -16,7 +17,7 @@ WebSocket 只承担 host→browser 下行。所有 client→host unary 调用和
 
 ## Upgrade 与生命周期边界
 
-`dsh-host-webserver` 提供与普通 route 并列的精确 upgrade-route 注册点,只按 pathname 分发 Node upgrade socket,隔离原始 socket 错误,并在 server teardown 期间等待仍存活的升级连接关闭;它不认识 Harness 帧或 WebSocket 消息。`dsh-client-connection` 拥有 WebSocket handshake、frame 写出和流取消,并在 upgrade 前复用 `/api` 的 Host/Origin 信任栅栏。未受信任的 authority 或跨来源 Origin 在 `ctx.apiProxy.events.*` 启动前即被拒绝
+`dsh-host-webserver` 提供与普通 route 并列的精确 upgrade-route 注册点,只按 pathname 分发 Node upgrade socket,隔离原始 socket 错误,并在 server teardown 期间等待仍存活的升级连接关闭;它不认识 Harness 帧或 WebSocket 消息。`dsh-client-connection` 拥有 WebSocket handshake、frame 写出和流取消。upgrade 前先执行 `/api` Host/Origin 校验,再执行与一元 HTTP 相同的签名浏览器 cookie 认证。未受信任的 authority 或跨来源 Origin 得到 403;Host 可信但未认证的请求得到 401;两者都不会启动 Remote stream
 
 浏览器 abort 或 socket close 会取消对应的 host 流;插件 teardown 还会等待该 source iterator 完成清理。host 流中途抛错时,载体发送一个现有的 `stream/error` frame 后关闭 socket;客户端把该 frame 收敛为连接丢失,不投递给业务 sink。每条 WebSocket 独立报告 open,既有 readiness handshake 仍等待 mux、host 都 open 且 `host.describe` HTTP 调用成功后才发布 connected。
 

+ 6 - 0
.agents/notes/archived/architecture/2026-08-11-plugin-settings-tabs.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-11-plugin-settings-tabs.md: 1f1701e000b891b4fc00bc666f603ee00bae50a7
+2026-08-11-plugin-settings-tabs.zh.md: f76a4a9e2317eb6603b48e1a7e451abdc55e00ff

+ 1 - 0
.agents/notes/implemented/architecture/2026-08-11-plugin-settings-tabs.md → .agents/notes/archived/architecture/2026-08-11-plugin-settings-tabs.md

@@ -1,6 +1,7 @@
 # Agent Note: Feature-owned tabs in Plugins settings
 
 Status: implemented
+Archived: 2026-08-22
 
 English | [中文](2026-08-11-plugin-settings-tabs.zh.md)
 

+ 1 - 0
.agents/notes/implemented/architecture/2026-08-11-plugin-settings-tabs.zh.md → .agents/notes/archived/architecture/2026-08-11-plugin-settings-tabs.zh.md

@@ -1,6 +1,7 @@
 # Agent Note: “插件”设置中的功能自有标签页
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-11-plugin-settings-tabs.md) | 中文
 

+ 6 - 0
.agents/notes/archived/bug-fix/2026-07-31-composer-text-layers-share-one-scrollport.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-07-31-composer-text-layers-share-one-scrollport.md
+2026-07-31-composer-text-layers-share-one-scrollport.md: eb50673bb5fac50e12b0325c22c67072e130efb6
+2026-07-31-composer-text-layers-share-one-scrollport.zh.md: f0af130d34682fcdfe145eb73b18187ca316c0d2

+ 1 - 0
.agents/notes/implemented/bug-fix/2026-07-31-composer-text-layers-share-one-scrollport.md → .agents/notes/archived/bug-fix/2026-07-31-composer-text-layers-share-one-scrollport.md

@@ -1,6 +1,7 @@
 # Agent Note: The composer's two text layers share one scrollport
 
 Status: implemented
+Archived: 2026-08-20
 
 English | [中文](2026-07-31-composer-text-layers-share-one-scrollport.zh.md)
 

+ 2 - 1
.agents/notes/implemented/bug-fix/2026-07-31-composer-text-layers-share-one-scrollport.zh.md → .agents/notes/archived/bug-fix/2026-07-31-composer-text-layers-share-one-scrollport.zh.md

@@ -1,6 +1,7 @@
 # Agent Note: composer 的两层文本共用同一个滚动容器
 
 Status: implemented
+Archived: 2026-08-20
 
 [English](2026-07-31-composer-text-layers-share-one-scrollport.md) | 中文
 
@@ -24,7 +25,7 @@ composer 的文本由两层叠放绘制(见 [InputBar](../../../../packages/cl
 
 于是浏览器在同一帧、同一个合成器上,把同一个偏移施加给两层。光标与字形的绑定来自结构本身,而不是来自持续维护:没有代码要跑,没有事件要等,也没有任何状态可能落后一帧。滚轮接力处理器保留,只是从 textarea 改挂到滚动容器上,并且仍是这个盒子上唯一的监听。
 
-Safari 的原生文本控件存在一个引擎例外:跨过软换行阈值的删除可能在镜像层收缩后仍保留原先的行布局。[Safari 软换行恢复](2026-08-13-safari-textarea-soft-wrap-reflow.md)会在绘制前恢复零溢出不变量,而不改变单滚动容器设计。
+Safari 的原生文本控件存在一个引擎例外:跨过软换行阈值的删除可能在镜像层收缩后仍保留原先的行布局。[Safari 软换行恢复](2026-08-13-safari-textarea-soft-wrap-reflow.zh.md)会在绘制前恢复零溢出不变量,而不改变单滚动容器设计。
 
 上一版机制所需要的两样东西随它一起消失:
 

+ 6 - 0
.agents/notes/archived/bug-fix/2026-08-04-large-history-pagination-call-stack.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-04-large-history-pagination-call-stack.md: 12e9bbf72c2eea2058bf83fe864e09b4a520d391
+2026-08-04-large-history-pagination-call-stack.zh.md: 288687b05ecdfc2858b4d67e1be199135ea20227

+ 1 - 0
.agents/notes/implemented/bug-fix/2026-08-04-large-history-pagination-call-stack.md → .agents/notes/archived/bug-fix/2026-08-04-large-history-pagination-call-stack.md

@@ -1,6 +1,7 @@
 # Agent Note: Large history provenance is scanned without argument expansion
 
 Status: implemented
+Archived: 2026-08-22
 
 English | [中文](2026-08-04-large-history-pagination-call-stack.zh.md)
 

+ 1 - 0
.agents/notes/implemented/bug-fix/2026-08-04-large-history-pagination-call-stack.zh.md → .agents/notes/archived/bug-fix/2026-08-04-large-history-pagination-call-stack.zh.md

@@ -1,6 +1,7 @@
 # Agent Note: 大规模历史记录的溯源信息通过扫描处理,不做参数展开
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-04-large-history-pagination-call-stack.md) | 中文
 

+ 6 - 0
.agents/notes/archived/bug-fix/2026-08-06-plan-narrow-viewport-regression.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-06-plan-narrow-viewport-regression.md: c42a110bf487ffab8f5975e65a8eb9bff4f1b0ae
+2026-08-06-plan-narrow-viewport-regression.zh.md: 3df4f8aca57a1830d7f8062cefe76ac1afa9c2ce

+ 1 - 0
.agents/notes/implemented/bug-fix/2026-08-06-plan-narrow-viewport-regression.md → .agents/notes/archived/bug-fix/2026-08-06-plan-narrow-viewport-regression.md

@@ -1,6 +1,7 @@
 # Agent Note: narrow-viewport plan chip click-area regression test
 
 Status: implemented
+Archived: 2026-08-22
 
 English | [中文](2026-08-06-plan-narrow-viewport-regression.zh.md)
 

+ 2 - 1
.agents/notes/implemented/bug-fix/2026-08-06-plan-narrow-viewport-regression.zh.md → .agents/notes/archived/bug-fix/2026-08-06-plan-narrow-viewport-regression.zh.md

@@ -1,6 +1,7 @@
 # Agent Note: 窄视口下 Plan chip 点击区域回归测试
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-06-plan-narrow-viewport-regression.md) | 中文
 
@@ -8,7 +9,7 @@ Status: implemented
 
 外部报告 dsh-external/issues#107(内部聚类为 deepseek-harness#1406)测得视口宽度在 760px 到 850px 之间时 Plan 控件与模型选择器发生重叠,模型选择器覆盖 Plan 控件的点击区域,导致在 800×720 下无法用鼠标退出 Plan 模式。其验收清单要求增加浏览器回归测试,断言 Plan 中心命中 Plan 按钮。
 
-浏览器回归测试在当前 master 上复现了报告:800×720 下 Plan chip 与模型 trigger 重叠 36.9px,chip 中心命中 trigger 的 label。composer 控制行是 `display: flex; justify-content: space-between` 且 `.trailing { flex: none }`:当控件总宽超过卡片时,可收缩的 `.tools` 组把流内子项留在 `min-width: 0` 的盒内,于是 chip——溢出前最后一个流内子项——被绘制到 trailing 组上方。报告以来 Plan 控件形态已变(select → chip,`c20b988166`/`fe91919346`),控制行也获得过自适应能力(`c8c75ec891`,[web-composer-shared-width-axis](../feature/2026-08-04-web-composer-shared-width-axis.md)),但该行没有换行,重叠在两次重构后依然存在。
+浏览器回归测试在当前 master 上复现了报告:800×720 下 Plan chip 与模型 trigger 重叠 36.9px,chip 中心命中 trigger 的 label。composer 控制行是 `display: flex; justify-content: space-between` 且 `.trailing { flex: none }`:当控件总宽超过卡片时,可收缩的 `.tools` 组把流内子项留在 `min-width: 0` 的盒内,于是 chip——溢出前最后一个流内子项——被绘制到 trailing 组上方。报告以来 Plan 控件形态已变(select → chip,`c20b988166`/`fe91919346`),控制行也获得过自适应能力(`c8c75ec891`,[web-composer-shared-width-axis](../feature/2026-08-04-web-composer-shared-width-axis.zh.md)),但该行没有换行,重叠在两次重构后依然存在。
 
 ## 决策
 

+ 6 - 0
.agents/notes/archived/bug-fix/2026-08-11-preset-card-description-clamp.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-11-preset-card-description-clamp.md: b9088b46184cde6f000fa39afbfe2d1145137b24
+2026-08-11-preset-card-description-clamp.zh.md: a7a3c4f26a55405715fe017ec3a7deb164432b0e

+ 1 - 0
.agents/notes/implemented/bug-fix/2026-08-11-preset-card-description-clamp.md → .agents/notes/archived/bug-fix/2026-08-11-preset-card-description-clamp.md

@@ -1,6 +1,7 @@
 # Agent Note: Preset cards clamp their description instead of sizing the roster
 
 Status: implemented
+Archived: 2026-08-22
 
 English | [中文](2026-08-11-preset-card-description-clamp.zh.md)
 

+ 1 - 0
.agents/notes/implemented/bug-fix/2026-08-11-preset-card-description-clamp.zh.md → .agents/notes/archived/bug-fix/2026-08-11-preset-card-description-clamp.zh.md

@@ -1,6 +1,7 @@
 # Agent Note: 预设卡片截断自身描述,而不是由描述决定整份名单的高度
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-11-preset-card-description-clamp.md) | 中文
 

+ 6 - 0
.agents/notes/archived/bug-fix/2026-08-13-safari-textarea-soft-wrap-reflow.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-13-safari-textarea-soft-wrap-reflow.md
+2026-08-13-safari-textarea-soft-wrap-reflow.md: 45cb3f39c50c72b44b8ae952ce3a861210e9f00a
+2026-08-13-safari-textarea-soft-wrap-reflow.zh.md: 37409b010c0009edf3c944076ba8c3db1b140de9

+ 1 - 0
.agents/notes/implemented/bug-fix/2026-08-13-safari-textarea-soft-wrap-reflow.md → .agents/notes/archived/bug-fix/2026-08-13-safari-textarea-soft-wrap-reflow.md

@@ -1,6 +1,7 @@
 # Agent Note: Safari textarea soft-wrap shrink recovery
 
 Status: implemented
+Archived: 2026-08-20
 
 English | [中文](2026-08-13-safari-textarea-soft-wrap-reflow.zh.md)
 

+ 2 - 1
.agents/notes/implemented/bug-fix/2026-08-13-safari-textarea-soft-wrap-reflow.zh.md → .agents/notes/archived/bug-fix/2026-08-13-safari-textarea-soft-wrap-reflow.zh.md

@@ -1,12 +1,13 @@
 # Agent Note: Safari textarea 软换行收缩恢复
 
 Status: implemented
+Archived: 2026-08-20
 
 [English](2026-08-13-safari-textarea-soft-wrap-reflow.md) | 中文
 
 ## 问题
 
-composer 把光标与选区留在透明的原生 textarea 中,由 backdrop 绘制可见字形,并由隐藏的镜像层决定完整草稿高度。因此,[单滚动容器决策](2026-07-31-composer-text-layers-share-one-scrollport.md)依赖 textarea 不持有可滚动溢出:每次草稿提交后,它的 `scrollHeight` 与 `clientHeight` 相等,`scrollTop` 为零。
+composer 把光标与选区留在透明的原生 textarea 中,由 backdrop 绘制可见字形,并由隐藏的镜像层决定完整草稿高度。因此,[单滚动容器决策](2026-07-31-composer-text-layers-share-one-scrollport.zh.md)依赖 textarea 不持有可滚动溢出:每次草稿提交后,它的 `scrollHeight` 与 `clientHeight` 相等,`scrollTop` 为零。
 
 当 Backspace 让草稿跨过软换行阈值,同时 React 更新镜像层时,Safari 26.5.2 可能保留 textarea 原先的原生行布局。在复现出的两行变一行转换中,镜像层、backdrop、自增高栈和 textarea 盒都变为 28px 高,但 textarea 仍报告 `scrollHeight=52` 与 `scrollTop=20`。光标留在陈旧的原生行中,而 backdrop 已正确绘制为一行。
 

+ 6 - 0
.agents/notes/archived/bug-fix/2026-08-20-composer-edit-range-from-selection.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-20-composer-edit-range-from-selection.md
+2026-08-20-composer-edit-range-from-selection.md: 46eaa0add61bdab9fdcb4fcfd0ec08b44481126d
+2026-08-20-composer-edit-range-from-selection.zh.md: 73a3903ad6c7c0aad55a35aacc5e1396084b6e7a

+ 48 - 0
.agents/notes/archived/bug-fix/2026-08-20-composer-edit-range-from-selection.md

@@ -0,0 +1,48 @@
+# Agent Note: Composer edits carry the range they applied to
+
+Status: implemented
+Archived: 2026-08-20
+
+English | [中文](2026-08-20-composer-edit-range-from-selection.zh.md)
+
+## Problem
+
+The input machine keeps its reference occurrences aligned by reconciling them against one edit range: entries before the range shift, entries after it hold, and an entry the range intersects loses its structured identity and stays behind as ordinary draft text. That last rule is the deliberate meaning of editing inside a reference.
+
+Ordinary typing supplied no range. A controlled textarea's change event carries only the resulting string, so the machine recovered the range by scanning the two drafts for a common prefix and suffix. That recovery is ambiguous whenever the inserted text repeats the text it lands against, and the greedy scan always resolves the ambiguity the same way: it slides the edit as late as the characters allow.
+
+A reference renders as `@` followed by its label, so typing `@` immediately before one produces exactly that collision. The user inserts at the reference's own offset; the scan reports an insertion one character later, inside the reference; reconcile applies the intersect rule and drops the occurrence. Deleting a character in front of such a reference slides the same way.
+
+The draft then still reads correctly to the eye while carrying no structured reference, and submission takes the occurrence-free path that sends the draft verbatim. The host receives the human-facing label instead of the owner's model form and resolves nothing. The serialization guard that exists to prevent exactly this downgrade never runs, because it only fires when an occurrence survives to be serialized.
+
+This became reachable when references [became literal inline text](../feature/2026-07-27-web-file-and-session-references.md). A reference previously occupied one `U+FFFC`, a character no keystroke produces, so the scan had nothing to collide with.
+
+## Decision
+
+`InputBar` records the textarea's selection and `inputType` during `beforeinput` and passes the resulting range to `setDraft`, which the machine already accepts and prefers over its own scan. A textarea exposes the edit no other way — `getTargetRanges()` is empty for form controls.
+
+An edit that replaces a selection reports that selection, and it is the range outright; the inserted length is whatever the draft grew by once the replaced range is accounted for. A caret delete replaces nothing and reports the bare caret, so its range comes from the direction `inputType` names and the number of characters the draft actually lost. The count is measured rather than assumed to be one, because a single caret gesture removes a multi-unit grapheme, a word, or a line just as readily. Chromium, WebKit, and Firefox all report the collapsed caret for `deleteContentBackward` and `deleteContentForward`, and all three derive the same range from it.
+
+Only the `insert` and `delete` families are recorded. A history replay reports wherever the caret happens to sit, which would survive every check while naming the wrong span; ignoring it leaves that path on the scan.
+
+The record is consumed once and cleared. A record whose draft length disagrees with the draft the change reports, a selection past the draft, a shrinking edit over a selection the caret cannot explain, or an undirected delete all yield no range, and the machine falls back to its scan. Paste and the boundary Backspace and Delete gestures already supplied their own ranges and are untouched.
+
+## Testing
+
+Component tests cover the trigger character typed in front of a reference, a caret Backspace, a caret Delete, a caret word delete, and a delete over a selection, asserting in each case that the occurrence survives at the shifted offset. The caret cases fail against the scan-recovered range, and the word case fails against a fixed one-character step.
+
+An assembled browser scenario drives the same gestures as real key presses against the shipped composition, which is the only place the range an engine reports for them can be observed; its golden projects the backdrop's segments, since the decoration layer is aria-hidden and the accessibility tree cannot see the chip. A real composition driven through the browser's IME path reports the composing segment as the selection at every intermediate state, and the reference survives each one.
+
+## Alternatives considered
+
+**Disambiguate the scan with the post-edit caret.** The caret pins which of the textually equivalent readings happened, and the change event already carries it. Rejected because it keeps a reconstruction where an exact fact is available, and it cannot separate the deleted and inserted halves of a replaced selection at all.
+
+**Give references a leading marker no keystroke produces.** A private-use character in place of the literal `@` removes the collision at the representation level, and the reject list for pasted text already names that range. Rejected because it re-adds a character that every serialization, selection, and accessibility path has to strip, to buy what an exact range buys directly, and it would leave ordinary typing reconstructing its range for every other reason.
+
+**Widen reconcile to keep an occurrence when the range only touches its edge.** Rejected because the misattributed offset lands strictly inside the reference, not on its boundary, so the rule change would not reach this defect while making the intersect rule vaguer.
+
+## Consequences
+
+Every native textarea edit that reaches `onChange` now names the range it applied to, so occurrence offsets follow the edit that actually happened rather than one merely consistent with the resulting characters. Draft writes that originate in the facade rather than the DOM — `insertText` and the command-token splices among them — still carry no range and keep the scan, as do the fallbacks above.
+
+The composer now depends on `beforeinput` preceding each value change, and on `inputType` naming the direction of a caret delete. Any future edit path that mutates the value without either silently returns to the scan rather than breaking, which keeps the failure mode the old behavior instead of a wrong range.

+ 48 - 0
.agents/notes/archived/bug-fix/2026-08-20-composer-edit-range-from-selection.zh.md

@@ -0,0 +1,48 @@
+# Agent Note: 输入框的编辑自带它所作用的范围
+
+Status: implemented
+Archived: 2026-08-20
+
+[English](2026-08-20-composer-edit-range-from-selection.md) | 中文
+
+## 问题
+
+输入机器靠一个编辑范围来对齐引用 occurrence:范围之前的条目右移,之后的条目不动,被范围相交的条目失去结构化身份、以普通草稿文本留在原地。最后一条是"在引用内部编辑"的刻意含义。
+
+普通打字不提供范围。受控 textarea 的 change 事件只带结果字符串,于是机器靠扫描两份草稿的公共前后缀来还原范围。只要插入的文本与它落点处的文本重复,这个还原就是有歧义的,而贪心扫描永远以同一种方式消解歧义:把编辑尽量往后滑。
+
+引用渲染为 `@` 加标签,所以紧挨着引用前面打一个 `@` 恰好构成这种撞车。用户在引用自身的偏移处插入;扫描报告的插入位置晚一个字符,落在引用内部;reconcile 执行相交规则,删掉这个 occurrence。删除这类引用前面的一个字符会以同样方式滑动。
+
+此时草稿看上去仍然正确,却已不携带任何结构化引用,提交走的是无 occurrence 的那条路,把草稿原样发出。宿主收到的是给人看的标签而不是所有者的模型形式,什么也解析不出来。专为阻止这种降级而存在的序列化守卫从不运行,因为它只在还有 occurrence 需要序列化时才触发。
+
+这条路径是在引用[变成字面内联文本](../feature/2026-07-27-web-file-and-session-references.md)之后才可达的。此前一个引用占据一个 `U+FFFC`——任何按键都打不出的字符,扫描无从撞车。
+
+## 决策
+
+`InputBar` 在 `beforeinput` 期间记录 textarea 的 selection 与 `inputType`,并把由此得到的范围传给 `setDraft`;机器本就接受该参数,并优先于自身的扫描。textarea 没有别的途径暴露这次编辑——`getTargetRanges()` 对表单控件返回空。
+
+替换一段选区的编辑会报告那段 selection,它直接就是范围;插入长度是扣除被替换范围后草稿增长的量。折叠光标的删除不替换任何东西、只报告光标本身,因此它的范围来自 `inputType` 指明的方向加上草稿实际减少的字符数。这个数量是**测量**得到而非假定为 1,因为一次折叠手势同样可能删掉一个多码元字形、一个词或一整行。Chromium、WebKit 与 Firefox 对 `deleteContentBackward` 和 `deleteContentForward` 都报告折叠光标,三者由此推导出相同的范围。
+
+只有 `insert` 与 `delete` 两族会被记录。历史回放报告的是光标当时碰巧所在的位置,那会通过全部校验却指向错误区间;忽略它即让该路径留在扫描上。
+
+记录只消费一次即清空。记录的草稿长度与 change 报告的草稿不符、selection 越过草稿末尾、选区之上出现光标无法解释的收缩、以及方向不明的删除,这几种情况都不产出范围,机器回落到扫描。粘贴以及边界处的 Backspace 与 Delete 手势本就自带范围,未受影响。
+
+## 测试
+
+组件测试覆盖在引用正前方输入触发字符、折叠 Backspace、折叠 Delete、折叠整词删除,以及选区替换式删除,每种都断言 occurrence 在右移后的偏移处存活。折叠类用例在扫描还原的范围下失败,整词用例在固定一字符步长的实现下失败。
+
+组装层浏览器场景以真实按键对已发布组合驱动同样的手势——那是唯一能观察到引擎为这些手势报告何种范围的地方;其 golden 投影的是 backdrop 的分段,因为装饰层是 aria-hidden 的,无障碍树看不到 chip。经浏览器 IME 路径驱动的真实组合在每个中间态都把组合段报告为 selection,引用在每一步都存活。
+
+## 备选方案
+
+**用编辑后的光标位置消解扫描的歧义。** 光标能钉住若干文本等价读法中真正发生的那一种,而 change 事件本就携带它。拒绝:在已有精确事实可用时仍保留一次重建,而且它根本无法把"替换一段选区"拆成删除与插入两半。
+
+**给引用一个按键打不出的前导标记。** 用私有区字符取代字面 `@`,在表示层消除撞车,而粘贴文本的剔除名单本就点名了那个区段。拒绝:为了换取一个精确范围本就能直接换到的东西,却重新引入一个必须在所有序列化、选择和无障碍路径上剥离的字符,而且普通打字仍会因为其他原因继续重建自己的范围。
+
+**放宽 reconcile,让范围只触及边缘时保留 occurrence。** 拒绝:误判出的偏移严格落在引用内部而非边界上,规则放宽够不到这个缺陷,只会让相交规则本身更含糊。
+
+## 后果
+
+每一次经 `onChange` 到达的原生 textarea 编辑现在都指明它作用的范围,因此 occurrence 偏移跟随的是真实发生的编辑,而不是某个仅仅与结果字符一致的编辑。源自 facade 而非 DOM 的草稿写入——`insertText` 和命令 token 的替换等——仍不带范围并保留扫描,上述各类回落同样如此。
+
+输入框由此依赖 `beforeinput` 先于每次取值变更发生,并依赖 `inputType` 指明折叠删除的方向。未来任何绕过其中之一改写取值的编辑路径会静默回落到扫描而不是出错,也就是说失效模式退回旧行为,而不是一个错误的范围。

+ 6 - 0
.agents/notes/archived/bug-fix/2026-08-20-composer-reference-decoration-keys.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-20-composer-reference-decoration-keys.md
+2026-08-20-composer-reference-decoration-keys.md: 316d45841c658d3d65246fb7425526b10e2f6bf3
+2026-08-20-composer-reference-decoration-keys.zh.md: 90ac7c8011bb7f7f45312c25ffccb7dbbbb70505

+ 40 - 0
.agents/notes/archived/bug-fix/2026-08-20-composer-reference-decoration-keys.md

@@ -0,0 +1,40 @@
+# Agent Note: Composer reference decorations key by draft-order ordinal
+
+Status: implemented
+Archived: 2026-08-20
+
+English | [中文](2026-08-20-composer-reference-decoration-keys.zh.md)
+
+## Problem
+
+The composer backdrop renders the draft as an array of segments: plain strings, a leading claim-token mark, one element per structured reference, and one mark per plain-text reference range. React reconciles that array by key.
+
+Structured references carry an identity — the occurrence table mints an `occurrenceId` that survives every edit — so their chips key by it. Plain-text reference ranges have no such identity: `scanTextRefs` re-derives them from the draft on every render, and nothing outside that scan remembers a range between two keystrokes.
+
+Keying those ranges by their draft offset made the key change whenever earlier text changed length. React then treated the range as a different element, unmounted the mark with its nested spans and inline glyph, and mounted a replacement. Every character typed or deleted ahead of a reference rebuilt every reference after the caret, and the work grew with the reference count. [Directory-syntax ranges](../feature/2026-07-27-web-file-and-session-references.md) made that path routine: they match on `@path/` syntax without a lexicon, and each one renders an icon.
+
+## Decision
+
+A plain-text reference mark keys by its index in the offset-sorted `textRefs` list, computed where the boundary list is assembled so a skipped boundary cannot shift it. The scan already returns the ranges in draft order, so the ordinal names the render slot a range occupies, which is the only identity a scan-derived range has.
+
+Structured chips keep `occurrenceId`. The two key strategies differ because the two range kinds differ in identity, not by oversight: a range the occurrence table owns keeps its node across reordering, and a range only a scan knows keeps its node across offset shifts.
+
+A range that stops matching the scan still loses its decoration, because it disappears from `textRefs` and the ordinal it held no longer exists.
+
+## Testing
+
+A component test holds the mark element and its glyph, types a character ahead of the range, and asserts the same nodes are still mounted; it then edits the token out of match shape and asserts the decoration is gone. The test fails against an offset-derived key.
+
+## Alternatives considered
+
+**Key by the range text.** Rejected: duplicate references collide on one key, and editing inside a range changes its key, which reintroduces the remount this fixes.
+
+**Give scan-derived ranges an identity table.** Rejected: it adds mutable state whose only consumer is a render key, and the scan would have to diff against the previous draft to maintain it. An edit that breaks a match simply dropping the range on the next scan is what keeps `scanTextRefs` a pure derivation.
+
+**Drop the keys and let React match by position.** Rejected: React requires keys on elements inside an array, and the plain string segments between them already match by index, so an unkeyed element warns without changing the outcome.
+
+## Consequences
+
+Typing ahead of a reference updates text nodes only; the mark and its icon stay mounted. The backdrop's per-keystroke DOM work no longer scales with the number of references in the draft.
+
+Because the key names a position, inserting a reference ahead of existing ones reuses the earlier nodes with new content instead of re-creating them. That is correct for these marks, which hold no focus, selection, or animation state, and it is the condition any future decoration on this layer meets before it keys by ordinal.

+ 40 - 0
.agents/notes/archived/bug-fix/2026-08-20-composer-reference-decoration-keys.zh.md

@@ -0,0 +1,40 @@
+# Agent Note: 输入框引用装饰按草稿顺序序号取 key
+
+Status: implemented
+Archived: 2026-08-20
+
+[English](2026-08-20-composer-reference-decoration-keys.md) | 中文
+
+## 问题
+
+输入框 backdrop 把草稿渲染成一组片段:纯文本字符串、开头的 claim token 标记、每个结构化引用一个元素、每个纯文本引用范围一个标记。React 按 key 协调这个数组。
+
+结构化引用带有身份——occurrence 表铸造的 `occurrenceId` 在任何编辑后都保持不变——因此它们的 chip 用它作 key。纯文本引用范围没有这种身份:`scanTextRefs` 在每次渲染时从草稿重新推导它们,扫描之外没有任何东西在两次按键之间记住某个范围。
+
+用草稿偏移量给这些范围取 key,会让前面文本长度一变 key 就变。React 于是把该范围当作另一个元素,卸载带嵌套 span 和内联图标的标记,再挂载一个替代品。在引用前面输入或删除任意字符,都会重建光标之后的每一个引用,工作量随引用数量增长。[目录语法范围](../feature/2026-07-27-web-file-and-session-references.zh.md)让这条路径成为常态:它们按 `@path/` 语法匹配,不依赖 lexicon,而且每个都渲染一个图标。
+
+## 决策
+
+纯文本引用标记以它在按偏移排序的 `textRefs` 列表中的下标作 key,在组装 boundary 列表处计算,因此被跳过的 boundary 不会让它偏移。扫描本身已按草稿顺序返回范围,所以该序号命名的是范围占据的渲染槽位,而这正是扫描推导出的范围唯一拥有的身份。
+
+结构化 chip 保留 `occurrenceId`。两种 key 策略不同,是因为两类范围的身份不同,而非疏漏:occurrence 表拥有的范围在重排后保住自己的节点,只有扫描知道的范围在偏移变化后保住自己的节点。
+
+不再匹配扫描规则的范围仍然失去装饰,因为它从 `textRefs` 中消失,它占据的序号也不复存在。
+
+## 测试
+
+组件测试持有标记元素及其图标,在范围之前输入一个字符,断言仍是同一批节点;随后把 token 编辑成不再匹配的形态,断言装饰消失。该测试在偏移量 key 下失败。
+
+## 备选方案
+
+**按范围文本取 key。** 拒绝:重复引用会撞同一个 key,且在范围内部编辑会改变 key,重新引入本次修复消除的重挂载。
+
+**为扫描推导的范围建立身份表。** 拒绝:这会引入唯一消费者是渲染 key 的可变状态,而且扫描必须与上一版草稿做 diff 才能维护它。破坏匹配的编辑在下一次扫描时直接丢掉该范围,正是这一点让 `scanTextRefs` 保持为纯推导。
+
+**去掉 key,让 React 按位置匹配。** 拒绝:React 要求数组内的元素带 key,而它们之间的纯文本片段本就按下标匹配,因此无 key 元素只会告警,不改变结果。
+
+## 后果
+
+在引用之前输入只更新文本节点;标记及其图标保持挂载。backdrop 每次按键的 DOM 工作量不再随草稿中的引用数量增长。
+
+由于 key 命名的是位置,在已有引用之前插入新引用会以新内容复用先前的节点,而不是重建它们。对这些不持有焦点、选择区或动画状态的标记而言这是正确的,这也是该图层上任何未来装饰按序号取 key 前需要满足的条件。

+ 6 - 0
.agents/notes/archived/bug-fix/2026-08-24-system-prompt-section-order-ties.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-24-system-prompt-section-order-ties.md
+2026-08-24-system-prompt-section-order-ties.md: d92756e751e893b1d03b8892ef71ff9faac9d2c6
+2026-08-24-system-prompt-section-order-ties.zh.md: 4a822b7925a38feb254dbc534fc6153c76a93e19

+ 28 - 0
.agents/notes/archived/bug-fix/2026-08-24-system-prompt-section-order-ties.md

@@ -0,0 +1,28 @@
+# Agent Note: Equal-order system-prompt sections render in activation order
+
+Status: implemented
+Archived: 2026-08-25
+
+English | [中文](2026-08-24-system-prompt-section-order-ties.zh.md)
+
+## Problem
+
+`SystemPromptRegistry` sorts sections by `order` with a stable sort, so equal orders render in plugin-activation order. `tool:cordis` and `tool:workflow` both declared `order: 115`, while their activation order varies between clean platform compositions. ACP and SDK snapshot replays could therefore assemble the same sections in a different order from their committed `system-prompt.expected.md` files.
+
+## Decision
+
+Give the affected sequence distinct values without changing its established relative order: `tool:cordis` stays at 115, `tool:workflow` uses 115.5, `tool:ralph` stays at 116, continuable subagent guidance stays at 116.5, and child-report guidance stays at 117. Prompt text and tool schemas remain unchanged.
+
+## Alternatives considered
+
+**Normalize section order in the snapshot harness.** Rejected because the runtime, request header, and model prompt would remain sensitive to activation timing while only the fixture comparison hid the difference.
+
+**Tie-break equal orders by section name in the registry.** Rejected because it would silently reorder every existing tie. Explicit orders keep each model-visible placement local to the contributing plugin.
+
+## Consequences
+
+The Cordis and workflow guidance has a platform-independent order while Ralph remains before continuable subagent and child-report guidance. Prompt-section placements that require a stable relative position need distinct `order` values; other equal-order sections retain activation-order semantics and are outside this decision.
+
+## Testing
+
+The keyless ACP and SDK snapshot replays pin Cordis before workflow and preserve the workflow, Ralph, continuable-subagent, and child-report sequence. The full snapshot suite verifies the refreshed fixtures.

+ 28 - 0
.agents/notes/archived/bug-fix/2026-08-24-system-prompt-section-order-ties.zh.md

@@ -0,0 +1,28 @@
+# Agent Note: 等序系统提示词分段按激活顺序渲染
+
+Status: implemented
+Archived: 2026-08-25
+
+[English](2026-08-24-system-prompt-section-order-ties.md) | 中文
+
+## Problem
+
+`SystemPromptRegistry` 使用稳定排序按 `order` 排列分段,因此相同 order 的分段会按插件激活顺序渲染。`tool:cordis` 与 `tool:workflow` 都声明了 `order: 115`,但两者在不同平台的全新组合中激活顺序不同。因此,ACP(Agent Client Protocol)与 SDK 的快照回放可能把相同分段组装成不同于已提交 `system-prompt.expected.md` 文件的顺序。
+
+## Decision
+
+在不改变既有相对顺序的前提下,为受影响的分段序列指定互不相同的 order:`tool:cordis` 保持 115,`tool:workflow` 使用 115.5,`tool:ralph` 保持 116,可继续运行的子代理指引保持 116.5,子代理报告指引保持 117。提示词文本与工具 schema 保持不变。
+
+## Alternatives considered
+
+**在快照 harness 中规范化分段顺序。** 已否决,因为运行时、请求标头和模型提示词仍然受激活时序影响,只有 fixture 比较会隐藏差异。
+
+**在注册表中用分段名称打破并列。** 已否决,因为这会静默重排每一组现有并列。显式 order 让每个模型可见位置都由贡献该分段的插件就地决定。
+
+## Consequences
+
+Cordis 与 workflow 指引具有不依赖平台的顺序,同时 Ralph 仍排在可继续运行的子代理指引和子代理报告指引之前。需要稳定相对位置的提示词分段必须使用互不相同的 `order`;其他等序分段仍采用激活顺序,不属于本决策的范围。
+
+## Testing
+
+无密钥 ACP 与 SDK 快照回放会固定 Cordis 排在 workflow 之前,并保留 workflow、Ralph、可继续运行的子代理和子代理报告指引的顺序。完整快照套件验证刷新的 fixture。

+ 6 - 0
.agents/notes/archived/feature/2026-07-30-versioned-gui-welcome-onboarding.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-07-30-versioned-gui-welcome-onboarding.md: 370793dd4e6d744ea61fc9319a94728dbbf3e1fe
+2026-07-30-versioned-gui-welcome-onboarding.zh.md: 7b99377d00127174d5bfd8d080107c2cb67e6fff

+ 1 - 0
.agents/notes/implemented/feature/2026-07-30-versioned-gui-welcome-onboarding.md → .agents/notes/archived/feature/2026-07-30-versioned-gui-welcome-onboarding.md

@@ -1,6 +1,7 @@
 # Agent Note: Versioned GUI welcome onboarding
 
 Status: implemented
+Archived: 2026-08-22
 
 English | [中文](2026-07-30-versioned-gui-welcome-onboarding.zh.md)
 

+ 3 - 2
.agents/notes/implemented/feature/2026-07-30-versioned-gui-welcome-onboarding.zh.md → .agents/notes/archived/feature/2026-07-30-versioned-gui-welcome-onboarding.zh.md

@@ -1,6 +1,7 @@
 # Agent Note: 版本化 GUI 欢迎引导
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-07-30-versioned-gui-welcome-onboarding.md) | 中文
 
@@ -10,9 +11,9 @@ GUI 的凭据引导从 DeepSeek 专用的就绪状态检查开始,但内部测
 
 ## 决策
 
-**设置外壳协调有序步骤。** `settings.onboarding` 仍是根作用域 list,但 `ui-settings` 会把其中各条目的 id 和顺序投影到一个协调器中,并且只挂载第一个未完成的步骤。当前注册方会收到 `complete()` 和 `openSection(id)`;所有权转移前,不会挂载后续步骤。`ui-settings-models` 现在以顺序 `-100` 注册恢复后的欢迎声明,以顺序 `0` 注册 DeepSeek 条件式凭据步骤;两者当前的共用展示由[共用弹窗引导决策](2026-08-13-shared-modal-product-onboarding.md)持有。
+**设置外壳协调有序步骤。** `settings.onboarding` 仍是根作用域 list,但 `ui-settings` 会把其中各条目的 id 和顺序投影到一个协调器中,并且只挂载第一个未完成的步骤。当前注册方会收到 `complete()` 和 `openSection(id)`;所有权转移前,不会挂载后续步骤。`ui-settings-models` 现在以顺序 `-100` 注册恢复后的欢迎声明,以顺序 `0` 注册 DeepSeek 条件式凭据步骤;两者当前的共用展示由[共用弹窗引导决策](2026-08-13-shared-modal-product-onboarding.zh.md)持有。
 
-**产品欢迎步骤按版本管理并归功能插件所有。** 该声明曾由[移除首次启动内测声明](../simplification/2026-08-13-remove-first-run-beta-notice.md)历史决策移除,现在以新的测试阶段文案恢复在 `ui-settings-models` 中。`ui-settings-general` 仍不注册任何引导步骤;持有当前两个步骤的插件也持有文案、store 和共用弹窗。
+**产品欢迎步骤按版本管理并归功能插件所有。** 该声明曾由[移除首次启动内测声明](../simplification/2026-08-13-remove-first-run-beta-notice.zh.md)历史决策移除,现在以新的测试阶段文案恢复在 `ui-settings-models` 中。`ui-settings-general` 仍不注册任何引导步骤;持有当前两个步骤的插件也持有文案、store 和共用弹窗。
 
 **持久化的 `ui-onboarding` 分节持有确认状态。** 宿主端在 user-settings seam 中注册它,存入当前 `$DSH_HOME/settings.yaml`;当前欢迎 store 通过既有公开 settings API 读写其中的 `welcomeNoticeVersion`。connection 插件通过 `ctx.connection.isLoopback` 统一发布当前页面是否使用 loopback authority;hostname 判定留在 connection 包内,其他客户端插件只消费服务状态,而不导入其实现。API Proxy 在可配置提供方 namespace 之外,通过封闭的允许列表暴露这一个产品 namespace,同时不会把它的变更视为模型目录失效事件。
 

+ 6 - 0
.agents/notes/archived/feature/2026-08-06-bundled-dsh-badge-skill.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-06-bundled-dsh-badge-skill.md: 2909736d53f8aff41ca69e705de44657bc1b4f1e
+2026-08-06-bundled-dsh-badge-skill.zh.md: de85e9476d3945cd13335ef596243bc2a126ae55

+ 1 - 0
.agents/notes/implemented/feature/2026-08-06-bundled-dsh-badge-skill.md → .agents/notes/archived/feature/2026-08-06-bundled-dsh-badge-skill.md

@@ -1,6 +1,7 @@
 # Agent Note: Bundled dsh badge skill
 
 Status: implemented
+Archived: 2026-08-22
 
 English | [中文](2026-08-06-bundled-dsh-badge-skill.zh.md)
 

+ 2 - 1
.agents/notes/implemented/feature/2026-08-06-bundled-dsh-badge-skill.zh.md → .agents/notes/archived/feature/2026-08-06-bundled-dsh-badge-skill.zh.md

@@ -1,12 +1,13 @@
 # Agent Note: 内置 dsh 徽章 skill
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-06-bundled-dsh-badge-skill.md) | 中文
 
 ## 问题
 
-[Cordis 教程](../../../../docs/cordis-tutorial/index.md)的各个页面都使用官方「powered by dsh」徽章,但交付的 CLI(命令行界面)既没有用于在其他位置应用同样署名的可复用指令,也没有可显式选择加入的提供方。
+[Cordis 教程](../../../../docs/cordis-tutorial/index.zh.md)的各个页面都使用官方「powered by dsh」徽章,但交付的 CLI(命令行界面)既没有用于在其他位置应用同样署名的可复用指令,也没有可显式选择加入的提供方。
 
 ## 决策
 

+ 6 - 0
.agents/notes/archived/feature/2026-08-07-workspace-picker-composer-entry.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-07-workspace-picker-composer-entry.md: 023cbe09dd75015a1555103642d1b66ce75aafc9
+2026-08-07-workspace-picker-composer-entry.zh.md: 6b84885b11fb5372a51d620b40ea7d24fe7e45a2

+ 1 - 0
.agents/notes/implemented/feature/2026-08-07-workspace-picker-composer-entry.md → .agents/notes/archived/feature/2026-08-07-workspace-picker-composer-entry.md

@@ -1,6 +1,7 @@
 # Agent Note: The no-Workspace composer opens the existing picker
 
 Status: implemented
+Archived: 2026-08-22
 
 English | [中文](2026-08-07-workspace-picker-composer-entry.zh.md)
 

+ 2 - 1
.agents/notes/implemented/feature/2026-08-07-workspace-picker-composer-entry.zh.md → .agents/notes/archived/feature/2026-08-07-workspace-picker-composer-entry.zh.md

@@ -1,12 +1,13 @@
 # Agent Note: 未选择 Workspace 时从编辑器打开现有选择器
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-07-workspace-picker-composer-entry.md) | 中文
 
 ## 问题
 
-[Session scope 决策](../architecture/2026-07-25-web-client-session-scope-and-provide-channel.md)会在 Workspace 存在前保留同一个常驻编辑器,但 textarea 处于禁用状态,只有较小的 Workspace chip 能打开选择器。用户首次点击最显眼、也最熟悉的输入区域时,界面不会响应,尽管同一界面已有继续操作的入口。
+[Session scope 决策](../architecture/2026-07-25-web-client-session-scope-and-provide-channel.zh.md)会在 Workspace 存在前保留同一个常驻编辑器,但 textarea 处于禁用状态,只有较小的 Workspace chip 能打开选择器。用户首次点击最显眼、也最熟悉的输入区域时,界面不会响应,尽管同一界面已有继续操作的入口。
 
 ## 决策
 

+ 6 - 0
.agents/notes/archived/feature/2026-08-10-creator-guidance-introduce-cue.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-10-creator-guidance-introduce-cue.md: 2954bb9dca6bd5359ab3ed4b7e32bd8336709a10
+2026-08-10-creator-guidance-introduce-cue.zh.md: 4f818b3a444cbc7bbd4355ac8e7a883aaa4bfa51

+ 1 - 0
.agents/notes/implemented/feature/2026-08-10-creator-guidance-introduce-cue.md → .agents/notes/archived/feature/2026-08-10-creator-guidance-introduce-cue.md

@@ -1,6 +1,7 @@
 # Agent Note: Creator guidance lands as an introduce cue on the preset chip
 
 Status: implemented
+Archived: 2026-08-22
 
 English | [中文](2026-08-10-creator-guidance-introduce-cue.zh.md)
 

+ 1 - 0
.agents/notes/implemented/feature/2026-08-10-creator-guidance-introduce-cue.zh.md → .agents/notes/archived/feature/2026-08-10-creator-guidance-introduce-cue.zh.md

@@ -1,6 +1,7 @@
 # Agent Note: 创造模式引导以介绍动效落在预设 chip 上
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-10-creator-guidance-introduce-cue.md) | 中文
 

+ 6 - 0
.agents/notes/archived/feature/2026-08-11-collapsible-ask-user-question-card.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-11-collapsible-ask-user-question-card.md: 08e87b0d1f05f47c5bc87ef9b32cab05ef229e5c
+2026-08-11-collapsible-ask-user-question-card.zh.md: fd3b838ff174dcdb3d4994fe30b193d63f5c4d15

+ 1 - 0
.agents/notes/implemented/feature/2026-08-11-collapsible-ask-user-question-card.md → .agents/notes/archived/feature/2026-08-11-collapsible-ask-user-question-card.md

@@ -1,6 +1,7 @@
 # Agent Note: Collapsible Ask-User Question Card
 
 Status: implemented
+Archived: 2026-08-22
 
 English | [中文](2026-08-11-collapsible-ask-user-question-card.zh.md)
 

+ 1 - 0
.agents/notes/implemented/feature/2026-08-11-collapsible-ask-user-question-card.zh.md → .agents/notes/archived/feature/2026-08-11-collapsible-ask-user-question-card.zh.md

@@ -1,6 +1,7 @@
 # Agent Note: 可收起的提问卡片
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-11-collapsible-ask-user-question-card.md) | 中文
 

+ 6 - 0
.agents/notes/archived/feature/2026-08-11-web-export-command-and-dialog.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-11-web-export-command-and-dialog.md: aba9048f26237ea01e861a5ee6e31b89429629c8
+2026-08-11-web-export-command-and-dialog.zh.md: be4a3a53b1ff75cfbe176e258fb6a73e5abfee22

+ 1 - 0
.agents/notes/implemented/feature/2026-08-11-web-export-command-and-dialog.md → .agents/notes/archived/feature/2026-08-11-web-export-command-and-dialog.md

@@ -1,6 +1,7 @@
 # Agent Note: Web `/export` shares the streamed Session ZIP download
 
 Status: implemented
+Archived: 2026-08-22
 
 English | [中文](2026-08-11-web-export-command-and-dialog.zh.md)
 

+ 1 - 0
.agents/notes/implemented/feature/2026-08-11-web-export-command-and-dialog.zh.md → .agents/notes/archived/feature/2026-08-11-web-export-command-and-dialog.zh.md

@@ -1,6 +1,7 @@
 # Agent Note: Web `/export` 共用流式 Session ZIP 下载
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-11-web-export-command-and-dialog.md) | 中文
 

+ 6 - 0
.agents/notes/archived/feature/2026-08-18-product-subagent-failure-facts.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write .agents/notes/archived/feature/2026-08-18-product-subagent-failure-facts.md
+2026-08-18-product-subagent-failure-facts.md: b1d80cf66172ac67d38dbad873fa4cbd970a775c
+2026-08-18-product-subagent-failure-facts.zh.md: df4b14b4a243f7768240678b8d434c7aef7d48a7

+ 81 - 0
.agents/notes/archived/feature/2026-08-18-product-subagent-failure-facts.md

@@ -0,0 +1,81 @@
+# Agent Note: Product subagents expose bounded structured failure facts
+
+Status: implemented
+Archived: 2026-08-21
+
+English | [中文](2026-08-18-product-subagent-failure-facts.zh.md)
+
+## Problem
+
+The [Claude Code and Codex product providers](2026-08-04-claude-code-and-codex-subagent-backends.md) receive structured product failures, but a published run historically flattened most of them to the shared `error` stop reason. Product logs retained detail that the foreground parent and a [one-shot background Job](2026-08-12-product-subagent-one-shot-background-tasks.md) could not use to distinguish a product limit, an execution failure, or an early process exit.
+
+Copying SDK error text, app-server payloads, or stderr into the result would expose task text, paths, environment values, credentials, or product internals. Adding shared error fields would also make the provider-neutral [subagent seam](2026-06-21-subagent-capability-seam.md) own product version vocabularies that change independently.
+
+## Decision
+
+Each product Provider owns the mapping from its pinned official structured failures, current operation, and managed process outcome to one fixed safe diagnostic line. `SubagentResult` remains unchanged: consumers receive the existing bounded `diagnostic` string and do not parse its product-private fields. The [minimal-diagnostics decision](../simplification/2026-08-21-product-subagent-minimal-diagnostics.md) supersedes this note's complete Claude Code subtype mirror; this note continues to own the current detailed Codex categories until that provider adopts the same simplification.
+
+### Safe diagnostic
+
+The structured line has this fixed order:
+
+```text
+Product subagent failure (product: <product>; stage: <stage>; category: <category>; HTTP status: <status>; exit code: <code>; signal: <signal>)
+```
+
+The Provider omits unavailable optional fields. Exit code and signal are independent facts and are each retained when observed. A contributing permission decision from the [non-interactive permissions decision](2026-08-15-product-subagent-noninteractive-permissions.md) follows the structured line; the latest safe permission fact remains operation-local. The shared result boundary limits the complete text to 4096 UTF-8 bytes.
+
+Successful results and local cancellation expose no failure fact. Raw product errors, stderr, tool input, paths, environment values, credentials, and protocol payloads never enter the diagnostic. Startup and cleanup rejections use the same safe line in their Error message. Original failures remain on internal cause chains; Provider Host logs and forwarded stderr remain product-local observation only.
+
+### Claude Code facts
+
+The [minimal-diagnostics decision](../simplification/2026-08-21-product-subagent-minimal-diagnostics.md) exclusively owns Claude Code categories, stages, process facts, permission ordering, and verification for Agent SDK 0.3.241 and Claude Code 2.1.241. This note carries no separate Claude category contract.
+
+### Codex facts
+
+Codex app-server 0.147.0 defines eleven string categories and five object variants. The Provider preserves `contextWindowExceeded`, `sessionBudgetExceeded`, `usageLimitExceeded`, `serverOverloaded`, `cyberPolicy`, `internalServerError`, `unauthorized`, `badRequest`, `threadRollbackFailed`, `sandboxError`, and `other`. It also preserves `httpConnectionFailed`, `responseStreamConnectionFailed`, `responseStreamDisconnected`, `responseTooManyFailedAttempts`, and `activeTurnNotSteerable`; the four connection/stream variants retain numeric `httpStatusCode`, while the active-turn variant does not expose `turnKind`. Unknown strings, objects with another variant set, malformed values, and unclassified exceptions use `unknown`.
+
+| Stage | Owned operation | Observable failure |
+| --- | --- | --- |
+| `initialize` | App-server spawn and initialize/initialized handshake | `start()` rejects with fixed safe facts and any process outcome already observed |
+| `thread-start` | Ephemeral `thread/start` request and response validation | `start()` rejects with the thread stage and any available process outcome |
+| `turn-start` | Published `turn/start` request, provisional ids, and early frames | The run resolves as `error` with a safe unknown fallback when no structured category exists |
+| `turn` | Terminal notification, final-answer selection, and error-info mapping | The complete category and optional HTTP status reach the non-completed result |
+| `process` | Managed app-server exits before another terminal path settles | The run resolves as `error` with `process-exit` and any available code and signal |
+| `teardown` | Wire close and process-tree release | `dispose()` rejects independently; startup rollback aggregation exposes both startup and teardown lines |
+
+`contextWindowExceeded` remains `max-tokens`; every other known or unknown Codex category remains `error`, and `cyberPolicy` does not become `refusal`.
+
+### Ownership and lifecycle
+
+| Fact or resource | Owner | Consumer behavior |
+| --- | --- | --- |
+| Codex error category | Codex Provider over its pinned official app-server | The Provider preserves its current structured category and uses `unknown` outside the recognized set |
+| Current failure stage | Product Provider operation | Derived at the failure site; never persisted or used as a recovery state |
+| Exit code and signal | `dsh-subprocess` process handle | The Provider displays observed values without inferring missing ones |
+| Diagnostic bytes and delivery | `dsh-subagent`, foreground tool, and Job runtime | The same bounded text is presented separately from assistant output in both scheduling modes |
+| Raw product failure | Product runtime, internal cause chain, and Host observation | It remains internal and never becomes model-visible result text |
+
+## Verification
+
+Claude Code verification is owned by the [minimal-diagnostics decision](../simplification/2026-08-21-product-subagent-minimal-diagnostics.md). Codex package tests pin all sixteen current error-info variants, HTTP status presence and absence, all six stages, unknown fallback, stop-reason preservation, permission ordering, sanitization, cancellation, concurrency, and cleanup aggregation. The real app-server fixture produces an actual Codex `internalServerError` and covers process/protocol failure and whole-tree quiescence. The keyless ACP snapshot records the Codex diagnostic in foreground error output, a background completion notice, and `job_output`.
+
+## Alternatives considered
+
+**Return raw SDK errors, app-server payloads, or stderr.** These values can contain commands, paths, workspace content, environment values, credentials, or upstream prose. A fixed allowlisted mapping preserves actionable facts without expanding the model-visible trust boundary.
+
+**Add a shared product-error enum or structured result fields.** Claude Code and Codex version their error unions independently. A shared enum would duplicate those authorities and force unrelated Providers and consumers to track product releases.
+
+**Parse generic stderr and exception messages.** Free-form text is neither stable nor safe. Only pinned structured product fields and the managed process outcome qualify as diagnostic input.
+
+**Persist stages or add a recovery controller.** The stage is derived from the current call site only when a failure is reported. Persistence, retries, resume, and remediation need separate ownership and user contracts.
+
+**Map product limits to new shared stop reasons.** Claude Code turn and budget limits are not token-window exhaustion, and an error category does not establish refusal semantics. Existing stop reasons remain unchanged.
+
+## Consequences
+
+The parent can distinguish the current Codex budget, usage, service, policy, request, connection, stream, rollback, sandbox, and active-turn categories without receiving raw product text. The [minimal-diagnostics decision](../simplification/2026-08-21-product-subagent-minimal-diagnostics.md) owns the corresponding Claude result. Foreground and background scheduling preserve the same fact because both consume one `SubagentResult`.
+
+The diagnostic is display text rather than a new public protocol. Callers may present it but must not branch on its punctuation or product-private category names. A pinned product-version upgrade revalidates the Provider mapping and evidence without requiring every official error member to remain model-visible.
+
+This decision adds no product session persistence, retry policy, recovery state, stderr classifier, authentication or configuration taxonomy, progress stream, or human interaction path.

+ 81 - 0
.agents/notes/archived/feature/2026-08-18-product-subagent-failure-facts.zh.md

@@ -0,0 +1,81 @@
+# Agent Note: 产品 subagent 公开有界结构化失败事实
+
+Status: implemented
+Archived: 2026-08-21
+
+[English](2026-08-18-product-subagent-failure-facts.md) | 中文
+
+## Problem
+
+[Claude Code 与 Codex 产品提供方](2026-08-04-claude-code-and-codex-subagent-backends.zh.md)会收到结构化产品失败,但已发布运行以往会把其中大多数压成共享的 `error` 终止原因。产品日志保留了细节,前台父 agent 与[一次性后台 Job](2026-08-12-product-subagent-one-shot-background-tasks.zh.md)却无法据此区分产品限制、执行失败或进程提前退出。
+
+若把 SDK 错误文本、app-server payload 或 stderr 复制进结果,就会暴露任务文本、路径、环境值、凭证或产品内部信息。若增加共享错误字段,又会让提供方无关的 [subagent seam](2026-06-21-subagent-capability-seam.zh.md)拥有彼此独立变化的产品版本词汇。
+
+## Decision
+
+每个产品提供方分别拥有从锁定版本官方结构化失败、当前操作和受管进程结果到一行固定安全诊断的映射。`SubagentResult` 保持不变:消费方仍接收现有的有界 `diagnostic` 字符串,而且不解析其中由产品私有的字段。[最小诊断决策](../simplification/2026-08-21-product-subagent-minimal-diagnostics.zh.md)已经取代本说明对 Claude Code 完整 subtype 的镜像;在 Codex 采用同一简化前,本说明继续负责其当前详细类别。
+
+### 安全诊断
+
+结构化行采用以下固定顺序:
+
+```text
+Product subagent failure (product: <product>; stage: <stage>; category: <category>; HTTP status: <status>; exit code: <code>; signal: <signal>)
+```
+
+提供方会省略不可用的可选字段。退出码与信号是相互独立的事实,只要已观测到就分别保留。来自[非交互权限决策](2026-08-15-product-subagent-noninteractive-permissions.zh.md)且参与失败的权限决定会跟在结构化行之后;最新的安全权限事实仍只属于当前操作。共享结果边界会把完整文本限制在 4096 个 UTF-8 字节以内。
+
+成功结果与本地取消都不公开失败事实。原始产品错误、stderr、工具输入、路径、环境值、凭证和协议 payload 绝不会进入诊断。启动与清理拒绝会在 Error 消息中使用同一安全行。原始失败保留在内部 cause 链中;提供方 Host 日志与转发的 stderr 也只作为产品本地观测。
+
+### Claude Code 事实
+
+[最小诊断决策](../simplification/2026-08-21-product-subagent-minimal-diagnostics.zh.md)独占负责 Agent SDK 0.3.241 与 Claude Code 2.1.241 的 Claude Code 类别、阶段、进程事实、权限顺序与验证。本说明不再承载独立的 Claude 类别约定。
+
+### Codex 事实
+
+Codex app-server 0.147.0 定义十一种字符串类别与五种对象 variant。提供方会保留 `contextWindowExceeded`、`sessionBudgetExceeded`、`usageLimitExceeded`、`serverOverloaded`、`cyberPolicy`、`internalServerError`、`unauthorized`、`badRequest`、`threadRollbackFailed`、`sandboxError` 和 `other`。它还会保留 `httpConnectionFailed`、`responseStreamConnectionFailed`、`responseStreamDisconnected`、`responseTooManyFailedAttempts` 与 `activeTurnNotSteerable`;四种连接/stream variant 会保留数值 `httpStatusCode`,而 active-turn variant 不公开 `turnKind`。未知字符串、同时含其他 variant 的对象、格式错误值与未分类异常统一使用 `unknown`。
+
+| 阶段 | 归属操作 | 可观察失败 |
+| --- | --- | --- |
+| `initialize` | App-server spawn 与 initialize/initialized 握手 | `start()` 以固定安全事实和已经观测到的进程结果拒绝 |
+| `thread-start` | 临时 `thread/start` 请求与响应校验 | `start()` 以线程阶段和可用进程结果拒绝 |
+| `turn-start` | 已发布 `turn/start` 请求、暂定 id 与早到 frame | 没有结构化类别时,运行以 `error` 和安全 unknown 回退兑现 |
+| `turn` | 终态通知、最终答案选择与 error-info 映射 | 完整类别与可选 HTTP status 进入非完成结果 |
+| `process` | 受管 app-server 在另一终态路径结算前退出 | 运行以 `error` 兑现,并携带 `process-exit` 以及可用的退出码与信号 |
+| `teardown` | Wire 关闭与进程树释放 | `dispose()` 独立拒绝;启动回滚聚合会同时公开启动与 teardown 两行 |
+
+`contextWindowExceeded` 仍是 `max-tokens`;其他所有已知或未知 Codex 类别仍是 `error`,`cyberPolicy` 不会变成 `refusal`。
+
+### 所有权与生命周期
+
+| 事实或资源 | Owner | 消费方行为 |
+| --- | --- | --- |
+| Codex 错误类别 | Codex 提供方及其锁定的官方 app-server | 提供方保留当前结构化类别,并在已识别集合之外使用 `unknown` |
+| 当前失败阶段 | 产品提供方操作 | 只在失败点派生;绝不持久化,也不作为恢复状态 |
+| 退出码与信号 | `dsh-subprocess` 进程句柄 | 提供方展示已观测值,不推测缺失值 |
+| 诊断字节与送达 | `dsh-subagent`、前台工具与 Job 运行时 | 两种调度模式都把同一份有界文本与 assistant 输出分开呈现 |
+| 原始产品失败 | 产品运行时、内部 cause 链与 Host 观测 | 只保留在内部,绝不成为模型可见的结果文本 |
+
+## Verification
+
+Claude Code 验证由[最小诊断决策](../simplification/2026-08-21-product-subagent-minimal-diagnostics.zh.md)负责。Codex 包测试固定当前全部十六种 error-info variant、HTTP status 存在与缺失、六个阶段、unknown 回退、终止原因保持不变、权限顺序、脱敏、取消、并发与清理聚合。真实 app-server fixture 会产生实际 Codex `internalServerError`,并覆盖进程/协议失败与整棵进程树完全停稳。无密钥 ACP snapshot 会在前台错误输出、后台完成通知和 `job_output` 中记录 Codex 诊断。
+
+## Alternatives considered
+
+**返回原始 SDK 错误、app-server payload 或 stderr。** 这些值可能包含命令、路径、工作区内容、环境值、凭证或上游文本。固定白名单映射可以保留可操作事实,同时不扩大模型可见的信任边界。
+
+**增加共享产品错误 enum 或结构化结果字段。** Claude Code 与 Codex 各自独立版本化错误联合。共享 enum 会复制这些权威,并迫使无关提供方和消费方跟随产品版本。
+
+**解析通用 stderr 与异常消息。** 自由文本既不稳定也不安全。只有锁定版本产品提供的结构化字段和受管进程结果可以成为诊断输入。
+
+**持久化阶段或增加恢复控制器。** 阶段只在报告失败时从当前调用点派生。持久化、重试、resume 与修复需要独立的所有权和用户约定。
+
+**把产品限制映射为新的共享终止原因。** Claude Code 的轮次和预算限制并不表示 token 窗口耗尽,错误类别也不能证明拒绝语义。既有终止原因保持不变。
+
+## Consequences
+
+父 agent 可以区分当前 Codex 的预算、用量、服务、策略、请求、连接、stream、回滚、sandbox 与 active-turn 类别,而不会收到原始产品文本。[最小诊断决策](../simplification/2026-08-21-product-subagent-minimal-diagnostics.zh.md)负责对应的 Claude 结果。前台与后台调度会保留同一事实,因为二者都消费同一个 `SubagentResult`。
+
+诊断只是展示文本,不是新的公开协议。调用方可以呈现它,但不得根据其标点或产品私有类别名称进行分支。锁定产品版本升级时必须重新验证提供方映射与证据,但不要求每个官方错误成员都继续模型可见。
+
+本决策不增加产品会话持久化、重试策略、恢复状态、stderr 分类器、身份验证或配置分类体系、进度流或人工交互路径。

+ 6 - 0
.agents/notes/archived/feature/2026-08-18-web-home-path-tilde.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-18-web-home-path-tilde.md: 108674740c804a42ec3b0491505186215a9d9fcd
+2026-08-18-web-home-path-tilde.zh.md: 1f742158f62b9b7fbb8eae8be35c13adc95f3a09

+ 38 - 0
.agents/notes/archived/feature/2026-08-18-web-home-path-tilde.md

@@ -0,0 +1,38 @@
+# Agent Note: Web UI abbreviates POSIX home paths as `~`
+
+Status: implemented
+Archived: 2026-08-22
+
+English | [中文](2026-08-18-web-home-path-tilde.zh.md)
+
+## Problem
+
+Workspace hover cards and Tool call summaries showed full POSIX home paths. Those strings are long, repeat the same prefix on every row, and make the sidebar and transcript harder to scan. Windows paths must stay verbatim because `~` is not a Windows filesystem convention.
+
+## Decision
+
+`host.describe` reports the host account `home` as a required field. Client and Host ship together, so the field is required rather than optional. ApiProxy fills it from `homedir()` at describe time.
+
+`abbreviateHomePath` in `dsh-client-runtime` is the display-only helper. It returns `~` or `~/…` when the path is the POSIX home or a descendant, and leaves the path unchanged when `home` is missing, empty, or `/`, when either value is a Windows drive or UNC path, or when the match is only a prefix (`/Users/u` does not claim `/Users/u2`). Tool summaries run workspace-relative shortening first, then this helper, so a path inside the session cwd stays short. `filePath`, Host open, and Workspace hover copy keep the authored filesystem path.
+
+`ui-tool` and `ui-workspace` inject `connection.hostDescription` at their own slot registrations. ChatView does not grow a Host-description hook. The field is required on `ConnectionHandle`; test fakes supply a source whose snapshot may be undefined before connect.
+
+The fixture Host home is `/home/fixture`. A second fixture Workspace at `/home/fixture/Documents/project` lets assembled replay hover `~/Documents/project` without moving the existing `/tmp/fixture` account. TerminalBlock's own prompt-label collapse is unchanged.
+
+## Alternatives considered
+
+**Guess `/Users` or `/home` without the real home.** Rejected because a shared prefix is not an account home, and `/Users/shared` or `/home/src` would abbreviate incorrectly.
+
+**Abbreviate Windows `%USERPROFILE%` as `~` as well.** Rejected because the acceptance rule keeps Windows paths verbatim, and `~` is not how Explorer or `cmd` spell those paths.
+
+**Put the helper in `dsh-home-paths`.** Rejected because that package expands configuration tildes on Node; this helper is a browser display rewrite and must not pull Node `os` into client bundles.
+
+**Thread `home` from ChatView owner props.** Rejected because it enlarges the conversation inject face and every ChatView test harness for a display fact only Tool and Workspace cards consume.
+
+## Consequences
+
+POSIX home-rooted Workspace hover paths and leftover Tool path summaries display as `~`. Copy and open still use the full path. Windows drive and UNC paths never become `~`. A Host that reports `/` as home does not turn the whole filesystem into `~`. Before the first describe, or while reconnecting, the source snapshot is undefined and paths stay unabbreviated.
+
+## Testing
+
+Package tests cover `abbreviateHomePath`, `toolRowModel` / `readCardModel` home abbreviation, Workspace hover display versus copy, and `host.describe` schema plus live `homedir()`. Assembled replay `apps/web/tests/home-path-tilde.snapshot.ts` hovers the fixture home-descendant Workspace. Product-GUI PRs still record a real-browser GIF of the hover card.

+ 38 - 0
.agents/notes/archived/feature/2026-08-18-web-home-path-tilde.zh.md

@@ -0,0 +1,38 @@
+# Agent Note: Web UI abbreviates POSIX home paths as `~`
+
+Status: implemented
+Archived: 2026-08-22
+
+[English](2026-08-18-web-home-path-tilde.md) | 中文
+
+## Problem
+
+Workspace 悬停卡片和 Tool 调用摘要会显示完整的 POSIX 家目录路径。这些字符串很长,每行重复同一前缀,侧边栏和对话记录更难扫读。Windows 路径必须保持原样,因为 `~` 不是 Windows 文件系统约定。
+
+## Decision
+
+`host.describe` 把宿主账户的 `home` 作为必填字段上报。Client 与 Host 一同发布,因此该字段是必填而不是可选。ApiProxy 在 describe 时用 `homedir()` 填入。
+
+`dsh-client-runtime` 中的 `abbreviateHomePath` 是仅用于展示的辅助函数。当路径是 POSIX 家目录或其后代时返回 `~` 或 `~/…`;`home` 缺失、为空或为 `/`,任一侧是 Windows 盘符或 UNC 路径,或只是前缀命中(`/Users/u` 不能收走 `/Users/u2`)时,路径保持不变。Tool 摘要先做工作区相对缩短,再调用该辅助函数,因此会话 cwd 内的路径仍然更短。`filePath`、Host 打开以及 Workspace 悬停复制仍使用作者给出的文件系统路径。
+
+`ui-tool` 与 `ui-workspace` 在各自的 slot 注册上注入 `connection.hostDescription`。ChatView 不增加 Host 描述钩子。该字段在 `ConnectionHandle` 上是必填的;测试假对象提供一个来源,其快照在连接完成前可以为 undefined。
+
+fixture 的 Host 家目录是 `/home/fixture`。第二个 fixture Workspace 位于 `/home/fixture/Documents/project`,组装回放可以悬停出 `~/Documents/project`,而不必移动现有的 `/tmp/fixture` 账户。TerminalBlock 自有的提示符标签折叠保持不变。
+
+## Alternatives considered
+
+**在没有真实 home 的情况下猜测 `/Users` 或 `/home`。** 否决,因为共享前缀不是账户家目录,`/Users/shared` 或 `/home/src` 会被错误缩写。
+
+**同样把 Windows `%USERPROFILE%` 缩写成 `~`。** 否决,因为验收规则要求 Windows 路径保持原样,而且 Explorer 与 `cmd` 并不这样拼写这些路径。
+
+**把辅助函数放进 `dsh-home-paths`。** 否决,因为该包在 Node 上展开配置里的波浪号;本辅助函数是浏览器展示改写,不能把 Node `os` 拉进 client 包。
+
+**从 ChatView owner props 向下传递 `home`。** 否决,因为它会扩大 conversation 注入面和每一份 ChatView 测试夹具,而只有 Tool 与 Workspace 卡片消费这个展示事实。
+
+## Consequences
+
+POSIX 家目录下的 Workspace 悬停路径,以及缩短 cwd 后仍落在家目录里的 Tool 路径摘要,会显示为 `~`。复制与打开仍使用完整路径。Windows 盘符和 UNC 路径永远不会变成 `~`。若 Host 把 `/` 报成 home,不会把整个文件系统收成 `~`。首次 describe 之前或重连期间,来源快照为 undefined,路径保持未缩写。
+
+## Testing
+
+包测试覆盖 `abbreviateHomePath`、`toolRowModel`/`readCardModel` 的家目录缩写、Workspace 悬停展示与复制,以及 `host.describe` schema 与实时 `homedir()`。组装回放 `apps/web/tests/home-path-tilde.snapshot.ts` 悬停 fixture 中位于家目录下的 Workspace。面向产品 GUI 的 PR 仍需录制悬停卡片的真实浏览器 GIF。

+ 6 - 0
.agents/notes/archived/feature/2026-08-19-high-cache-hit-decimal-display.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-19-high-cache-hit-decimal-display.md: 83c031bd1049ec26029d2e9ba0dc5cd623c3f867
+2026-08-19-high-cache-hit-decimal-display.zh.md: 62f27e39d37cf2445ac6796030092e892d82b581

+ 51 - 0
.agents/notes/archived/feature/2026-08-19-high-cache-hit-decimal-display.md

@@ -0,0 +1,51 @@
+# Agent Note: High cache-hit decimal display
+
+Status: implemented
+Archived: 2026-08-22
+
+English | [中文](2026-08-19-high-cache-hit-decimal-display.zh.md)
+
+## Problem
+
+The Web conversation stats line rounded every non-empty cache-hit ratio to an integer. Once the actual ratio passed 99%, the display hid further progress, and a ratio of at least 99.5% appeared as 100% even while uncached input or cache writes remained.
+
+Users therefore could not distinguish a nearly complete cache hit from a true full hit.
+
+## Decision
+
+`StatsLine` continues to derive the ratio from the whole-session `tokenUsage` projection owned by `@deepseek-ai/dsh-token-meter`; the projection remains the only owner of the uncached-input, cache-read, cache-write, and output counts ([projection decision](../architecture/2026-07-29-projected-token-usage-and-request-context.md)). The presentation layer changes only the text inserted into the existing `stats.cacheHit` locale template.
+
+| Actual ratio | Display |
+|---|---|
+| No billed input | Cache-hit group omitted |
+| Integer rounding is below 100% | Rounded integer |
+| Non-full ratio whose current rounding is 100% | Minimum decimal precision whose rounded result is below 100% |
+| 100% | `100%` |
+
+Every non-empty ratio starts at zero decimal places. A non-full ratio increases precision one place at a time only while rounding would produce 100%, so `99.1%` and `99.49%` remain `99%`, while `99.5%`, `99.95%`, and `99.995%` retain one, two, and three decimal places respectively. `StatsLine` uses exact small-factor comparisons over the safe-integer token counts, then scales the near-full gap only while the intermediate remains within that range. This avoids floating-point tie errors without imposing a precision cap or substitute label. A full hit does not carry a redundant decimal. The same derived string feeds the inline row and its overflow tooltip.
+
+## Ownership and lifecycle
+
+Token-meter continues to fold usage from the complete durable session log. `StatsLine` performs a synchronous display derivation whenever the standard projection value changes. It introduces no setting, stored percentage, event, wire field, client state, or recovery path.
+
+Live updates, reload replay, and reconnect recovery all restore the same `tokenUsage` counts and run the same display function. A missing projection still omits every token group, and a zero input denominator still omits only the cache-hit group.
+
+## Verification
+
+The component spec pins the zero denominator, ordinary integer rounding, half-step rounding at several decimal precisions, each precision boundary through three decimal places, a near-full cumulative sample that needs fourteen decimal places, the true `100%` result, both locales, and equality between inline and tooltip values. The assembled `lifecycle-chrome` replay sidecar selects `9,950 / 10,000 = 99.5%` as a deterministic ratio that integer rounding would misreport as 100% while the base session fixture remains recordable; the live assertion and post-reload browser snapshot both display `99.5%` without another model call.
+
+## Alternatives considered
+
+**Keep integer rounding for every ratio.** Rejected because it hides all movement above 99% and still reports some non-full hits as 100%.
+
+**Truncate the high band to one decimal.** Rejected because `99.95%`, `99.995%`, and still closer ratios all collapse to `99.9%` instead of retaining the minimum precision that distinguishes them from a full hit.
+
+**Cap precision and use a substitute such as `<100%`.** Rejected because the exact cumulative counts can produce the required numeric result, and a cap would make display behavior depend on an arbitrary presentation limit.
+
+**Show one decimal at every ratio.** Rejected because the additional low-band motion adds noise and changes the established display where integer precision is sufficient.
+
+**Persist a display percentage in token-meter.** Rejected because the projection already carries the exact counts, while presentation precision belongs to the Web stats line. A second stored value would duplicate derivable state and expand replay and wire responsibilities.
+
+## Consequences
+
+High cache-hit sessions remain visually stable until integer rounding would falsely report a full hit, then expose only the decimal places needed to preserve that distinction. Extremely close non-full ratios can therefore produce long decimal strings; this is the accepted cost of having no arbitrary precision cap or nonnumeric fallback. Every delivery and recovery path stays on the existing durable projection lifecycle.

+ 51 - 0
.agents/notes/archived/feature/2026-08-19-high-cache-hit-decimal-display.zh.md

@@ -0,0 +1,51 @@
+# Agent Note: 高缓存命中率的小数显示
+
+Status: implemented
+Archived: 2026-08-22
+
+[English](2026-08-19-high-cache-hit-decimal-display.md) | 中文
+
+## 问题
+
+Web 会话统计行会把所有非空缓存命中率舍入为整数。真实比率超过 99% 后,显示会隐藏后续提升;比率达到 99.5% 时,即使仍有未缓存输入或缓存写入,也会显示为 100%。
+
+用户因此无法区分接近完整的缓存命中与真实满命中。
+
+## 决策
+
+`StatsLine` 继续从 `@deepseek-ai/dsh-token-meter` 所拥有的完整会话 `tokenUsage` 投影派生比率;该投影仍是未缓存输入、缓存读取、缓存写入与输出计数的唯一所有方([投影决策](../architecture/2026-07-29-projected-token-usage-and-request-context.zh.md))。展示层只改变插入现有 `stats.cacheHit` locale 模板的文本。
+
+| 真实比率 | 显示结果 |
+|---|---|
+| 没有计费输入 | 省略缓存命中分组 |
+| 整数舍入结果低于 100% | 舍入后的整数 |
+| 当前舍入结果为 100% 的非满命中 | 舍入结果低于 100% 所需的最少小数位 |
+| 100% | `100%` |
+
+所有非空比率都从零位小数开始。非满命中只有在舍入结果会成为 100% 时才逐位增加精度,因此 `99.1%` 与 `99.49%` 仍显示为 `99%`,而 `99.5%`、`99.95%` 与 `99.995%` 分别保留一位、两位与三位小数。`StatsLine` 对安全整数 token 计数执行精确的小因子比较,并且只在中间值仍处于该范围内时缩放接近满命中的差值。该算法既避开浮点临界值误差,也不设置精度上限或替代文案。真实满命中不会携带多余的小数。同一份派生字符串同时用于行内统计与溢出 tooltip。
+
+## 归属与生命周期
+
+token-meter 继续从完整持久会话日志折叠用量。标准投影值变化时,`StatsLine` 同步派生显示文本。本决策不引入设置、持久百分比、事件、协议字段、客户端状态或恢复路径。
+
+实时更新、刷新回放与重连恢复都会还原同一组 `tokenUsage` 计数,并运行同一个显示函数。投影缺失时仍会省略全部 token 分组;输入分母为零时仍只省略缓存命中分组。
+
+## 验证
+
+组件测试固定了零分母、普通整数舍入、多个小数精度上的半步舍入、直至三位小数的各个精度边界、需要十四位小数的近满累计样本、真实 `100%`、两种 locale,以及行内值与 tooltip 值的一致性。组装后的 `lifecycle-chrome` replay sidecar 将 `9,950 / 10,000 = 99.5%` 选作确定性测试输入;该比率按整数舍入会误报为 100%,同时基础会话 fixture 仍可重录。活跃页面断言与刷新后的浏览器快照都会显示 `99.5%`,且不会产生额外模型调用。
+
+## 备选方案
+
+**对所有比率继续使用整数舍入。** 不予采纳,因为它会隐藏 99% 以上的全部变化,并继续把部分非满命中显示为 100%。
+
+**把高位区间向下截取到一位小数。** 不予采纳,因为 `99.95%`、`99.995%` 以及更接近满命中的比率都会坍缩为 `99.9%`,无法保留区分真实满命中所需的最少精度。
+
+**限制精度并使用 `<100%` 等替代文案。** 不予采纳,因为精确累计计数能够产生所需的数值结果,而精度上限会让显示行为依赖任意的展示限制。
+
+**所有比率都显示一位小数。** 不予采纳,因为低位区间的额外变化会增加无效抖动,并改变整数精度已经足够的既有显示。
+
+**在 token-meter 中持久化显示百分比。** 不予采纳,因为投影已经携带精确计数,而展示精度属于 Web 统计行。第二个持久值会复制可派生状态,并扩大回放与协议职责。
+
+## 后果
+
+高缓存命中率会保持稳定的整数显示,直到整数舍入会错误地报告满命中;此时界面只展示维持区分所需的小数位。极接近满命中的非满比率可能因此产生较长的小数字符串,这是不设置任意精度上限或非数值回退所接受的代价。所有交付与恢复路径继续沿用既有持久投影生命周期。

+ 82 - 1
.agents/notes/archived/manifest.json

@@ -25,6 +25,9 @@
     "architecture/2026-07-05-windows-fs-permissions.i18n.yaml": "sha256:7e61ee9bbd9de4bf3285a6f250d9625bd062e5fb90279dbffd64c820f1f7fe6b",
     "architecture/2026-07-05-windows-fs-permissions.md": "sha256:03734da511eae3b0736f7cad73d9da76ae2f69f9d5ed09089b0121ccb135a861",
     "architecture/2026-07-05-windows-fs-permissions.zh.md": "sha256:454848057ea905fe76c88d17264e71e71fb685f08f82088de6976878372865c3",
+    "architecture/2026-07-19-gui-layering-and-rpc-protocol.i18n.yaml": "sha256:855477999c84236430dc9308e16797eb21658a67a72b8537315c6964ff0c0c0a",
+    "architecture/2026-07-19-gui-layering-and-rpc-protocol.md": "sha256:3517f37e98e74865dced37d5e1559d443e8fa827031c8335e99a1e910586e9ac",
+    "architecture/2026-07-19-gui-layering-and-rpc-protocol.zh.md": "sha256:8181386d957fa6d6b3eb9b05d29adb10804b5a926853425415d368cc7fceaefa",
     "architecture/2026-07-22-tui-interactive-extension-service.i18n.yaml": "sha256:1b4822af5c8d642b73e3a0b04fb0a1dea9f50d0147046fbef53f5e49c030fb91",
     "architecture/2026-07-22-tui-interactive-extension-service.md": "sha256:ca6b2774f4821e66f7c8397f20fcd34926728ded853fa48cbe451db7a8d2f883",
     "architecture/2026-07-22-tui-interactive-extension-service.zh.md": "sha256:5b060c7626ee796c27108be7467a5e4be0677d7525d383336e7ec31ddce5c303",
@@ -43,6 +46,12 @@
     "architecture/2026-07-28-dsh-native-typescript-source-launch.i18n.yaml": "sha256:af071e07bce5d9bc8f3df65fed9dcd9b3779a98c5864badbd530363bda021b55",
     "architecture/2026-07-28-dsh-native-typescript-source-launch.md": "sha256:1b56e3454277ace713e2a01c4da538c756c45bf633fd24d7b16443d584afac5d",
     "architecture/2026-07-28-dsh-native-typescript-source-launch.zh.md": "sha256:8c0f97472c2c89d2c19ae5cfa68c6e67f32b50960b08b60b46496f78ea6ffad1",
+    "architecture/2026-08-04-websocket-downlink-carrier.i18n.yaml": "sha256:b9d742d068a0e36df2f3030f6a04a3638f3461f7e10b50ed0cd6bd5e85de5019",
+    "architecture/2026-08-04-websocket-downlink-carrier.md": "sha256:b9be27a4cda8abd410c6e8b728c571f96b4891eb003c5200e9a0ffbbc9145b42",
+    "architecture/2026-08-04-websocket-downlink-carrier.zh.md": "sha256:118b71b33710a7a3d28375c48b42c1ec19993ca7e13f286dd6ea64f934456f46",
+    "architecture/2026-08-11-plugin-settings-tabs.i18n.yaml": "sha256:0365da2b317fc5f94dd190064198565f4c624afc91d2e62161ab9170f79d11bc",
+    "architecture/2026-08-11-plugin-settings-tabs.md": "sha256:fdd92cfe55b6c4cd31b3f768dd46a2ecf129a04c9818249cbdd33857cf722bbf",
+    "architecture/2026-08-11-plugin-settings-tabs.zh.md": "sha256:8993df1a0178aba1ea35c460ee67c522900344a4b386287bba9dfac2bfb87efa",
     "bug-fix/2026-07-20-code-mode-result-card-completeness.i18n.yaml": "sha256:1035dae11d049d32ab09fd7d4f950eceae44bf46ba498b3cfaf3c75102b9fb64",
     "bug-fix/2026-07-20-code-mode-result-card-completeness.md": "sha256:6ca2c9d4df98be18813ef38b7462db880900b5bcd6944fbcd1b8f2258006b93e",
     "bug-fix/2026-07-20-code-mode-result-card-completeness.zh.md": "sha256:ed85fa7f935e5f525d566bc37a92014614983e649c75de9a9f244939097a7991",
@@ -85,6 +94,9 @@
     "bug-fix/2026-07-30-web-details-default-closed.i18n.yaml": "sha256:2af5559d727f3e4afdd4946eaf89ac212c81db611db78dbd9bfabb1c4661db17",
     "bug-fix/2026-07-30-web-details-default-closed.md": "sha256:27a280a817c8048718bb22927e7d9572cf99ffd0c044631e99e0fd6ea236876f",
     "bug-fix/2026-07-30-web-details-default-closed.zh.md": "sha256:e047c7d02cf4b95b0c7f78f4b79af254091294b05cc75e98a8bb860ae2074189",
+    "bug-fix/2026-07-31-composer-text-layers-share-one-scrollport.i18n.yaml": "sha256:36fc626dcbf1e276a36713e85860752cef0b36a5881f2493bdeb6d9654621b02",
+    "bug-fix/2026-07-31-composer-text-layers-share-one-scrollport.md": "sha256:3ece47f91ee5f7354ef73ca0562aafeec19f89a19d9a64c9e0a565fe6d8c2049",
+    "bug-fix/2026-07-31-composer-text-layers-share-one-scrollport.zh.md": "sha256:578e772ecbc1a4a39bddbb0a9f3fdbf67c70ff8c8952cc80d2caa3d8b76e9b36",
     "bug-fix/2026-07-31-hero-visible-while-blank-session-opens.i18n.yaml": "sha256:42218a762ce0141d3cb43deb6c688d3705cdc4405e03851d486c78f3d25b70ef",
     "bug-fix/2026-07-31-hero-visible-while-blank-session-opens.md": "sha256:a40992e89736131f5c487e5357848f14accd06e135dbec9ce242c968a5b11d43",
     "bug-fix/2026-07-31-hero-visible-while-blank-session-opens.zh.md": "sha256:e0cc576bc1c196affc9220ddabf15d735c347029c530c56454f0e585979101e1",
@@ -94,12 +106,33 @@
     "bug-fix/2026-08-03-tui-long-session-render-costs.i18n.yaml": "sha256:f65f7bf8fc84c7a1f022ee393c8d969c06d9bde8bed3a0206de86fb35b246ac6",
     "bug-fix/2026-08-03-tui-long-session-render-costs.md": "sha256:6ecf2ef831f527f361ade18a882d79bc6eccf15cc676d05728e7753f41cde051",
     "bug-fix/2026-08-03-tui-long-session-render-costs.zh.md": "sha256:5f44e707b332e13fa06d625212173ea055c1c3c0aee60888435a0ff099ec6037",
+    "bug-fix/2026-08-04-large-history-pagination-call-stack.i18n.yaml": "sha256:9bb1ceec013521116ee73eb9ec28c5708ae9520d6e53dcd4a3621fd2283b215c",
+    "bug-fix/2026-08-04-large-history-pagination-call-stack.md": "sha256:38c5afd347b131abd6b73634d25210d593bcb1fd72c7ba501bad0b33fb639810",
+    "bug-fix/2026-08-04-large-history-pagination-call-stack.zh.md": "sha256:2a2790b3b3400c747e20b998edfa96788b4035ccfa5fd4100dbc9a0e694ed30e",
+    "bug-fix/2026-08-06-plan-narrow-viewport-regression.i18n.yaml": "sha256:fe0539da9ce4015c6deaf585350e586e99d86e0073a36e131b6f1f62cc13382b",
+    "bug-fix/2026-08-06-plan-narrow-viewport-regression.md": "sha256:ccecdf52213dd1f6ab9935db31906520b83a7d9166f612376877d612230d1331",
+    "bug-fix/2026-08-06-plan-narrow-viewport-regression.zh.md": "sha256:be10805f0cd5a4f0812c883ab7f3e1e9396b579be455696d5cd726434a26b3e1",
     "bug-fix/2026-08-10-web-favicon-dark-mode.i18n.yaml": "sha256:859c4399f9a017a68ba89552fdafa05e73c0599d94cee9551c84ea5b749a14f3",
     "bug-fix/2026-08-10-web-favicon-dark-mode.md": "sha256:4d17e247abd76ae3aed5fb4e075fd66a2838292f89f7021c82a79fe37ed905e6",
     "bug-fix/2026-08-10-web-favicon-dark-mode.zh.md": "sha256:7bbff8a3b7061c127afcc75cd2a8043b02a999b78c0180edd8f7e4807fcfe71d",
+    "bug-fix/2026-08-11-preset-card-description-clamp.i18n.yaml": "sha256:d50452503b59aa22c81617888f9391f31f12a779c4b18efb2b4b6de1bd9702a6",
+    "bug-fix/2026-08-11-preset-card-description-clamp.md": "sha256:7eb8db697f3ad3dea8c0a6045331c05730a010404a89e2b08348cb7b0fad26c8",
+    "bug-fix/2026-08-11-preset-card-description-clamp.zh.md": "sha256:6d2f7b55ce02275a45adfdd853805e7daf2d6534929b77beb86685a54fc34f85",
     "bug-fix/2026-08-12-collapsed-sidebar-shared-entry-motion.i18n.yaml": "sha256:3ce4f6e39e173fc304bf64deca9c95bcddc1dbb492e065ca8c267a7a40788588",
     "bug-fix/2026-08-12-collapsed-sidebar-shared-entry-motion.md": "sha256:7b169aa4543edfc965de5a8b7b9e60aa9d9d5218693cd0b57908e2d482280723",
     "bug-fix/2026-08-12-collapsed-sidebar-shared-entry-motion.zh.md": "sha256:88db36c698800bf55c3c7531d6f92665576d978c29c15ff7d74215fb93376cb1",
+    "bug-fix/2026-08-13-safari-textarea-soft-wrap-reflow.i18n.yaml": "sha256:23c26323f92a2172fd30fd724177b84d012cf4e18f1eff79ab092d4e0687ad4e",
+    "bug-fix/2026-08-13-safari-textarea-soft-wrap-reflow.md": "sha256:f9edea8501df36d444d84790ef9b0ae5bed4283a9cc5a5403800b80908f3db39",
+    "bug-fix/2026-08-13-safari-textarea-soft-wrap-reflow.zh.md": "sha256:ddcf6bb67823d19dc98964fcb9d663a10bcf663573394cfd7b235d9801d6525a",
+    "bug-fix/2026-08-20-composer-edit-range-from-selection.i18n.yaml": "sha256:c91ed2d9cb2a9891011fcbbe46885bc1808e36831279d56bc5cea0b9b1515b55",
+    "bug-fix/2026-08-20-composer-edit-range-from-selection.md": "sha256:e36920dee0318a35eaf49bff8c574698902f3be51d6115d40a3f97fa1436bd47",
+    "bug-fix/2026-08-20-composer-edit-range-from-selection.zh.md": "sha256:41f44adc93797cf9073f19f954b6ac87147a2e6806f1ad051c80c3423f0175ae",
+    "bug-fix/2026-08-20-composer-reference-decoration-keys.i18n.yaml": "sha256:cadf1de336aa2756d1bc1c20c7679449390b0a7a4217fe9602996801b6bc1958",
+    "bug-fix/2026-08-20-composer-reference-decoration-keys.md": "sha256:0093eabd710f10ae1faca53be01c9404a9d63cf6a2cf4dbf226e458e6315e201",
+    "bug-fix/2026-08-20-composer-reference-decoration-keys.zh.md": "sha256:a5fb2a748cf6ff8353d536448a5469e731157ccc2d0bb43210ea5dc44dd8ed31",
+    "bug-fix/2026-08-24-system-prompt-section-order-ties.i18n.yaml": "sha256:f7a20bddd4544738ec0dbbfc52ea931f42317defa1674beb9a3c0daebd52fc2d",
+    "bug-fix/2026-08-24-system-prompt-section-order-ties.md": "sha256:108a97346eb7a62f1ab01f48dbb9fdd965e8991f53e382b0f501b916af0e9e23",
+    "bug-fix/2026-08-24-system-prompt-section-order-ties.zh.md": "sha256:3deaddfcf9736b3ff8d61b51093d7e46fdcc86103705033e4aa4c9d043794b16",
     "feature/2026-06-14-acp-agent-client-protocol.i18n.yaml": "sha256:006795baa43ae962a8d125cc0f1e9f134bc2ee9fb758b6e7669e3fa0126e1918",
     "feature/2026-06-14-acp-agent-client-protocol.md": "sha256:6828c0af74bb3fb96206ca6b21c0e56a000b50e4744aad4bc2c05092f3a5a31b",
     "feature/2026-06-14-acp-agent-client-protocol.zh.md": "sha256:ba104e841a1fb84edbd3b6c8119d50445b7785255a7a8d13bb9ac8a2cb4d2e69",
@@ -241,6 +274,9 @@
     "feature/2026-07-30-tui-details-command.i18n.yaml": "sha256:033cea6df0a16fc68cbdb435babdc6e75c1199a8e70e1a71d87c800c40f5a044",
     "feature/2026-07-30-tui-details-command.md": "sha256:a13478d4e55ec6d358209b51b541413ec75d0e20dfc22196ace28020f03f0c2d",
     "feature/2026-07-30-tui-details-command.zh.md": "sha256:de9c449b98468cef34ce4f9a9d2a854a5d8905eecd61f80e27a9a0e4495e9901",
+    "feature/2026-07-30-versioned-gui-welcome-onboarding.i18n.yaml": "sha256:3d453f1a8f1a642ed569d1900009b785e582614bcabf9fede566ecbd9842e3ef",
+    "feature/2026-07-30-versioned-gui-welcome-onboarding.md": "sha256:cfaa38cfec722ac3792a4770f7733372805a6c0571f4f08519f367976b0d2379",
+    "feature/2026-07-30-versioned-gui-welcome-onboarding.zh.md": "sha256:0ce0e4616580c583725aa3d28063dc009889d7f0a260a3cdda53ff48721c1ae4",
     "feature/2026-07-30-versioned-tui-first-run-welcome.i18n.yaml": "sha256:4c3fc380b0512ad7c00baacd0ac610e1a78ae45374311d9bd43bab6b5e29e630",
     "feature/2026-07-30-versioned-tui-first-run-welcome.md": "sha256:296f153e6c839f3743078e4f5aab3b2befc211c934835238668c57bdeae52231",
     "feature/2026-07-30-versioned-tui-first-run-welcome.zh.md": "sha256:82871a9cca1fec46bb08a5b39daad28a44bb2419dea367b4ae41af3cf07bfa65",
@@ -259,9 +295,33 @@
     "feature/2026-07-31-web-cards-toolrow.i18n.yaml": "sha256:f9a6ab72a77934cdcc02167c7313f08d7e9925362017b34bed7ad56c8c70fbaa",
     "feature/2026-07-31-web-cards-toolrow.md": "sha256:5058f7cec4497d1cb0a5c8e77b88fddacac6eead034f3edec88e8514919b8a3e",
     "feature/2026-07-31-web-cards-toolrow.zh.md": "sha256:ba84ef2e1be61211ab5ba6950b78ede3d3a979f252bc068d3e04e2c025f7bc03",
+    "feature/2026-08-06-bundled-dsh-badge-skill.i18n.yaml": "sha256:4b568d89976a71b7b3864e13b36925bf055479213739ffd4ac81614e00e93e36",
+    "feature/2026-08-06-bundled-dsh-badge-skill.md": "sha256:7b67f7c09b7e2b2ca756983a8951dad3a15786b8cd3adc6e819f316c67d31b2c",
+    "feature/2026-08-06-bundled-dsh-badge-skill.zh.md": "sha256:dcc0acb2dca596196ac034a8e86a644131c5b7fb09b184ec9d8493f93019d2b1",
+    "feature/2026-08-07-workspace-picker-composer-entry.i18n.yaml": "sha256:24a8bb2956371c7c840a662ac16dffbe04a6bb40a7296d01db86cb85da58d238",
+    "feature/2026-08-07-workspace-picker-composer-entry.md": "sha256:036212fbae6f5d7194e8c7fc9b1e7cd1c35251e9c227e895834a7d00bd5f69f8",
+    "feature/2026-08-07-workspace-picker-composer-entry.zh.md": "sha256:fb65c3330e8324f90d1270345e1ac941fc800e8caaf3b4bbee1bbb743f713262",
     "feature/2026-08-08-dsh-run-headless-command.i18n.yaml": "sha256:1c2b4c5b61b9263b6267275d6fc69faeaad3cc887f0728a7ed4172d817af812b",
     "feature/2026-08-08-dsh-run-headless-command.md": "sha256:7695fe7fd322377d5986f14e35f13337f4cd376405c758218a81230f6d182d1c",
     "feature/2026-08-08-dsh-run-headless-command.zh.md": "sha256:113c14a36c64d2facc8ae46f37c7aa76359d8cacb9c18fcba26a723f15d036fb",
+    "feature/2026-08-10-creator-guidance-introduce-cue.i18n.yaml": "sha256:74f519839f0cf82c7304bdeae41ae1cab8bb930bfb94f79ab44708acd3b72128",
+    "feature/2026-08-10-creator-guidance-introduce-cue.md": "sha256:3e25409dda498de150de18943ee332e1760963e377a40a365902b66f667fdc9f",
+    "feature/2026-08-10-creator-guidance-introduce-cue.zh.md": "sha256:203847010cab9e9d13c3969f17921d3a5aa0d69377eccfef555c7ff96572f162",
+    "feature/2026-08-11-collapsible-ask-user-question-card.i18n.yaml": "sha256:9c0873bbb1437bcd5025f5859e1dc447a6b936f19c2c2ad2250521a3aa773a12",
+    "feature/2026-08-11-collapsible-ask-user-question-card.md": "sha256:4f3b3f5d7020fefbbac8a3c36a97642721ef14a0476a7d8117bde8a128d25f42",
+    "feature/2026-08-11-collapsible-ask-user-question-card.zh.md": "sha256:e7186c92f77d337a875f981ae39b16331a1c5466a948415bcacfe108ad98fb63",
+    "feature/2026-08-11-web-export-command-and-dialog.i18n.yaml": "sha256:db7d523a2a1f82a86f532661bd2953ee8538d971d91f886e4bd4e0d88f7226b2",
+    "feature/2026-08-11-web-export-command-and-dialog.md": "sha256:ec44b47589ca7924018dc24f7fa73379a97b8f053d9e8ccce2aebb600230e47b",
+    "feature/2026-08-11-web-export-command-and-dialog.zh.md": "sha256:ad28e67d397c87300cfe1705ba3d206cc4d054e07f5647c095c718ac8cf4ec98",
+    "feature/2026-08-18-product-subagent-failure-facts.i18n.yaml": "sha256:0aa7a873fdd878ee7f4b0a850ecf16d7b652b4f85de979acb7efcdf90883b6c1",
+    "feature/2026-08-18-product-subagent-failure-facts.md": "sha256:f7e05703c44106359798e6e4b76e442a4107b62ff0363554382d4767e4806788",
+    "feature/2026-08-18-product-subagent-failure-facts.zh.md": "sha256:19d2619fb5b5c6e40305dd82432d837357afa433ab735504ec204a2c25582ce6",
+    "feature/2026-08-18-web-home-path-tilde.i18n.yaml": "sha256:f151e3e3514f59784fc646c2feb3075dc954c65110d48c2cc482ad486fc0b86f",
+    "feature/2026-08-18-web-home-path-tilde.md": "sha256:8c7ecf120ff8c81826160acab5fc906a2a0a14213bcd2958343cfea47328d68e",
+    "feature/2026-08-18-web-home-path-tilde.zh.md": "sha256:3486c5b42aed5bcadf12c62c5e1e6cf7c1b493fc1085ad7d154cdf2ec34076cc",
+    "feature/2026-08-19-high-cache-hit-decimal-display.i18n.yaml": "sha256:c2cb839ed676040ed62153c2aab65b677fa59739f69253af50246e79a2347620",
+    "feature/2026-08-19-high-cache-hit-decimal-display.md": "sha256:08cb68bfc379da47a05b816afac26126146d36d6248350d4380f7cb98607d573",
+    "feature/2026-08-19-high-cache-hit-decimal-display.zh.md": "sha256:9d7afe3e2fc3029fbccc643b432a01bcb3b5671750adb6945ac414ec843ca063",
     "process/2026-06-11-doc-sync-enforcement.i18n.yaml": "sha256:33b6d5874427bd7a2bd82e7e2f4f482b12448b2464aef15a9c57975edb48554d",
     "process/2026-06-11-doc-sync-enforcement.md": "sha256:aa2fe83d519fc30d48dff19e596e83c8922aacc9e063e14fe2cc35b769b9100e",
     "process/2026-06-11-doc-sync-enforcement.zh.md": "sha256:698017bd35f030fdea3eac51df9e43138c48140f504739d687b7251d13fced2b",
@@ -322,6 +382,9 @@
     "process/2026-08-08-review-driven-issue-lifecycle-triggers.i18n.yaml": "sha256:4c28c59d3fc323e7cd01eff31f1fe759834719c5bede1e82b39f868970bf856d",
     "process/2026-08-08-review-driven-issue-lifecycle-triggers.md": "sha256:1b0514de5d030170e91e12e4d6ba788a9247f840e82700faa385a1c0c76ab857",
     "process/2026-08-08-review-driven-issue-lifecycle-triggers.zh.md": "sha256:028d78d61f603d8bac64c4cce20b393a78f8e029d3bb4976e79a47ecaefa6032",
+    "process/2026-08-12-documentation-site-navigation-and-chrome.i18n.yaml": "sha256:dde0041399b253e3758045f0858488db8178ffc563ce889c8b396c87af6c3730",
+    "process/2026-08-12-documentation-site-navigation-and-chrome.md": "sha256:56cb836ed862378afd33eb5c1a9dc159958b35a0aed3bf4336fcf26ab0b84b8b",
+    "process/2026-08-12-documentation-site-navigation-and-chrome.zh.md": "sha256:f2dd4adde38a09fe312866a1e6dad0f465684d809287862f40f1a488acd4fe18",
     "simplification/2026-06-20-drop-unconsumed-llm-adapter-change-event.i18n.yaml": "sha256:ad3d1263cb0051b885173bf064de62065e2c646ccaae2d7250723da3b4eab90c",
     "simplification/2026-06-20-drop-unconsumed-llm-adapter-change-event.md": "sha256:8fb061d51c8c23b47d2367814bab3623c6d5b972f38d207a273caa9030b579bd",
     "simplification/2026-06-20-drop-unconsumed-llm-adapter-change-event.zh.md": "sha256:2ffeaca91f82844a5616d6dcce6b4af514bb8a7c46f78e47f668b204ac6edc04",
@@ -334,6 +397,9 @@
     "simplification/2026-07-02-remove-stream-chunk-mirror.i18n.yaml": "sha256:eef600eafd70a576b2ac16a74f5dd5010ee601376008a90be10f1da56d746cee",
     "simplification/2026-07-02-remove-stream-chunk-mirror.md": "sha256:0c22a896260c6eb8991cc8babd8172f7b6889fc41bb891d748f34650b3eee5ec",
     "simplification/2026-07-02-remove-stream-chunk-mirror.zh.md": "sha256:ae7a3c2450b16fdf2f8da9e1f83cd987bf387671ecc8ebb76d2e7541695e7ee1",
+    "simplification/2026-07-04-drop-image-content-block.i18n.yaml": "sha256:6af8bc85be1fc23b445b17ff96df69488afa82c7194fcb47beb7a6b7b5a1de6a",
+    "simplification/2026-07-04-drop-image-content-block.md": "sha256:31e619d09405044a4db4951084f8d12417868b8f255ca26a44af0a5a13d43e6b",
+    "simplification/2026-07-04-drop-image-content-block.zh.md": "sha256:8fa6558bbb014a38853796102099ffbd5d8151371d68d40b2bf262ad07f4c976",
     "simplification/2026-07-04-drop-inert-request-knobs.i18n.yaml": "sha256:e4c992a27ae0e37e5ef663c2cddf55eefe20387fd6103bebf655834d8e75e9db",
     "simplification/2026-07-04-drop-inert-request-knobs.md": "sha256:8735c2b868a85b13235e0491a0fa7b9570dd090eef5170324fc5e93782687b67",
     "simplification/2026-07-04-drop-inert-request-knobs.zh.md": "sha256:78b243f5d580f2a6fbbdb7d26574295d6ed74feb8d9bba34bbcdf4aa87624b5c",
@@ -403,6 +469,18 @@
     "simplification/2026-08-03-explicit-config-dsh-entrypoint.i18n.yaml": "sha256:5466161f3fb8f2e8117fe8ff242675cc9fe9ef264d1e29b9bc586891c73c051a",
     "simplification/2026-08-03-explicit-config-dsh-entrypoint.md": "sha256:f23accae7d05c2e75cb73ec69b492307f1ce7526ecfa9f6b12a621e02fd1a0c3",
     "simplification/2026-08-03-explicit-config-dsh-entrypoint.zh.md": "sha256:a32d2c6ecf748a16a2c35b59cd2da2fda75769e3ab24be6a2e026d8655466db4",
+    "simplification/2026-08-11-cmdline-program-action.i18n.yaml": "sha256:e33b6dee66e23beabf03275e4e4f15134d23a82740ae7be6afd28c11c3163fca",
+    "simplification/2026-08-11-cmdline-program-action.md": "sha256:e6a274bd92a35c98ea24704161b408507876de3162c0f640b4bc70a86ab4d86f",
+    "simplification/2026-08-11-cmdline-program-action.zh.md": "sha256:bd213ad65ea6129c5360f28b2f52e6f3e224a58d07f56da190702939e7b402ee",
+    "simplification/2026-08-11-quickstart-documentation-home.i18n.yaml": "sha256:548c0ff16d40fed3b3318b0b9a26e11d53a60582ff457098a212fc64e7d67eac",
+    "simplification/2026-08-11-quickstart-documentation-home.md": "sha256:21946a828417aca4a214a874a35e88fe5a3e5989c330421f3849937b35bb9a9b",
+    "simplification/2026-08-11-quickstart-documentation-home.zh.md": "sha256:cb292a428d427cf36aff0a184347f0ab653331edb874daf3c5b58a0d1f8e6964",
+    "simplification/2026-08-13-remove-first-run-beta-notice.i18n.yaml": "sha256:51267b74e39544991bfe606e3f749a26914162e454cf357f26223a6ed8de5fad",
+    "simplification/2026-08-13-remove-first-run-beta-notice.md": "sha256:7ef5c712b8dff1152becee6a3f800acd5f7589d7b000f01544f57b175660bcc1",
+    "simplification/2026-08-13-remove-first-run-beta-notice.zh.md": "sha256:f899c79f838b97d1eea4a118de2cf00a97bae910d86d4aabdc447b4e02fb585f",
+    "simplification/2026-08-19-knip-config-cleanup.i18n.yaml": "sha256:ca8f5726aed57ce376c3fbd8b70113e235f3ba37dbf290683157fb4bf143ab13",
+    "simplification/2026-08-19-knip-config-cleanup.md": "sha256:18c61713b3358d3019dac096afc26ce8e5189002f626b25e858dfc5e6f626c8d",
+    "simplification/2026-08-19-knip-config-cleanup.zh.md": "sha256:b8ff16089c1a331603bb80278544c637cb16c1fa3bcfca3c5e1187152a1a0947",
     "testing/2026-06-20-remove-redundant-snapshot-log-expected-output.i18n.yaml": "sha256:4177012c0821a8c22499852ecdf096af56d7263cb91c5d9d1bcd552cc26a3e00",
     "testing/2026-06-20-remove-redundant-snapshot-log-expected-output.md": "sha256:45234e7cc04b6010c6141f8d5924c04547300098f96262d423c50108e7c7011a",
     "testing/2026-06-20-remove-redundant-snapshot-log-expected-output.zh.md": "sha256:15e5a4ad3dee0bb711480cabe45cd97ec37bbdba19c2c2b47d1e9c203b07a48b",
@@ -426,6 +504,9 @@
     "testing/2026-07-18-tui-terminal-state-snapshots.zh.md": "sha256:26750f240f6c8a7b28746f62fe161b357e9c5dd52867cc7037399f1ed6ff37fa",
     "testing/2026-07-26-execa-for-test-subprocess-plumbing.i18n.yaml": "sha256:dd45cddb591b892739b75b0c180bde7f14008f4769227b863571475be295e1e0",
     "testing/2026-07-26-execa-for-test-subprocess-plumbing.md": "sha256:1f45a69d0a7367ec5afbf112a77b355339b35270af8ff52696bee879cdf770d3",
-    "testing/2026-07-26-execa-for-test-subprocess-plumbing.zh.md": "sha256:8a24bdc8376373d7a97f65cefc07078824bf918d6a9934056a025ecfafe8634b"
+    "testing/2026-07-26-execa-for-test-subprocess-plumbing.zh.md": "sha256:8a24bdc8376373d7a97f65cefc07078824bf918d6a9934056a025ecfafe8634b",
+    "testing/2026-08-12-required-python-runtime-pull-request-ci.i18n.yaml": "sha256:741e7e58e5e8a9c82d901c4a16a70cea9bd256eac0e94179b5a24a231bb9fe1f",
+    "testing/2026-08-12-required-python-runtime-pull-request-ci.md": "sha256:1f1273d7a550667533e29c76efd148aebf57581a91729c877b44a5e43a52d9ad",
+    "testing/2026-08-12-required-python-runtime-pull-request-ci.zh.md": "sha256:6b9bf126c6b83d9b21e135d38df677c0d5623168b4353c6ddb706f76762c2193"
   }
 }

+ 6 - 0
.agents/notes/archived/process/2026-08-12-documentation-site-navigation-and-chrome.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-12-documentation-site-navigation-and-chrome.md: f33f017d54bcbb3583f37be27dcd6c69952bc66a
+2026-08-12-documentation-site-navigation-and-chrome.zh.md: 7f3ff5c829c561167d8e2475cd1c2adf050975be

+ 1 - 0
.agents/notes/implemented/process/2026-08-12-documentation-site-navigation-and-chrome.md → .agents/notes/archived/process/2026-08-12-documentation-site-navigation-and-chrome.md

@@ -1,6 +1,7 @@
 # Agent Note: Documentation-site navigation and repository chrome
 
 Status: implemented
+Archived: 2026-08-22
 
 English | [中文](2026-08-12-documentation-site-navigation-and-chrome.zh.md)
 

+ 1 - 0
.agents/notes/implemented/process/2026-08-12-documentation-site-navigation-and-chrome.zh.md → .agents/notes/archived/process/2026-08-12-documentation-site-navigation-and-chrome.zh.md

@@ -1,6 +1,7 @@
 # Agent Note: 文档站导航与仓库 chrome
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-12-documentation-site-navigation-and-chrome.md) | 中文
 

+ 6 - 0
.agents/notes/archived/simplification/2026-07-04-drop-image-content-block.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-07-04-drop-image-content-block.md
+2026-07-04-drop-image-content-block.md: 362afbbe7c5c1a3b46b1e8abda3b0fec77d1a0e6
+2026-07-04-drop-image-content-block.zh.md: 07fbbd1f165887bf3305ccfa7ba137656ce0a99c

+ 1 - 0
.agents/notes/implemented/simplification/2026-07-04-drop-image-content-block.md → .agents/notes/archived/simplification/2026-07-04-drop-image-content-block.md

@@ -1,6 +1,7 @@
 # Agent Note: Drop the `image` content block until a path can honor it
 
 Status: implemented
+Archived: 2026-08-19
 
 English | [中文](2026-07-04-drop-image-content-block.zh.md)
 

+ 1 - 0
.agents/notes/implemented/simplification/2026-07-04-drop-image-content-block.zh.md → .agents/notes/archived/simplification/2026-07-04-drop-image-content-block.zh.md

@@ -1,6 +1,7 @@
 # Agent Note: 移除 `image` 内容块,直到有路径能真正处理它
 
 Status: implemented
+Archived: 2026-08-19
 
 [English](2026-07-04-drop-image-content-block.md) | 中文
 

+ 6 - 0
.agents/notes/archived/simplification/2026-08-11-cmdline-program-action.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-11-cmdline-program-action.md: 96cbe2342eef90e68dece3c78b12a2de1bbea7c0
+2026-08-11-cmdline-program-action.zh.md: f5a9fea1447c78c9f099d3b54acd5b90a21aa503

+ 1 - 0
.agents/notes/implemented/simplification/2026-08-11-cmdline-program-action.md → .agents/notes/archived/simplification/2026-08-11-cmdline-program-action.md

@@ -1,6 +1,7 @@
 # Agent Note: parseCmdline runs the program's own commander action
 
 Status: implemented
+Archived: 2026-08-22
 
 English | [中文](2026-08-11-cmdline-program-action.zh.md)
 

+ 2 - 1
.agents/notes/implemented/simplification/2026-08-11-cmdline-program-action.zh.md → .agents/notes/archived/simplification/2026-08-11-cmdline-program-action.zh.md

@@ -1,12 +1,13 @@
 # Agent Note: parseCmdline 运行 program 自己的 commander action
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-11-cmdline-program-action.md) | 中文
 
 ## Problem
 
-`dsh-cmdline`([应用自有命令行](../architecture/2026-08-06-app-owned-command-line.md))的 `parseCmdline` 曾带着一个自造的回调:`CmdlinePlan<T> = (program, ctx) => T`,在解析成功后于该适配器的 catch 之内调用,使 plan 的 `program.error(...)` 与 help/解析错误共用同一条退出路径;它还带有只被测试使用、类型不健全的默认值 `(() => ({}) as T)`,以及没有任何 plan 读取的 `ctx` 参数。这整条接缝复制了 commander 本就定义的席位:命令的 action 处理器在 `parse` 内部运行,从中抛出的 `program.error(...)` 与语法拒绝一样遵循 `exitOverride`。
+`dsh-cmdline`([应用自有命令行](../architecture/2026-08-06-app-owned-command-line.zh.md))的 `parseCmdline` 曾带着一个自造的回调:`CmdlinePlan<T> = (program, ctx) => T`,在解析成功后于该适配器的 catch 之内调用,使 plan 的 `program.error(...)` 与 help/解析错误共用同一条退出路径;它还带有只被测试使用、类型不健全的默认值 `(() => ({}) as T)`,以及没有任何 plan 读取的 `ctx` 参数。这整条接缝复制了 commander 本就定义的席位:命令的 action 处理器在 `parse` 内部运行,从中抛出的 `program.error(...)` 与语法拒绝一样遵循 `exitOverride`。
 
 ## Decision
 

+ 6 - 0
.agents/notes/archived/simplification/2026-08-11-quickstart-documentation-home.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-11-quickstart-documentation-home.md: 653c702eba4c90e52ee0539959d926ae23a98e6c
+2026-08-11-quickstart-documentation-home.zh.md: 3d21566f9e4a822d095a115a5e65bfbaa3f947df

+ 1 - 0
.agents/notes/implemented/simplification/2026-08-11-quickstart-documentation-home.md → .agents/notes/archived/simplification/2026-08-11-quickstart-documentation-home.md

@@ -1,6 +1,7 @@
 # Agent Note: Route documentation roots to quick start
 
 Status: implemented
+Archived: 2026-08-22
 
 English | [中文](2026-08-11-quickstart-documentation-home.zh.md)
 

+ 2 - 1
.agents/notes/implemented/simplification/2026-08-11-quickstart-documentation-home.zh.md → .agents/notes/archived/simplification/2026-08-11-quickstart-documentation-home.zh.md

@@ -1,6 +1,7 @@
 # Agent Note: 将文档根路由指向快速开始
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-11-quickstart-documentation-home.md) | 中文
 
@@ -12,7 +13,7 @@ Status: implemented
 
 每个 locale 根路由都是重定向页面。`/` 将读者导向 `./guide/quickstart`,`/en/` 则把同一相对目标解析为 `/en/guide/quickstart`。当网站托管在源站的子路径下时,相对目标仍会保留配置的 `DOCS_BASE`。
 
-重定向由 `docs/user/index.md` 与 `docs/user/index.zh.md` 的 VitePress frontmatter 维护。对于 locale 首页,[文档网站投影器](../process/2026-07-13-documentation-site-projection.md)只发布这段 frontmatter,因此权威 Markdown 保留中英文语言切换行,且不会渲染第二个首页。投影器测试验证两个 locale 根路由都使用相对于各自 locale 的同一快速开始目标。
+重定向由 `docs/user/index.md` 与 `docs/user/index.zh.md` 的 VitePress frontmatter 维护。对于 locale 首页,[文档网站投影器](../process/2026-07-13-documentation-site-projection.zh.md)只发布这段 frontmatter,因此权威 Markdown 保留中英文语言切换行,且不会渲染第二个首页。投影器测试验证两个 locale 根路由都使用相对于各自 locale 的同一快速开始目标。
 
 文档网站不承载产品定位和功能摘要。快速开始页面仍提供指南、开发、参考、搜索和 locale 导航。
 

+ 6 - 0
.agents/notes/archived/simplification/2026-08-13-remove-first-run-beta-notice.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-13-remove-first-run-beta-notice.md: 535d0a20a5805c137551e6047f40fc5cf53153b8
+2026-08-13-remove-first-run-beta-notice.zh.md: 20626bbd9d0bd13c00d4ee66f5dbc267c2e92082

+ 1 - 0
.agents/notes/implemented/simplification/2026-08-13-remove-first-run-beta-notice.md → .agents/notes/archived/simplification/2026-08-13-remove-first-run-beta-notice.md

@@ -1,6 +1,7 @@
 # Agent Note: Remove the first-run beta notice
 
 Status: implemented
+Archived: 2026-08-22
 
 English | [中文](2026-08-13-remove-first-run-beta-notice.zh.md)
 

+ 3 - 2
.agents/notes/implemented/simplification/2026-08-13-remove-first-run-beta-notice.zh.md → .agents/notes/archived/simplification/2026-08-13-remove-first-run-beta-notice.zh.md

@@ -1,16 +1,17 @@
 # Agent Note: 移除首次启动内测声明
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-13-remove-first-run-beta-notice.md) | 中文
 
 ## 问题
 
-GUI 每次首启都会先显示占满视口的内测声明:内部测试的定位表述,加上通过 `DSH_TELEMETRY_MODE` 开启 Session Log 上传的说明。会话遥测在 mode 未设置时已解析为 `DISABLED`([遥测默认关闭](../feature/2026-08-10-telemetry-default-off.md)),因此引导流程中关于遥测的全部内容就是一段教用户如何开启的提示,而内部测试的定位表述本身也不应出现在发布版本里。
+GUI 每次首启都会先显示占满视口的内测声明:内部测试的定位表述,加上通过 `DSH_TELEMETRY_MODE` 开启 Session Log 上传的说明。会话遥测在 mode 未设置时已解析为 `DISABLED`([遥测默认关闭](../feature/2026-08-10-telemetry-default-off.zh.md)),因此引导流程中关于遥测的全部内容就是一段教用户如何开启的提示,而内部测试的定位表述本身也不应出现在发布版本里。
 
 ## 决策
 
-本决策当时把首启声明从组装后的产品中整体移除,而不是改写。`ui-settings-general` 不再注册任何 `settings.onboarding` 步骤;声明组件、确认 store、文案所有者文件和 locale 键均被删除,Host 则保留 `ui-onboarding` namespace,使既有设置文档继续有效。后续的[共用弹窗产品引导](../feature/2026-08-13-shared-modal-product-onboarding.md)在 `ui-settings-models` 中恢复了一份新的简洁测试阶段声明,复用该字段与后端契约,但不会恢复已移除的接管式布局或遥测说明。遥测的开启仍是显式的部署环境变量选择,记录在 [CLI reference README](../../../../apps/cli/reference/README.md) 中;恢复后的声明不涉及如何开启遥测。
+本决策当时把首启声明从组装后的产品中整体移除,而不是改写。`ui-settings-general` 不再注册任何 `settings.onboarding` 步骤;声明组件、确认 store、文案所有者文件和 locale 键均被删除,Host 则保留 `ui-onboarding` namespace,使既有设置文档继续有效。后续的[共用弹窗产品引导](../feature/2026-08-13-shared-modal-product-onboarding.zh.md)在 `ui-settings-models` 中恢复了一份新的简洁测试阶段声明,复用该字段与后端契约,但不会恢复已移除的接管式布局或遥测说明。遥测的开启仍是显式的部署环境变量选择,记录在 [CLI reference README](../../../../apps/cli/reference/README.zh.md) 中;恢复后的声明不涉及如何开启遥测。
 
 ## 曾考虑的替代方案
 

+ 6 - 0
.agents/notes/archived/simplification/2026-08-19-knip-config-cleanup.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write
+2026-08-19-knip-config-cleanup.md: 56426aeb7ff53caf7828b3f252269559e596940d
+2026-08-19-knip-config-cleanup.zh.md: a74fa831f2301d9b95d5e34b003585293501c874

+ 32 - 0
.agents/notes/archived/simplification/2026-08-19-knip-config-cleanup.md

@@ -0,0 +1,32 @@
+# Agent Note: Deleted stale and duplicative knip.json workspace entries
+
+Status: implemented
+Archived: 2026-08-22
+
+English | [中文](2026-08-19-knip-config-cleanup.zh.md)
+
+## Problem
+
+`knip.json` carried workspace entries that did no work. Some pointed at packages that no longer exist, and some duplicated the `packages/*/*` glob default exactly. Both kinds made the file larger — 790 lines — and signaled a config that had outgrown the packages it described, so a reader could not tell which entries protected real behavior and which were inert.
+
+## Decision
+
+Deleted 15 `workspaces` entries: 2 stale keys naming packages absent from the working tree and from `HEAD`, and 13 entries whose `entry`/`project` values were byte-identical to the `packages/*/*` glob default.
+
+- Stale keys: `packages/util/home` (removed in `4a09d9b34d`, the harness-home resolver collapse) and `packages/client/web-ui` (no directory and no git history, an orphan key). knip 6.16 does not flag stale workspace keys — that stability check arrived in knip 6.18 — so these were inert config that only deleted when their packages disappeared.
+- Glob-duplicate entries: `packages/host/webserver`, `packages/client/runtime`, `packages/core/tools`, `packages/context/tmux-context`, `packages/util/timeout`, `packages/util/output-retention`, `packages/goal/goal-round-driver`, `packages/goal/tool-goal`, `packages/util/home-paths`, `packages/fs/tool-fs-search`, `packages/client/ui-settings`, `packages/client/modules`, `packages/client/hmr`. Each declared exactly `entry: ["tests/**/*.spec.ts"]` and `project: ["src/**/*.ts", "tests/**/*.ts"]`, which equals the `packages/*/*` glob, and each package still exists, so the glob now covers it identically.
+
+The change is a deletion only: `knip.json` went from 790 to 655 lines with no behavioral change. `pnpm run knip` runs clean (zero issues, exit 0) before and after, because knip selects one workspace config per matched key (`getConfigKeyForWorkspace` uses specificity, not array merge), so a removed entry either lost an unresolvable target or fell back to an identical glob config.
+
+## Alternatives considered
+
+- Fold `zod` and other workspace-level `ignoreDependencies` up to the root. Rejected: the root `ignoreDependencies` is a repository-wide fallback, and these exemptions are deliberately workspace-scoped (the README of `cordis-host-runner` records why `src` cannot import the flagged dependency while the generated TypeRT face in `lib` needs it). Widening scope would mask a genuinely misplaced dependency in any future package.
+- Upgrade knip to 6.18+ to get an automatic stale-workspace check. Deferred: 6.32.2 (latest at the time) re-flags many `@deepseek-ai/...` test dependencies as unused, i.e. it changes analysis semantics, not just adds hints. That is a separate dependency-upgrade decision with its own CI blast radius, not part of this cleanup.
+- Keep the entries as documentation of intent. Rejected: an entry identical to the glob it sits under documents nothing beyond the glob itself, and a key naming an absent package actively misleads.
+
+## Consequences
+
+- `knip.json` is 135 lines shorter and names only packages that exist with config that differs from the glob default.
+- Still-explicit entries (54) all carry a real reason to differ — an `e2e`/fixture/tsx `entry`, a `project` outside the default, or a workspace-scoped `ignoreDependencies`.
+- knip 6.16 cannot itself detect the next stale key, so a package removal must still remember to drop its `knip.json` key; upgrading to 6.18+ (after the analysis-semantics change is separately assessed) restores that guard.
+- This realizes the "never a restatement of the default stanza" criterion of the package-inventory proposal ([topic](../../proposed/process/2026-06-20-discover-package-inventory.md)); its remaining items — the e2e entry folding and the generated inventory — stay open there.

+ 32 - 0
.agents/notes/archived/simplification/2026-08-19-knip-config-cleanup.zh.md

@@ -0,0 +1,32 @@
+# Agent Note: 删除 knip.json 中失效与重复的 workspace 条目
+
+Status: implemented
+Archived: 2026-08-22
+
+[English](2026-08-19-knip-config-cleanup.md) | 中文
+
+## 问题
+
+`knip.json` 携带了大量不产生任何作用的 workspace 条目。其中一些指向已经不复存在的包,另一些与 `packages/*/*` 通配默认完全重复。这两类都让文件变大——790 行——并显现出配置已经超出了它所描述的包:读者无法分辨哪些条目在保护真实行为、哪些是惰性的。
+
+## 决策
+
+删除了 15 个 `workspaces` 条目:2 个指向工作树与 `HEAD` 中都不存在的包的失效键,以及 13 个 `entry`/`project` 与 `packages/*/*` 通配默认逐字节相同的条目。
+
+- 失效键:`packages/util/home`(在 `4a09d9b34d`,harness home 解析器的合并改动中删除)和 `packages/client/web-ui`(无对应目录、无 git 历史,是孤儿键)。knip 6.16 不会标记失效的 workspace 键——这项稳定性检查在 knip 6.18 才引入——所以这些是本应在包消失时一并删除、却残留的惰性配置。
+- 通配重复条目:`packages/host/webserver`、`packages/client/runtime`、`packages/core/tools`、`packages/context/tmux-context`、`packages/util/timeout`、`packages/util/output-retention`、`packages/goal/goal-round-driver`、`packages/goal/tool-goal`、`packages/util/home-paths`、`packages/fs/tool-fs-search`、`packages/client/ui-settings`、`packages/client/modules`、`packages/client/hmr`。每个都恰好声明了 `entry: ["tests/**/*.spec.ts"]` 和 `project: ["src/**/*.ts", "tests/**/*.ts"]`,与 `packages/*/*` 通配相等,且这些包仍然存在,因此通配现在以完全相同的方式覆盖它们。
+
+本改动只做删除:`knip.json` 从 790 行降到 655 行,行为不变。`pnpm run knip` 在改动前后都干净通过(零问题、退出码 0),因为 knip 为每个已匹配的键选取一条 workspace 配置(`getConfigKeyForWorkspace` 按特定优先、不做数组合并),所以被删条目要么丢掉了无法解析的目标,要么回退到一个完全相同的通配配置。
+
+## 备选方案
+
+- 把 `zod` 及其它 workspace 级 `ignoreDependencies` 上提到根级。否决:根级 `ignoreDependencies` 是全仓库兜底,而这些豁免是刻意限定在 workspace 的(`cordis-host-runner` 的 README 记录了为什么 `src` 无法 import 被标记的依赖、而生成的 `lib` 里的 TypeRT 契约面需要它)。扩大作用域会掩盖未来任何包里真正放错位置的依赖。
+- 升级 knip 到 6.18+ 以获得自动的失效 workspace 检查。延后:撰写时的最新版 6.32.2 会把大量 `@deepseek-ai/...` 测试依赖重新标记为未使用——也就是改变了分析语义,而不仅是新增提示。那是独立的依赖升级决定,带自己的 CI 影响面,不属于本次清理。
+- 保留这些条目作为意图的文档。否决:与它挂在下面的通配完全相同的条目,除了通配本身外不记录任何东西;而指向不存在包的键确实会误导人。
+
+## 结果
+
+- `knip.json` 缩短了 135 行,并且只列出确实存在、且配置与通配默认有差异的包。
+- 仍然显式的条目(54 个)都带有真实的特例理由——`e2e`/fixture/tsx 的 `entry`、超出默认的 `project`、或 workspace 级的 `ignoreDependencies`。
+- knip 6.16 自身无法检测下一个失效键,因此删除包时仍须记得清理它的 `knip.json` 键;升级到 6.18+(在分析语义的改动被单独评估之后)会恢复这道守卫。
+- 本改动落实了包清单提案中「绝不复述默认 stanza」的标准([议题](../../proposed/process/2026-06-20-discover-package-inventory.zh.md));其剩余项——e2e 入口折叠与生成的清单——仍在提案中保持开放。

+ 6 - 0
.agents/notes/archived/testing/2026-08-12-required-python-runtime-pull-request-ci.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-08-12-required-python-runtime-pull-request-ci.md
+2026-08-12-required-python-runtime-pull-request-ci.md: e7da767f22634bd50bc4fd38b1de34677c4124e7
+2026-08-12-required-python-runtime-pull-request-ci.zh.md: 702125b0da864eb35f1fe870748cc0e314b01a39

+ 1 - 0
.agents/notes/implemented/testing/2026-08-12-required-python-runtime-pull-request-ci.md → .agents/notes/archived/testing/2026-08-12-required-python-runtime-pull-request-ci.md

@@ -1,6 +1,7 @@
 # Agent Note: Required Python runtime pull-request validation
 
 Status: implemented
+Archived: 2026-08-23
 
 English | [中文](2026-08-12-required-python-runtime-pull-request-ci.zh.md)
 

+ 3 - 2
.agents/notes/implemented/testing/2026-08-12-required-python-runtime-pull-request-ci.zh.md → .agents/notes/archived/testing/2026-08-12-required-python-runtime-pull-request-ci.zh.md

@@ -1,6 +1,7 @@
 # Agent Note: 必需的 Python 运行时拉取请求验证
 
 Status: implemented
+Archived: 2026-08-23
 
 [English](2026-08-12-required-python-runtime-pull-request-ci.md) | 中文
 
@@ -12,9 +13,9 @@ Status: implemented
 
 每个拉取请求都在 [CI](../../../../.github/workflows/ci.yml) 中运行必需的 `python-runtime` 作业。该作业不使用路径过滤,调用共享的[单文件可执行程序构建器](../../../../.github/workflows/build-exe-for-python-sdk.yml)构建 `node24-linux-x64`,并参与 `all checks passed`。被调用的工作流会构建真实可执行文件,运行全部无密钥 Python 完整轮次和直接二进制场景(包括两份检入的快照),构建 SDK 与运行时 wheel 包,将二者安装进干净的虚拟环境,检查可执行文件与原生 addon 的 GLIBC 依赖,并在 manylinux 2.28 容器中运行已安装的 wheel 包。
 
-必需作业与 [Python 发布工作流](../process/2026-08-11-python-publication-workflow.md)共用同一构建器。其并发键包含调用方工作流,因此同一 ref 上的必需 CI 与显式完整发布验证不会互相取消。完整的 linux-x64、linux-arm64 和 macos-arm64 矩阵仍属于发布验证:平台无关的运行时、SDK 与快照行为只需要一个阻断合并的原生载体,而架构相关的可执行文件、addon、wheel 包标签与部署目标行为在发布前仍需要全部发布目标验证。
+必需作业与 [Python 发布工作流](../process/2026-08-11-python-publication-workflow.zh.md)共用同一构建器。其并发键包含调用方工作流,因此同一 ref 上的必需 CI 与显式完整发布验证不会互相取消。完整的 linux-x64、linux-arm64 和 macos-arm64 矩阵仍属于发布验证:平台无关的运行时、SDK 与快照行为只需要一个阻断合并的原生载体,而架构相关的可执行文件、addon、wheel 包标签与部署目标行为在发布前仍需要全部发布目标验证。
 
-进阶 exe 快照会在比较前规范化不透明的会话、消息、subagent 和工作流运行标识符。因此,新增的持久化工作流事件会改变经过审阅的预期输出,但不会把随机运行标识符写入其中。极简场景的[模型可见快照](2026-08-13-python-minimal-model-visible-snapshot.md)覆盖了这份快照所占位化的已组装系统提示词、工具 schema 与消息列表。
+进阶 exe 快照会在比较前规范化不透明的会话、消息、subagent 和工作流运行标识符。因此,新增的持久化工作流事件会改变经过审阅的预期输出,但不会把随机运行标识符写入其中。极简场景的[模型可见快照](2026-08-13-python-minimal-model-visible-snapshot.zh.md)覆盖了这份快照所占位化的已组装系统提示词、工具 schema 与消息列表。
 
 ## 曾考虑的替代方案
 

+ 2 - 2
.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.md
-2026-06-11-content-block-vocabulary.md: 5228724bb9101307db9929aaf7831b477c2a6022
-2026-06-11-content-block-vocabulary.zh.md: b43de335917c6b5304a94b296fcb8253827b0600
+2026-06-11-content-block-vocabulary.md: d7d3f6b43a3f65d1421f026e5b6c2cc1ba1eadd2
+2026-06-11-content-block-vocabulary.zh.md: ed4f915dff6dcb6dbc91400f9bfa5384253aea7b

+ 2 - 2
.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.md

@@ -22,7 +22,7 @@ In-session context injection (`context/message`) and mid-turn steering originall
 ## Consequences
 
 - Reasoning has a core home without provider-specific shapes.
-- Multimodal blocks return only with coordinated adapter, UI, and compaction support; see [the drop-image Agent Note](../simplification/2026-07-04-drop-image-content-block.md).
+- Multimodal blocks return only with coordinated adapter, UI, and compaction support; see [the drop-image Agent Note](../../archived/simplification/2026-07-04-drop-image-content-block.md).
 - Cache hints and assistant prefill remain absent until a shipping adapter can honor them; see the [producer-less variants](../../archived/simplification/2026-07-04-prune-producerless-vocabulary-variants.md) and [inert request knobs](../../archived/simplification/2026-07-04-drop-inert-request-knobs.md) Agent Notes.
 - Every adapter pays a translation cost; the first real adapters have since validated the streaming protocol, and new adapters should continue proving their provider-specific mapping in adapter-local tests.
-- IDs that cross package boundaries are branded (`CallId`, the shared agent/session `SessionId`) — nominal typing at zero runtime cost.
+- IDs that cross package boundaries are branded (`ToolCallId`, the shared agent/session `SessionId`) — nominal typing at zero runtime cost.

+ 3 - 3
.agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.zh.md

@@ -12,7 +12,7 @@ harness 需要一套统一的内部消息语言,供 agent loop(智能体循
 
 自主拥有词汇:消息是类型化内容块的数组(`text`、`reasoning`、`tool-call`、`tool-result`),其联合类型派生自可合并扩展的 `ContentBlockMap`,插件通过声明合并添加新的块类型。同一可合并扩展映射模式为所有「字符串化」字段提供类型(`MessageSource`、`FinishReason`、`TurnTrigger`、`TurnEndReason`)。流式输出采用原始分片协议;`BlockAssembler` 是唯一的共享组装实现。适配器负责转换为提供方的协议格式(wire format)——映射成本留在适配器中,正是它该在的地方。
 
-会话内上下文注入(`context/message`)和轮次中途 steering(中途引导)最初渲染为带标签的 user-role 信封(system-reminder 模式),而非引入新角色,因此适配器无需承担额外负担。如今两者都投影为无包装的普通用户内容;见[注入内容信封 Agent Note](../simplification/2026-07-20-unwrap-injected-content-envelopes.md)。实际适配器验证已确认此渲染方式符合当前 DeepSeek 的行为;如果未来某提供方出现不兼容,应在该适配器内处理,而非引入新的规范角色。
+会话内上下文注入(`context/message`)和轮次中途 steering(中途引导)最初渲染为带标签的 user-role 信封(system-reminder 模式),而非引入新角色,因此适配器无需承担额外负担。如今两者都投影为无包装的普通用户内容;见[注入内容信封 Agent Note](../simplification/2026-07-20-unwrap-injected-content-envelopes.zh.md)。实际适配器验证已确认此渲染方式符合当前 DeepSeek 的行为;如果未来某提供方出现不兼容,应在该适配器内处理,而非引入新的规范角色。
 
 ## 曾考虑的替代方案
 
@@ -22,7 +22,7 @@ harness 需要一套统一的内部消息语言,供 agent loop(智能体循
 ## 后果
 
 - 推理(reasoning)在核心层有了归属,无需依赖提供方特有的结构。
-- 多模态块只有在适配器、UI 和上下文压缩(context compaction)三方协同支持后才会回归;见 [drop-image Agent Note](../simplification/2026-07-04-drop-image-content-block.md)。
+- 多模态块只有在适配器、UI 和上下文压缩(context compaction)三方协同支持后才会回归;见 [drop-image Agent Note](../../archived/simplification/2026-07-04-drop-image-content-block.md)。
 - 缓存提示与 assistant prefill 在有实际适配器能兑现之前保持缺席;见[无生产者的词汇变体](../../archived/simplification/2026-07-04-prune-producerless-vocabulary-variants.md)与[无端到端可用路径的请求旋钮](../../archived/simplification/2026-07-04-drop-inert-request-knobs.md) Agent Note。
 - 每个适配器都需承担翻译成本;首批真实适配器已验证了流式输出协议,新适配器应继续在适配器本地测试中验证其提供方特有的映射。
-- 跨包边界的 ID 使用品牌类型(`CallId`、agent 与会话共享的 `SessionId`)——零运行时开销的名义类型。
+- 跨包边界的 ID 使用品牌类型(`ToolCallId`、agent 与会话共享的 `SessionId`)——零运行时开销的名义类型。

+ 1 - 1
.agents/notes/implemented/architecture/2026-06-11-dev-invariants-over-deep-readonly.i18n.yaml

@@ -3,4 +3,4 @@
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-11-dev-invariants-over-deep-readonly.md
 2026-06-11-dev-invariants-over-deep-readonly.md: 66980f1ee09c6112f72786d6c3a147aadbc57f6c
-2026-06-11-dev-invariants-over-deep-readonly.zh.md: 0d694ea84e1b7c265491e9adb64757378b4185f1
+2026-06-11-dev-invariants-over-deep-readonly.zh.md: 576e53e0b27e65f6fa071ff649509223a7bc30ff

+ 1 - 1
.agents/notes/implemented/architecture/2026-06-11-dev-invariants-over-deep-readonly.zh.md

@@ -32,7 +32,7 @@ TypeScript readonly 类型不是充分的运行时边界。它们在程序运行
 
 ### 包拥有的不变式配套插件检查关系
 
-`dsh-invariants` 注册可配置的 `ctx.invariants` 服务,本身不包含产品检查。每个包发布一个 `./invariant` 所有权配套插件;`dsh-session`、`dsh-agent`、`dsh-scope` 和 `dsh-agent-loop` 目前添加需要跟踪状态或观察另一个 seam 的规则:单调递增的序列号、轮次与步骤嵌套、工具调用/结果配对、合法的 agent(智能体)状态转换、主体正确的作用域分发,以及循环构建的请求与从其会话日志前缀重建的请求之间的相等性。全局启用和包名 regex 过滤器归该服务所有(见[包拥有的不变式服务](2026-07-19-package-owned-invariant-service.md))。
+`dsh-invariants` 注册可配置的 `ctx.invariants` 服务,本身不包含产品检查。每个包发布一个 `./invariant` 所有权配套插件;`dsh-session`、`dsh-agent`、`dsh-scope` 和 `dsh-agent-loop` 目前添加需要跟踪状态或观察另一个 seam 的规则:单调递增的序列号、轮次与步骤嵌套、工具调用/结果配对、合法的 agent(智能体)状态转换、主体正确的作用域分发,以及循环构建的请求与从其会话日志前缀重建的请求之间的相等性。全局启用和包名 regex 过滤器归该服务所有(见[包拥有的不变式服务](2026-07-19-package-owned-invariant-service.zh.md))。
 
 当会话配套插件附加到已有会话或以种子记录初始化的会话时,它回放不可变日志以重建跟踪状态。服务为每项贡献提供一个可 dispose(资源释放)的子 fiber,因此轮次中途热重载是安全的,同时不赋予诊断逻辑对会话存储的所有权。
 

+ 1 - 1
.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.i18n.yaml

@@ -3,4 +3,4 @@
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.md
 2026-06-11-event-sourced-sessions.md: b6d17d2db1d9b489f3d4224683b61e62be485014
-2026-06-11-event-sourced-sessions.zh.md: a78349ea2385b3c9d32870757bb607f15996196d
+2026-06-11-event-sourced-sessions.zh.md: 11e5740dc2636fc002ed7158167b1dfbb39a971d

+ 1 - 1
.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.zh.md

@@ -24,5 +24,5 @@ MVP 要求严格的基于事件的追踪,以及完全可回放的会话(严
 
 - 回放、追踪与遥测在结构上得到保证,而非事后附加。
 - 持久化仍是插件关注点;内存存储随 dsh-session 一起提供。
-- 事件词汇可通过合并扩展(插件可添加如压缩(compaction)事件);[会话持久化](2026-06-14-session-persistence.md)在日志具备持久性后固定了其结构。
+- 事件词汇可通过合并扩展(插件可添加如压缩(compaction)事件);[会话持久化](2026-06-14-session-persistence.zh.md)在日志具备持久性后固定了其结构。
 - 派生成本随日志长度增长,压缩(dsh-compaction)是预期的缓解手段,而不是改写日志。

+ 1 - 1
.agents/notes/implemented/architecture/2026-06-11-microkernel-event-taxonomy.i18n.yaml

@@ -3,4 +3,4 @@
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-11-microkernel-event-taxonomy.md
 2026-06-11-microkernel-event-taxonomy.md: 6cacbc30f29c863de0f8ddfa4df7251a64bc80ca
-2026-06-11-microkernel-event-taxonomy.zh.md: 2e43b57d62d8fca692ffab379d1841e6a3e61fad
+2026-06-11-microkernel-event-taxonomy.zh.md: 1c7919392b835c491b9dc606d46f638a708d2948

+ 1 - 1
.agents/notes/implemented/architecture/2026-06-11-microkernel-event-taxonomy.zh.md

@@ -25,7 +25,7 @@ Status: implemented
 
 ## 后果
 
-- 每个 MVP 功能都映射到一个监听器([功能→机制映射](../../../../docs/cookbook/extension-cookbook.md#the-feature--mechanism-map)是证明义务,保持更新)。
+- 每个 MVP 功能都映射到一个监听器([功能→机制映射](../../../../docs/cookbook/extension-cookbook.zh.md#the-feature--mechanism-map)是证明义务,保持更新)。
 - HMR 与 dispose 无需额外工作:监听器和注册均为 Cordis effect。
 - waterfall 语义(调用 `next()` 或短路)不直观,需要教学——在 AGENTS.md 中记录,并由组合测试覆盖。
 - 循环必须具备防御性:插件异常在轮次级别被隔离,来自任何扩展点的 steering(中途引导)永远不会被搁置(有回归测试保障)。

+ 1 - 1
.agents/notes/implemented/architecture/2026-06-11-runtime-arg-validation.i18n.yaml

@@ -3,4 +3,4 @@
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-11-runtime-arg-validation.md
 2026-06-11-runtime-arg-validation.md: 520823c76f147205805d306e97b5461f38b84c35
-2026-06-11-runtime-arg-validation.zh.md: 0a6ef40c93ec3550d6e991836950be849e86ede7
+2026-06-11-runtime-arg-validation.zh.md: bc2f743300be78cc2a01f027d5aca81fcb18b468

+ 3 - 3
.agents/notes/implemented/architecture/2026-06-11-runtime-arg-validation.zh.md

@@ -6,7 +6,7 @@ Status: implemented
 
 ## 问题
 
-`defineTool`([统一 schema DSL](2026-07-20-unified-json-value-schema-dsl.md))为工具作者的 `execute(args)` 提供了经 `InferArgs<S>` 映射的类型化参数。但该类型只是对运行时值的编译期声明,而这个值实际上是模型生成的 JSON:没有任何机制强制模型遵守 schema,因此畸形调用(缺少必需键、声明为数字的位置传入字符串,或字面量超出声明的集合)会以「仅在名义上类型化」的状态到达 `execute`。工具函数体随后要么在处理结构错误的数据时崩溃,要么在不报错的情况下行为异常。
+`defineTool`([统一 schema DSL](2026-07-20-unified-json-value-schema-dsl.zh.md))为工具作者的 `execute(args)` 提供了经 `InferArgs<S>` 映射的类型化参数。但该类型只是对运行时值的编译期声明,而这个值实际上是模型生成的 JSON:没有任何机制强制模型遵守 schema,因此畸形调用(缺少必需键、声明为数字的位置传入字符串,或字面量超出声明的集合)会以「仅在名义上类型化」的状态到达 `execute`。工具函数体随后要么在处理结构错误的数据时崩溃,要么在不报错的情况下行为异常。
 
 ## 决策
 
@@ -17,8 +17,8 @@ Status: implemented
 ## 后果
 
 - 模型会收到有关自身畸形调用的可操作反馈,而不是遭遇不透明的崩溃,弥合了 `InferArgs` 的承诺与运行时现实之间的鸿沟。
-- 校验器与 `InferArgs` 必须保持一致;一项[属性测试](../testing/2026-06-11-property-based-testing.md)生成满足 spec 的参数并断言它们通过 `validateArgs`(同时通过针对性改坏参数来断言其会被拒绝),通过自动化检查消除这种漂移风险。
-- `ToolArgsError` 是[结构化错误分类体系](2026-06-11-structured-error-taxonomy.md)中 `HarnessError` 的子类,保留其 `code` 字段;读取 `.message` 的调用方不受该层级结构影响。
+- 校验器与 `InferArgs` 必须保持一致;一项[属性测试](../testing/2026-06-11-property-based-testing.zh.md)生成满足 spec 的参数并断言它们通过 `validateArgs`(同时通过针对性改坏参数来断言其会被拒绝),通过自动化检查消除这种漂移风险。
+- `ToolArgsError` 是[结构化错误分类体系](2026-06-11-structured-error-taxonomy.zh.md)中 `HarnessError` 的子类,保留其 `code` 字段;读取 `.message` 的调用方不受该层级结构影响。
 - 校验开销相对于一次模型调用可忽略不计。
 
 <!-- agent-note-format: alternatives-not-recorded (pre-format Agent Note) -->

+ 2 - 2
.agents/notes/implemented/architecture/2026-06-13-capability-seams.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-13-capability-seams.md
-2026-06-13-capability-seams.md: 2a166278ea454895177fa12b58f5493276f19cd1
-2026-06-13-capability-seams.zh.md: 0874af5826960ab9e718eb07b00c12b446edfd78
+2026-06-13-capability-seams.md: 46a2c39e927e859c7eb95956d8586f3bf04c7b1c
+2026-06-13-capability-seams.zh.md: f44e3e68d2153149435b0fd0aaa5fd121cf3ecad

+ 1 - 1
.agents/notes/implemented/architecture/2026-06-13-capability-seams.md

@@ -6,7 +6,7 @@ English | [中文](2026-06-13-capability-seams.zh.md)
 
 ## Problem
 
-The harness has swappable capabilities — bash execution today, sandboxed/remote executors and alternative model providers tomorrow. A capability has three concerns that change at different rates and for different reasons: the *contract* (what the capability is), the *implementation* (how it runs), and the *consumer API* (what the model and other plugins program against). Bundling them in one package couples those rates of change — swapping a local executor for a sandboxed one would churn the tool schemas the model sees, even though the model-facing contract never changed.
+The harness has swappable capabilities, including shell execution and model providers. A capability has three concerns that change at different rates and for different reasons: the *contract* (what the capability is), the *implementation* (how it runs), and the *consumer API* (what the model and other plugins program against). Bundling them in one package couples those rates of change — swapping a local executor for a sandboxed one would churn the tool schemas the model sees, even though the model-facing contract never changed.
 
 This is distinct from "who provides vs. needs a capability at runtime", which Cordis already answers with services + `inject` (a provider registers `ctx.shell`; a consumer declares `inject: ['bash']` and its fiber pends until the service exists). That mechanism is necessary but doesn't dictate package boundaries; this Agent Note does.
 

+ 3 - 3
.agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md

@@ -6,7 +6,7 @@ Status: implemented
 
 ## 问题
 
-harness 具有可替换的能力:当前是 bash 执行,未来会有沙箱化/远程执行器和替代模型提供方。一项能力涉及三个关注点,它们以不同速率、因不同原因变化:*约定*(这项能力是什么)、*实现*(它如何运行)、*消费方 API*(模型和其他插件面向什么编程)。将三者捆绑在一个包中会耦合这些变化速率——把本地执行器换成沙箱化执行器时,模型看到的工具 schema 也会被搅动,尽管面向模型的约定从未改变。
+harness 具有可替换的能力,包括 shell 执行和模型提供方。一项能力涉及三个关注点,它们以不同速率、因不同原因变化:*约定*(这项能力是什么)、*实现*(它如何运行)、*消费方 API*(模型和其他插件面向什么编程)。将三者捆绑在一个包中会耦合这些变化速率——把本地执行器换成沙箱化执行器时,模型看到的工具 schema 也会被搅动,尽管面向模型的约定从未改变。
 
 这与「谁在运行时提供、谁需要一项能力」是不同的问题,后者 Cordis 已通过服务 + `inject` 解决(提供方注册 `ctx.shell`;消费方声明 `inject: ['bash']`,其 fiber 挂起直到服务存在)。该机制是必要的,但不决定包的边界;本 Agent Note 决定的是包的边界。
 
@@ -26,7 +26,7 @@ Service Provider 与 Consumer 由此独立演进:沙箱化执行器替换 `dsh
 
 ## 术语:seam 指三者组合,而非接口
 
-一个 **seam** 是完整的能力——三个角色合在一起:**Service Definition**(拥有 `ctx.<key>` 和词汇的 Cordis `Service`)、一个或多个 **Service Provider**,以及一个或多个 **Consumer**。`packages/shell` 是规范范例——`dsh-shell` / `dsh-bash-local`+`dsh-bash-sandbox` / `dsh-tool-bash`。一个包可以承担多个角色,但单个角色本身不是 seam。「seam」一词严格保留给这种完整能力;命名其中一个组成部分时,应使用其角色、类、服务、约定或扩展点。[术语表](../../../../docs/glossary.md#capability-seam)是规范条目。
+一个 **seam** 是完整的能力——三个角色合在一起:**Service Definition**(拥有 `ctx.<key>` 和词汇的 Cordis `Service`)、一个或多个 **Service Provider**,以及一个或多个 **Consumer**。`packages/shell` 是规范范例——`dsh-shell` / `dsh-bash-local`+`dsh-bash-sandbox` / `dsh-tool-bash`。一个包可以承担多个角色,但单个角色本身不是 seam。「seam」一词严格保留给这种完整能力;命名其中一个组成部分时,应使用其角色、类、服务、约定或扩展点。[术语表](../../../../docs/glossary.zh.md#capability-seam)是规范条目。
 
 ## 曾考虑的替代方案
 
@@ -35,4 +35,4 @@ Service Provider 与 Consumer 由此独立演进:沙箱化执行器替换 `dsh
 
 ## 后果
 
-分离角色会增加包和样板代码(`package.json`、`tsconfig`、README 和注入接线)。换来的是:Service Provider 与 Consumer 独立发布和版本管理,新后端永远不会波及面向模型的约定。[AGENTS.md](../../../../AGENTS.md) 和 [architecture.md](../../../../docs/architecture.md) 载有这项规则;bash 三件套是参考模板。本 Agent Note 记录为什么独立变化的角色通常需要拆分,而确实共享的关注点可以保持合并。
+分离角色会增加包和样板代码(`package.json`、`tsconfig`、README 和注入接线)。换来的是:Service Provider 与 Consumer 独立发布和版本管理,新后端永远不会波及面向模型的约定。[AGENTS.md](../../../../AGENTS.md) 和 [architecture.md](../../../../docs/architecture.zh.md) 载有这项规则;bash 三件套是参考模板。本 Agent Note 记录为什么独立变化的角色通常需要拆分,而确实共享的关注点可以保持合并。

+ 1 - 1
.agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.i18n.yaml

@@ -3,4 +3,4 @@
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.md
 2026-06-13-twin-llm-adapters.md: a4c87325a0b0d1ebe6cf8f95672e5de74ef37d57
-2026-06-13-twin-llm-adapters.zh.md: 2af7e7cca4d4c40e18cece1a4dd5c9cdb11901c8
+2026-06-13-twin-llm-adapters.zh.md: 36996750a16cc95393d727cffee3bcc53573eaf2

+ 1 - 1
.agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.zh.md

@@ -6,7 +6,7 @@ Status: implemented
 
 ## 问题
 
-`dsh-llm` 拥有一套提供方无关的流式词汇:`StreamChunk` 协议(`block-start`、`text-delta`、`reasoning-delta`、`tool-call-delta`、`block-end`、`usage`、`finish`)以及内容块类型([内容块词汇](2026-06-11-content-block-vocabulary.md))。如果词汇仅针对单个适配器定义,就有可能将该适配器的特异行为固化到「中立」约定中:唯一实现碰巧做了什么,什么就成为事实上的规范;在第二个提供方到来之前,抽象层未经验证——而届时修复这种泄漏的代价已经很高。
+`dsh-llm` 拥有一套提供方无关的流式词汇:`StreamChunk` 协议(`block-start`、`text-delta`、`reasoning-delta`、`tool-call-delta`、`block-end`、`usage`、`finish`)以及内容块类型([内容块词汇](2026-06-11-content-block-vocabulary.zh.md))。如果词汇仅针对单个适配器定义,就有可能将该适配器的特异行为固化到「中立」约定中:唯一实现碰巧做了什么,什么就成为事实上的规范;在第二个提供方到来之前,抽象层未经验证——而届时修复这种泄漏的代价已经很高。
 
 ## 决策
 

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio