Browse Source

Merge remote-tracking branch 'origin/xtr/session-format-migration' into xtr/message-tool-call-id

# Conflicts:
#	.agents/notes/implemented/architecture/2026-06-20-branded-ids.i18n.yaml
#	.agents/notes/implemented/architecture/2026-06-20-branded-ids.md
#	.agents/notes/implemented/architecture/2026-06-20-branded-ids.zh.md
#	packages/fs/tool-fs/tests/read-image.spec.ts
#	packages/llm/llm-deepseek/tests/adapter.e2e.ts
#	packages/llm/llm-deepseek/tests/serialize.spec.ts
#	packages/llm/llm-pi-ai/src/context.ts
#	packages/llm/llm-pi-ai/tests/context.spec.ts
#	packages/llm/llm-pi-ai/tests/convert.spec.ts
#	packages/llm/llm/src/message.ts
#	packages/llm/llm/tests/content.spec.ts
_Kerman 2 weeks ago
parent
commit
3cd80a6f3f
100 changed files with 267 additions and 78 deletions
  1. 6 0
      .agents/notes/archived/architecture/2026-08-11-plugin-settings-tabs.i18n.yaml
  2. 1 0
      .agents/notes/archived/architecture/2026-08-11-plugin-settings-tabs.md
  3. 1 0
      .agents/notes/archived/architecture/2026-08-11-plugin-settings-tabs.zh.md
  4. 6 0
      .agents/notes/archived/bug-fix/2026-08-04-large-history-pagination-call-stack.i18n.yaml
  5. 1 0
      .agents/notes/archived/bug-fix/2026-08-04-large-history-pagination-call-stack.md
  6. 1 0
      .agents/notes/archived/bug-fix/2026-08-04-large-history-pagination-call-stack.zh.md
  7. 6 0
      .agents/notes/archived/bug-fix/2026-08-06-plan-narrow-viewport-regression.i18n.yaml
  8. 1 0
      .agents/notes/archived/bug-fix/2026-08-06-plan-narrow-viewport-regression.md
  9. 1 0
      .agents/notes/archived/bug-fix/2026-08-06-plan-narrow-viewport-regression.zh.md
  10. 6 0
      .agents/notes/archived/bug-fix/2026-08-11-preset-card-description-clamp.i18n.yaml
  11. 1 0
      .agents/notes/archived/bug-fix/2026-08-11-preset-card-description-clamp.md
  12. 1 0
      .agents/notes/archived/bug-fix/2026-08-11-preset-card-description-clamp.zh.md
  13. 6 0
      .agents/notes/archived/feature/2026-07-30-versioned-gui-welcome-onboarding.i18n.yaml
  14. 1 0
      .agents/notes/archived/feature/2026-07-30-versioned-gui-welcome-onboarding.md
  15. 1 0
      .agents/notes/archived/feature/2026-07-30-versioned-gui-welcome-onboarding.zh.md
  16. 6 0
      .agents/notes/archived/feature/2026-08-06-bundled-dsh-badge-skill.i18n.yaml
  17. 1 0
      .agents/notes/archived/feature/2026-08-06-bundled-dsh-badge-skill.md
  18. 1 0
      .agents/notes/archived/feature/2026-08-06-bundled-dsh-badge-skill.zh.md
  19. 6 0
      .agents/notes/archived/feature/2026-08-07-workspace-picker-composer-entry.i18n.yaml
  20. 1 0
      .agents/notes/archived/feature/2026-08-07-workspace-picker-composer-entry.md
  21. 1 0
      .agents/notes/archived/feature/2026-08-07-workspace-picker-composer-entry.zh.md
  22. 6 0
      .agents/notes/archived/feature/2026-08-10-creator-guidance-introduce-cue.i18n.yaml
  23. 1 0
      .agents/notes/archived/feature/2026-08-10-creator-guidance-introduce-cue.md
  24. 1 0
      .agents/notes/archived/feature/2026-08-10-creator-guidance-introduce-cue.zh.md
  25. 6 0
      .agents/notes/archived/feature/2026-08-11-collapsible-ask-user-question-card.i18n.yaml
  26. 1 0
      .agents/notes/archived/feature/2026-08-11-collapsible-ask-user-question-card.md
  27. 1 0
      .agents/notes/archived/feature/2026-08-11-collapsible-ask-user-question-card.zh.md
  28. 6 0
      .agents/notes/archived/feature/2026-08-11-web-export-command-and-dialog.i18n.yaml
  29. 1 0
      .agents/notes/archived/feature/2026-08-11-web-export-command-and-dialog.md
  30. 1 0
      .agents/notes/archived/feature/2026-08-11-web-export-command-and-dialog.zh.md
  31. 6 0
      .agents/notes/archived/feature/2026-08-18-web-home-path-tilde.i18n.yaml
  32. 1 0
      .agents/notes/archived/feature/2026-08-18-web-home-path-tilde.md
  33. 1 0
      .agents/notes/archived/feature/2026-08-18-web-home-path-tilde.zh.md
  34. 6 0
      .agents/notes/archived/feature/2026-08-19-high-cache-hit-decimal-display.i18n.yaml
  35. 1 0
      .agents/notes/archived/feature/2026-08-19-high-cache-hit-decimal-display.md
  36. 1 0
      .agents/notes/archived/feature/2026-08-19-high-cache-hit-decimal-display.zh.md
  37. 51 0
      .agents/notes/archived/manifest.json
  38. 6 0
      .agents/notes/archived/process/2026-08-12-documentation-site-navigation-and-chrome.i18n.yaml
  39. 1 0
      .agents/notes/archived/process/2026-08-12-documentation-site-navigation-and-chrome.md
  40. 1 0
      .agents/notes/archived/process/2026-08-12-documentation-site-navigation-and-chrome.zh.md
  41. 6 0
      .agents/notes/archived/simplification/2026-08-11-cmdline-program-action.i18n.yaml
  42. 1 0
      .agents/notes/archived/simplification/2026-08-11-cmdline-program-action.md
  43. 1 0
      .agents/notes/archived/simplification/2026-08-11-cmdline-program-action.zh.md
  44. 6 0
      .agents/notes/archived/simplification/2026-08-11-quickstart-documentation-home.i18n.yaml
  45. 1 0
      .agents/notes/archived/simplification/2026-08-11-quickstart-documentation-home.md
  46. 1 0
      .agents/notes/archived/simplification/2026-08-11-quickstart-documentation-home.zh.md
  47. 6 0
      .agents/notes/archived/simplification/2026-08-13-remove-first-run-beta-notice.i18n.yaml
  48. 1 0
      .agents/notes/archived/simplification/2026-08-13-remove-first-run-beta-notice.md
  49. 1 0
      .agents/notes/archived/simplification/2026-08-13-remove-first-run-beta-notice.zh.md
  50. 6 0
      .agents/notes/archived/simplification/2026-08-19-knip-config-cleanup.i18n.yaml
  51. 1 0
      .agents/notes/archived/simplification/2026-08-19-knip-config-cleanup.md
  52. 1 0
      .agents/notes/archived/simplification/2026-08-19-knip-config-cleanup.zh.md
  53. 2 2
      .agents/notes/implemented/architecture/2026-06-13-capability-seams.i18n.yaml
  54. 1 1
      .agents/notes/implemented/architecture/2026-06-13-capability-seams.md
  55. 1 1
      .agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md
  56. 2 2
      .agents/notes/implemented/architecture/2026-06-20-branded-ids.i18n.yaml
  57. 1 1
      .agents/notes/implemented/architecture/2026-06-20-branded-ids.md
  58. 1 1
      .agents/notes/implemented/architecture/2026-06-20-branded-ids.zh.md
  59. 2 2
      .agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.i18n.yaml
  60. 1 1
      .agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.md
  61. 1 1
      .agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.zh.md
  62. 2 2
      .agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.i18n.yaml
  63. 1 0
      .agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.md
  64. 1 0
      .agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.zh.md
  65. 2 2
      .agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.i18n.yaml
  66. 1 1
      .agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.md
  67. 1 1
      .agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.zh.md
  68. 2 2
      .agents/notes/implemented/architecture/2026-07-06-tool-result-retention-library.i18n.yaml
  69. 5 5
      .agents/notes/implemented/architecture/2026-07-06-tool-result-retention-library.md
  70. 5 5
      .agents/notes/implemented/architecture/2026-07-06-tool-result-retention-library.zh.md
  71. 2 2
      .agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.i18n.yaml
  72. 5 5
      .agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.md
  73. 5 5
      .agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.zh.md
  74. 2 2
      .agents/notes/implemented/architecture/2026-07-15-llm-model-catalog-and-acp-selection.i18n.yaml
  75. 1 1
      .agents/notes/implemented/architecture/2026-07-15-llm-model-catalog-and-acp-selection.md
  76. 1 1
      .agents/notes/implemented/architecture/2026-07-15-llm-model-catalog-and-acp-selection.zh.md
  77. 2 2
      .agents/notes/implemented/architecture/2026-07-19-gui-layering-and-rpc-protocol.i18n.yaml
  78. 1 1
      .agents/notes/implemented/architecture/2026-07-19-gui-layering-and-rpc-protocol.md
  79. 1 1
      .agents/notes/implemented/architecture/2026-07-19-gui-layering-and-rpc-protocol.zh.md
  80. 2 2
      .agents/notes/implemented/architecture/2026-07-23-toolview-dissolution.i18n.yaml
  81. 1 1
      .agents/notes/implemented/architecture/2026-07-23-toolview-dissolution.md
  82. 1 1
      .agents/notes/implemented/architecture/2026-07-23-toolview-dissolution.zh.md
  83. 2 2
      .agents/notes/implemented/architecture/2026-07-25-web-client-session-scope-and-provide-channel.i18n.yaml
  84. 1 1
      .agents/notes/implemented/architecture/2026-07-25-web-client-session-scope-and-provide-channel.md
  85. 1 1
      .agents/notes/implemented/architecture/2026-07-25-web-client-session-scope-and-provide-channel.zh.md
  86. 2 2
      .agents/notes/implemented/architecture/2026-07-26-job-registry-seam.i18n.yaml
  87. 1 1
      .agents/notes/implemented/architecture/2026-07-26-job-registry-seam.md
  88. 1 1
      .agents/notes/implemented/architecture/2026-07-26-job-registry-seam.zh.md
  89. 2 2
      .agents/notes/implemented/architecture/2026-07-28-api-browser-trust-boundary.i18n.yaml
  90. 1 1
      .agents/notes/implemented/architecture/2026-07-28-api-browser-trust-boundary.md
  91. 1 1
      .agents/notes/implemented/architecture/2026-07-28-api-browser-trust-boundary.zh.md
  92. 2 2
      .agents/notes/implemented/architecture/2026-07-28-directory-picker-capability-seam.i18n.yaml
  93. 1 1
      .agents/notes/implemented/architecture/2026-07-28-directory-picker-capability-seam.md
  94. 1 1
      .agents/notes/implemented/architecture/2026-07-28-directory-picker-capability-seam.zh.md
  95. 2 2
      .agents/notes/implemented/architecture/2026-07-29-dsh-source-launch-tsx-esm.i18n.yaml
  96. 1 1
      .agents/notes/implemented/architecture/2026-07-29-dsh-source-launch-tsx-esm.md
  97. 1 1
      .agents/notes/implemented/architecture/2026-07-29-dsh-source-launch-tsx-esm.zh.md
  98. 2 2
      .agents/notes/implemented/architecture/2026-07-30-config-plane-boundaries.i18n.yaml
  99. 1 1
      .agents/notes/implemented/architecture/2026-07-30-config-plane-boundaries.md
  100. 1 1
      .agents/notes/implemented/architecture/2026-07-30-config-plane-boundaries.zh.md

