docs: bilingual counterparts for the projection READMEs; review-driven RFC precision

New zh pairs for the session-projection group and package READMEs (both
gained their missing language-switcher lines); the packages/README rows,
apiproxy README, and tool-todo README zh sides catch up with their edited
English; the group README's stale ProjectionProvider name becomes
ProjectionDefinition. RFC precision from review: asOfSeq is the last
event's seq (session.seq - 1, -1 empty; subscribed.lastSeq vocabulary) and
a new risk names the accepted dev-only staleness window when registry
churn changes the key set mid-session. Pairing re-recorded; 540 pairs
consistent.
This commit is contained in:
imccyu
2026-07-28 01:19:30 +08:00
parent c10edbbc85
commit 4d7b30ab72
15 changed files with 98 additions and 18 deletions

View File

@@ -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 packages/session-projection/README.md
README.md: 81c67d56e136ba4853e86d889b485d4df80ac1fe
README.zh.md: 72e23b78a48a989f355f9be3d34d81a440ca1d04

View File

@@ -1,7 +1,9 @@
# session-projection/
English | [中文](README.zh.md)
Session-projection capability family: the seam through which domain host plugins serve whole current values of log-derived per-session state to client carriers.
| Package | ctx key | Role |
|---|---|---|
| [`session-projection`](session-projection/README.md) | `sessionProjections` | The interface package: the merge-extensible `SessionProjectionMap` type table, the `ProjectionProvider` contract, and the provider registry carriers walk synchronously |
| [`session-projection`](session-projection/README.md) | `sessionProjections` | The interface package: the merge-extensible `SessionProjectionMap` type table, the `ProjectionDefinition` unit contract, and the eagerly driven registry carriers read synchronously |

View File

@@ -0,0 +1,9 @@
# session-projection/
[English](README.md) | 中文
会话投影能力家族:领域 host 插件经由此 seam把日志派生的按会话状态的当前全量值供给客户端载体。
| 包 | ctx 键 | 职责 |
|---|---|---|
| [`session-projection`](session-projection/README.md) | `sessionProjections` | 接口包packagemerge-extensible 的 `SessionProjectionMap` 类型表、`ProjectionDefinition` 单元契约,以及供载体同步读取的正向驱动注册表 |

View File

@@ -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 packages/session-projection/session-projection/README.md
README.md: 2e026aab55933c96ba961481f9597bc18cbbe910
README.zh.md: a3e0b0f46466d19321b0950dc41d06473a54a1ce

View File

@@ -1,5 +1,7 @@
# @deepseek-ai/dsh-session-projection
English | [中文](README.zh.md)
Session-projection seam. It owns `ctx.sessionProjections`, the registry that DRIVES every registered projection unit forward over committed session events and serves finished whole values to carriers (the api-proxy history tail page and `session/projection` push frame today; TUI/ACP/headless consumers later). A domain registers pure mathematics; the framework owns the drive. Design authority: the [session-projection RFC](../../../.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md).
## Service: `SessionProjectionRegistry` (ctx key: `sessionProjections`)

View File

