dsh-plugin-guide 0.3.3 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/README.es.md +5 -1
  2. package/README.hi.md +5 -1
  3. package/README.md +5 -1
  4. package/README.pt.md +5 -1
  5. package/README.zh.md +5 -1
  6. package/dist/dsh-plugin-dev.js +3 -3
  7. package/guide/plugin-dev-guide.md +2 -2
  8. package/guide/quick-reference.es.md +2 -2
  9. package/guide/quick-reference.hi.md +1 -1
  10. package/guide/quick-reference.md +2 -2
  11. package/guide/quick-reference.pt.md +2 -2
  12. package/guide/quick-reference.zh-CN.md +2 -2
  13. package/package.json +5 -4
  14. package/references/official-docs/AGENTS.md +2 -2
  15. package/references/official-docs/SNAPSHOT.md +3 -3
  16. package/references/official-docs/THIRD_PARTY_NOTICES.md +4 -6
  17. package/references/official-docs/docs/agent-lifecycle.i18n.yaml +2 -2
  18. package/references/official-docs/docs/agent-lifecycle.md +5 -3
  19. package/references/official-docs/docs/agent-lifecycle.zh.md +5 -3
  20. package/references/official-docs/docs/architecture.i18n.yaml +2 -2
  21. package/references/official-docs/docs/architecture.md +7 -3
  22. package/references/official-docs/docs/architecture.zh.md +7 -3
  23. package/references/official-docs/docs/capability-seams.i18n.yaml +2 -2
  24. package/references/official-docs/docs/capability-seams.md +5 -0
  25. package/references/official-docs/docs/capability-seams.zh.md +5 -0
  26. package/references/official-docs/docs/config-catalog.i18n.yaml +2 -2
  27. package/references/official-docs/docs/config-catalog.md +15 -21
  28. package/references/official-docs/docs/config-catalog.zh.md +15 -21
  29. package/references/official-docs/docs/cookbook/extension-cookbook.i18n.yaml +2 -2
  30. package/references/official-docs/docs/cookbook/extension-cookbook.md +12 -10
  31. package/references/official-docs/docs/cookbook/extension-cookbook.zh.md +12 -10
  32. package/references/official-docs/docs/deepseek-llm-api-wire-extensions.i18n.yaml +2 -2
  33. package/references/official-docs/docs/deepseek-llm-api-wire-extensions.md +16 -12
  34. package/references/official-docs/docs/deepseek-llm-api-wire-extensions.zh.md +16 -12
  35. package/references/official-docs/docs/event-producer-consumer.i18n.yaml +2 -2
  36. package/references/official-docs/docs/event-producer-consumer.md +28 -27
  37. package/references/official-docs/docs/event-producer-consumer.zh.md +32 -31
  38. package/references/official-docs/docs/module-graph.i18n.yaml +2 -2
  39. package/references/official-docs/docs/module-graph.md +36 -14
  40. package/references/official-docs/docs/module-graph.zh.md +36 -14
  41. package/references/official-docs/docs/persistence-catalog.i18n.yaml +2 -2
  42. package/references/official-docs/docs/persistence-catalog.md +49 -39
  43. package/references/official-docs/docs/persistence-catalog.zh.md +39 -29
  44. package/references/official-docs/docs/subsystems/attachment.i18n.yaml +2 -2
  45. package/references/official-docs/docs/subsystems/attachment.md +157 -4
  46. package/references/official-docs/docs/subsystems/attachment.zh.md +157 -4
  47. package/references/official-docs/docs/subsystems/commands.i18n.yaml +2 -2
  48. package/references/official-docs/docs/subsystems/commands.md +24 -15
  49. package/references/official-docs/docs/subsystems/commands.zh.md +24 -15
  50. package/references/official-docs/docs/subsystems/conversation.i18n.yaml +2 -2
  51. package/references/official-docs/docs/subsystems/conversation.md +4 -4
  52. package/references/official-docs/docs/subsystems/conversation.zh.md +4 -4
  53. package/references/official-docs/docs/subsystems/core.i18n.yaml +2 -2
  54. package/references/official-docs/docs/subsystems/core.md +62 -1
  55. package/references/official-docs/docs/subsystems/core.zh.md +62 -1
  56. package/references/official-docs/docs/subsystems/llm-streaming.i18n.yaml +2 -2
  57. package/references/official-docs/docs/subsystems/llm-streaming.md +23 -2
  58. package/references/official-docs/docs/subsystems/llm-streaming.zh.md +23 -2
  59. package/references/official-docs/docs/subsystems/persistence.i18n.yaml +2 -2
  60. package/references/official-docs/docs/subsystems/persistence.md +10 -10
  61. package/references/official-docs/docs/subsystems/persistence.zh.md +10 -10
  62. package/references/official-docs/docs/subsystems/session-projection.i18n.yaml +2 -2
  63. package/references/official-docs/docs/subsystems/session-projection.md +19 -0
  64. package/references/official-docs/docs/subsystems/session-projection.zh.md +19 -0
  65. package/references/official-docs/docs/subsystems/session-reference.i18n.yaml +2 -2
  66. package/references/official-docs/docs/subsystems/session-reference.md +25 -1
  67. package/references/official-docs/docs/subsystems/session-reference.zh.md +25 -1
  68. package/references/official-docs/docs/subsystems/session-telemetry.i18n.yaml +2 -2
  69. package/references/official-docs/docs/subsystems/session-telemetry.md +6 -5
  70. package/references/official-docs/docs/subsystems/session-telemetry.zh.md +6 -5
  71. package/references/official-docs/docs/subsystems/session.i18n.yaml +2 -2
  72. package/references/official-docs/docs/subsystems/session.md +52 -40
  73. package/references/official-docs/docs/subsystems/session.zh.md +52 -40
  74. package/references/official-docs/docs/subsystems/web-client.i18n.yaml +2 -2
  75. package/references/official-docs/docs/subsystems/web-client.md +1 -1
  76. package/references/official-docs/docs/subsystems/web-client.zh.md +1 -1
  77. package/references/official-docs/docs/subsystems/workspace.i18n.yaml +2 -2
  78. package/references/official-docs/docs/subsystems/workspace.md +8 -8
  79. package/references/official-docs/docs/subsystems/workspace.zh.md +8 -8
  80. package/references/official-docs/docs/testing.i18n.yaml +2 -2
  81. package/references/official-docs/docs/testing.md +2 -2
  82. package/references/official-docs/docs/testing.zh.md +2 -2
  83. package/references/official-docs/docs/user/guide/network-proxy.i18n.yaml +6 -0
  84. package/references/official-docs/docs/user/guide/network-proxy.md +85 -0
  85. package/references/official-docs/docs/user/guide/network-proxy.zh.md +85 -0
  86. package/references/official-docs/docs/user/guide/providers.i18n.yaml +2 -2
  87. package/references/official-docs/docs/user/guide/providers.md +70 -17
  88. package/references/official-docs/docs/user/guide/providers.zh.md +70 -17
  89. package/references/official-docs/docs/web-styling.i18n.yaml +2 -2
  90. package/references/official-docs/docs/web-styling.md +1 -0
  91. package/references/official-docs/docs/web-styling.zh.md +1 -0
  92. package/references/official-docs/website-docs.ts +8 -0
  93. package/templates/js/README.es.md +1 -1
  94. package/templates/js/README.hi.md +1 -1
  95. package/templates/js/README.md +1 -1
  96. package/templates/js/README.pt.md +1 -1
  97. package/templates/js/README.zh.md +1 -1
  98. package/templates/ts/README.es.md +1 -1
  99. package/templates/ts/README.hi.md +1 -1
  100. package/templates/ts/README.md +1 -1
  101. package/templates/ts/README.pt.md +1 -1
  102. package/templates/ts/README.zh.md +1 -1