+ 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-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)
 

+ 1 - 0
.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) | 中文
 

+ 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/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)
 

+ 1 - 0
.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) | 中文
 

+ 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)
 

+ 1 - 0
.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,6 +1,7 @@
 # Agent Note: 内置 dsh 徽章 skill
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-06-bundled-dsh-badge-skill.md) | 中文
 

+ 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)
 

+ 1 - 0
.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,6 +1,7 @@
 # Agent Note: 未选择 Workspace 时从编辑器打开现有选择器
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-07-workspace-picker-composer-entry.md) | 中文
 

+ 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-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

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

@@ -1,6 +1,7 @@
 # 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)
 

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

@@ -1,6 +1,7 @@
 # Agent Note: Web UI abbreviates POSIX home paths as `~`
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-18-web-home-path-tilde.md) | 中文
 

+ 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

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

@@ -1,6 +1,7 @@
 # Agent Note: High cache-hit decimal display
 
 Status: implemented
+Archived: 2026-08-22
 
 English | [中文](2026-08-19-high-cache-hit-decimal-display.zh.md)
 

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

@@ -1,6 +1,7 @@
 # Agent Note: 高缓存命中率的小数显示
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-19-high-cache-hit-decimal-display.md) | 中文
 

+ 51 - 0
.agents/notes/archived/manifest.json

@@ -43,6 +43,9 @@
     "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-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",
@@ -94,9 +97,18 @@
     "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",
@@ -241,6 +253,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 +274,30 @@
     "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-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 +358,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",
@@ -406,6 +445,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",

+ 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-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)
 

+ 1 - 0
.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,6 +1,7 @@
 # Agent Note: parseCmdline 运行 program 自己的 commander action
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-11-cmdline-program-action.md) | 中文
 

+ 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)
 

+ 1 - 0
.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) | 中文
 

+ 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)
 

+ 1 - 0
.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,6 +1,7 @@
 # Agent Note: 移除首次启动内测声明
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-13-remove-first-run-beta-notice.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

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

@@ -1,6 +1,7 @@
 # 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)
 

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

@@ -1,6 +1,7 @@
 # Agent Note: 删除 knip.json 中失效与重复的 workspace 条目
 
 Status: implemented
+Archived: 2026-08-22
 
 [English](2026-08-19-knip-config-cleanup.md) | 中文
 

+ 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: 28b45cbbc7f65a0b783db3d91a2e559132b5779f
+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.
 

+ 1 - 1
.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 决定的是包的边界。
 

+ 2 - 2
.agents/notes/implemented/architecture/2026-06-20-branded-ids.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-20-branded-ids.md
-2026-06-20-branded-ids.md: 68558071c47fb2b74e559b6b9936366911eb6548
-2026-06-20-branded-ids.zh.md: 5ea2547b8ab45534188a6a4a9e61f3458358beb3
+2026-06-20-branded-ids.md: b282993be1cfbb1ee67057ab8ba7bd2cbbfd1eac
+2026-06-20-branded-ids.zh.md: 862c7eb72b08f4cf0be8ff9cd9bc757e5b36c32a

+ 1 - 1
.agents/notes/implemented/architecture/2026-06-20-branded-ids.md

@@ -56,7 +56,7 @@ Kept deliberately narrow per the "not every string needs a brand" policy. Each o
 - **`ToolName`** (the `ToolRuntime` key) — author-defined, human-readable, and rarely confused with another id; the weakest candidate, likely not worth a brand.
 - **`ErrorCode`** (`HarnessError.code`) — a closed vocabulary (`ABORTED`, `NO_ADAPTER`, …), not a per-instance id; better served by a string-literal union than a brand, if anything.
 - **Numeric ordinals** — turn number, step number, and the event `seq` are `number`, not `string`, so `Branded<string>` does not apply; a parallel `number & { readonly [BRAND]: B }` variant could brand them, but they are positional ordinals rarely passed across boundaries, so the payoff is low.
-- **Validated construction** — the brand factories are pure casts with no runtime check, and every boundary (ACP `sessionId`, provider-issued `call.id`, the empty-string fallback in `dsh-llm-deepseek`) trusts the raw string today. A `SessionId.parse()` / `isValid()` companion that throws on malformed input at boundaries is a genuine gap, but it is a *runtime-behavior* change with its own design (what is "malformed"? what happens on failure?) and belongs in its own decision, not bundled into this type-only change.
+- **Validated construction** — the brand factories are pure casts with no runtime check, and every boundary (ACP `sessionId`, provider-issued `call.id`, the empty-string fallback in `dsh-llm-deepseek`) trusts the raw string. A `SessionId.parse()` / `isValid()` companion that throws on malformed input at boundaries is a genuine gap, but it is a *runtime-behavior* change with its own design (what is "malformed"? what happens on failure?) and belongs in its own decision, not bundled into this type-only change.
 
 ## Verification
 

+ 1 - 1
.agents/notes/implemented/architecture/2026-06-20-branded-ids.zh.md