@@ -0,0 +1,47 @@
# @deepseek-ai/dsh-session-projection
[English](README.md) | 中文
会话投影 seam。它拥有 `ctx.sessionProjections`——该注册表驱动每个已注册的投影单元在已提交会话事件上前进,并向载体供给成品全量值(今天是 api-proxy 历史尾页与 `session/projection` 推送帧;日后是 TUI、ACPAgent Client Protocol、headless 消费方)。领域注册的只是纯数学;驱动权归框架。设计权威:[session-projection RFC](../../../.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md)。
## 服务:`SessionProjectionRegistry`ctx 键:`sessionProjections`
### 公开 API
- `ctx.sessionProjections.register(definition): () => void` 注册一个领域的单元。key 重复或 `stateVersion` 非法都会 throw注册是挂在调用方 fiber 上的 effect领域插件卸载后其 key连同缓存的 cell从后续驱动与快照中消失——客户端将其读作能力缺失。
- `ctx.sessionProjections.onChanged(listener): () => void` 订阅变更流:每个已提交事件、每个状态引用发生变化的单元各回调一次,携带经 schema 校验的 view 与致因 seq。与 `register` 一样绑定 effect。
- `ctx.sessionProjections.snapshot(session): ProjectionSnapshot` 对全部已注册单元做一次一致的同步切面——`{ asOfSeq, values }`,其中 `asOfSeq` = 所有值共同反映到的最后一个事件的 seq空日志为 `-1`)。
### 关键类型
- `SessionProjectionMap`——整条链路唯一的 merge-extensible 类型表host 侧单元、协议块、React 钩子)。值是协议层 JSON 全量值;渲染归 slot 体系管,永远不归本层。
- `ProjectionDefinition<K, S>`——`{ key, schema, init(), apply(state, event), view(state), stateVersion }`由三个纯同步函数外加若干声明构成的状态驱动计算单元state-driven computation unit绝不是一个不透明的 getter。
## 契约
- **框架负责驱动,领域负责计算。** 注册表只订阅一次 `session/event`;每个已提交事件都正向经过每个单元的 `apply`。领域不持有任何订阅。cell每会话每单元一份 `{state, observedSeq}`,以 WeakMap 为键)惰性构建——在事件流过之后才注册的单元,或读取一个早于该注册的会话,都在首次触达时从 `init` 出发在内存日志上折叠。
- **同引用即无工作。** 对与单元无关的事件,`apply` 必须返回同一个状态引用;驱动以 `Object.is` 把守变更流,因此不匹配的事件只花一次调用,不产生任何下游工作。
- **全量值事件规则(承重)。** 携带状态的日志事件必须携带变更后的完整状态,绝不携带裸增量——这让每次状态转移始终足够廉价,也让每个被供给的值自描述(对消费方即 last-wins
- **单元的同步纪律。** `init`/`apply`/`view` 必须是同步的;载体在切出页面切片的同一 tick 内读取 `snapshot()``asOfSeq` 之所以是一个一致切面正系于此。误写成异步的 `view` 会返回 Promise让边界的 `schema.parse` 当场大声失败。
- **状态是纯 JSON`stateVersion` 是其失效锚点。** 持久投影缓存persisted projection cache后续阶段存储 `(sessionId, key, stateVersion, observedSeq, stateJson)` 行;状态形状或折叠语义一旦变化就递增 `stateVersion`,使陈旧行被丢弃,而不是被正向 apply 成垃圾。
- **本层没有协议词汇。** 注册表只暴露变更流与快照读取面载体api-proxy据此自铸各自的帧`session/projection`)与块。
- **可选 seam。** 领域插件在 `ctx.inject(['sessionProjections'], …)` 下注册,因此不带注册表的 headless 组装完全不受影响;载体使用 `ctx.get('sessionProjections')`,注册表缺席时完全省略自己的块与帧。
## 职责
这是能力 seam 拆分中「接口 + 驱动」的那个包:领域 host 插件(如 `dsh-tool-todo`)贡献单元,载体(`dsh-host-apiproxy`)消费快照与变更流,两侧互不相识。
## 模型体验
无——注册表只对已入日志的会话状态计算面向客户端的读模型不触碰任何提示词、消息、schema、流或工具结果。
#### KV Cache 影响
无;投影从不组装或发送提供方请求。
## 已知限制与延期工作
- **每个尾页携带每个已注册的 key**——尚无逐 key 的 opt-out 或惰性 key 请求形状;在值都是 UI 量级的全量状态(一张 todo 清单、一份 goal 快照)时可以接受,若某领域的值变大再重议。
- **正向驱动eager drive逐事件触达每个单元**——按构造开销很低(全量值规则、同引用闸门),但若出现热点路径,可加按单元的事件类型预过滤,契约不变。
- **持久投影缓存属于后续阶段**——cell 目前只活在内存里;重启后首次触达时靠折叠内存日志重建。`stateVersion` 字段是为该阶段预先声明的失效锚点。
- **单元同步纪律只有部分可机械把关**——边界 `schema.parse` 能拒绝返回 Promise 的 `view`,但阻塞的 `apply`、或读取撕裂的非会话状态的 `apply`只能靠评审把关invariant 配套记载了为何不存在运行时检查。