@@ -8,7 +8,7 @@ The seam is a [capability seam](../../.agents/notes/implemented/architecture/202
8
8
 
9
9
  ## `SessionHandle` — one open channel onto a stored session
10
10
 
11
- Every log read and write flows through a handle, never through id-addressed service methods: the handle is the single door a future cross-process write lease will guard. One handle type serves both accesses — a mutation on a `read` handle is a runtime `SessionReadOnlyError` rather than a typed split — and in-process single-writer ownership makes a second `open(id, 'write')` reject with `SessionAlreadyOwnedError` while an owner is active.
11
+ Every log read and write flows through a handle, never through id-addressed service methods: the handle is the single door the cross-process write lease guards. One handle type serves both accesses — a mutation on a `read` handle is a runtime `SessionReadOnlyError` rather than a typed split — and in-process single-writer ownership makes a second `open(id, 'write')` reject with `SessionAlreadyOwnedError` while an owner is active.
12
12
 
13
13
  ```ts type-equiv
14
14
  /**
@@ -133,11 +133,10 @@ Source: [`packages/core/session/src/types.ts`](../../packages/core/session/src/t
133
133
  */
134
134
  interface SessionHeader {
135
135
  /**
136
- * On-disk format version, stamped from {@link SESSION_FORMAT_VERSION} when the
137
- * session is created. A persistence backend rejects any other version on load
138
- * (no migration — see the constant).
136
+ * Current logical format version, stamped from {@link SESSION_FORMAT_VERSION}.
137
+ * Historical physical headers are translated before entering this interface.
139
138
  */
140
- readonly version: number
139
+ readonly version: typeof SESSION_FORMAT_VERSION
141
140
  /** The session's id (mirrors the {@link Session}'s id). */
142
141
  readonly id: SessionId
143
142
  /** Non-negative safe-integer Unix epoch milliseconds when the session was created. */
@@ -174,11 +173,11 @@ interface SessionHeader {
174
173
 
175
174
  ## Format refusal — logs a build cannot faithfully read
176
175
 
177
- A backend refuses a log it cannot faithfully interpret with `SessionFormatUnsupportedError`, distinct from `SessionPersistenceCorruptionError` because nothing is damaged. A header `version` ahead of `SESSION_FORMAT_VERSION` names the direction ("written by a newer harness upgrade the harness to open it"); one behind it states that this build ships no upgrade path. An event type outside this build's generated vocabulary (`KNOWN_SESSION_EVENT_TYPES`, emitted by `gen-persistence-catalog`) refuses the same way unless the event's envelope carries `ignorable: true` silently skipping an unrecognized required event could change how the rest of the log must be read. The message appends the raw log path when the backend keeps one artifact per session, so the refused text stays reachable. The JSONL backend refuses a foreign version straight from the raw header line, before validating this format version's header shape or decoding any event row — a structurally different future format still reports the upgrade direction, never "corrupt". An out-of-tree backend must enforce the equivalent direction-aware refusal at its own physical-format boundary. Design rationale and the deferred upgrader chain live in the [session-log-version-mechanism note](../../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md).
176
+ A backend refuses a log it cannot faithfully interpret with `SessionFormatUnsupportedError`, distinct from `SessionPersistenceCorruptionError` because nothing is damaged. `stat` and `list` classify the highest canonical generation and translate a supported historical header without reading or mutating its body. `open` runs the build-static adjacent migration chain under per-id serialization before returning a handle, leaves every source path, byte, and inode unchanged, and exclusively publishes only the final current generation. A future highest generation refuses even when an older readable generation remains. Current v2 restoration retains installed extensions and unknown events carrying `ignorable: true`; historical v0/v1 migration refuses an unknown type even when marked ignorable. The message appends the selected raw log path when the backend keeps one artifact per session. The JSONL backend migrates released v0 or v1 to current v2 and refuses a future version before interpreting its version-specific fields or event rows. An out-of-tree backend must enforce equivalent current-only handle values and direction-aware refusals at its physical-format entry. The [released-format migration decision](../../.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.md) owns the chain and immutable-publication rules.
178
177
 
179
178
  ## `CreateSessionOptions` — seeding and metadata
180
179
 
181
- Creating a `Session` through the store takes a `seed` (initial replay or fork history), an optional exact `inheritedEventCount`, and `meta` (the storage-level fields the store folds into a `SessionHeader`). The store fills in `version`/`id` and defaults `createdAt`; the caller may supply the validated absolute `cwd`, `parentSession` lineage, `isSeeded` lineage bit, optional coarse `origin`, `delegationDepth`, `agentPreset`, and an existing `createdAt`. A seeded creation requires both an explicit seed and exact cut because child-owned setup events may follow the inherited prefix. `origin: 'subagent'` lets product navigation hide duplicate child rows; it does not prove that a descriptor is valid or that the child can resume.
180
+ Creating a `Session` through the store takes a `seed` (initial replay or fork history), an optional exact `inheritedEventCount`, and `meta` (the storage-level fields the store folds into a `SessionHeader`). The store fills in `version`/`id` and defaults `createdAt`; the caller may supply the validated absolute `cwd`, `parentSession` lineage, `isSeeded` lineage bit, optional coarse `origin`, `delegationDepth`, `agentPreset`, and an existing `createdAt`. A seeded creation requires an explicit seed equal to its inherited prefix and an exact cut; the constructor appends the child-owned tagged end-seed marker at that cut before setup adds child-owned events. `origin: 'subagent'` lets product navigation hide duplicate child rows; it does not prove that a descriptor is valid or that the child can resume.
182
181
 
183
182
  ```ts type-equiv
184
183
  /**
@@ -190,8 +189,9 @@ interface CreateSessionOptions {
190
189
  /** Initial replay or fork history supplied at construction. */
191
190
  readonly seed?: readonly SessionEvent[]
192
191
  /**
193
- * Exact fork-inherited prefix length when `meta.isSeeded` is true. A
194
- * constructor seed may also contain child-owned setup events after this cut.
192
+ * Exact fork-inherited prefix length when `meta.isSeeded` is true. In v2 the
193
+ * constructor seed is exactly this inherited prefix; the constructor
194
+ * appends the child-owned tagged marker at the cut.
195
195
  */
196
196
  readonly inheritedEventCount?: SessionLogOffset
197
197
  /**
@@ -299,7 +299,7 @@ interface SessionPersistenceSnapshot {
299
299
  }
300
300
  ```
301
301
 
302
- The optional `eventCount`/`sizeBytes` hints let the session list's cold blank probe bound its work from metadata alone (session-controller config `coldBlankProbeMaxEvents`/`coldBlankProbeMaxBytes`) without opening any log.
302
+ The optional `eventCount`/`sizeBytes` fields remain cheap backend observations for consumers that explicitly need them. Session listing does not use either field to open cold logs: it reads headers plus identity-checked projection-cache hints only, so a cache or Session-format upgrade never turns startup into a body scan.
303
303
 
304
304
  ## The backend
305
305
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  ## `SessionHandle`——通向已存储会话的一条打开通道
10
10
 
11
- 每一次日志读写都经由句柄流动,绝不经由按 id 寻址的服务方法:句柄是未来跨进程写租约将要把守的那扇唯一的门。一种句柄类型同时服务两种访问——在 `read` 句柄上执行修改是运行时的 `SessionReadOnlyError`,而非类型层面的拆分——而进程内单写者所有权使得在已有活跃持有者时第二次 `open(id, 'write')` 以 `SessionAlreadyOwnedError` 拒绝。
11
+ 每一次日志读写都经由句柄流动,绝不经由按 id 寻址的服务方法:句柄是跨进程写租约把守的那扇唯一的门。一种句柄类型同时服务两种访问——在 `read` 句柄上执行修改是运行时的 `SessionReadOnlyError`,而非类型层面的拆分——而进程内单写者所有权使得在已有活跃持有者时第二次 `open(id, 'write')` 以 `SessionAlreadyOwnedError` 拒绝。
12
12
 
13
13
  ```ts type-equiv
14
14
  /**
@@ -133,11 +133,10 @@ interface SessionLocation {
133
133
  */
134
134
  interface SessionHeader {
135
135
  /**
136
- * On-disk format version, stamped from {@link SESSION_FORMAT_VERSION} when the
137
- * session is created. A persistence backend rejects any other version on load
138
- * (no migration — see the constant).
136
+ * Current logical format version, stamped from {@link SESSION_FORMAT_VERSION}.
137
+ * Historical physical headers are translated before entering this interface.
139
138
  */
140
- readonly version: number
139
+ readonly version: typeof SESSION_FORMAT_VERSION
141
140
  /** The session's id (mirrors the {@link Session}'s id). */
142
141
  readonly id: SessionId
143
142
  /** Non-negative safe-integer Unix epoch milliseconds when the session was created. */
@@ -174,11 +173,11 @@ interface SessionHeader {
174
173
 
175
174
  ## 格式拒绝:本构建无法可靠读取的日志
176
175
 
177
- 后端用 `SessionFormatUnsupportedError` 拒绝无法可靠解读的日志,它与 `SessionPersistenceCorruptionError` 区分,因为数据没有损坏。header `version` `SESSION_FORMAT_VERSION` 新时,消息说明方向("由更新的 harness 写入,请升级 harness 后打开");比它旧时说明本构建没有升级路径。本构建生成词汇表(`KNOWN_SESSION_EVENT_TYPES`,由 `gen-persistence-catalog` 生成)之外的事件类型同样被拒绝,除非该事件的信封带 `ignorable: true`:静默跳过一个不认识的必需事件可能改变日志其余部分的解读方式。后端为每个会话保留独立文件时,消息附上原始日志路径,被拒绝的文本仍然可读。JSONL 后端直接从原始 header 行拒绝外来版本,先于本格式版本的 header 形状校验和任何事件行解码,因此结构完全不同的未来格式仍会报告升级方向,绝不会报"损坏"。仓库外后端必须在自己的物理格式入口执行等价的方向感知拒绝。设计理由与推迟建设的升级器链见 [session-log 版本机制 Agent Note](../../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.zh.md)
176
+ 后端用 `SessionFormatUnsupportedError` 拒绝无法可靠解读的日志,它与 `SessionPersistenceCorruptionError` 区分,因为数据没有损坏。`stat` `list` 会对最高规范 generation 分类,并在不读取或改变正文的前提下转换受支持的历史 header。`open` 会在按 id 串行化的区段内运行构建时静态确定的相邻迁移链,再返回句柄;每个源路径、字节与 inode 都保持不变,并且只排他发布最终的当前 generation。即使仍有较旧的可读 generation,最高的未来 generation 仍会导致拒绝。当前 v2 恢复会保留已安装扩展和带 `ignorable: true` 的未知事件;历史 v0/v1 迁移则会拒绝未知类型,即使它带有 ignorable 标记。后端为每个会话保留独立文件时,消息附上选定的原始日志路径。JSONL 后端把已发布 v0 v1 迁移到当前 v2,并在解读其版本专属字段或事件行前拒绝未来版本。仓库外后端必须在自己的物理格式入口提供等价的仅当前句柄值与方向感知拒绝。[已发布格式迁移决策](../../.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.zh.md)负责迁移链与不可变发布规则。
178
177
 
179
178
  ## `CreateSessionOptions`:seed 与元数据
180
179
 
181
- 通过 store 创建 `Session` 时会接收 `seed`(初始回放或 fork 历史)、可选的精确 `inheritedEventCount` 与 `meta`(store 整合进 `SessionHeader` 的存储层字段)。store 填充 `version`/`id` 并为 `createdAt` 提供默认值;调用方可以提供已校验的绝对 `cwd`、`parentSession` 谱系、`isSeeded` 谱系标记、可选的粗粒度 `origin`、`delegationDepth`、用于组装该 agent(智能体)的 `agentPreset` 以及已有的 `createdAt`。seeded 创建必须同时显式提供 seed 与精确 cut,因为继承前缀之后还可能存在 child-owned setup event。`origin: 'subagent'` 让产品导航能够隐藏重复的 child 行;它不证明描述符有效,也不证明 child 可以恢复。
180
+ 通过 store 创建 `Session` 时会接收 `seed`(初始回放或 fork 历史)、可选的精确 `inheritedEventCount` 与 `meta`(store 整合进 `SessionHeader` 的存储层字段)。store 填充 `version`/`id` 并为 `createdAt` 提供默认值;调用方可以提供已校验的绝对 `cwd`、`parentSession` 谱系、`isSeeded` 谱系标记、可选的粗粒度 `origin`、`delegationDepth`、用于组装该 agent(智能体)的 `agentPreset` 以及已有的 `createdAt`。seeded 创建必须显式提供与 inherited prefix 完全相等的 seed 和精确 cut;constructor 会先在该 cut 追加 child-owned tagged end-seed marker,setup 再添加 child-owned event。`origin: 'subagent'` 让产品导航能够隐藏重复的 child 行;它不证明描述符有效,也不证明 child 可以恢复。
182
181
 
183
182
  ```ts type-equiv
184
183
  /**
@@ -190,8 +189,9 @@ interface CreateSessionOptions {
190
189
  /** Initial replay or fork history supplied at construction. */
191
190
  readonly seed?: readonly SessionEvent[]
192
191
  /**
193
- * Exact fork-inherited prefix length when `meta.isSeeded` is true. A
194
- * constructor seed may also contain child-owned setup events after this cut.
192
+ * Exact fork-inherited prefix length when `meta.isSeeded` is true. In v2 the
193
+ * constructor seed is exactly this inherited prefix; the constructor
194
+ * appends the child-owned tagged marker at the cut.
195
195
  */
196
196
  readonly inheritedEventCount?: SessionLogOffset
197
197
  /**
@@ -299,7 +299,7 @@ interface SessionPersistenceSnapshot {
299
299
  }
300
300
  ```
301
301
 
302
- 可选的 `eventCount`/`sizeBytes` 提示让会话列表的冷空白探测(cold blank probe)仅凭元数据即可限定其工作量(session-controller 配置 `coldBlankProbeMaxEvents`/`coldBlankProbeMaxBytes`),而无需打开任何日志。
302
+ 可选的 `eventCount`/`sizeBytes` 字段仍是供明确需要它们的 consumer 使用的低成本 backend observation。Session 列表不借助这两个字段打开冷日志,只读取 header 与经过 identity 校验的 projection cache hint,因此 cache 或 Session format 升级不会把启动变成 body scan。
303
303
 
304
304
  ## 后端
305
305
 
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write docs/subsystems/session-projection.md
5
- session-projection.md: e02ae8e36e79c4630a3799bf125ba8567db732cd
6
- session-projection.zh.md: f95545ab3d5492c80400eea413ad0cfa4ff7fb90
5
+ session-projection.md: 8568b6df94b1427a341568777c64c82d74176a17
6
+ session-projection.zh.md: 5e50341a6443efde2a3b49b7f5185bc44896efc6
@@ -137,6 +137,25 @@ The persisted projection cache service. Opens the `session_projcache` domain at
137
137
  */
138
138
  cachedSnapshot( meta: SessionHeader, inheritedEventCount: SessionLogOffset, keys?: readonly Extract<keyof SessionProjectionMap, string>[], ): ProjectionSnapshot | undefined
139
139
 
140
+ /**
141
+ * Read only a predecessor checkpoint's title as a zero-I/O listing hint.
142
+ *
143
+ * The authoritative Session header supplies the lifecycle identity. A cache
144
+ * checkpoint can lag that log but cannot lead it because writes flush the
145
+ * log first, so a matching predecessor title is a genuine (possibly stale)
146
+ * fact from this Session. The registry still requires the current title
147
+ * projection's row version and schema. No other predecessor projection is
148
+ * exposed: format normalization can change their current meaning, and the
149
+ * strict {@link cachedSnapshot} / hydration paths continue to reject them.
150
+ * @param meta - authoritative listed Session header.
151
+ * @param inheritedEventCount - exact inherited cut completing the lifecycle identity.
152
+ * @returns a title-only checkpoint view with `asOfSeq: -1`, or `undefined`
153
+ * when the record is current, newer, unrelated, missing, or incompatible
154
+ * with the title unit. The sentinel avoids reusing a sequence that a
155
+ * cardinality-changing Session migration may have remapped.
156
+ */
157
+ cachedPredecessorTitle( meta: SessionHeader, inheritedEventCount: SessionLogOffset, ): ProjectionSnapshot | undefined
158
+
140
159
  /**
141
160
  * Hydrate projection cells for an already-prepared Session without another
142
161
  * persistence read. The cache seeds matching rows; the supplied exact log
@@ -137,6 +137,25 @@ The persisted projection cache service. Opens the `session_projcache` domain at
137
137
  */
138
138
  cachedSnapshot( meta: SessionHeader, inheritedEventCount: SessionLogOffset, keys?: readonly Extract<keyof SessionProjectionMap, string>[], ): ProjectionSnapshot | undefined
139
139
 
140
+ /**
141
+ * Read only a predecessor checkpoint's title as a zero-I/O listing hint.
142
+ *
143
+ * The authoritative Session header supplies the lifecycle identity. A cache
144
+ * checkpoint can lag that log but cannot lead it because writes flush the
145
+ * log first, so a matching predecessor title is a genuine (possibly stale)
146
+ * fact from this Session. The registry still requires the current title
147
+ * projection's row version and schema. No other predecessor projection is
148
+ * exposed: format normalization can change their current meaning, and the
149
+ * strict {@link cachedSnapshot} / hydration paths continue to reject them.
150
+ * @param meta - authoritative listed Session header.
151
+ * @param inheritedEventCount - exact inherited cut completing the lifecycle identity.
152
+ * @returns a title-only checkpoint view with `asOfSeq: -1`, or `undefined`
153
+ * when the record is current, newer, unrelated, missing, or incompatible
154
+ * with the title unit. The sentinel avoids reusing a sequence that a
155
+ * cardinality-changing Session migration may have remapped.
156
+ */
157
+ cachedPredecessorTitle( meta: SessionHeader, inheritedEventCount: SessionLogOffset, ): ProjectionSnapshot | undefined
158
+
140
159
  /**
141
160
  * Hydrate projection cells for an already-prepared Session without another
142
161
  * persistence read. The cache seeds matching rows; the supplied exact log
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write docs/subsystems/session-reference.md
5
- session-reference.md: 1dd5cc1ee8c594b34015f9bf2d765f68621b86a1
6
- session-reference.zh.md: 75b5018a6afbd1bbe21f303013e0e7fa0d1f89ab
5
+ session-reference.md: 4921c29d25083a75c7a4fed8dd14202a4da9b2d2
6
+ session-reference.zh.md: 7cd03ea31258eadd207a5dcbbcbf208f291021f8
@@ -68,7 +68,31 @@ interface SessionReferenceMentionCandidate extends SessionReferenceCandidate {
68
68
 
69
69
  ## Prepared messages
70
70
 
71
- Preparation preserves readable current-message content and returns at most one aggregated context.
71
+ Preparation preserves readable current-message content and returns at most one aggregated context. Its durable source records keep `capturedThroughSeq` as a coordinate in the referenced Session's original generation; they never reinterpret it as a seq in the containing Session. `capturedFormatVersion` records that generation, with absence meaning released format v0.
72
+
73
+ ```ts type-equiv
74
+ /** Durable source session, cited event seqs, and snapshot facts for prepared cross-session context. */
75
+ interface SessionReferenceSource {
76
+ kind: 'session-reference'
77
+ /** Material lifted out of another session's log (`recall` context form). */
78
+ form: 'recall'
79
+ version: 1
80
+ references: {
81
+ sessionId: string
82
+ label: string
83
+ /** Source Session format generation; absence identifies version 0. */
84
+ capturedFormatVersion?: number
85
+ capturedThroughSeq: OptionalSessionSeq
86
+ compacted: boolean
87
+ originalMessages: number
88
+ retainedMessages: number
89
+ omittedMessages: number
90
+ omittedBytes: number
91
+ truncated: boolean
92
+ inputIndex: number
93
+ }[]
94
+ }
95
+ ```
72
96
 
73
97
  ```ts type-equiv
74
98
  /** Direct message content and optional referenced-session context. */
@@ -68,7 +68,31 @@ interface SessionReferenceMentionCandidate extends SessionReferenceCandidate {
68
68
 
69
69
  ## 准备后的消息
70
70
 
71
- 准备过程保留可读的当前消息内容,并最多返回一个聚合上下文。
71
+ 准备过程保留可读的当前消息内容,并最多返回一个聚合上下文。其持久 source 记录会把 `capturedThroughSeq` 保留为被引用 Session 原始 generation 中的坐标,绝不会把它重新解释为所在 Session 的 seq。`capturedFormatVersion` 记录该 generation;缺失表示已发布格式 v0。
72
+
73
+ ```ts type-equiv
74
+ /** Durable source session, cited event seqs, and snapshot facts for prepared cross-session context. */
75
+ interface SessionReferenceSource {
76
+ kind: 'session-reference'
77
+ /** Material lifted out of another session's log (`recall` context form). */
78
+ form: 'recall'
79
+ version: 1
80
+ references: {
81
+ sessionId: string
82
+ label: string
83
+ /** Source Session format generation; absence identifies version 0. */
84
+ capturedFormatVersion?: number
85
+ capturedThroughSeq: OptionalSessionSeq
86
+ compacted: boolean
87
+ originalMessages: number
88
+ retainedMessages: number
89
+ omittedMessages: number
90
+ omittedBytes: number
91
+ truncated: boolean
92
+ inputIndex: number
93
+ }[]
94
+ }
95
+ ```
72
96
 
73
97
  ```ts type-equiv
74
98
  /** Direct message content and optional referenced-session context. */
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write docs/subsystems/session-telemetry.md
5
- session-telemetry.md: 718fe5dabfd1c059a6a02077407480e96bdd271a
6
- session-telemetry.zh.md: d4081664a121877e36a2cba123e9c5840108b529
5
+ session-telemetry.md: 83224cf03005909f9b3d600a950c2d6402ca3b2a
6
+ session-telemetry.zh.md: a093590819d62839fb69a0e50b2d11f495171ec8
@@ -2,7 +2,7 @@
2
2
 
3
3
  English | [中文](session-telemetry.zh.md)
4
4
 
5
- Outbound session reporting is split as a [capability seam](../capability-seams.md): the Service Definition and capture coordinator ([dsh-session-telemetry](../../packages/session/session-telemetry), `ctx.sessionTelemetry`) own the capture points, fixed chunk projection, `session-telemetry/record` redaction waterfall, handoff cursor, and minimal backend contract; the Service Provider a deployment loads ([dsh-session-telemetry-otel](../../packages/session/session-telemetry-otel)) is the OpenTelemetry JS SDK's log pipeline configured verbatim. It is one optional capability, not part of the agent-loop spine, and nothing here reaches a model request. The boundary axiom — the harness's aspect ends at `emit()`; batching, retry, queueing, and loss policy belong to the reporting SDK — and the rejected alternatives are pinned in the [revival Agent Note](../../.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.md); the capture points, cursor, and projection contracts live in the [Service Definition README](../../packages/session/session-telemetry/README.md).
5
+ Outbound session reporting is split as a [capability seam](../capability-seams.md): the Service Definition and capture coordinator ([dsh-session-telemetry](../../packages/session/session-telemetry), `ctx.sessionTelemetry`) own complete canonical-event capture, the `session-telemetry/record` redaction waterfall, the handoff cursor, and the minimal backend contract; the Service Provider a deployment loads ([dsh-session-telemetry-otel](../../packages/session/session-telemetry-otel)) is the OpenTelemetry JS SDK's log pipeline configured verbatim. It is one optional capability, not part of the agent-loop spine, and nothing here reaches a model request. The boundary axiom — the harness's aspect ends at `emit()`; batching, retry, queueing, and loss policy belong to the reporting SDK — and the rejected alternatives are pinned in the [revival Agent Note](../../.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.md); the capture and cursor contracts live in the [Service Definition README](../../packages/session/session-telemetry/README.md).
6
6
 
7
7
  Source: [`packages/session/session-telemetry/src/index.ts`](../../packages/session/session-telemetry/src/index.ts)
8
8
 
@@ -37,8 +37,9 @@ interface SessionTelemetryRecord {
37
37
  severity: SessionTelemetrySeverity
38
38
  /**
39
39
  * Identity attributes, deliberately minimal: ledger records carry
40
- * `session.id`, `event.type`, `event.seq`, plus `session.cwd` /
41
- * `session.parent_id` / `session.seed_length` when the header has them;
40
+ * `session.id`, `session.format_version`, `event.type`, `event.seq`, plus optional
41
+ * `session.cwd` / `session.parent_id`; a seeded Session also carries
42
+ * `session.seed_length` from its exact inherited event count;
42
43
  * ops records carry `telemetry.op`, `session.id`, and (for `agent-error`)
43
44
  * `agent.id`, `turn`, `step`, `error.name`. Anything recoverable from the
44
45
  * body is intentionally NOT duplicated here.
@@ -54,7 +55,7 @@ interface SessionTelemetryRecord {
54
55
  }
55
56
  ```
56
57
 
57
- Only the first `assistant/chunk` of each `(turn, step)` ships the stream-started signal; the rest drop at capture, so `seq` gaps are routine on the wire and never a loss signal. Every other [session event](session.md) type, including plugin-merged ones the seam never heard of, passes through whole. Delivery is best-effort: the cursor marks handed-off, not delivered, records can be lost (crash, reload window) and duplicated (cursor-less re-adoption, SDK retries), so receivers dedupe ledger records on `(session.id, event.seq)`; ops records deliberately omit that identity — they are signals to alert on, not entries to sum, and tolerate duplicates instead.
58
+ Every canonical [session event](session.md), including each `assistant/message` or `assistant/attempt` with its complete compact stream and every plugin-merged type the seam never heard of, passes through whole as one ordered ledger record. Process-local `agent/assistant-stream` frames do not enter this durable feed. A new Session object replays its complete log from seq 0, including constructor seed history; re-adopting the same object resumes after its handoff cursor. Delivery is best-effort: the cursor marks handed-off, not delivered, and records can be lost (crash, reload window) or duplicated (new-object replay, SDK retries), so receivers dedupe ledger records on `(session.id, session.format_version, event.seq)`; ops records deliberately omit that identity — they are signals to alert on, not entries to sum, and tolerate duplicates instead.
58
59
 
59
60
  ## The sharing disclosure
60
61
 
@@ -122,7 +123,7 @@ interface SessionTelemetrySink {
122
123
 
123
124
  ## The redact waterfall: `session-telemetry/record`
124
125
 
125
- Every record passes the `session-telemetry/record` [waterfall](../cordis-primer.md#cordis-waterfall-semantics) between projection and `emit()` ([event entry](#session-telemetryrecord--waterfall)). The seam ships NO rules of its own: with no listener mounted, records reach the backend exactly as captured, so exported data is precisely as clean as the rules a deployment mounts. Listeners stack by transforming `next()`'s return value; returning without `next()` replaces everything beneath; a throwing listener withholds that one record fail-closed inside the coordinator's containment. Redaction applies to the exported copy only — the canonical session log is never rewritten.
126
+ Every record passes the `session-telemetry/record` [waterfall](../cordis-primer.md#cordis-waterfall-semantics) between the canonical-event copy and `emit()` ([event entry](#session-telemetryrecord--waterfall)). The seam ships NO rules of its own: with no listener mounted, records reach the backend exactly as captured, so exported data is precisely as clean as the rules a deployment mounts. Listeners stack by transforming `next()`'s return value; returning without `next()` replaces everything beneath; a throwing listener withholds that one record fail-closed inside the coordinator's containment. Redaction applies to the exported copy only — the canonical session log is never rewritten.
126
127
 
127
128
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
128
129
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  [English](session-telemetry.md) | 中文
4
4
 
5
- 对外的会话上报拆分为一项[能力 seam](../capability-seams.zh.md):Service Definition 与捕获协调器([dsh-session-telemetry](../../packages/session/session-telemetry),`ctx.sessionTelemetry`)拥有捕获点、固定分片投影、`session-telemetry/record` 脱敏 waterfall(瀑布式事件)、handoff 游标与最小后端约定;部署方加载的 Service Provider([dsh-session-telemetry-otel](../../packages/session/session-telemetry-otel))则是原样配置的 OpenTelemetry JS SDK 日志流水线。它是一项可选能力,不属于 agent loop(智能体循环)主干,这里也没有任何内容会进入模型请求。边界公理(harness 的职责止于 `emit()`;批处理、重试、排队与丢失策略都属于上报 SDK)连同被否决的替代方案,均已在[复活 Agent Note](../../.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.zh.md)中定案;捕获点、游标与投影的约定见 [Service Definition README](../../packages/session/session-telemetry/README.zh.md)。
5
+ 对外的会话上报拆分为一项[能力 seam](../capability-seams.zh.md):Service Definition 与捕获协调器([dsh-session-telemetry](../../packages/session/session-telemetry),`ctx.sessionTelemetry`)拥有完整的权威事件捕获、`session-telemetry/record` 脱敏 waterfall(瀑布式事件)、handoff 游标与最小后端约定;部署方加载的 Service Provider([dsh-session-telemetry-otel](../../packages/session/session-telemetry-otel))则是原样配置的 OpenTelemetry JS SDK 日志流水线。它是一项可选能力,不属于 agent loop(智能体循环)主干,这里也没有任何内容会进入模型请求。边界公理(harness 的职责止于 `emit()`;批处理、重试、排队与丢失策略都属于上报 SDK)连同被否决的替代方案,均已在[复活 Agent Note](../../.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.zh.md)中定案;捕获与游标约定见 [Service Definition README](../../packages/session/session-telemetry/README.zh.md)。
6
6
 
7
7
  源码:[`packages/session/session-telemetry/src/index.ts`](../../packages/session/session-telemetry/src/index.ts)
8
8
 
@@ -37,8 +37,9 @@ interface SessionTelemetryRecord {
37
37
  severity: SessionTelemetrySeverity
38
38
  /**
39
39
  * Identity attributes, deliberately minimal: ledger records carry
40
- * `session.id`, `event.type`, `event.seq`, plus `session.cwd` /
41
- * `session.parent_id` / `session.seed_length` when the header has them;
40
+ * `session.id`, `session.format_version`, `event.type`, `event.seq`, plus optional
41
+ * `session.cwd` / `session.parent_id`; a seeded Session also carries
42
+ * `session.seed_length` from its exact inherited event count;
42
43
  * ops records carry `telemetry.op`, `session.id`, and (for `agent-error`)
43
44
  * `agent.id`, `turn`, `step`, `error.name`. Anything recoverable from the
44
45
  * body is intentionally NOT duplicated here.
@@ -54,7 +55,7 @@ interface SessionTelemetryRecord {
54
55
  }
55
56
  ```
56
57
 
57
- 每个 `(turn, step)` 只发出第一条 `assistant/chunk`,即「流已开始」的信号;其余分片在捕获时丢弃,因此传输中的 `seq` 缺口是常态,绝不是数据丢失的信号。其他所有[会话事件](session.zh.md)类型都会完整透传,包括该 seam 从未听说过、由插件合并进来的事件类型。投递是尽力而为的:游标标记的是「已交接」而非「已送达」,记录可能丢失(崩溃、重载窗口)也可能重复(无游标的重新接管、SDK 重试),因此接收端对 ledger 记录基于 `(session.id, event.seq)` 去重;ops 记录刻意省略这类标识——它们是用于告警的信号,而非用于累加的条目,重复被容忍而非被去重。
58
+ 每条权威[会话事件](session.zh.md)都会完整透传为一条有序 ledger 记录,包括每个携带完整紧凑 stream 的 `assistant/message` `assistant/attempt`,以及该 seam 从未听说过、由插件合并进来的类型。进程本地 `agent/assistant-stream` frame 不进入该持久 feed。新 Session 对象会从 seq 0 回放完整日志,包括构造 seed 历史;重新收养同一对象时会从 handoff 游标之后继续。投递是尽力而为的:游标标记的是「已交接」而非「已送达」,记录可能丢失(崩溃、重载窗口)也可能重复(新对象回放、SDK 重试),因此接收端对 ledger 记录基于 `(session.id, session.format_version, event.seq)` 去重;ops 记录刻意省略这类标识——它们是用于告警的信号,而非用于累加的条目,重复被容忍而非被去重。
58
59
 
59
60
  ## 共享披露
60
61
 
@@ -122,7 +123,7 @@ interface SessionTelemetrySink {
122
123
 
123
124
  ## 脱敏 waterfall:`session-telemetry/record`
124
125
 
125
- 每条记录在投影与 `emit()` 之间都要经过 `session-telemetry/record` [waterfall](../cordis-primer.zh.md#cordis-waterfall-semantics)([事件条目](#session-telemetryrecord--waterfall))。seam 自身不带任何规则:未挂载监听器时,记录以捕获时的原样到达后端;导出数据能干净到什么程度,恰恰取决于部署方挂载了什么规则。监听器通过变换 `next()` 的返回值来堆叠;不调用 `next()` 就返回,即替换其下方的全部逻辑;抛出异常的监听器会在协调器的隔离范围内以 fail-closed 方式扣下这一条记录。脱敏只作用于导出副本;权威会话日志永不改写。
126
+ 每条记录在权威事件副本与 `emit()` 之间都要经过 `session-telemetry/record` [waterfall](../cordis-primer.zh.md#cordis-waterfall-semantics)([事件条目](#session-telemetryrecord--waterfall))。seam 自身不带任何规则:未挂载监听器时,记录以捕获时的原样到达后端;导出数据能干净到什么程度,恰恰取决于部署方挂载了什么规则。监听器通过变换 `next()` 的返回值来堆叠;不调用 `next()` 就返回,即替换其下方的全部逻辑;抛出异常的监听器会在协调器的隔离范围内以 fail-closed 方式扣下这一条记录。脱敏只作用于导出副本;权威会话日志永不改写。
126
127
 
127
128
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
128
129
 
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write docs/subsystems/session.md
5
- session.md: 48a80ccb92af774db2f5bedea8e2e00043932d31
6
- session.zh.md: df5cfd631a15bfe015c766842956cc0c344c2ccd
5
+ session.md: d10c2d9a797eccb4a4cdc7e9ad8d607732dbc877
6
+ session.zh.md: 890d930a6ef979ec1b57eeb2d43ac3eb700a28c4