@@ -56,7 +56,7 @@ export function OwnerToken(id: string): OwnerToken {
 - **`ToolName`**(`ToolRuntime` 的键):由作者定义、人类可读,且很少与其他 id 混淆;最弱的候选,可能不值得加 brand。
 - **`ErrorCode`**(`HarnessError.code`):一个封闭词汇(`ABORTED`、`NO_ADAPTER`……),不是逐实例的 id;如果要做,string 字面量联合类型比 brand 更合适。
 - **数值序号**:轮次号、步骤号和事件 `seq` 是 `number` 而非 `string`,`Branded<string>` 不适用;可以用并行的 `number & { readonly [BRAND]: B }` 变体来 brand 它们,但它们是位置序号、很少跨边界传递,收益较低。
-- **带校验的构造**:brand 工厂是纯 cast,无运行时检查,且每个边界(ACP `sessionId`、提供方签发的 `call.id`、`dsh-llm-deepseek` 中的空字符串回退)今天都信任裸 string。一个在边界处对格式错误的输入抛异常的 `SessionId.parse()` / `isValid()` 配套工具确实是缺口,但它是*运行时行为*变更,有自己的设计问题(什么算「格式错误」?失败时会怎样?),应在独立决策中处理,不应捆绑进这次纯类型变更。
+- **带校验的构造**:brand 工厂是纯 cast,无运行时检查,且每个边界(ACP `sessionId`、提供方签发的 `call.id`、`dsh-llm-deepseek` 中的空字符串回退)都信任裸 string。一个在边界处对格式错误的输入抛异常的 `SessionId.parse()` / `isValid()` 配套工具确实是缺口,但它是*运行时行为*变更,有自己的设计问题(什么算「格式错误」?失败时会怎样?),应在独立决策中处理,不应捆绑进这次纯类型变更。
 
 ## 验证
 

+ 2 - 2
.agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.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-21-mandatory-app-attribution-headers.md
-2026-06-21-mandatory-app-attribution-headers.md: 479d3a46dc41c5cc9ae9b77b81dbef3d6524370b
-2026-06-21-mandatory-app-attribution-headers.zh.md: 1b11cb6ef1e96609c6777134a85de298ca979c58
+2026-06-21-mandatory-app-attribution-headers.md: 9e0c029dc03c722512680a563c24e470128ee322
+2026-06-21-mandatory-app-attribution-headers.zh.md: 1427daf8f6065ec2dee324075a8381a625d9e960

+ 1 - 1
.agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.md

@@ -42,7 +42,7 @@ Wire mapping (`attributionHeaders`; header names lowercase in code - HTTP field
 |---|---|
 | All HTTP-based adapters | `User-Agent: {product}/{version} (+{url})` - the parenthesized `+url` comment stays within RFC 9110's conservative product/comment syntax. |
 | Direct DeepSeek endpoint | `User-Agent` for app attribution; `x-deepseek-harness-user-id` and conditional `x-deepseek-harness-session-id` are separate request identity under the DeepSeek-specific decision. Do not send OpenRouter-only headers unless DeepSeek documents an equivalent contract. |
-| OpenRouter endpoints | `User-Agent` only for now. Do not send `HTTP-Referer`, `X-OpenRouter-Title`, `X-Title`, or `X-OpenRouter-Categories` under this decision. |
+| OpenRouter endpoints | `User-Agent` only. This decision excludes `HTTP-Referer`, `X-OpenRouter-Title`, `X-Title`, and `X-OpenRouter-Categories`. |
 | Future providers | `User-Agent` only unless a later provider-specific Agent Note accepts additional headers. Do not reuse `HTTP-Referer` by analogy. |
 
 Endpoint detection is not part of this Agent Note because no endpoint-specific mapping is accepted here. If OpenRouter support lands later, detection must be explicit: either a dedicated OpenRouter provider package or an explicit `provider: 'openrouter'` / `attributionTarget: 'openrouter'` config, not arbitrary path fragments or model names.

+ 1 - 1
.agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.zh.md

@@ -42,7 +42,7 @@ OpenRouter 应用归属刻意未实现。`HTTP-Referer`、`X-OpenRouter-Title`
 |---|---|
 | 所有基于 HTTP 的适配器 | `User-Agent: {product}/{version} (+{url})`——括号中的 `+url` 注释符合 RFC 9110 保守的 product/comment 语法。 |
 | 直连 DeepSeek 端点 | `User-Agent` 用于应用归属;`x-deepseek-harness-user-id` 与条件性的 `x-deepseek-harness-session-id` 由 DeepSeek 特有决策作为独立请求身份管理。除非 DeepSeek 文档化了等效约定,否则不发送 OpenRouter 特有头部。 |
-| OpenRouter 端点 | 目前仅 `User-Agent`。本决策下不发送 `HTTP-Referer`、`X-OpenRouter-Title`、`X-Title` 或 `X-OpenRouter-Categories`。 |
+| OpenRouter 端点 | 仅发送 `User-Agent`。本决策排除 `HTTP-Referer`、`X-OpenRouter-Title`、`X-Title` 与 `X-OpenRouter-Categories`。 |
 | 未来提供方 | 仅 `User-Agent`,除非后续提供方特有的 Agent Note 接受额外头部。不要类比复用 `HTTP-Referer`。 |
 
 端点检测不在本 Agent Note 范围内,因为此处不接受任何端点特有的映射。如果后续支持 OpenRouter,检测必须是显式的:要么是专门的 OpenRouter 提供方包,要么是显式的 `provider: 'openrouter'` / `attributionTarget: 'openrouter'` 配置,而非任意路径片段或模型名称。

+ 2 - 2
.agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.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-07-05-reconstructable-requests.md
-2026-07-05-reconstructable-requests.md: 63146fa2d392a45543daa32ce2b00158782fddb2
-2026-07-05-reconstructable-requests.zh.md: 94c1d323be0107eb8b6072a05d1e8832ebd1fffc
+2026-07-05-reconstructable-requests.md: 3f49ba71a6b98a84b05530c900e902b0cf9f6449
+2026-07-05-reconstructable-requests.zh.md: 7b8a9df65b60f975bc3ae60b2c1b0c3a8cc22e95

+ 1 - 0
.agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.md

@@ -51,5 +51,6 @@ Like MiniCode, the conversation advances append-only and resets only when model-
 - What still costs full price at the provider is inherent and logged: compaction (its `compaction/*` events and replacement entry), a real prompt, tool, or config change (`request/header` with reason `change`), or a process boundary with drift (a differing `resume` snapshot). The provider's own reasoning-content exclusion is managed server-side.
 - `agent/pre-step` is the current-request message channel; direct inbox mutation is the eventual later-request channel.
 - Tool-result trimming needs no new mechanism: a logged single-entry surface replace (`start === end`) carrying a trimmed `tool/result` under the same `callId` — compaction-family, replay-correct, cache-bust batched by the same pressure logic.
+- Unreadable referenced attachment objects still fail model requests; [automatic attachment quarantine](../../proposed/bug-fix/2026-08-20-attachment-read-quarantine.md) records the proposed recovery without weakening byte-exact reconstruction.
 - Session logs grow one `request/header` snapshot per loop instance plus snapshots on real changes. This is larger than a delta codec but small beside chunk-heavy logs and retains one replay representation. `SESSION_FORMAT_VERSION` stays `0`; legacy delta events are rejected rather than migrated.
 - Snapshot expected outputs changed once (every transcript gains its header events); the fs-writing fixtures are stored in the normalized authored form with cwd-relative tool arguments, because replay only round-trips cwd-independent argument paths.

+ 1 - 0
.agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.zh.md

@@ -51,5 +51,6 @@ Status: implemented
 - 在提供方处仍需全价计算的内容是固有的且已记录的:压缩(其 `compaction/*` 事件和替换条目)、真正的提示词、工具或配置变更(reason 为 `change` 的 `request/header`),或带漂移的进程边界(不同的 `resume` 快照)。提供方自身的 reasoning-content 排除由服务端管理。
 - `agent/pre-step` 是当前请求的消息通道;直接修改 inbox 则是最终进入后续请求的通道。
 - 工具结果裁剪无需新机制:一个已记录的单条目 surface replace(`start === end`),携带同一 `callId` 下裁剪后的 `tool/result`——属压缩家族,回放正确,缓存失效由相同的压力逻辑批量处理。
+- 无法读取的被引用附件对象仍会让模型请求失败;[附件自动隔离](../../proposed/bug-fix/2026-08-20-attachment-read-quarantine.zh.md)记录了不削弱字节精确重建的拟议恢复方案。
 - 会话日志每个循环实例增长一个 `request/header` 快照,并在真正变更时增加快照。它比 delta 编解码器更大,但相对分片密集型日志仍然很小,并只保留一种回放表示。`SESSION_FORMAT_VERSION` 保持 `0`;旧的 delta 事件被拒绝而非迁移。
 - 快照预期输出变更一次(每个 transcript(文本记录)增加其 header 事件);写入文件系统的 fixture(测试前置数据)以规范化的撰写形式存储,工具参数使用 cwd 相对路径,因为回放只对 cwd 无关的参数路径做往返。

+ 2 - 2
.agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.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-07-06-timeout-deadline-library.md
-2026-07-06-timeout-deadline-library.md: 38f048d16ecba0e5278ae34b0c88b7889dcfa47a
-2026-07-06-timeout-deadline-library.zh.md: c8d189c2a7588ee57b0f7fe02137b78c9ad7ff9d
+2026-07-06-timeout-deadline-library.md: 95adc41bffff6d7711685ebc52cb73b2b455df41
+2026-07-06-timeout-deadline-library.zh.md: 8b7b18a2d1e7757102afc81bea03245de2707d86

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.md

@@ -8,7 +8,7 @@ English | [中文](2026-07-06-timeout-deadline-library.zh.md)
 
 Timeout handling was drifting apart across the tool-bearing capabilities, and the divergence was not superficial — it was the same logic re-implemented three ways, each with its own subtle correctness burden.
 
-- **bash** (then in the bash-local implementation's `run.ts`) had a full, correct timeout inside the process plumbing: a config-clamped `timeoutMs`, two independent triggers — a `killTimer` for the timeout and an `onAbort` listener for upstream cancellation — each calling one `kill()` closure that escalates SIGTERM→grace→SIGKILL on the process group, and two orthogonal outcome booleans (`timedOut`, `aborted`) latched independently. After this consolidation, the plumbing — today [packages/subprocess/subprocess-local/src/spawn.ts](../../../../packages/subprocess/subprocess-local/src/spawn.ts) — only reacts to aborts; [packages/shell/bash-local/src/index.ts](../../../../packages/shell/bash-local/src/index.ts) owns the fused deadline and the `timedOut`/`aborted` classification.
+- **bash** (then in the bash-local implementation's `run.ts`) had a full, correct timeout inside the process plumbing: a config-clamped `timeoutMs`, two independent triggers — a `killTimer` for the timeout and an `onAbort` listener for upstream cancellation — each calling one `kill()` closure that escalates SIGTERM→grace→SIGKILL on the process group, and two orthogonal outcome booleans (`timedOut`, `aborted`) latched independently. After this consolidation, the plumbing — [packages/subprocess/subprocess-local/src/spawn.ts](../../../../packages/subprocess/subprocess-local/src/spawn.ts) — only reacts to aborts; [packages/shell/bash-local/src/index.ts](../../../../packages/shell/bash-local/src/index.ts) owns the fused deadline and the `timedOut`/`aborted` classification.
 - **web_fetch** ([packages/web/web-fetch-http/src/provider.ts](../../../../packages/web/web-fetch-http/src/provider.ts)) had a correct but *hand-rolled* timeout: it constructed an `AbortController`, wired `setTimeout(() => controller.abort(new WebError(…, 'WEB_FETCH_TIMEOUT')))`, manually added and removed the upstream-signal listener, cleared the timer in a `finally`, and recovered the timeout reason from `signal.reason` in a `translateAbortOrNetwork` helper because the reader surfaces a bare `AbortError`.
 - **web_search** ([packages/web/tool-web/src/search.ts](../../../../packages/web/tool-web/src/search.ts)) had **no timeout at all**: `WebSearchRequest` ([packages/web/web/src/types.ts](../../../../packages/web/web/src/types.ts)) carries no `timeoutMs` field, and each provider's `search()` only forwards `exec.signal`. (web_search stays untimed here — see Consequences.)
 

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.zh.md

@@ -8,7 +8,7 @@ Status: implemented
 
 超时处理在各个承载工具的能力之间逐渐分化,而且这种分化并非表面的:同一套逻辑被以三种方式重新实现,各自带有微妙的正确性负担。
 
-- **bash**(当时位于 bash-local 实现的 `run.ts`)在进程管道内部有一套完整、正确的超时实现:一个经配置钳位的 `timeoutMs`,两个独立触发器(用于超时的 `killTimer` 和用于上游取消的 `onAbort` 监听器),各自调用同一个 `kill()` 闭包对进程组执行 SIGTERM→宽限期→SIGKILL 升级,以及两个正交的结果布尔值(`timedOut`、`aborted`)独立锁存。经此次整合之后,这套管道——今天位于 [packages/subprocess/subprocess-local/src/spawn.ts](../../../../packages/subprocess/subprocess-local/src/spawn.ts)——只响应中止;[packages/shell/bash-local/src/index.ts](../../../../packages/shell/bash-local/src/index.ts) 拥有融合的 deadline 以及 `timedOut`/`aborted` 分类。
+- **bash**(当时位于 bash-local 实现的 `run.ts`)在进程管道内部有一套完整、正确的超时实现:一个经配置钳位的 `timeoutMs`,两个独立触发器(用于超时的 `killTimer` 和用于上游取消的 `onAbort` 监听器),各自调用同一个 `kill()` 闭包对进程组执行 SIGTERM→宽限期→SIGKILL 升级,以及两个正交的结果布尔值(`timedOut`、`aborted`)独立锁存。经此次整合之后,这套管道——位于 [packages/subprocess/subprocess-local/src/spawn.ts](../../../../packages/subprocess/subprocess-local/src/spawn.ts)——只响应中止;[packages/shell/bash-local/src/index.ts](../../../../packages/shell/bash-local/src/index.ts) 拥有融合的 deadline 以及 `timedOut`/`aborted` 分类。
 - **web_fetch**([packages/web/web-fetch-http/src/provider.ts](../../../../packages/web/web-fetch-http/src/provider.ts))有一套正确但*手写*的超时:构造一个 `AbortController`,连接 `setTimeout(() => controller.abort(new WebError(…, 'WEB_FETCH_TIMEOUT')))`,手动添加和移除上游信号监听器,在 `finally` 中清除定时器,并在 `translateAbortOrNetwork` 辅助函数中从 `signal.reason` 恢复超时原因(因为 reader 只抛出裸 `AbortError`)。
 - **web_search**([packages/web/tool-web/src/search.ts](../../../../packages/web/tool-web/src/search.ts))**完全没有超时**:`WebSearchRequest`([packages/web/web/src/types.ts](../../../../packages/web/web/src/types.ts))不携带 `timeoutMs` 字段,各提供方的 `search()` 只转发 `exec.signal`。(web_search 在本次设计中保持无超时——见「后果」。)
 

+ 2 - 2
.agents/notes/implemented/architecture/2026-07-06-tool-result-retention-library.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-07-06-tool-result-retention-library.md
-2026-07-06-tool-result-retention-library.md: 8d938db8f5fa78398a39e97cc877308200f7d60f
-2026-07-06-tool-result-retention-library.zh.md: 747b545ee8c900c13d80c7aef6caecc8ae8dc0ad
+2026-07-06-tool-result-retention-library.md: 464e3d51a0051487b7c29f0c01a11acb91d160e5
+2026-07-06-tool-result-retention-library.zh.md: 49361eec4b649d2d68dc36929baa0f9ff580eb68

+ 5 - 5
.agents/notes/implemented/architecture/2026-07-06-tool-result-retention-library.md

@@ -16,7 +16,7 @@ The shared abstraction the tools need is **retention**, not generic collection.
 
 The library has two independent retainers:
 
-- `ItemRetainer<T>` handles ordered logical units such as paths, grep matches, or search sources. It supports `head` retention only in v1, while keeping the retainer shape open to additional retention strategies later.
+- `ItemRetainer<T>` handles ordered logical units such as paths, grep matches, or search sources. It supports only `head` retention, while keeping the retainer shape open to additional strategies.
 - `TextRetainer` handles byte-oriented text streams such as bash stdout/stderr or web response bodies. It supports `head`, `tail`, and `headTail` retention while preserving UTF-8 boundaries at `finish()`.
 
 Both retainers return a small `PushDecision` after each `push()` so callers can tell whether that unit/chunk was fully retained and whether the accumulated result is now truncated. Omission counts are exact because callers keep feeding every observed item/chunk.
@@ -95,7 +95,7 @@ type TextRetentionStrategy =
 
 ### Tool mapping
 
-`read` is intentionally outside the v1 retention library. Its `read-render` helper owns a file-specific pagination contract: `offset` / `limit`, line numbers, `totalLines`, offset-out-of-range errors, per-line preview truncation, and a selected-output byte cap that can stop scanning mid-window. That is a line-window renderer, not a generic retention primitive. It may share future neutral notice helpers, but it should not pass its already-selected window through `ItemRetainer`.
+`read` is intentionally outside the retention library. Its `read-render` helper owns a file-specific pagination contract: `offset` / `limit`, line numbers, `totalLines`, offset-out-of-range errors, per-line preview truncation, and a selected-output byte cap that can stop scanning mid-window. That is a line-window renderer, not a generic retention primitive. It may share future neutral notice helpers, but it should not pass its already-selected window through `ItemRetainer`.
 
 `FsGlobEntry` and `FlatGrepMatch` below are the intended discovery-tool item shapes, not existing retention-library exports. `FsGlobEntry` is one backend-derived path, and `FlatGrepMatch` is one ungrouped grep match before the backend groups retained matches by file.
 
@@ -142,15 +142,15 @@ The formatter hook is deliberately small: a tool turns a `RetentionNotice` into
 
 **Boundaries the library holds.** `truncated` means the retainer omitted otherwise-available content because of a budget; it never means the upstream was incomplete. Tool-specific states — `incomplete`, permission failures, provider partial failures, binary skips, bash spill-path recovery, invalid UTF-8 — stay in tool-domain fields, outside the retainer. When a future change migrates a tool, that package's README and tests must prove the model-facing result text is unchanged except for deliberate notice wording.
 
-**Tradeoffs accepted.** The v1 API deliberately supports only item `head` retention and text `head` / `tail` / `headTail`; windows, grouped budgets, sort-aware caps, and upstream-stop control wait until a second consumer proves the need. Text retention counts bytes for process/body safety, leaving character- and line-level preview budgets as separate tool-owned concerns.
+**Tradeoffs accepted.** The API deliberately supports only item `head` retention and text `head` / `tail` / `headTail`; windows, grouped budgets, sort-aware caps, and upstream-stop control wait until a second consumer proves the need. Text retention counts bytes for process/body safety, leaving character- and line-level preview budgets as separate tool-owned concerns.
 
 ## Alternatives considered
 
 **Post-hoc `truncate(text)` only.** Rejected: it matches Codex's history/tool-output truncation use case but loses item counts, grouping boundaries, UTF-8-safe byte windows, and exact omission metadata.
 
-**One generic `Collector<T>` with pluggable callbacks.** Rejected for v1: it hides the two important resource modes. Logical item retention counts items; text retention counts bytes and preserves UTF-8 boundaries. Separate `ItemRetainer` and `TextRetainer` names make that difference explicit while keeping the API small.
+**One generic `Collector<T>` with pluggable callbacks.** Rejected: it hides the two important resource modes. Logical item retention counts items; text retention counts bytes and preserves UTF-8 boundaries. Separate `ItemRetainer` and `TextRetainer` names make that difference explicit while keeping the API small.
 
-**Put `read` windowing behind `ItemRetainer`.** Rejected for v1: `read` is the only current window consumer, and its semantics are file pagination rather than generic retention. A single `Omitted` count cannot represent both sides of a line window, and `read` also carries `totalLines`, offset-range errors, per-line preview truncation, and a byte cap over selected output. Keeping `read-render` tool-owned avoids growing the shared library around one special case.
+**Put `read` windowing behind `ItemRetainer`.** Rejected: `read` is the only shipped window consumer, and its semantics are file pagination rather than generic retention. A single `Omitted` count cannot represent both sides of a line window, and `read` also carries `totalLines`, offset-range errors, per-line preview truncation, and a byte cap over selected output. Keeping `read-render` tool-owned avoids growing the shared library around one special case.
 
 **Make truncation part of `ToolExecutionResult`.** Rejected: the tool registry would have to understand tool-specific recovery guidance, grouping, line numbering, exit status, and provider semantics. Retention is a library used by a tool's Native renderer; the model-facing projection remains tool-owned while the [canonical value](2026-07-20-canonical-tool-output-contract.md) may retain the complete acquired result.
 

+ 5 - 5
.agents/notes/implemented/architecture/2026-07-06-tool-result-retention-library.zh.md

@@ -16,7 +16,7 @@ Status: implemented
 
 该库包含两个相互独立的 retainer:
 
-- `ItemRetainer<T>` 处理有序逻辑单元,例如路径、grep 匹配项或搜索来源。v1 只支持 `head` 保留,同时维持 retainer 形态,以便未来加入其他保留策略。
+- `ItemRetainer<T>` 处理有序逻辑单元,例如路径、grep 匹配项或搜索来源。只支持 `head` 保留,同时维持 retainer 形态,以便未来加入其他保留策略。
 - `TextRetainer` 处理面向字节的文本流,例如 bash stdout/stderr 或 web 响应正文。它支持 `head`、`tail` 和 `headTail` 保留,并在 `finish()` 时维持 UTF-8 边界。
 
 两个 retainer 都会返回一个小型 `PushDecision`;每次调用 `push()` 后,调用方都能得知该单元/分片是否完整保留,以及累积结果此时是否已被截断。因为调用方会继续输入每一个已观察到的条目/分片,所以省略计数是精确的。
@@ -95,7 +95,7 @@ type TextRetentionStrategy =
 
 ### 工具映射
 
-`read` 被有意排除在 v1 保留库之外。它的 `read-render` 辅助函数拥有文件专用的分页约定:`offset`/`limit`、行号、`totalLines`、offset 越界错误、逐行预览截断,以及能够在窗口中途停止扫描的所选输出字节上限。这是行窗口渲染器,不是通用保留原语。它未来可以共享中性的提示辅助函数,但不应把已经选定的窗口再传入 `ItemRetainer`。
+`read` 被有意排除在保留库之外。它的 `read-render` 辅助函数拥有文件专用的分页约定:`offset`/`limit`、行号、`totalLines`、offset 越界错误、逐行预览截断,以及能够在窗口中途停止扫描的所选输出字节上限。这是行窗口渲染器,不是通用保留原语。它未来可以共享中性的提示辅助函数,但不应把已经选定的窗口再传入 `ItemRetainer`。
 
 下文的 `FsGlobEntry` 与 `FlatGrepMatch` 是预期由发现工具使用的条目形态,不是现有保留库的导出。`FsGlobEntry` 是一个由后端派生的路径;`FlatGrepMatch` 是后端将保留匹配项按文件分组之前的一条未分组 grep 匹配。
 
@@ -142,15 +142,15 @@ const formatGrepNotice = (notice: RetentionNotice): string =>
 
 **该库维持的边界。** `truncated` 表示 retainer 因预算省略了原本可用的内容,绝不表示上游不完整。工具专用状态,包括 `incomplete`、权限失败、提供方局部失败、跳过二进制文件、bash spill 路径恢复和无效 UTF-8,均留在工具领域字段中、位于 retainer 之外。未来改动迁移某项工具时,该包的 README 与测试必须证明,除了有意改变的提示措辞外,模型可见的结果文本没有变化。
 
-**接受的取舍。** v1 接口刻意只支持条目的 `head` 保留,以及文本的 `head`/`tail`/`headTail` 保留;窗口、分组预算、感知排序的上限和上游停止控制,要等第二个消费方证明需求后再引入。文本保留按字节计数,以保障进程/正文安全;字符级和行级预览预算继续由具体工具负责。
+**接受的取舍。**接口刻意只支持条目的 `head` 保留,以及文本的 `head`/`tail`/`headTail` 保留;窗口、分组预算、感知排序的上限和上游停止控制,要等第二个消费方证明需求后再引入。文本保留按字节计数,以保障进程/正文安全;字符级和行级预览预算继续由具体工具负责。
 
 ## 考虑过的替代方案
 
 **只进行事后 `truncate(text)`。** 不予采纳:它适合 Codex 的历史/工具输出截断场景,却会丢失条目计数、分组边界、UTF-8 安全的字节窗口与精确省略元数据。
 
-**使用一个带可插拔回调的通用 `Collector<T>`。** v1 不予采纳,因为它会掩盖两种重要的资源模式。逻辑条目保留按条目计数;文本保留按字节计数并维持 UTF-8 边界。独立的 `ItemRetainer` 与 `TextRetainer` 名称明确表达这种差异,同时保持 API 精简。
+**使用一个带可插拔回调的通用 `Collector<T>`。**不予采纳,因为它会掩盖两种重要的资源模式。逻辑条目保留按条目计数;文本保留按字节计数并维持 UTF-8 边界。独立的 `ItemRetainer` 与 `TextRetainer` 名称明确表达这种差异,同时保持 API 精简。
 
-**把 `read` 窗口交给 `ItemRetainer`。** v1 不予采纳:`read` 是当前唯一的窗口消费方,其语义属于文件分页,而不是通用保留。一个 `Omitted` 计数无法表示行窗口两侧,而且 `read` 还携带 `totalLines`、offset 范围错误、逐行预览截断和针对所选输出的字节上限。让 `read-render` 由工具所有,可以避免共享库围绕一项特例膨胀。
+**把 `read` 窗口交给 `ItemRetainer`。**不予采纳:`read` 是唯一已交付的窗口消费方,其语义属于文件分页,而不是通用保留。一个 `Omitted` 计数无法表示行窗口两侧,而且 `read` 还携带 `totalLines`、offset 范围错误、逐行预览截断和针对所选输出的字节上限。让 `read-render` 由工具所有,可以避免共享库围绕一项特例膨胀。
 
 **让截断成为 `ToolExecutionResult` 的一部分。** 不予采纳:工具注册表将不得不理解工具专用的恢复指引、分组、行号、退出状态和提供方语义。保留是由工具的 Native renderer(原生渲染器)使用的库;模型可见投影继续由工具所有,而[规范值](2026-07-20-canonical-tool-output-contract.zh.md)可以保留完整的已采集结果。
 

+ 2 - 2
.agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.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-07-08-tool-output-spill-files.md
-2026-07-08-tool-output-spill-files.md: 341cb1ce131f627eed0f76ca6eb6a26fbb9dc689
-2026-07-08-tool-output-spill-files.zh.md: bd7c5dc058a8c753cefff3dd81802802426529ec
+2026-07-08-tool-output-spill-files.md: 343b1af889ec14d5cac265ca6a7d073f9c0e4a06
+2026-07-08-tool-output-spill-files.zh.md: d6a163500a9e247fde46fadd2ada38ce60ce7b18

+ 5 - 5
.agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.md

@@ -147,8 +147,8 @@ Those cases can consume `ctx.spillStore` directly in later work. They are not pa
 
 ## Non-goals
 
-- No new model-facing `artifact_read` or `artifact_search` tool in v1.
-- No per-tool retention configuration in v1.
+- This decision adds no model-facing `artifact_read` or `artifact_search` tool.
+- This decision adds no per-tool retention configuration.
 - No model-facing timeout/truncation arguments.
 - No migration of `read` output into spill files.
 - No replacement for provider/resource caps such as `web-fetch-http.maxBodyChars`.
@@ -174,9 +174,9 @@ Those cases can consume `ctx.spillStore` directly in later work. They are not pa
 
 The default policy only sees final formatted text. It cannot preserve provider-internal content that was already capped or runtime artifacts that were never part of the result. This is acceptable for the first cut because the showcase is final-result spill, not early spill; tool-owned early spill remains deferred work.
 
-Returning real paths from the local backend keeps v1 simple and matches proven agent-tool behavior, while the seam itself only promises an opaque locator plus retrieval hint so remote backends can return non-file locators.
+Returning real paths keeps the local backend simple and matches proven agent-tool behavior, while the seam itself only promises an opaque locator plus retrieval hint so remote backends can return non-file locators.
 
-The local-backend value proposition depends on the existing `read`/`grep` tools being able to inspect the returned local path, even when the spill directory is outside the session cwd. That holds today because the filesystem policy records observations and write guards but does not confine reads to the workspace. A future workspace-confinement policy must either allow local spill paths explicitly or use a non-file spill backend whose retrieval hint points at a supported reader.
+The local-backend value proposition depends on the existing `read`/`grep` tools being able to inspect the returned local path, even when the spill directory is outside the session cwd. That holds because the filesystem policy records observations and write guards but does not confine reads to the workspace. A future workspace-confinement policy must either allow local spill paths explicitly or use a non-file spill backend whose retrieval hint points at a supported reader.
 
 **Snapshot gap.** No ACP snapshot scenario covers the transcript-visible `web_fetch` spill notice yet. The ACP snapshot harness replays keyless and cannot hit the live web, and a `web_fetch` spill requires a real over-cap HTTP body; a deterministic scenario would need a seeded loopback fetch target the replay tree does not currently wire (the examples do not load `tool-web` at all). The behavior is covered instead by the `dsh-tool-web` integration test against a loopback server. Closing the gap is follow-up work: wire `tool-web` + a seeded fetch target into the ACP example, then record a `web-fetch-spill` scenario.
 
@@ -184,7 +184,7 @@ The policy can become too large if it starts owning tool-specific semantics. It
 
 ## Alternatives considered
 
-**Require each tool to opt in with a retention declaration.** Rejected for v1: the goal is a default behavior similar to Claude Code's generic tool-result persistence. A single `maxInlineBytes` deployment knob is enough to prove the shape.
+**Require each tool to opt in with a retention declaration.** Rejected: the goal is a default behavior similar to Claude Code's generic tool-result persistence. A single `maxInlineBytes` deployment knob is enough to prove the shape.
 
 **Make `tool-results` a broad tool-result platform.** Rejected: a broad package name invites retention policy, result replacement, preview wording, search, and early spill into one seam. The shared storage part is smaller: save text and return a locator plus retrieval hint.
 

+ 5 - 5
.agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.zh.md

@@ -147,8 +147,8 @@ ctx.tools.register(defineTool({
 
 ## 非目标
 
-- v1 不增加面向模型的 `artifact_read` 或 `artifact_search` 工具。
-- v1 不增加逐工具的保留配置。
+- 本决策不增加面向模型的 `artifact_read` 或 `artifact_search` 工具。
+- 本决策不增加逐工具的保留配置。
 - 不增加面向模型的超时/截断参数。
 - 不把 `read` 输出迁移到 spill 文件。
 - 不取代 `web-fetch-http.maxBodyChars` 等提供方/资源上限。
@@ -174,9 +174,9 @@ ctx.tools.register(defineTool({
 
 默认策略只能看见最终格式化文本。它无法保留已经由提供方限制的内部内容,也无法保留从未成为结果一部分的运行时产物。第一版聚焦最终结果 spill 而不是提前 spill,因此可以接受这一限制;由工具负责的提前 spill 仍属于后续工作。
 
-本地后端返回真实路径,使 v1 保持简单并符合已经验证的 agent(智能体)工具行为;seam 本身只承诺一个不透明定位符加检索提示,所以远程后端可以返回非文件定位符。
+本地后端返回真实路径,使保持简单并符合已经验证的 agent(智能体)工具行为;seam 本身只承诺一个不透明定位符加检索提示,所以远程后端可以返回非文件定位符。
 
-本地后端的价值取决于现有 `read`/`grep` 工具能否检查返回的本地路径,即使 spill 目录位于会话 cwd 之外。目前这一条件成立,因为文件系统策略会记录观察结果并设置写保护,但不会把读取限制在工作区内。未来的工作区限制策略必须显式允许本地 spill 路径,或改用检索提示指向受支持读取器的非文件 spill 后端。
+本地后端的价值取决于现有 `read`/`grep` 工具能否检查返回的本地路径,即使 spill 目录位于会话 cwd 之外。这一条件成立,因为文件系统策略会记录观察结果并设置写保护,但不会把读取限制在工作区内。未来的工作区限制策略必须显式允许本地 spill 路径,或改用检索提示指向受支持读取器的非文件 spill 后端。
 
 **快照缺口。** 目前没有 ACP 快照场景覆盖 transcript(文本记录)可见的 `web_fetch` spill 提示。ACP 快照 harness 在无密钥环境中回放,无法访问实时 web,而 `web_fetch` spill 需要一个真实的超上限 HTTP 正文;确定性场景需要一个预置的 loopback fetch 目标,但当前回放树尚未接线(示例根本没有加载 `tool-web`)。该行为改由 `dsh-tool-web` 针对 loopback server 的集成测试覆盖。弥补该缺口属于后续工作:把 `tool-web` 和预置 fetch 目标接入 ACP 示例,然后录制 `web-fetch-spill` 场景。
 
@@ -184,7 +184,7 @@ ctx.tools.register(defineTool({
 
 ## 考虑过的替代方案
 
-**要求每个工具通过保留声明选择加入。** v1 不予采纳,因为目标是实现类似 Claude Code 通用工具结果持久化的默认行为。只需一个 `maxInlineBytes` 部署配置项即可验证该形态。
+**要求每个工具通过保留声明选择加入。**不予采纳,因为目标是实现类似 Claude Code 通用工具结果持久化的默认行为。只需一个 `maxInlineBytes` 部署配置项即可验证该形态。
 
 **把 `tool-results` 建成宽泛的工具结果平台。** 不予采纳:宽泛的包名会诱使系统把保留策略、结果替换、预览措辞、搜索和提前 spill 合并进一个 seam。可共享的存储部分更小:保存文本,并返回定位符与检索提示。
 

+ 2 - 2
.agents/notes/implemented/architecture/2026-07-15-llm-model-catalog-and-acp-selection.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-07-15-llm-model-catalog-and-acp-selection.md
-2026-07-15-llm-model-catalog-and-acp-selection.md: 8a7b882c3c6b6e6153a2d3b26d5c56440cb09658
-2026-07-15-llm-model-catalog-and-acp-selection.zh.md: 77c27bf1f2148ecae7ab8857572bf58fbc3086a9
+2026-07-15-llm-model-catalog-and-acp-selection.md: 55d6f58ce05e72fc28d55320695f67216f3f8061
+2026-07-15-llm-model-catalog-and-acp-selection.zh.md: b1a43a0092bc2f71d058a69dca28aed4f18380e7

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-15-llm-model-catalog-and-acp-selection.md

@@ -28,7 +28,7 @@ Catalog membership is advisory. It drives selectors and diagnostics but never ch
 
 ### Per-session selection in the front end
 
-A selection is owned by the front end that offers it (today the TUI `/model` selector), never by `LlmRuntime` or `AgentOptions`: those are deployment-wide or creation-wide objects, and mutating them would couple concurrent sessions. Each opaque choice carries the full provider/model pair, because the same model id may appear under multiple routes.
+A selection is owned by the front end that offers it, never by `LlmRuntime` or `AgentOptions`: those are deployment-wide or creation-wide objects, and mutating them would couple concurrent sessions. Each opaque choice carries the full provider/model pair, because the same model id may appear under multiple routes.
 
 The ACP automation transport is not a catalog consumer. Its deployment config supplies one optional provider/model target for newly created agents, and it advertises no model selector or configuration-option interface.
 

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-15-llm-model-catalog-and-acp-selection.zh.md

@@ -28,7 +28,7 @@ ACP 选择还必须保留提供方维度。同一个模型 ID 可能存在于多
 
 ### 前端内的会话级选择
 
-选择由提供它的前端拥有(今天是 TUI 的 `/model` 选择器),而不由 `LlmRuntime` 或 `AgentOptions` 拥有:它们是部署级或创建级对象,改动它们会把并发会话耦合在一起。每个不透明选项都携带完整的提供方/模型对,因为同一模型 ID 可能出现在多个路由下。
+选择由提供它的前端拥有,而不由 `LlmRuntime` 或 `AgentOptions` 拥有:它们是部署级或创建级对象,改动它们会把并发会话耦合在一起。每个不透明选项都携带完整的提供方/模型对,因为同一模型 ID 可能出现在多个路由下。
 
 ACP 自动化传输层不是目录消费方。它通过部署配置为新创建的 agent 提供一个可选的提供方/模型目标,不展示模型选择器或配置选项接口。
 

+ 2 - 2
.agents/notes/implemented/architecture/2026-07-19-gui-layering-and-rpc-protocol.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-07-19-gui-layering-and-rpc-protocol.md
-2026-07-19-gui-layering-and-rpc-protocol.md: 620803668e88f5a462ab2a75e6e916a85d433ed6
-2026-07-19-gui-layering-and-rpc-protocol.zh.md: 137cbce3e5dbc0be2736472f6e26d58112422697
+2026-07-19-gui-layering-and-rpc-protocol.md: 372bf4926011835999ebae9b1e2d1f5beb8eb663
+2026-07-19-gui-layering-and-rpc-protocol.zh.md: ecce57c01c155c2a0b19b7729da13c39d1a520a6

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

@@ -209,7 +209,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)
 

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

@@ -207,7 +207,7 @@ export type ResponseValue<K> =
 
 ### 实例级 envelope 观测切面
 
-四象限全形均过 `onEnvelope`;基类实现是**实例持有的微任务合批缓冲**(帧风暴不逐帧惊扰消费方;模块级状态会跨实例/测试泄漏,故实例持有)。观测者经 `subscribeEnvelopes(listener)` 订阅(收整批 `readonly RpcMessage[]`,返回退订函数);listener 抛异常被隔离(观测不得反噬载体)。无订阅者时零缓冲成本。当前没有任何现役消费方订阅——该切面是 wire 诊断的预留位(已退役的 RPC 调试面板是它的首个消费方,将来的诊断消费方接入时不动载体)。
+四象限全形均过 `onEnvelope`;基类实现是**实例持有的微任务合批缓冲**(帧风暴不逐帧惊扰消费方;模块级状态会跨实例/测试泄漏,故实例持有)。观测者经 `subscribeEnvelopes(listener)` 订阅(收整批 `readonly RpcMessage[]`,返回退订函数);listener 抛异常被隔离(观测不得反噬载体)。无订阅者时零缓冲成本。没有任何已交付消费方订阅——该切面是 wire 诊断的预留位(已退役的 RPC 调试面板是它的首个消费方,将来的诊断消费方接入时不动载体)。
 
 ### 子类表(传输承载)
 

+ 2 - 2
.agents/notes/implemented/architecture/2026-07-23-toolview-dissolution.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-07-23-toolview-dissolution.md
-2026-07-23-toolview-dissolution.md: 173af01ff6cd5dc74f2f0916fd49ad278636d1bb
-2026-07-23-toolview-dissolution.zh.md: 23f6f5dd037531892fde93ea170f958b535d89db
+2026-07-23-toolview-dissolution.md: 3e38d2faf45d851b3f8f9a10459588570190b3fb
+2026-07-23-toolview-dissolution.zh.md: 79c1f7d7630389462bf77d34df614bfd32798d50

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-23-toolview-dissolution.md

@@ -18,7 +18,7 @@ This decision originally placed `'conversation.chat.toolview'` under the chat en
 
 ## Accepted semantic changes
 
-Four behavioral deltas were accepted deliberately, not overlooked. Cross-view appearance was initially per-view registration; the follow-up note records why root/subcall composition later justified one Tool-wide presentation owner. Same-key double registration is a loud throw where the registry let later-wins silently override — a discipline correction, not a loss. Session-dimension dispatch, when a row needs it, belongs inside the component (the standard kit already carries `useSessions`), not in registry predicates — there is no shipped session-variant exemplar today. Registry-level shape override by third parties (a scoped registration shadowing a global one) has no equivalent; a real future need routes through key-naming conventions or a small in-component resolver, never a revived parallel registry.
+Four behavioral deltas were accepted deliberately, not overlooked. Cross-view appearance was initially per-view registration; the follow-up note records why root/subcall composition later justified one Tool-wide presentation owner. Same-key double registration is a loud throw where the registry let later-wins silently override — a discipline correction, not a loss. Session-dimension dispatch, when a row needs it, belongs inside the component (the standard kit already carries `useSessions`), not in registry predicates — there is no shipped session-variant exemplar. Registry-level shape override by third parties (a scoped registration shadowing a global one) has no equivalent; a real future need routes through key-naming conventions or a small in-component resolver, never a revived parallel registry.
 
 ## Alternatives considered
 

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-23-toolview-dissolution.zh.md

@@ -18,7 +18,7 @@ Status: implemented
 
 ## 接受的语义变化
 
-四项行为增量是刻意接受而非疏漏。跨视图出场最初采用逐视图注册;后续 Note 记录了为何 root/subcall 编排后来证明由一个 Tool 级展示所有者统一负责是合理的。同 key 重复注册从注册表的 later-wins 静默覆盖变为 loud throw——纪律修正而非损失。会话维分发若行需要,归组件内部(标配 kit 已带 `useSessions`),不走注册表谓词——今天没有已落地的会话变体样例。第三方在 registry 级覆盖形态(scoped 注册压过 global)不复存在;真出现的未来需求走 key 命名空间约定或组件内小 resolver,永不复活平行注册表。
+四项行为增量是刻意接受而非疏漏。跨视图出场最初采用逐视图注册;后续 Note 记录了为何 root/subcall 编排后来证明由一个 Tool 级展示所有者统一负责是合理的。同 key 重复注册从注册表的 later-wins 静默覆盖变为 loud throw——纪律修正而非损失。会话维分发若行需要,归组件内部(标配 kit 已带 `useSessions`),不走注册表谓词——没有已交付的会话变体样例。第三方在 registry 级覆盖形态(scoped 注册压过 global)不复存在;真出现的未来需求走 key 命名空间约定或组件内小 resolver,永不复活平行注册表。
 
 ## Alternatives considered
 

+ 2 - 2
.agents/notes/implemented/architecture/2026-07-25-web-client-session-scope-and-provide-channel.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-07-25-web-client-session-scope-and-provide-channel.md
-2026-07-25-web-client-session-scope-and-provide-channel.md: 81ae4bdfa4f9666efc9eccd05bc4fe95d24b3dba
-2026-07-25-web-client-session-scope-and-provide-channel.zh.md: dd5c09696525b0391b1c74693753ff2f6d372eba
+2026-07-25-web-client-session-scope-and-provide-channel.md: 6f159dc16e0e4063f9077c31829a10caca98eae0
+2026-07-25-web-client-session-scope-and-provide-channel.zh.md: 2cb082dce75f1845e52a52289a8e3eaa1a000931

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-25-web-client-session-scope-and-provide-channel.md

@@ -132,5 +132,5 @@ Slot scope is the closed set `root | session-maybe | session`:
 - Plugins gain session context isomorphic to the host's: per-session state hangs on the actx and mounts/tears down in one piece with the scope fiber, making leaks structurally impossible; two-session isolation is structurally guaranteed by the scope filter.
 - The client object layer converges to a wire mirror: session identity, lifecycle, and capability adjudication all defer to the host entity — the input system (the next layer) always faces a session with a real Agent, and providers like slash/skill uniformly address by sessionId directly.
 - Blank-session governance takes zero dedicated mechanisms: state rides one derived bit, visibility rides the unified list projection (only the current blank shows, as `New Session`), reclamation rides lazy persistence's existing contract (evaporation on restart), and the ordinary ceiling rides same-Workspace reuse.
-- The cost: the id→ctx handoff discipline and provide's Concurrent discipline are conventions rather than type-enforced, pinned by review and tests. The single state axis still withholds machine faces until a Session exists; the resident card routes activation to the Workspace picker during that interval ([decision](../feature/2026-08-07-workspace-picker-composer-entry.md)).
+- The cost: the id→ctx handoff discipline and provide's Concurrent discipline are conventions rather than type-enforced, pinned by review and tests. The single state axis still withholds machine faces until a Session exists; the [resident conversation shell](../../../../packages/client/ui-conversation/README.md) routes activation to the Workspace picker during that interval.
 - Known gaps: approval/question recovery across prune (TODO); model selection returns in live-mutation shape (the host `selectModel` trio is ready-made, its client consumer not yet built).

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-25-web-client-session-scope-and-provide-channel.zh.md

@@ -132,5 +132,5 @@ slot scope 是闭集 `root | session-maybe | session`:
 - 插件获得与 host 同构的会话上下文:逐会话状态挂 actx、随 scope fiber 一次拆装,泄漏结构性不可能;双会话隔离由 scope filter 结构性保证。
 - client 对象层收敛为 wire 镜像:会话身份、生命周期、能力判别全部以 host 实体为准——输入体系(下一层)面对的永远是「有真 Agent 的会话」,slash/skill 等提供方一律以 sessionId 直接寻址。
 - 空会话治理零专用机制:状态靠一个派生位,可见性靠统一列表投影(仅 current blank 以 `New Session` 展示),回收靠 lazy persistence 的既有约定(重启蒸发),常规上限靠同 Workspace 复用。
-- 代价:id→ctx 换乘纪律、provide 的 Concurrent 纪律都是约定而非类型强制,靠 review 与测试钉住。单一状态轴仍会在 Session 存在前隐藏 machine face;这段时间内,常驻卡片会把激活操作转到 Workspace picker([决策](../feature/2026-08-07-workspace-picker-composer-entry.zh.md))
+- 代价:id→ctx 换乘纪律、provide 的 Concurrent 纪律都是约定而非类型强制,靠 review 与测试钉住。单一状态轴仍会在 Session 存在前隐藏 machine face;这段时间内,[常驻会话壳](../../../../packages/client/ui-conversation/README.zh.md)会把激活操作转到 Workspace picker
 - 已知欠账:approval/question 跨 prune 恢复(TODO);模型选择以 live-mutation 形状回归(host `selectModel` 三件套现成,其 client 消费方尚未构建)。

+ 2 - 2
.agents/notes/implemented/architecture/2026-07-26-job-registry-seam.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-07-26-job-registry-seam.md
-2026-07-26-job-registry-seam.md: b4a8a66ef63f1a4955e2497cad2d0d0b1ef138ec
-2026-07-26-job-registry-seam.zh.md: 1e990542e946854d85dd7d1accf3e5bba8ca2ccb
+2026-07-26-job-registry-seam.md: fc344c9a9b24c13871475993dc52d7fdb92ed3be
+2026-07-26-job-registry-seam.zh.md: 692937cfbae599b4dcaacdc31220a15f17a912aa

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-26-job-registry-seam.md

@@ -22,7 +22,7 @@ The seam keeps the in-process contract semantics unchanged: `JobStart.run()` sti
 
 ## Alternatives considered
 
-**Keep the concrete service until a second backend exists (status quo).** This was the original runtime note's position: extracting a Service Definition before a second provider risks freezing the wrong boundary. It lost because the boundary is no longer speculative — the nine service methods and their semantics have been stable across every producer integration since introduction, they are exactly the API `dsh-tool-jobs` and the producers already program against, and the repository convention treats swappable capabilities as three packages by default. The residual risk (a durable backend needing contract changes) is unchanged by the split: those changes would land in the Service Definition package either way, and today they would also churn every Consumer's provider dependency.
+**Keep the concrete service until a second backend exists (status quo).** This was the original runtime note's position: extracting a Service Definition before a second provider risks freezing the wrong boundary. It lost because the boundary is no longer speculative — the nine service methods and their semantics have been stable across every producer integration since introduction, they are exactly the API `dsh-tool-jobs` and the producers already program against, and the repository convention treats swappable capabilities as three packages by default. The residual risk (a durable backend needing contract changes) is unchanged by the split: those changes would land in the Service Definition package either way, and they would also churn every Consumer's provider dependency.
 
 **Service-Definition-only extraction inside one package (export an abstract class beside the concrete one).** Rejected because it separates nothing operationally: Consumers still depend on the package that carries the provider and its dependencies, and a replacement backend still cannot ship without the local one in its graph. The package boundary is the unit of independent evolution here.
 

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-26-job-registry-seam.zh.md

@@ -22,7 +22,7 @@ Status: implemented
 
 ## 曾考虑的替代方案
 
-**在第二个后端出现之前保持具体服务(维持现状)。**这正是运行时 Agent Note 当初的立场:在第二个 Service Provider 出现前抽取 Service Definition,可能固化错误的边界。该方案落选,因为这条边界已不再是臆测:九个服务方法及其语义自引入以来在每一次生产方集成中都保持稳定,它们正是 `dsh-tool-jobs` 与各生产方已经面向编程的那套接口,而且仓库约定默认将可替换能力拆成三个包。剩余风险(持久化后端可能需要变更约定)不因这次拆分而改变:无论拆分与否,这类变更都会落在 Service Definition 包里;而若维持现状,它们今天还会连带搅动每个 Consumer 的提供方依赖。
+**在第二个后端出现之前保持具体服务(维持现状)。**这正是运行时 Agent Note 当初的立场:在第二个 Service Provider 出现前抽取 Service Definition,可能固化错误的边界。该方案落选,因为这条边界已不再是臆测:九个服务方法及其语义自引入以来在每一次生产方集成中都保持稳定,它们正是 `dsh-tool-jobs` 与各生产方已经面向编程的那套接口,而且仓库约定默认将可替换能力拆成三个包。剩余风险(持久化后端可能需要变更约定)不因这次拆分而改变:无论拆分与否,这类变更都会落在 Service Definition 包里;而若维持现状,它们还会连带搅动每个 Consumer 的提供方依赖。
 
 **在单个包内仅抽取 Service Definition(在具体类旁导出一个抽象类)。**否决,因为它在运作层面并未分离任何东西:Consumer 依然依赖携带 Service Provider 及其依赖项的那个包,而替换后端若不把本地 Service Provider 纳入自身依赖图,就仍然无法发布。在这里,包边界才是独立演进的单位。
 

+ 2 - 2
.agents/notes/implemented/architecture/2026-07-28-api-browser-trust-boundary.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-07-28-api-browser-trust-boundary.md
-2026-07-28-api-browser-trust-boundary.md: f4d14201d052299bb6063553e962a5d7c74fdb4b
-2026-07-28-api-browser-trust-boundary.zh.md: 8c8e414e5f76b2ef2090ddc99916defa196da352
+2026-07-28-api-browser-trust-boundary.md: 92b76c109aa9b55bc72bb76f8b208ea2d814d8ce
+2026-07-28-api-browser-trust-boundary.zh.md: 653ff32f2e62bf0e2982517f82649ff2d06e40d4

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-28-api-browser-trust-boundary.md

@@ -21,7 +21,7 @@ Two boundaries stay deliberately out of scope: reachability is the webserver bin
 
 - **Per-RPC guards (status quo extended).** Rejected: the guard list trails the method list forever, the highest-value methods were already unguarded, and a loopback rule on browse RPCs would break the remote deployments they exist for.
 - **CORS headers + credential omission.** Rejected: we never want cross-origin reads at all, so answering preflights only widens the surface; refusing them is strictly stronger and simpler.
-- **Auth tokens now.** Rejected for this change: token minting/storage/rotation is real product surface; the fence closes the browser-deputy holes today without pre-deciding the auth design.
+- **Authentication tokens.** Rejected for this change: token minting/storage/rotation is real product surface; the fence closes the browser-deputy holes without pre-deciding the auth design.
 
 ## Consequences
 

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-28-api-browser-trust-boundary.zh.md

@@ -21,7 +21,7 @@ Web GUI 宿主以纯 HTTP 提供 `/api`(默认 `127.0.0.1:3080`,支持 `--ho
 
 - **按 RPC 设防(延续现状)。** 否决:守卫清单永远追着方法清单跑,价值最高的方法本来就没被守住,而 browse RPC 上的回环规则会破坏它们为之存在的远程部署。
 - **CORS 头与省略凭据。** 否决:我们根本不想要任何跨源读取,应答预检只会扩大暴露面;拒绝预检严格更强也更简单。
-- **现在就上认证令牌。** 在本变更中否决:令牌的签发、存储、轮换是真实的产品面;栅栏今天就能封死浏览器混淆代理人漏洞,无需预先决定认证设计。
+- **认证令牌。** 在本变更中否决:令牌的签发、存储、轮换是真实的产品面;栅栏能封死浏览器混淆代理人漏洞,无需预先决定认证设计。
 
 ## 后果
 

+ 2 - 2
.agents/notes/implemented/architecture/2026-07-28-directory-picker-capability-seam.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-07-28-directory-picker-capability-seam.md
-2026-07-28-directory-picker-capability-seam.md: 2e663e9bc90841dd843bf8a8ff5676e4ca3b91b3
-2026-07-28-directory-picker-capability-seam.zh.md: 46d62aeaadd73d00de71be8ecd7c478b978f918d
+2026-07-28-directory-picker-capability-seam.md: 423fec3ad517e645f1cdee3513bad312a56989a8
+2026-07-28-directory-picker-capability-seam.zh.md: f652157fc152dee44a50ab8b55cc6120d92a1a26

File diff suppressed because it is too large
+ 1 - 1
.agents/notes/implemented/architecture/2026-07-28-directory-picker-capability-seam.md


File diff suppressed because it is too large
+ 1 - 1
.agents/notes/implemented/architecture/2026-07-28-directory-picker-capability-seam.zh.md


+ 2 - 2
.agents/notes/implemented/architecture/2026-07-29-dsh-source-launch-tsx-esm.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-07-29-dsh-source-launch-tsx-esm.md
-2026-07-29-dsh-source-launch-tsx-esm.md: 425cf46ca802e8d3ac1d49a1955c5e7ea208bd20
-2026-07-29-dsh-source-launch-tsx-esm.zh.md: 87b323c82f28135396d1d16991e2365c691fcc6a
+2026-07-29-dsh-source-launch-tsx-esm.md: 23cf4023e91d148b2e129faa7395fdccdd3e0a2b
+2026-07-29-dsh-source-launch-tsx-esm.zh.md: e2dede0036dd1128718bdf41a11f5949555b69a5

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-29-dsh-source-launch-tsx-esm.md

@@ -26,7 +26,7 @@ The node-compat CI matrix (Node 22.19 and 26) gains `dsh-source-launch-smoke` (`
 
 **Make the source graph erasable-only so Node 26 strip mode accepts it.** Rejected: parameter properties and value namespaces pervade vendored Cordis/cosmokit/loader/schemastery; rewriting them is unbounded churn re-applied on every vendor sync.
 
-**A repo-owned in-thread loader (`module.registerHooks()` + esbuild or `@swc/core` transform).** Rejected for now: prototypes measured ~0.45s (esbuild path untested end-to-end; SWC breaks on `vendor/hmr`'s decorator + namespace merge in both decorator modes), but it means owning transform correctness and a resolve hook that tsx already provides. Revisit only if the ~0.3s gap becomes a real cost; the profiling evidence lives in the PR discussion.
+**A repo-owned in-thread loader (`module.registerHooks()` plus an esbuild or `@swc/core` transform).** Rejected: prototypes measured about 0.45s, while the esbuild path lacked end-to-end validation and SWC failed on `vendor/hmr`'s decorator plus namespace merge in both decorator modes. This option also makes the repository own transform correctness and a resolve hook that tsx already provides. Revisit only if the measured 0.3s gap becomes a material cost.
 
 **Run built `lib/` for Node 26 and keep native for 24.** Rejected: loses the zero-build development loop on the newest Node line and mixes source and artifact planes.
 

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-29-dsh-source-launch-tsx-esm.zh.md

@@ -26,7 +26,7 @@ node-compat CI 矩阵(Node 22.19 与 26)新增 `dsh-source-launch-smoke`(`
 
 **把源码图改成 erasable-only 以适配 Node 26 strip 模式。** 拒绝:参数属性与值 namespace 遍布 vendor 的 Cordis/cosmokit/loader/schemastery;改写是无界 churn,且每次 vendor sync 都要重做。
 
-**仓库自有的同线程 loader(`module.registerHooks()` + esbuild 或 `@swc/core` 转换)。** 暂拒:原型实测约 0.45s(esbuild 路径未端到端验证;SWC 在 `vendor/hmr` 的装饰器 + namespace 合并上两种装饰器模式都会崩),但这意味着要自行负责转换正确性,以及实现 tsx 已经提供的解析钩子。仅当约 0.3s 的差距成为真实成本时再重新考虑;性能分析证据在 PR 讨论中
+**仓库自有的同线程 loader(`module.registerHooks()` 加 esbuild 或 `@swc/core` 转换)。**不予采纳:原型实测约 0.45s,而 esbuild 路径缺少端到端验证,SWC 在两种装饰器模式下都会因 `vendor/hmr` 的装饰器与 namespace 合并失败。该方案还会让仓库负责转换正确性和 tsx 已经提供的解析钩子。仅当实测约 0.3s 的差距成为实质成本时再重新考虑
 
 **Node 26 运行构建产物 `lib/`,24 保留原生。** 拒绝:在最新 Node 版本线上失去零构建开发循环,且混淆源码面与产物面。
 

+ 2 - 2
.agents/notes/implemented/architecture/2026-07-30-config-plane-boundaries.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-07-30-config-plane-boundaries.md
-2026-07-30-config-plane-boundaries.md: aab0d7a80c2732b33637ec721a9ab7c1b50fce3f
-2026-07-30-config-plane-boundaries.zh.md: 7e01aad93947266362cec31fdeab18524ea14cd9
+2026-07-30-config-plane-boundaries.md: 7b234ec64669cc1e6f0d5a67437005747edcea98
+2026-07-30-config-plane-boundaries.zh.md: f543c511d9374a50955331911b2eb2d62dab0675

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-30-config-plane-boundaries.md

@@ -22,7 +22,7 @@ Three smaller defects sat beside them. `llm/adapters-updated` documented contain
 
 **Reading configuration is as privileged as writing it.** `settings.describe` and `credentials.describe` join the loopback-only set, so the whole configuration plane stays same-origin until real authentication exists. The model catalog (`llm.providers`, `llm.models`) deliberately does not: it carries provider ids, display names, and model lists — no endpoints, no key state — and a LAN client's model picker needs it. The boundary is asserted over a real HTTP server rather than a hand-assembled request, because the `Host` header a browser actually sends is what decides it.
 
-**The plane serves exactly the namespaces a registered model provider addresses.** `ctx.llm.listConfigurableProviders()` is the allow-list, so the product boundary is enforced rather than inferred from today's plugin set, and a future namespace becomes web-configurable only by joining that directory. An unregistered namespace and an unexposed one answer identically (`settings-not-exposed`), so probing cannot enumerate the registry.
+**The plane serves exactly the namespaces a registered model provider addresses.** `ctx.llm.listConfigurableProviders()` is the allow-list, so the product boundary is enforced rather than inferred from the installed plugin set, and a future namespace becomes web-configurable only by joining that directory. An unregistered namespace and an unexposed one answer identically (`settings-not-exposed`), so probing cannot enumerate the registry.
 
 **A caller with a partial view names the field it means.** `SettingsProvider.mutate(ns, ops)` applies `set`/`unset` path ops to the section as it stands at the front of the write queue. The client builds ops by diffing its opening snapshot against its draft, so it mentions only fields it can see: a secret absent from both sides produces no op and survives by construction, not by care. `replace` remains the deliberate wholesale reset.
 

+ 1 - 1
.agents/notes/implemented/architecture/2026-07-30-config-plane-boundaries.zh.md

@@ -22,7 +22,7 @@ Status: implemented
 
 **读取配置与写入配置同样属于特权操作。**`settings.describe` 与 `credentials.describe` 加入仅限回环的集合,因此在真正的认证层出现之前,整个配置面都保持同源。模型目录(`llm.providers`、`llm.models`)刻意不在其中:它携带的是提供方 id、显示名与模型列表——没有端点、没有密钥状态——而 LAN 客户端的模型选择器正需要它。这条边界由一台真实 HTTP 服务器来断言,而不是手工拼装的请求,因为真正决定它的,是浏览器实际发出的那个 `Host` 头。
 
-**这个面恰好服务于已注册模型提供方所指向的那些 namespace。**`ctx.llm.listConfigurableProviders()` 就是允许列表,于是产品边界是被执行的,而不是从今天的插件集合里推断出来的;将来的 namespace 只有加入该目录才会变得可在 Web 上配置。未注册的 namespace 与未暴露的 namespace 得到完全相同的答复(`settings-not-exposed`),因此探测无法枚举注册表。
+**这个面恰好服务于已注册模型提供方所指向的那些 namespace。**`ctx.llm.listConfigurableProviders()` 就是允许列表,于是产品边界是被执行的,而不是从已安装的插件集合里推断出来的;将来的 namespace 只有加入该目录才会变得可在 Web 上配置。未注册的 namespace 与未暴露的 namespace 得到完全相同的答复(`settings-not-exposed`),因此探测无法枚举注册表。
 
 **持有局部视图的调用方,点名它真正要改的字段。**`SettingsProvider.mutate(ns, ops)` 会把 `set`/`unset` 路径 op 施加在写入排到队首那一刻的分节上。客户端通过对比自己打开时的快照与草稿来构造 op,因此它只提及自己看得见的字段:两侧都没有的机密不会产生任何 op,它的留存是构造使然,而非小心使然。`replace` 仍是那个刻意的整体重置。
 

Some files were not shown because too many files changed in this diff