docs(i18n): include complete proofreading corpus
This commit is contained in:
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-06-16-typed-event-schemas.md
|
||||
2026-06-16-typed-event-schemas.md: 8a73970d59fa75cc26e0518e441e704393c692f8
|
||||
2026-06-16-typed-event-schemas.zh.md: 5998be3cea98e1937eb7fe1298cb252cbf3ee171
|
||||
2026-06-16-typed-event-schemas.zh.md: 35afc9b977749b5b74b3634d14ee88f842d9bf33
|
||||
|
||||
@@ -10,7 +10,7 @@ harness 将其核心词汇——内容块、消息来源、结束原因、轮次
|
||||
|
||||
该模式**仅存在于编译期**。类型在运行时消失:没有 schema 对象可供校验传入值、解析不可信输入或在运行时枚举变体。[会话持久化约定](../../implemented/architecture/2026-06-14-session-persistence.md)暴露了两个后果:
|
||||
|
||||
1. **持久化将 `event.data` 视为不透明 JSON。** JSONL/SQLite 后端对每个事件逐字 `JSON.stringify`/`JSON.parse`;唯一的运行时守卫是 `isJsonValue`(往返可序列化性检查:拒绝 BigInt、函数、循环引用、非有限数等),而非结构校验。一个损坏但仍为合法 JSON 的事件数据(字段类型错误、字段缺失)会静默往返,只有在后续消费方的 `switch` 中才可能被捕获。
|
||||
1. **持久化将 `event.data` 视为不透明 JSON。** JSONL/SQLite 后端对每个事件原样执行 `JSON.stringify`/`JSON.parse`;唯一的运行时守卫是 `isJsonValue`(往返可序列化性检查:拒绝 BigInt、函数、循环引用、非有限数等),而非结构校验。一个损坏但仍为合法 JSON 的事件数据(字段类型错误、字段缺失)会静默往返,只有在后续消费方的 `switch` 中才可能被捕获。
|
||||
2. **插件新增变体没有运行时约定。** 一个通过声明合并添加新 `SessionEventMap` 键的插件,在自身代码中获得了编译期类型,但没有任何机制校验它产出的值是否符合它所声明的形状——无论是在生产者处、持久化边界处还是重新加载时。
|
||||
|
||||
由此引出问题:事件词汇是否应迁移到 **Zod** 或其他运行时 schema 库,使持久化边界和插件边界拥有运行时 schema 而非被擦除的类型。
|
||||
@@ -23,10 +23,10 @@ harness 将其核心词汇——内容块、消息来源、结束原因、轮次
|
||||
|
||||
## 影响范围(已度量)
|
||||
|
||||
将事件/词汇表面迁移到运行时 schema,至少涉及:
|
||||
将事件/词汇接口迁移到运行时 schema,至少涉及:
|
||||
|
||||
- **六个 merge-extensible map**(约 370 行核心类型):`ContentBlockMap`、`MessageSourceMap`、`FinishReasonMap`(位于 `dsh-llm`);`TurnTriggerMap`、`TurnEndReasonMap`、`SessionEventMap`(位于 `dsh-session`)。
|
||||
- **约 10 处 `declare module` 扩展点**,分布在 `dsh-agent`、`dsh-agent-loop`、`dsh-bash`、`dsh-llm`、`dsh-session`、`dsh-session-persistence`、`dsh-system-prompt`、`dsh-tools` 各包中——每处都将从声明合并改为运行时 `register()` 调用。
|
||||
- **约 10 处 `declare module` 声明增补位置**,分布在 `dsh-agent`、`dsh-agent-loop`、`dsh-bash`、`dsh-llm`、`dsh-session`、`dsh-session-persistence`、`dsh-system-prompt`、`dsh-tools` 各包中——每处都将从声明合并改为运行时 `register()` 调用。
|
||||
- **事件生产者**——agent loop(智能体循环)中 16 处 `session.append(...)` 调用——形状不变,但现在在边界处被校验。
|
||||
- **约 7 个 switch 消费方**,对这些联合类型进行分支:`deriveMessages` 与包自有的不变式 companion(`dsh-session`)、`BlockAssembler`(`dsh-llm`)、两个 LLM(大语言模型)适配器(`dsh-llm-deepseek`、`dsh-llm-pi-ai`)以及工具 schema 层(`dsh-tools`)。`assertNever` 对封闭联合类型的穷举 vs 对可扩展联合类型的 fall-through 约定(一条已记录的 lint 规则)需要重新考量——运行时变体在静态层面不可穷举。
|
||||
- **`defineTool` 的 `InferArgs` DSL**(`dsh-tools`),它从编译期 schema 规范派生出零类型转换的 `execute` 参数类型——这是当前方案的标杆用例。
|
||||
@@ -37,7 +37,7 @@ harness 将其核心词汇——内容块、消息来源、结束原因、轮次
|
||||
## 曾考虑的替代方案
|
||||
|
||||
### A. 维持现状——merge-extensible 类型 + 持久化边界处 `isJsonValue`
|
||||
保留编译期模式。持久化继续使用不透明 JSON + 可序列化性守卫。插件通过声明合并扩展;事件*形状*的正确性由生产者负责,并由 TypeScript 在编译期保证。启用包自有的不变式 companion 后,它们会检查选定的跨记录关系,但不提供通用运行时形状 schema。
|
||||
保留编译期模式。持久化继续使用不透明 JSON + 可序列化性守卫。插件通过声明合并扩展;事件 *形状*的正确性由生产者负责,并由 TypeScript 在编译期保证。启用包自有的不变式 companion 后,它们会检查选定的跨记录关系,但不提供通用运行时形状 schema。
|
||||
|
||||
- **优点**:零变动;插件扩展只需一行 `interface` 增补,享有完整类型推断,无需运行时注册仪式;无新运行时依赖;`defineTool` DSL 与 `assertNever` 穷举继续工作。
|
||||
- **缺点**:持久化边界和插件边界处无运行时结构校验;格式错误但仍为合法 JSON 的数据被延迟捕获。
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-07-19-required-cancellation-through-tool-capability-seams.md
|
||||
2026-07-19-required-cancellation-through-tool-capability-seams.md: 1909b8451b6c70bde7c67f0cc0c1c3f4db443f7f
|
||||
2026-07-19-required-cancellation-through-tool-capability-seams.zh.md: 7a9c78c71afe4d51f3d0f46f2cb59fc7cb5bf133
|
||||
2026-07-19-required-cancellation-through-tool-capability-seams.zh.md: 631abfaa1cd21578437458cc194e277dc7883792
|
||||
|
||||
@@ -6,9 +6,9 @@ Status: proposed
|
||||
|
||||
## 问题
|
||||
|
||||
已经实现的[工具注册表取消约定](../../implemented/architecture/2026-07-19-cooperative-tool-cancellation.md)让每个工具主体中的 `exec.signal` 成为必填值,但许多由工具主体调用的异步能力接口仍接受可选信号。因此,工具可以满足自身类型,却在下一次同进程调用时意外丢失取消。
|
||||
已经实现的[工具注册表取消约定](../../implemented/architecture/2026-07-19-cooperative-tool-cancellation.md)让每个工具主体中的 `exec.signal` 成为必填值,但许多从这些工具主体可达的异步能力接口仍接受可选信号。因此,工具可以满足自身类型,却在下一次同进程调用时意外丢失取消。
|
||||
|
||||
这项缺口会沿调用链传递。文件系统工具可能调用路径解析和 I/O,Web 工具可能调用提供方,Bash 工具可能调用执行器,组合工具可能启动或等待任务、subagent 或工作流。只要某个控制工具所持有工作的、且会被工具等待的操作允许省略信号,TypeScript 就无法证明取消仍能到达拥有副作用的边界。
|
||||
这一缺口会沿调用链传递。文件系统工具可能调用路径解析和 I/O,Web 工具可能调用提供方,Bash 工具可能调用执行器,组合工具可能启动或等待任务、subagent 或工作流。只要某个控制工具所持有的工作且会被工具等待的操作允许省略信号,TypeScript 就无法证明取消仍能到达拥有副作用的边界。
|
||||
|
||||
要求仓库中所有异步函数都携带信号会过度扩张。有些操作无法从工具到达,有些同步查询无法等待或持有持续工作,而明确分离的工作在刻意交接后已经拥有新的所有者。
|
||||
|
||||
@@ -18,7 +18,7 @@ Status: proposed
|
||||
|
||||
每个直接调用方提供自己持有的信号,或从自身必填的操作上下文继续传递信号。实现可以派生子截止时间或取消作用域,但派生信号在委托期间仍须与上游信号关联。能力实现不得生成永不中止信号、使用环境式异步本地取消,也不得仅为重复类型化同进程约定而在运行时校验 `AbortSignal`。
|
||||
|
||||
迁移首先从每个第一方 `ToolDefinition.execute()` 出发,清点其等待的能力调用;随后按内聚的 Service Definition/Service provider/Consumer seam,将测试与生成的 API 文档一并修改。文件系统、Bash 与任务、Web 与提供方、工作流与 subagent、代码运行时等能力族可以通过独立 PR(Pull Request)迁移,以保持每项变更可审查;但根据仓库的预发布原则,已经迁移的接口不得保留可选兼容重载。
|
||||
迁移首先从每个第一方 `ToolDefinition.execute()` 出发,沿其等待的能力调用进行清点;随后按内聚的 Service Definition/Service provider/Consumer seam,将测试与生成的 API 文档一并修改。文件系统、Bash 与任务、Web 与提供方、工作流与 subagent、代码运行时等能力族可以通过独立 PR(Pull Request)迁移,以保持每项变更可审查;但根据仓库的预发布原则,已经迁移的接口不得保留可选兼容重载。
|
||||
|
||||
### 范围边界
|
||||
|
||||
@@ -58,7 +58,7 @@ Status: proposed
|
||||
|
||||
**错误划分分离工作。** 过早排除启动操作可能在发布提交前就让工作脱离控制;永久要求父信号又可能让已完成工具取消合法分离的工作。每次交接都需要明确提交点、新所有者、回滚行为和完全停稳的失败路径。
|
||||
|
||||
**信号所有权混淆。** 能力若在委托生命周期之外保存借用信号,可能让工作绑定到过期调用方。接口和测试必须区分借用的操作信号与长生命周期服务所持有的控制器。
|
||||
**信号所有权混淆。** 能力若在委托生命周期之外保存借用信号,可能让工作绑定到陈旧的调用方。接口和测试必须区分借用的操作信号与长生命周期服务所持有的控制器。
|
||||
|
||||
**只有机械合规而没有协作行为。** 必填参数只能证明信号可用,不能证明实现会观察或转发它。进程、worker、套接字、提供方和任务边界仍需集成测试证明实际行为。
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-07-25-client-settings-locale-theme.md
|
||||
2026-07-25-client-settings-locale-theme.md: 961a7d96705095486ed7e4b2044f8f0f4a3cd79c
|
||||
2026-07-25-client-settings-locale-theme.zh.md: 9c7be340f508f7bb12d1448625232258da412e10
|
||||
2026-07-25-client-settings-locale-theme.zh.md: a615bdf9296c1e31a9c8ad258d6ce0829c2bc8b9
|
||||
|
||||
@@ -16,11 +16,11 @@ Sidebar 声明 `sidebar.settings` single slot,`ui-settings` 占用它并声明
|
||||
|
||||
Settings 入口是 sidebar Foot 的 Settings 行,点击直接打开 1080×700 居中浮层(黑 24% 遮罩);close 按钮、点击遮罩、ESC 均关闭。无任何中间菜单形态。
|
||||
|
||||
`@deepseek-ai/dsh-client-locale` 提供 `ctx.locale`,`ui-theme` 提供 `ctx.theme`。两个服务都以 getter 读取、setter 写入并用 typed Cordis 变更事件发布 immutable snapshot;服务自己持久化偏好(只存 id,坏值回退默认)。
|
||||
`@deepseek-ai/dsh-client-locale` 提供 `ctx.locale`,`ui-theme` 提供 `ctx.theme`。两个服务都以 getter 读取、setter 写入并用 typed Cordis 变更事件发布不可变快照;服务自己持久化偏好(只存 id,无效值回退默认)。
|
||||
|
||||
功能行的 apply 层各自订阅自家变更事件(locale 订 `locale/change`,ui-theme 订 `theme/change`),把 snapshot 投影到该行注册时声明的 slot store。React 组件只读 `useStore`、写注入的 setter callback,不读取 ctx 或服务。
|
||||
功能行的 apply 层各自订阅自家变更事件(locale 订 `locale/change`,ui-theme 订 `theme/change`),把快照投影到该行注册时声明的 slot store。React 组件只读 `useStore`、写注入的 setter callback,不读取 ctx 或服务。
|
||||
|
||||
Theme 偏好三态:`light`、`dark`、`system`,默认 `system`(无持久化偏好或坏值时)。system 的解析属主题领域:ThemeService 持有 `prefers-color-scheme` matchMedia 监听(环境感知,非 DOM 呈现),偏好为 system 且系统配色变化时重发 snapshot;snapshot 同时携带 `preference` 与解析后的 `active` 定义。
|
||||
Theme 偏好三态:`light`、`dark`、`system`,默认 `system`(无持久化偏好或无效值时)。system 的解析属主题领域:ThemeService 持有 `prefers-color-scheme` matchMedia 监听(环境感知,非 DOM 呈现),偏好为 system 且系统配色变化时重发快照;快照同时携带 `preference` 与解析后的 `active` 定义。
|
||||
|
||||
Theme 服务不操作 DOM。`ui-layout` 初始读取 Theme getter,随后订阅 `theme/change`,由 Layout 持有的 presenter 按 `active` 更新 `body[data-ds-dark-theme]` 和主题 token;presenter 不感知 system,只消费已解析结果。
|
||||
|
||||
@@ -35,7 +35,7 @@ Theme 服务不操作 DOM。`ui-layout` 初始读取 Theme getter,随后订阅
|
||||
| Models section(order 10)| `ui-models` | 仅导航项,内容区为空;后续模型管理功能落在该包 |
|
||||
| 插件 | 无 | 首期不做,导航不出现该项(后续插件功能包注册 section 即自动出现) |
|
||||
|
||||
首期只对 Settings 浮层内文案进行本地化;字典就近——chrome + General 骨架归 `ui-settings-general` 的 `settings` namespace,功能行文案归各功能包(`settings.locale`、`settings.theme`、`settings.models`)。
|
||||
首期只对 Settings 浮层内文案进行本地化;字典就近存放——chrome + General 骨架归 `ui-settings-general` 的 `settings` namespace,功能行文案归各功能包(`settings.locale`、`settings.theme`、`settings.models`)。
|
||||
|
||||
### slot 拓扑
|
||||
|
||||
@@ -55,11 +55,11 @@ root
|
||||
└─ models (order 10) ui-models 注册
|
||||
```
|
||||
|
||||
section/item contribution 使用 `ctx.slots.inject()`,不依赖 client manifest 的 apply 顺序;本地化 label 走 [全量接入 Note](../../implemented/architecture/2026-07-30-client-locale-full-rollout.md) 的 label thunk。SlotMap 类型分家:trigger/header/close/section 正家在 ui-settings contract(消费者 general/models 均依赖壳,无环);`settings.general.item` 正家在 locale 包——它是全部 item 注册方的最低公共依赖(设置行必带文案),而声明方 general 的 contract 对 locale/ui-theme 不可达(会成环);ui-theme 经 re-export 出口消费。
|
||||
section/item contribution 使用 `ctx.slots.inject()`,不依赖 client manifest(元数据清单)的 apply 顺序;本地化 label 走 [全量接入 Note](../../implemented/architecture/2026-07-30-client-locale-full-rollout.md) 的 label thunk。SlotMap 类型分家:trigger/header/close/section 正家在 ui-settings 约定(消费方 general/models 均依赖壳,无环);`settings.general.item` 正家在 locale 包——它是全部 item 注册方的最低公共依赖(设置行必带文案),而声明方 general 的约定对 locale/ui-theme 不可达(会成环);ui-theme 经 re-export 出口消费。
|
||||
|
||||
### slot 声明是一等可注入等待对象
|
||||
|
||||
`SlotsService.inject()` 直接等待有类型约束的 ledger key;它不会将声明桥接为合成的 `slot:<name>` Cordis 服务。回调会跟随声明折叠与重新声明,而其控制器仍归贡献方插件 fiber 所有;直接向未声明 slot 注册仍会大声失败。这删除了陈旧 disposer 判在位机器和容易因拼写错误出错的平行服务命名空间。完整的生命周期与失败约定见 [slot 声明注入决策](../../implemented/architecture/2026-08-05-slot-declaration-injection.md)。
|
||||
`SlotsService.inject()` 直接等待有类型约束的 ledger key;它不会将声明桥接为合成的 `slot:<name>` Cordis 服务。回调会跟随声明折叠与重新声明,而其控制器仍归贡献方插件 fiber 所有;直接向未声明 slot 注册仍会直接报错。这删除了基于陈旧 disposer 的在位状态机,以及容易因拼写错误出错的平行服务命名空间。完整的生命周期与失败约定见 [slot 声明注入决策](../../implemented/architecture/2026-08-05-slot-declaration-injection.md)。
|
||||
|
||||
### 服务约定
|
||||
|
||||
@@ -106,13 +106,13 @@ Locale 内置中文和 English;`setLocale`/`setTheme` 是唯一写入口,未
|
||||
|
||||
**Theme 服务直接修改 DOM。**注册表服务因此依赖呈现环境,生命周期与全局样式所有权不清;Layout 已经拥有页面根呈现边界。
|
||||
|
||||
**system 由 Layout presenter 解析。** presenter 需自带 matchMedia 订阅并在 themes 列表里挑选具体定义,呈现层被迫理解偏好语义;解析放服务侧则所有消费方拿到一致的已解析 snapshot。
|
||||
**system 由 Layout presenter 解析。** presenter 需自带 matchMedia 订阅并在 themes 列表里挑选具体定义,呈现层被迫理解偏好语义;解析放服务侧则所有消费方拿到一致的已解析快照。
|
||||
|
||||
**Settings import 并枚举各 section。** 新增页面必须修改壳插件,破坏「每个功能由自己的插件占用 slot」的组合模型。
|
||||
|
||||
**按功能为每个 section 单开 `ui-settings-*` 卫星包。** 设置面与功能本体分家:改 Theme 行为要动两个包,包数随设置项线性膨胀,且卫星包反向依赖 locale/theme 服务,形成纯粹为拆包而生的中间层。功能属主自注册下不存在这层:preference 行随功能包交付;`ui-settings-general` 只收无主文案(chrome 与 General 骨架),不承载任何功能的设置面。
|
||||
|
||||
**把 Locale/Theme snapshot 直接注入 React。** inject 结果按 entry identity 缓存,易变值会陈旧;为每个服务自造 React 钩子也绕开 slot store 的统一绑定。
|
||||
**把 Locale/Theme 快照直接注入 React。** inject 结果按 entry identity 缓存,易变值会陈旧;为每个服务自造 React 钩子也绕开 slot store 的统一绑定。
|
||||
|
||||
## 验收标准
|
||||
|
||||
@@ -120,11 +120,11 @@ Locale 内置中文和 English;`setLocale`/`setTheme` 是唯一写入口,未
|
||||
- 新增一个设置项 = 功能包自己注册(section 或 general item),零壳改动。
|
||||
- Locale 与 Theme 的写入只走 setter,持续同步只走变更事件。
|
||||
- 功能行 store 初始化走 getter,后续由自家变更事件更新并局部重渲染。
|
||||
- Layout 独立应用 Theme snapshot,Theme 服务不访问 DOM;presenter 不出现 system 分支。
|
||||
- Layout 独立应用 Theme 快照,Theme 服务不访问 DOM;presenter 不出现 system 分支。
|
||||
- 中文/English 与 Light/Dark/System 能切换并刷新后恢复;偏好为 system 时系统配色变化即时生效。
|
||||
- Models 只有导航项与空内容区;Permission、Tool Call 骨架无写操作。
|
||||
- 浮层经 close 按钮、遮罩点击、ESC 均可关闭。
|
||||
|
||||
## 风险
|
||||
|
||||
slot 声明与 contribution 的 apply 顺序不固定,所有 section/item 注册方必须使用 `ctx.slots.inject()`,而不能以服务或本地 disposer 作为在位信号。service event 可能早于行首次渲染,功能行 store 的 init 与 inject attach 都必须从 getter 对齐当前 snapshot。`settings.general.item` 的重复合并副本(locale、ui-theme)与 ui-settings 正家必须逐字一致,漂移即三处一起改。Layout 卸载时必须清理自己设置的全局属性,ThemeService dispose 时必须移除 matchMedia 监听,避免 HMR 后残留。
|
||||
slot 声明与 contribution 的 apply 顺序不固定,所有 section/item 注册方必须使用 `ctx.slots.inject()`,而不能以服务或本地 disposer 作为在位信号。service event 可能早于行首次渲染,功能行 store 的 init 与 inject attach 都必须从 getter 对齐当前快照。`settings.general.item` 的重复合并副本(locale、ui-theme)与 ui-settings 正家必须逐字一致,漂移即三处一起改。Layout 卸载时必须清理自己设置的全局属性,ThemeService dispose(资源释放)时必须移除 matchMedia 监听,避免 HMR(热模块替换)后残留。
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md
|
||||
2026-07-27-session-projection-and-command-log.md: 01e77de47c7b5178ddc146e95487754a616639ec
|
||||
2026-07-27-session-projection-and-command-log.zh.md: 2de188bab9d51fb9d19f993653741a343f62e31c
|
||||
2026-07-27-session-projection-and-command-log.zh.md: 85da237976e2e0764c02369d16540f6489a5a3b6
|
||||
|
||||
@@ -123,7 +123,7 @@ type UseProjection = {
|
||||
'command/done': { commandId: string; kind: 'success' | 'error'; text?: string }
|
||||
```
|
||||
|
||||
host 侧命令执行器(`packages/interaction/commands`)在调用处理器前追加 `command/run`,在结算时追加 `command/done`——在接收 agent 的会话上直接独立追加,与[合成轮次移除](../../implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.md)之后所有插件自有 log-only 事件同一形状:没有轮次包裹它们(轮次只描述模型循环执行),持久化在常规检查点排空它们,run/done 配对由 commands 包自己的 invariant 伴生插件把守。载荷是结构化的——`name` 以及默认携带的 `args` 来自解析器自己的切分(`parseCommand` 的 name 与 rawInput),因此消费方(折叠自己命令记录的投影单元、富命令卡片)永远无需重新解析行文本。当载荷由权威领域事件持有时,命令定义会设置 `recordInput: false`;此时 `command/run` 省略 `args`,而不是重复该载荷。`text` 是处理器的原样结果——与 `tool/result.content` 同一性质的事实数据,不是呈现(版式如何编排仍由客户端在渲染时计算,满足「呈现永不入日志」这条红线)。想让模型知道结果的领域继续做它们今天在做的事(plan 的旁白、goal 的注入)——那是领域自己的决定,保持不变。
|
||||
host 侧命令执行器(`packages/interaction/commands`)在调用处理器前追加 `command/run`,在结算时追加 `command/done`——在接收 agent(智能体)的会话上直接独立追加,与[合成轮次移除](../../implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.md)之后所有插件自有 log-only 事件同一形状:没有轮次包裹它们(轮次只描述模型循环执行),持久化在常规检查点排空它们,run/done 配对由 commands 包自己的 invariant 伴生插件把守。载荷是结构化的——`name` 以及默认携带的 `args` 来自解析器自己的切分(`parseCommand` 的 name 与 rawInput),因此消费方(折叠自己命令记录的投影单元、富命令卡片)永远无需重新解析行文本。当载荷由权威领域事件持有时,命令定义会设置 `recordInput: false`;此时 `command/run` 省略 `args`,而不是重复该载荷。`text` 是处理器的原样结果——与 `tool/result.content` 同一性质的事实数据,不是呈现(版式如何编排仍由客户端在渲染时计算,满足「呈现永不入日志」这条红线)。想让模型知道结果的领域继续做它们今天在做的事(plan 的旁白、goal 的注入)——那是领域自己的决定,保持不变。
|
||||
|
||||
由于已提交事件会在 mux 流上广播,刷新后仍在、多标签页同步、fork/恢复后可还原这三件事随之全部自动获得。`command.execute` RPC 退化为准入判定——`{ matched, commandId? }`:该行是否匹配命中,以及命中时新铸的配对 id,发起命令的客户端据此把自己的请求与生命周期事件产出的 flow 节点关联起来。一次性通知通道(`runDetached` → `noticeFor`)就此下线。
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-07-28-storage-root-and-derived-medium-recovery.md
|
||||
2026-07-28-storage-root-and-derived-medium-recovery.md: 9463af00e2a2f5e2d3cee4cc7d386173007abf45
|
||||
2026-07-28-storage-root-and-derived-medium-recovery.zh.md: 215e43fac6bb52e1ecaf15d6d9d1ce1b5f913bc3
|
||||
2026-07-28-storage-root-and-derived-medium-recovery.zh.md: 2466b8e3341d3b85beb23cca97f365d71658e79d
|
||||
|
||||
@@ -33,7 +33,7 @@ Status: proposed
|
||||
|
||||
**保持按启动目录的 `.storages`(改动前现状)**——拒绝:会话是全局的,所以每个从会话派生的介质都与自己的真源劈叉;缓存的动机场景(一次列出全部会话)结构性丢行,工作区注册表索引着从另一个启动目录看不见的会话。
|
||||
|
||||
**launcher patch + `storageRoot` profile 键**——未采:一行 yml `!!js` 表达式即达全局根,与会话根的既有分层完全一致;launcher patch 多引入一个改写点,profile 键在有真实消费者前是空席(按行覆盖已有个人 config.yaml patch 层可用)。
|
||||
**launcher patch + `storageRoot` profile 键**——未采:一行 yml `!!js` 表达式即达全局根,与会话根的既有分层完全一致;launcher patch 多引入一个改写点,profile 键在有真实消费方前是空席(按行覆盖已有个人 config.yaml patch 层可用)。
|
||||
|
||||
**只把投影缓存的 route 指到全局根,`workspace.json` 留在 per-cwd**——拒绝:工作区注册表有一模一样的全局 vs per-cwd 错位,而且用户选择把缓存放在 `workspace.json` 旁边——一个 hub 根让介质同址、心智模型单一。
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-08-10-unary-apiproxy-remote-migration.md
|
||||
2026-08-10-unary-apiproxy-remote-migration.md: aa3546ec2b79a0cd6d2866c194e9d6c1c22f9e33
|
||||
2026-08-10-unary-apiproxy-remote-migration.zh.md: 653f560b38a1e6862ef6131f9e8189ed3cb3d6f8
|
||||
2026-08-10-unary-apiproxy-remote-migration.zh.md: d3ed8eed8ff5c55a11edb0c964f4adb4dac3a784
|
||||
|
||||
@@ -18,7 +18,7 @@ API Proxy 还包含一些不以业务方法为约定的 BFF 操作:Session 生
|
||||
|
||||
只迁移符合以下条件的一元调用:其业务操作已经有自然归属的服务,且其余适配只是少量参数或结果投影。当现有方法的签名就是预期的消费方约定时,服务应绑定 TypeRT namespace,并直接使用 `@Remote` 装饰现有方法。只有执行实质性适配时才有理由新增方法;不得添加只做恒等转发的 `remote*` 包装层。
|
||||
|
||||
`@deepseek-ai/dsh-api-remotes/client` 将挂载所选各业务包生成的 `/remote` 贡献。Client 业务包将调用 `ctx.remote.<service>`,并在包内执行归 Client 所有的关联或呈现投影。对应的 API Proxy 接口成员、schema、路由、处理程序、生成的客户端方法、fixture(测试前置数据)实现和生产调用点,将在该服务的纵向提交中一并移除。
|
||||
`@deepseek-ai/dsh-api-remotes/client` 将挂载所选各业务包生成的 `/remote` 贡献。Client 业务包将调用 `ctx.remote.<service>`,并在包内执行归 Client 所有的关联或呈现投影。对应的 API Proxy 接口成员、schema、路由、处理程序、生成的客户端方法、fixture 实现和生产调用点,将在该服务的纵向提交中一并移除。
|
||||
|
||||
大型 BFF 方法仍留在 `dsh-host-apiproxy` 中。如果实现过程中发现某个方法包含端点特有的生命周期策略、大量编排、Client 依赖仅存在于协议层的错误区分,或者其传输数据结构无法用归属方的小型适配器表达,则该方法不在此次迁移范围内。
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/proposed/feature/2026-07-06-recallable-compaction.md
|
||||
2026-07-06-recallable-compaction.md: e0817346112d33bfb475430f1a84846aa465d1e0
|
||||
2026-07-06-recallable-compaction.zh.md: e53e669b6111f10701353448927c5e37f4e13e0b
|
||||
2026-07-06-recallable-compaction.zh.md: db18ea93f84edae72aadb388378aab30e465eacd
|
||||
|
||||
@@ -8,7 +8,7 @@ Status: proposed
|
||||
|
||||
压缩(compaction)对模型的当前上下文不可逆。模型看到的摘要没有指向被其遮蔽内容的引用,因为 `shadowedRange` 只存在于仅写入日志、模型不可见的 `compact/summary` 事件上,也没有工具能让模型重新读取被遮蔽的区段。即使仅追加日志仍保存每一个字节,摘要器丢弃的内容也对模型不可用。重复压缩会进一步加重这些结果:每一轮都会重写头部检查点,因此请求前缀每次都会完全失去提示词缓存命中,而更早的摘要也会在后续每一轮中重新生成摘要。
|
||||
|
||||
根本原因是一个产物承担了两个互相冲突的角色。**索引** 需要冻结、按时间排序且成本低廉;模型的**工作记忆** 则需要全局视图、重新确定优先级并且可变。单一摘要无法同时胜任两者。
|
||||
根本原因是一个产物承担了两个互相冲突的角色。**索引**需要冻结、按时间排序且成本低廉;模型的**工作记忆**则需要全局视图、重新确定优先级并且可变。单一摘要无法同时胜任两者。
|
||||
|
||||
主流编码 harness 都没有让模型在循环内回溯,而且调研过的实现均未让压缩感知前缀缓存。事件溯源会话具备持久原文、可按 seq 寻址和精确回放的特征,是支持这两项功能的天然底座。
|
||||
|
||||
@@ -41,7 +41,7 @@ Status: proposed
|
||||
|
||||
### 回溯工具
|
||||
|
||||
新增包`@deepseek-ai/dsh-tool-recall`,它只是 `dsh-session` 与 `dsh-compact` 词汇之上的消费方,注册两个面向模型的工具:
|
||||
新增包 `@deepseek-ai/dsh-tool-recall`,它只是 `dsh-session` 与 `dsh-compact` 词汇之上的消费方,注册两个面向模型的工具:
|
||||
|
||||
- `history_read(checkpoint, offset?)`:把日志中任意检查点(包括已被取代的检查点)遮蔽的区段渲染为 `User:`/`Assistant:`/`Tool result:` transcript(文本记录),并按配置预算分页,提供续传游标。
|
||||
- `history_search(query, checkpoint?, limit?)`:对每个被遮蔽区段进行不区分大小写的字面量扫描;返回带检查点 id 的片段与覆盖元数据(`scanned`/`matched`/`truncated`)。零匹配提示会说明扫描按字面量执行,并建议对可能的检查点直接使用 `history_read`。
|
||||
@@ -89,7 +89,7 @@ Status: proposed
|
||||
- **FTS/向量索引伴随存储**:在会话内不予采纳,因为实时日志已在内存中且大小有界,在预算内进行字面量扫描已经足够;只有跨会话范围才能证明索引的价值。
|
||||
- **回溯路径中的语义搜索回退/次级模型提取**:不予采纳,因为其中的 LLM 或嵌入调用会破坏无密钥回放的确定性;回溯必须保持为日志的纯函数。
|
||||
- **使用原始事件而不是渲染后的 transcript**:不予采纳,因为这会泄漏仅日志可见的词汇与分片噪声;模型应读取模型曾经看到的内容。
|
||||
- **什么都不做(用 resume/fork 恢复)**:不予采纳,因为这会把恢复变成人工操作。
|
||||
- **什么都不做(用恢复/fork 补救)**:不予采纳,因为这会把恢复变成人工操作。
|
||||
|
||||
## 验收标准
|
||||
|
||||
@@ -98,7 +98,7 @@ Status: proposed
|
||||
- 在全部摘要就绪且保护逻辑通过同类核算前,不提交任何内容;保护失败不会提交任何内容,也不会让轮次失败;提交中途被终止后,下一次 pre-step 会恢复处理,从日志读取合并基线,并无条件提交状态区域以完成本轮;旧版头部检查点会被视为状态类。
|
||||
- `history_read` 在预算内渲染任意已记录检查点的区段,并提供可用游标;`history_search` 覆盖每个被遮蔽区段,返回带检查点 id 的片段与覆盖元数据,测试尤其要能找到只存在于被已取代状态检查点遮蔽区段中的内容,这是锁定尾随切片可达性的回归用例;两个工具都会拒绝非 agent 调用方,并对从未存在的 id 或遗留 `compact/start` 返回类型化错误;回溯内容作为普通 `tool/result` 出现;请求重建不变量会在同时包含压缩与回溯的会话上通过;一项无密钥快照场景端到端覆盖先压缩再回溯;工具 schema 与提示词章节在各轮之间逐字节相同。
|
||||
- 在长时间跨度 bench 套件中:任务成功率在预算相同的条件下不低于 `compact-basic`;交接保真探针(在一轮后重新陈述 K 项已知决策和约束)的得分不降低;每次运行都通过 dsh bench 报告流水线汇报回溯使用频率和命中有效性,并同时报告存根目录注意力度量与缓存命中遥测。
|
||||
- seam JSDoc、压缩能力 seam Agent Note、`architecture.md`,以及生成的工具、配置、持久化与模块图目录都在同一改动中更新;全部预算位于配置中;新源码目录具备逐文件 100% 覆盖率与 HMR(热模块替换)释放测试。
|
||||
- seam JSDoc、压缩能力 seam Agent Note、`architecture.md`,以及生成的工具、配置、持久化与模块图目录都在同一改动中更新;全部预算位于配置中;新源码目录具备逐文件 100% 覆盖率与 HMR(热模块替换)dispose(资源释放)测试。
|
||||
|
||||
## 风险
|
||||
|
||||
@@ -106,5 +106,5 @@ Status: proposed
|
||||
- **未知的未知仍然存在**:如果某项细节既未出现在摘要中,也未出现在关键词中,就不会触发回溯。回溯把「即使已经怀疑也无法触达」变成「怀疑时可以触达」。
|
||||
- **存根目录会占用注意力**:每次请求中包含数十张稳定的索引卡,可能稀释模型关注点;验收标准中的 bench 度量会将其与 `compact-basic` 对比。
|
||||
- **成本**:每轮摘要输入大约是当前实现的两倍;短会话的成本和质量接近当前水平,而设计收益随会话长度增长。
|
||||
- **状态漂移与职责分工泄漏** 可以通过交接探针和存根评审观察;对应措施已列为后续事项。
|
||||
- **两个后端** 会扩大维护范围;seam 约定和共享回溯消费方会限制这一范围,bench 对比则用于逐步决定默认实现。
|
||||
- **状态漂移与职责分工泄漏**可以通过交接探针和存根评审观察;对应措施已列为后续事项。
|
||||
- **两个后端**会扩大维护范围;seam 约定和共享回溯消费方会限制这一范围,bench 对比则用于逐步决定默认实现。
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/proposed/feature/2026-07-08-interactive-side-sessions.md
|
||||
2026-07-08-interactive-side-sessions.md: 653f77b931fe1149aad9e15b82f40fe3272f5469
|
||||
2026-07-08-interactive-side-sessions.zh.md: f81a3809231ac18ba6b134abd4a821f47af8b662
|
||||
2026-07-08-interactive-side-sessions.zh.md: 7a5c1a7409902edc50c4020cebf7c2e3a736816c
|
||||
|
||||
@@ -6,25 +6,25 @@ Status: proposed
|
||||
|
||||
## 问题
|
||||
|
||||
用户可能希望在不改变当前会话主上下文的前提下,探索一个来自活跃会话的问题。现有原语无法提供这种产品形态:[会话存储 fork](../../implemented/feature/2026-06-30-session-store-fork-api.md)创建的是一个无关联的会话,而 [fork subagent](../../implemented/feature/2026-06-21-subagent-capability-seam.md)是模型驱动的任务,其 transcript(文本记录)会折叠为一条工具结果。两者都不能给用户一个独立的对话,也都不能在父会话中同时记录结论和产生该结论的侧会话。
|
||||
用户可能希望在不改变当前会话主上下文的前提下,探索一个来自活跃会话的问题。现有原语无法提供这种产品形态:[会话存储 fork](../../implemented/feature/2026-06-30-session-store-fork-api.md) 创建的是一个未绑定的会话,而 [fork subagent](../../implemented/feature/2026-06-21-subagent-capability-seam.md) 是模型驱动的任务,其 transcript(文本记录)会折叠为一条工具结果。两者都不能给用户一个独立的对话,也都不能在父会话中同时记录结论和产生该结论的侧会话。
|
||||
|
||||
## 提案
|
||||
|
||||
**侧会话(side session)** 是一个普通的活跃会话,从源会话的最后一个已完成轮次 fork 而来,绑定到自己的 agent(智能体),定位为只读顾问,并能**合并回写**一条精简笔记。
|
||||
**侧会话(side session)**是一个普通的活跃会话,从源会话的最后一个已完成轮次 fork 而来,绑定到自己的 agent(智能体),定位为只读顾问,并能**合并回写**一条精简笔记。
|
||||
|
||||
- **Fork 并绑定:** 以父会话的平衡已完成轮次前缀创建子会话,并在其元数据中标记 `parentSession` 与 `seedLength`。这组合了 `ctx.agents.create({ seed, meta })`;不新增核心服务或会话存储方法。
|
||||
- **顾问定位:** 创建后注入一条插件来源的 `context/message`,告知子会话只做解释,不执行变更或继续任务。保持系统提示词逐字节一致,可在继承的历史上保留提供方的前缀缓存。
|
||||
- **合并回写:** 向子会话请求一条有长度上限的 handback,然后向父会话注入一条插件来源的 `context/message`。父会话的下一次请求在日志所记录的位置看到该消息,保持回放与[请求可重建性](../../implemented/architecture/2026-07-05-reconstructable-requests.md),无需新增会话事件。
|
||||
- **呈现:** 调用方式、会话切换与 handback 渲染属于首个客户端拥有的界面。本 Agent Note 仅规定与界面无关的机制。
|
||||
- **Fork 并绑定:**以父会话的平衡已完成轮次前缀创建子会话,并在其元数据中标记 `parentSession` 与 `seedLength`。这组合了 `ctx.agents.create({ seed, meta })`;不新增核心服务或会话存储方法。
|
||||
- **顾问定位:**创建后注入一条插件来源的 `context/message`,告知子会话只做解释,不执行变更或继续任务。保持系统提示词逐字节一致,可在继承的历史上保留提供方的前缀缓存。
|
||||
- **合并回写:**向子会话请求一条有长度上限的 handback,然后向父会话注入一条插件来源的 `context/message`。父会话的下一次请求在日志所记录的位置看到该消息,保持回放与[请求可重建性](../../implemented/architecture/2026-07-05-reconstructable-requests.md),无需新增会话事件。
|
||||
- **呈现:**调用方式、会话切换与 handback 渲染属于首个客户端拥有的界面。本 Agent Note 仅规定与界面无关的机制。
|
||||
|
||||
回退产品化、会话树视图、面向模型的侧会话工具,以及 `forkName`/`mergedInto` 元数据均不在本 Agent Note 范围内。一次真实适配器 spike 已验证了源日志隔离、继承上下文、多轮子会话交互,以及合并回写在父会话下一轮次中的可见性。
|
||||
|
||||
## 曾考虑的替代方案
|
||||
|
||||
- **使用 subagent seam:** 否决。侧会话是用户驱动的、客户端可见的,且可能存活超过父会话的一个轮次;subagent 是模型驱动的运行,返回一条工具结果。
|
||||
- **修改子会话的系统提示词:** 默认否决,因为任何字节变化都会从第零个 token 起使前缀缓存失效。部署方仍可选择这种更强的隔离方式。
|
||||
- **新增 `sidechat/*` 事件:** 延后。已标注来源的 `context/message` 已经持久记录内容、生产方和回放输入;只有当某个界面需要差异化渲染时,专用事件才有正当理由。
|
||||
- **现在就绑定一个协议界面:** 否决。当前 UI 由客户端拥有。实时呈现最终必须从持久消息派生,以使回放渲染出相同的记录。
|
||||
- **使用 subagent seam:**否决。侧会话是用户驱动的、客户端可见的,且可能存活超过父会话的一个轮次;subagent 是模型驱动的运行,返回一条工具结果。
|
||||
- **修改子会话的系统提示词:**默认否决,因为任何字节变化都会从第零个 token 起使前缀缓存失效。部署方仍可选择这种更强的隔离方式。
|
||||
- **新增 `sidechat/*` 事件:**延后。已标注来源的 `context/message` 已经持久记录内容、生产方和回放输入;只有当某个界面需要差异化渲染时,专用事件才有正当理由。
|
||||
- **现在就绑定一个协议接口:**否决。当前 UI 由客户端拥有。实时呈现最终必须从持久消息派生,以使回放渲染出相同的记录。
|
||||
|
||||
## 验收标准
|
||||
|
||||
@@ -32,10 +32,10 @@ Status: proposed
|
||||
- 顾问定位在子会话追加历史的头部恰好添加一条插件来源的 `context/message`,而非修改其系统提示词。
|
||||
- 合并回写恰好添加一条有长度上限的 `context/message`,来源为 `plugin: sidechat`;父会话的下一次请求与回放在相同位置看到它。
|
||||
- 父会话与子会话并发运行,日志和流之间无串扰。
|
||||
- 单元测试覆盖 fork/attach 与合并回写;快照覆盖率随首个绑定界面一起落地。
|
||||
- 单元测试覆盖 fork/attach 与合并回写;快照覆盖随首个绑定界面一起落地。
|
||||
|
||||
## 风险
|
||||
|
||||
- 只读行为在 `tools/pre-execute` 拒绝门禁强制执行之前仅为建议性质;[拦截点](../../implemented/feature/2026-06-30-interception-extension-points.md) 可在不改变本机制的前提下添加该门禁。
|
||||
- 只读行为在 `tools/pre-execute` 拒绝门禁强制执行之前仅为建议性质;[拦截点](../../implemented/feature/2026-06-30-interception-extension-points.md)可在不改变本机制的前提下添加该门禁。
|
||||
- 经过压缩(compaction)的源会话 fork 出的是其压缩视图,因此绑定的界面应当告知用户子会话继承的是摘要而非被替换的轮次。
|
||||
- 反复的 handback 会消耗父会话上下文。每次合并的长度上限约束了单条笔记的大小;后续的合并整理属于上下文压缩的职责。
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/proposed/feature/2026-08-04-task-surface.md
|
||||
2026-08-04-task-surface.md: 72fc9e12f1a02f66a02d3335ad2e8d0d4c1c3dc2
|
||||
2026-08-04-task-surface.zh.md: 32de8167affd48472469083a580e1dd3f98a3c24
|
||||
2026-08-04-task-surface.zh.md: 7d4b26218bc51da3182c4f4bacac8e8dc6807411
|
||||
|
||||
@@ -178,7 +178,7 @@ interface TaskSurfaceUserMessageSource {
|
||||
}
|
||||
```
|
||||
|
||||
`session/queue` 线上的条目已经携带完整 `Message`。客户端投影会显式扩展以保留其来源,不再丢失关联信息:
|
||||
`session/queue` 协议条目已经携带完整 `Message`。客户端投影会显式扩展以保留其来源,不再丢失关联信息:
|
||||
|
||||
```ts ignore-check
|
||||
interface QueuedMessage {
|
||||
@@ -226,7 +226,7 @@ Web 插件将未提交值保存在一个有界、按会话持久化的 slot stor
|
||||
|
||||
| 包 | 职责 |
|
||||
|---|---|
|
||||
| `packages/core/agent` 和 `packages/core/agent-loop` | 为已认领的下一轮 inbox 调用实例提供通用终态结果,让 Host 观察方无需使用 Task Surface 专用类型,即可区分持久接纳和丢弃 |
|
||||
| `packages/core/agent` 和 `packages/core/agent-loop` | 为已认领的下一轮 inbox 条目提供通用终态结果,让 Host 观察方无需使用 Task Surface 专用类型,即可区分持久接纳和丢弃 |
|
||||
| `packages/task-surface/task-surface` | 浏览器安全的模型、带品牌类型的 ID、关联和待处理类型、解析器、限制、提交校验器/格式化器、会话事件扩展、投影单元,以及 Host 服务约定 |
|
||||
| `packages/task-surface/tool-task-surface` | `show_task_surface`、规范输出、呈现元数据、通用 render intent、活动 Surface 检查和 `concludeTurn()` 行为 |
|
||||
| `packages/client/runtime` | 通用排队消息 `source` 投影和会话作用域的活动投影访问 |
|
||||
@@ -242,7 +242,7 @@ Web 插件将未提交值保存在一个有界、按会话持久化的 slot stor
|
||||
|
||||
1. 实现模型/解析器、`MarkdownText` 模型 URL 策略、投影单元、`show_task_surface`、呈现元数据、只读 Web 行、静态 `TaskSurfaceDock`、活动 Surface 读取,以及带只读块的通用回退。
|
||||
2. 增加字段、持久化草稿、经 Host 校验的提交/关闭、带品牌类型的关联信息、客户端排队来源传递、Task Surface `queued`/`claiming` 协调、已认领调用实例的终态报告、队列操作限制,以及可见用户消息接纳。
|
||||
3. 只增加有实际任务依据,并且拥有至少两个消费方或明确通用回退的组件类型。一个单独的显式用户操作可以启动生成式插件编写工作流,但只会创建候选项,绝不会直接推广代码。
|
||||
3. 只增加有实际任务依据,并且拥有至少两个消费方或明确通用回退的组件类型。一个单独的显式用户操作可以启动生成客户端插件的编写工作流,但只会创建一个候选方案,绝不会直接将代码转为正式实现。
|
||||
|
||||
## 考虑过的替代方案
|
||||
|
||||
@@ -263,10 +263,10 @@ Web 插件将未提交值保存在一个有界、按会话持久化的 slot stor
|
||||
- 在 `native` 或 `both` 工具模式下,真实模型可以调用一个稳定的 `show_task_surface` schema;调用结束当前轮次;具备相应能力的 Web 客户端在实时运行和回放后都能渲染同一份规范化模型;仅支持 `code` 的模式不会向模型公布该工具。
|
||||
- 静态 `TaskSurfaceDock` 是唯一的编辑器,即使活动结果位于已加载历史窗口之外也仍可操作;带 key 的 toolview 始终是 transcript 的只读摘要和回放。composer 接管会隐藏仍处于挂载状态的 Dock、保留其草稿,并在接管释放后重新显示同一个所有者。
|
||||
- 每个 `submissionId` 的提交操作恰好生成一条可见用户消息,通过普通队列接纳开始下一轮,并在保留 `source.kind: 'user'` 的同时维持带品牌类型的确切调用实例关联;关闭操作记录一条日志事件,且不启动轮次。
|
||||
- 客户端排队行保留已关联的消息来源。`getActive` 可在同一进程的重新连接前后公开 `queued` 或 `claiming`;提交会关闭投影,显式丢弃则会清除待处理状态并让 Surface 保持打开。队列行消失本身不会改变任何 UI 状态。系统会拒绝编辑和 steering,且移除操作只能在认领前成功。
|
||||
- 客户端排队行保留已关联的消息来源。`getActive` 可在同一进程的重新连接前后公开 `queued` 或 `claiming`;持久化完成后会关闭投影,显式丢弃则会清除待处理状态并让 Surface 保持打开。队列行消失本身不会改变任何 UI 状态。系统会拒绝编辑和 steering,且移除操作只能在认领前成功。
|
||||
- 刷新、重新连接、会话切换、fork 和回退都生成日志所决定的生命周期状态;`getActive` 可以恢复历史尾段之外的模型和待处理阶段,任何面板、待处理状态或草稿都不会泄漏到其他会话。
|
||||
- 不受支持的版本、格式错误的元数据以及客户端能力缺失时,系统回退到带普通消息绕过路径的可读工具结果内容;嵌套调用以及已有另一个活动 Surface 时发起的调用都无法打开 Surface,并以失败结束。
|
||||
- 线上的 schema 会校验 ID 字符串,领域 API 始终公开带品牌类型的 ID。模型解析器会在面板可交互前强制校验带标签的布局形态、字段值,以及配置的字节数和数量限制。浏览器测试证明:图片语法会变成替代文本,原始 HTML 和嵌入式媒体不会渲染,而且在用户显式操作前不会请求模型提供的 URL。
|
||||
- 协议 schema 会校验 ID 字符串,领域 API 始终公开带品牌类型的 ID。模型解析器会在面板可交互前强制校验带标签的布局形态、字段值,以及配置的字节数和数量限制。浏览器测试证明:图片语法会变成替代文本,原始 HTML 和嵌入式媒体不会渲染,而且在用户显式操作前不会请求模型提供的 URL。
|
||||
- 组件测试覆盖纯键盘操作、焦点恢复、无障碍名称、窄屏布局、两种主题,以及中英文产品界面。
|
||||
- 无密钥浏览器组合测试覆盖显示、Dock 与只读行的职责归属、窗口外恢复、编辑、接纳被拒后的重试、从 `queued` 到 `claiming` 的转换、丢弃、没有可编辑空档的持久交接、禁止的队列操作、关闭、重新连接和双重提交幂等性。
|
||||
- 前缀快照表明:无论任务特定模型如何变化,都只存在一个稳定的工具定义;只有调用参数和后续用户结论发生变化。
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/proposed/process/2026-07-13-human-review-skill-maintenance.md
|
||||
2026-07-13-human-review-skill-maintenance.md: b741c8b595fcd36613cb246af483863d1e056697
|
||||
2026-07-13-human-review-skill-maintenance.zh.md: 1c00577fdb08c30b1fff794c08da20ec38891de1
|
||||
2026-07-13-human-review-skill-maintenance.zh.md: 9191a4ed24002c533d139637501fe56afbd34c34
|
||||
|
||||
@@ -6,7 +6,7 @@ Status: proposed
|
||||
|
||||
## 问题
|
||||
|
||||
`dsh-code-review` skill(技能)记录需要评审人判断的失败模式,但一次性审计既难以重复,作用域也容易不一致。把每条评论都当作教训会让检查清单不断膨胀;把合并、讨论串已解决或作者回复「已修复」视为采纳证据,则会把最终代码可能并未落实的反馈提升为规则。维护流程需要足够的证据和独立评审,以便在证据不足时按不采纳处理,同时无需在工作流证明有用之前引入 webhook 服务、持久事件状态或自动仓库推广。
|
||||
`dsh-code-review` skill(技能)记录需要评审人判断的失败模式,但一次性审计重复开展起来成本高昂,作用域也容易不一致。把每条评论都当作教训会让检查清单不断膨胀;把合并、讨论串已解决或作者回复「已修复」视为采纳证据,则会把最终代码可能并未落实的反馈提升为规则。维护流程需要足够的证据和独立评审,以便在证据不足时按不采纳处理,同时无需在工作流证明有用之前引入 webhook 服务、持久事件状态或自动仓库推广。
|
||||
|
||||
## 提案
|
||||
|
||||
@@ -38,7 +38,7 @@ flowchart TD
|
||||
|
||||
### 双评审人分类与起草
|
||||
|
||||
两个独立配置的评审适配器,会对每个符合条件的条目分类:谁编写了它(`human-authored`、`forwarded-automation` 或 `unclear`),以及变更是否采纳了它(`adopted`、`rejected` 或 `unclear`)。只有两个适配器都判定为 `human-authored` 加 `adopted` 的条目才会继续。采纳集合随后会针对当前 skill 接受第二次独立分类:候选项、已经覆盖、实现专用或并非反馈。单个条目即可符合要求,不要求重复出现。意见分歧会得到一次有界的重新评估;如果仍未解决,则继续保留在运行产物中。单个批次的适配器输出如果未通过 schema 或 id 校验,系统会在批次层按不采纳处理:其中的每条反馈都标记为 unclear 并路由到 `excluded`,而不是中止整次运行;有问题的原始输出会保存在该次运行的私有产物中,供调试使用。如果任一适配器在某项操作的任何非空批次中都没有返回有效结果,运行会以非零状态退出并发出失败记录,而不会报告「没有候选项」。
|
||||
两个独立配置的评审适配器,会对每个符合条件的条目分类:谁编写了它(`human-authored`、`forwarded-automation` 或 `unclear`),以及变更是否采纳了它(`adopted`、`rejected` 或 `unclear`)。只有两个适配器都判定为 `human-authored` 加 `adopted` 的条目才会继续。采纳集合随后会针对当前 skill 接受第二次独立分类:候选项、已经覆盖、特定于实现或并非反馈。单个条目即可符合要求,不要求重复出现。意见分歧会得到一次有界的重新评估;如果仍未解决,则继续保留在运行产物中。单个批次的适配器输出如果未通过 schema 或 id 校验,系统会在批次层按不采纳处理:其中的每条反馈都标记为 unclear 并路由到 `excluded`,而不是中止整次运行;有问题的原始输出会保存在该次运行的私有产物中,供调试使用。如果任一适配器在某项操作的任何非空批次中都没有返回有效结果,运行会以非零状态退出并发出失败记录,而不会报告「没有候选项」。
|
||||
|
||||
主适配器只根据结构化的共同指引起草,绝不接收原始评审文本。根据适配器作者的约定,它保持无工具且只读:返回完整的候选文件内容,由工具校验后写入唯一目标。两个适配器随后评审同一份完整 skill diff;阻塞性问题会进入有界修订循环,而且两者必须批准同一版修订。工具会在运行文档和 lint 检查前,以及报告成功前,再次拒绝暂存改动和目标 skill 之外的编辑,因此检查或并发进程无法通过添加其他路径混入。失败时,工具使用尽力而为的比较并交换回滚自身写入,以免覆盖维护者的并发编辑。成功时,它保存一份候选资料包,其中包含源 `origin/master` commit、源 skill blob ID、已评审 diff、完整候选文件、源反馈 ID 与 URL、落地证据范围、适配器判定和检查结果;它绝不提交、推送、打开或合并 PR。
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/proposed/simplification/2026-07-04-prune-dead-core-spine-api.md
|
||||
2026-07-04-prune-dead-core-spine-api.md: ac0a72973f9c44e1f322eeff2e095d751497edf8
|
||||
2026-07-04-prune-dead-core-spine-api.zh.md: 9c00025027c11a0ee1a716c3cb3c65d19d71e990
|
||||
2026-07-04-prune-dead-core-spine-api.zh.md: aebc8cb7afbdcc85aab2d58b34fa0493ac7bcbb5
|
||||
|
||||
@@ -29,8 +29,8 @@ Status: proposed
|
||||
| `CodeLogEntry.source`/`level` 与 `RunCodeMeta.dispatches` | 每个生产消费方都将日志映射为文本;没有 presenter/模型路径读取其他字段或持久化的 dispatch 计数。 | 将 code-runtime 日志改为字符串(或纯文本条目),移除 result-meta 的 dispatch 管道;保留用于生成确定性 dispatch id 的本地计数器。 |
|
||||
| `CodeRuntime.language` 与 `CodeRuntime.isolation` | worker 后端提供唯一的生产值,而 Code Mode 及其他所有生产调用方只调用 `run()`。 | 移除未读描述符,同时保留 worker 的语言、隔离、预算、取消与资源释放行为。 |
|
||||
| `ToolNotFoundError.toolName`、`SystemPrompt.config` 与 `BashTask.command` | 每个存储的公开值都没有生产读取者。 | 移除未读字段,保留错误消息、已解析的配置行为和任务生命周期。 |
|
||||
| 后端包根实现辅助函数 | 下方精确清单仅通过相对路径的同包导入调用。生产命名空间导入挂载的是保留的插件约定,不读取这些属性;命名根消费方都是测试。 | 保留每个适配器/提供方/服务及其配置/错误约定;停止在包根导出所列辅助函数/常量。 |
|
||||
| 消费方包根实现辅助函数 | 下方精确清单只有同包生产调用者。生产命名空间导入挂载的是插件约定,不读取辅助属性;命名根消费方都是测试。 | 保留插件约定和稳定的错误码;将测试迁移到包内模块或公开行为,停止在包根导出所列辅助函数。 |
|
||||
| 后端包根实现辅助函数 | 下方精确清单仅通过相对路径的同包导入调用。生产命名空间导入挂载的是保留的插件约定,不读取这些属性;包根命名导入的消费方都是测试。 | 保留每个适配器/提供方/服务及其配置/错误约定;停止在包根导出所列辅助函数/常量。 |
|
||||
| 消费方包根实现辅助函数 | 下方精确清单只有同包生产调用者。生产命名空间导入挂载的是插件约定,不读取辅助属性;包根命名导入的消费方都是测试。 | 保留插件约定和稳定的错误码;将测试迁移到包内模块或公开行为,停止在包根导出所列辅助函数。 |
|
||||
|
||||
### 分组辅助导出清单
|
||||
|
||||
@@ -53,8 +53,8 @@ Status: proposed
|
||||
|
||||
## 验收标准
|
||||
|
||||
- 精确符号搜索显示:在本 Agent Note 及任何已实现 Agent Note 修正之外,没有被移除的接口。
|
||||
- 本 Agent Note 列出的每个接口均按指定方式缺失或降级;清单之外有意保留的扩展/测试约定不变。
|
||||
- 精确符号搜索显示:在本 Agent Note 及任何对已实现 Agent Note 的修正之外,没有被移除的接口。
|
||||
- 本 Agent Note 列出的每个接口均按指定方式移除或降级;清单之外有意保留的扩展/测试约定不变。
|
||||
- 工具执行、上下文压缩(context compaction)、两个 LLM 适配器、两个持久化后端、工作流隔离以及 agent 创建/恢复保持其已交付行为。
|
||||
- 类型检查、覆盖率、快照、doc-sync(文档同步门禁)、module-graph 校验、构建和 hygiene 通过。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user