dsh-plugin-dev-kb 1.0.2 → 1.0.4

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 (144) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/kb/README.md +1 -1
  3. package/kb/extra/cookbook/adding-a-vendored-package.zh.md +3 -3
  4. package/kb/extra/cookbook/maintaining-dsh-code-review.zh.md +1 -1
  5. package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.zh.md +1 -1
  6. package/kb/extra/defensive-patterns.zh.md +3 -1
  7. package/kb/extra/development.zh.md +15 -9
  8. package/kb/extra/event-producer-consumer.md +5 -2
  9. package/kb/extra/event-producer-consumer.zh.md +5 -2
  10. package/kb/extra/graph-atlas.zh.md +7 -7
  11. package/kb/extra/i18n/README.md +3 -3
  12. package/kb/extra/i18n/README.zh.md +9 -7
  13. package/kb/extra/i18n/style-samples.md +1 -1
  14. package/kb/extra/i18n/translation-prompt.md +3 -3
  15. package/kb/extra/i18n/translation-rules.md +2 -2
  16. package/kb/extra/i18n/translation-rules.zh.md +3 -3
  17. package/kb/extra/module-graph.md +18 -9
  18. package/kb/extra/module-graph.zh.md +18 -9
  19. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +1 -1
  20. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +1 -1
  21. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +1 -1
  22. package/kb/extra/postmortem/README.zh.md +5 -5
  23. package/kb/extra/rescope.zh.md +1 -1
  24. package/kb/extra/subsystems/agent-team.md +2 -2
  25. package/kb/extra/subsystems/agent-team.zh.md +6 -6
  26. package/kb/extra/subsystems/attachment.md +63 -12
  27. package/kb/extra/subsystems/attachment.zh.md +63 -12
  28. package/kb/extra/subsystems/extensions.md +9 -9
  29. package/kb/extra/subsystems/extensions.zh.md +12 -12
  30. package/kb/extra/subsystems/feedback.md +2 -2
  31. package/kb/extra/subsystems/feedback.zh.md +2 -2
  32. package/kb/extra/testing.md +1 -1
  33. package/kb/extra/testing.zh.md +7 -7
  34. package/kb/extra/web-styling.zh.md +2 -2
  35. package/kb/meta/search-index.json +132 -132
  36. package/kb/meta/source.json +2 -2
  37. package/kb/meta/topics.md +2 -2
  38. package/kb/site/develop/basic/index.md +1 -1
  39. package/kb/site/develop/basic/publish.md +3 -3
  40. package/kb/site/develop/cordis-tutorial/index.md +1 -1
  41. package/kb/site/en/reference/capability-seams.md +5 -0
  42. package/kb/site/en/reference/config-catalog.md +52 -17
  43. package/kb/site/en/reference/persistence-catalog.md +1 -1
  44. package/kb/site/en/reference/subsystems/approval.md +3 -3
  45. package/kb/site/en/reference/subsystems/client-modules.md +7 -7
  46. package/kb/site/en/reference/subsystems/code-runtime.md +2 -2
  47. package/kb/site/en/reference/subsystems/commands.md +3 -3
  48. package/kb/site/en/reference/subsystems/compaction.md +3 -3
  49. package/kb/site/en/reference/subsystems/core.md +19 -19
  50. package/kb/site/en/reference/subsystems/credentials.md +163 -8
  51. package/kb/site/en/reference/subsystems/filesystem.md +5 -5
  52. package/kb/site/en/reference/subsystems/goal.md +3 -3
  53. package/kb/site/en/reference/subsystems/invariants.md +2 -2
  54. package/kb/site/en/reference/subsystems/jobs.md +2 -2
  55. package/kb/site/en/reference/subsystems/llm-streaming.md +16 -4
  56. package/kb/site/en/reference/subsystems/lsp.md +2 -2
  57. package/kb/site/en/reference/subsystems/permission-presets.md +2 -2
  58. package/kb/site/en/reference/subsystems/persistence.md +2 -2
  59. package/kb/site/en/reference/subsystems/plan.md +2 -2
  60. package/kb/site/en/reference/subsystems/sandbox.md +3 -3
  61. package/kb/site/en/reference/subsystems/session-projection.md +60 -35
  62. package/kb/site/en/reference/subsystems/session-query.md +2 -2
  63. package/kb/site/en/reference/subsystems/session-reference.md +3 -3
  64. package/kb/site/en/reference/subsystems/session-telemetry.md +3 -3
  65. package/kb/site/en/reference/subsystems/session-title.md +2 -2
  66. package/kb/site/en/reference/subsystems/session.md +6 -6
  67. package/kb/site/en/reference/subsystems/settings.md +4 -4
  68. package/kb/site/en/reference/subsystems/shell.md +3 -3
  69. package/kb/site/en/reference/subsystems/skills.md +3 -3
  70. package/kb/site/en/reference/subsystems/spill.md +2 -2
  71. package/kb/site/en/reference/subsystems/storage.md +4 -4
  72. package/kb/site/en/reference/subsystems/subagent.md +6 -6
  73. package/kb/site/en/reference/subsystems/subprocess.md +3 -3
  74. package/kb/site/en/reference/subsystems/system-prompt.md +4 -4
  75. package/kb/site/en/reference/subsystems/terminal.md +2 -2
  76. package/kb/site/en/reference/subsystems/token-meter.md +2 -2
  77. package/kb/site/en/reference/subsystems/tools.md +8 -8
  78. package/kb/site/en/reference/subsystems/typert.md +4 -4
  79. package/kb/site/en/reference/subsystems/user-questions.md +2 -2
  80. package/kb/site/en/reference/subsystems/web-server.md +46 -6
  81. package/kb/site/en/reference/subsystems/web.md +2 -2
  82. package/kb/site/en/reference/subsystems/workflow.md +8 -8
  83. package/kb/site/en/reference/subsystems/workspace.md +3 -3
  84. package/kb/site/en/reference/tool-catalog.md +3 -3
  85. package/kb/site/guide/providers.md +2 -2
  86. package/kb/site/guide/python-sdk.md +2 -2
  87. package/kb/site/guide/quickstart.md +2 -2
  88. package/kb/site/reference/capability-seams.md +5 -0
  89. package/kb/site/reference/config-catalog.md +53 -18
  90. package/kb/site/reference/cookbook/adding-a-conversation-node.md +1 -1
  91. package/kb/site/reference/cookbook/adding-a-package.md +5 -3
  92. package/kb/site/reference/cookbook/adding-a-settings-card.md +1 -1
  93. package/kb/site/reference/cookbook/adding-a-tool.md +6 -6
  94. package/kb/site/reference/cookbook/adding-an-llm-adapter.md +2 -2
  95. package/kb/site/reference/cookbook/extension-cookbook.md +6 -4
  96. package/kb/site/reference/index.md +4 -4
  97. package/kb/site/reference/persistence-catalog.md +5 -5
  98. package/kb/site/reference/subsystems/approval.md +3 -3
  99. package/kb/site/reference/subsystems/client-modules.md +8 -8
  100. package/kb/site/reference/subsystems/code-runtime.md +4 -4
  101. package/kb/site/reference/subsystems/commands.md +5 -5
  102. package/kb/site/reference/subsystems/compaction.md +7 -7
  103. package/kb/site/reference/subsystems/core.md +26 -24
  104. package/kb/site/reference/subsystems/credentials.md +163 -8
  105. package/kb/site/reference/subsystems/filesystem.md +6 -6
  106. package/kb/site/reference/subsystems/goal.md +5 -5
  107. package/kb/site/reference/subsystems/index.md +5 -5
  108. package/kb/site/reference/subsystems/invariants.md +5 -5
  109. package/kb/site/reference/subsystems/jobs.md +4 -4
  110. package/kb/site/reference/subsystems/llm-streaming.md +21 -9
  111. package/kb/site/reference/subsystems/lsp.md +3 -3
  112. package/kb/site/reference/subsystems/permission-presets.md +3 -3
  113. package/kb/site/reference/subsystems/persistence.md +6 -6
  114. package/kb/site/reference/subsystems/plan.md +4 -4
  115. package/kb/site/reference/subsystems/sandbox.md +7 -5
  116. package/kb/site/reference/subsystems/schedule.md +1 -1
  117. package/kb/site/reference/subsystems/scope.md +1 -1
  118. package/kb/site/reference/subsystems/session-projection.md +61 -36
  119. package/kb/site/reference/subsystems/session-query.md +2 -2
  120. package/kb/site/reference/subsystems/session-reference.md +3 -3
  121. package/kb/site/reference/subsystems/session-telemetry.md +5 -5
  122. package/kb/site/reference/subsystems/session-title.md +2 -2
  123. package/kb/site/reference/subsystems/session.md +13 -11
  124. package/kb/site/reference/subsystems/settings.md +4 -4
  125. package/kb/site/reference/subsystems/shell.md +6 -6
  126. package/kb/site/reference/subsystems/skills.md +3 -3
  127. package/kb/site/reference/subsystems/spill.md +3 -3
  128. package/kb/site/reference/subsystems/storage.md +7 -7
  129. package/kb/site/reference/subsystems/subagent.md +11 -9
  130. package/kb/site/reference/subsystems/subprocess.md +4 -4
  131. package/kb/site/reference/subsystems/system-prompt.md +5 -5
  132. package/kb/site/reference/subsystems/terminal.md +3 -3
  133. package/kb/site/reference/subsystems/token-meter.md +2 -2
  134. package/kb/site/reference/subsystems/tools.md +9 -9
  135. package/kb/site/reference/subsystems/typert.md +5 -5
  136. package/kb/site/reference/subsystems/user-questions.md +2 -2
  137. package/kb/site/reference/subsystems/web-server.md +48 -8
  138. package/kb/site/reference/subsystems/web.md +3 -3
  139. package/kb/site/reference/subsystems/workflow.md +11 -11
  140. package/kb/site/reference/subsystems/workspace.md +5 -5
  141. package/kb/site/reference/tool-catalog.md +9 -5
  142. package/lib/index.js +9 -1
  143. package/package.json +2 -1
  144. package/skills/dsh-plugin-dev-kb.md +1 -1
@@ -5,33 +5,36 @@ outline: [2,3]
5
5
 
6
6
  # 会话投影
7
7
 
8
- 会话投影 seam 是一项[能力 seam](../capability-seams.md):领域 host 插件经由它向客户端载体供给按会话的日志派生状态的当前全量值;三方分别是 Service Definition 与注册表([dsh-session-projection](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/session/session-projection),`ctx.sessionProjections`)、领域贡献方(每个领域注册一个纯单元)与载体([dsh-host-apiproxy](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/host/apiproxy) 的历史尾页与 `session/projection` 推送帧)。它是一项可选能力,不属于 agent loop(智能体循环)主干。框架负责驱动,领域负责计算:注册表只订阅一次 `session/event`,并把每个已提交事件折叠进每个单元;领域不持有任何订阅,客户端也从不折叠领域事件——它们收到的是成品值。设计权威:[session-projection RFC](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md);驱动、缓存与变更流约定:[包 README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-projection/README.md)。
8
+ 会话投影 seam 是一项[能力 seam](../capability-seams.md):领域 host 插件经由它向客户端载体供给按会话的日志派生状态的当前全量值;三方分别是 Service Definition 与注册表([dsh-session-projection](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/session/session-projection),`ctx.sessionProjections`)、领域贡献方(每个领域注册一个纯单元)与载体([dsh-host-apiproxy](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/host/apiproxy) 的历史尾页与 `session/projection` 推送帧)。它是一项可选能力,不属于 agent loop(智能体循环)主干。框架负责驱动,领域负责计算:注册表只订阅一次 `session/event`,并把每个已提交事件折叠进每个单元;领域不持有任何订阅,客户端也从不折叠领域事件——它们收到的是成品值。设计权威:[session-projection RFC](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.zh.md);驱动、缓存与变更流约定:[包 README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-projection/README.zh.md)。
9
9
 
10
10
  源码:[`packages/session/session-projection/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-projection/src/index.ts)
11
11
 
12
12
  ## 投影单元
13
13
 
14
- `SessionProjectionMap` 是整条链路(host 侧单元、协议块、客户端钩子)的 merge-extensible 类型表;值是协议层 JSON 全量值,渲染归 slot 体系管,永远不归本层。领域为每个 key 贡献一个 `ProjectionDefinition`:
14
+ `SessionProjectionStateMap` host 侧折叠状态的 merge-extensible 类型表,`SessionProjectionMap` 则继续表示客户端可见的全量值。领域为每个状态 key 贡献一个 `ProjectionDefinition`;`wire` 块使该 key 对客户端可见,渲染归 slot 体系管,永远不归本层:
15
15
 
16
16
  ```ts type-equiv
17
17
  /**
18
- * One domain's state-driven computation unit: three pure synchronous
19
- * functions plus declarations — never an opaque getter. The framework drives
18
+ * One domain's state-driven computation unit: a pure synchronous fold plus
19
+ * declarations and an optional client view — never an opaque getter. The framework drives
20
20
  * `apply` on every committed session event; the domain holds no
21
- * subscriptions and owns only the mathematics. All three functions MUST be
22
- * synchronous (an async unit would tear the carriers' consistency cut) and
21
+ * subscriptions and owns only the computation. All functions MUST be
22
+ * synchronous (an async unit would tear the carriers' consistency cut), and
23
23
  * `state` MUST be plain JSON (the persisted-cache precondition).
24
24
  */
25
- interface ProjectionDefinition<K extends keyof SessionProjectionMap, S> {
26
- /** The projection key this unit owns (its `SessionProjectionMap` entry). */
25
+ interface ProjectionDefinition<
26
+ K extends keyof SessionProjectionStateMap,
27
+ S extends SessionProjectionStateMap[K] = SessionProjectionStateMap[K],
28
+ > {
29
+ /** The projection key this unit owns (its `SessionProjectionStateMap` entry). */
27
30
  key: K
28
- /** Validates the wire payload (`view` output) before it leaves the host. */
29
- schema: ZodType<SessionProjectionMap[K]>
31
+ /** Validates persisted state before it seeds a fold. */
32
+ stateSchema: ZodType<S>
30
33
  /**
31
34
  * State for the empty log.
32
35
  * @returns the initial state.
33
36
  */
34
- init(): S
37
+ init(): NoInfer<S>
35
38
  /**
36
39
  * Pure transition: previous state + one committed event → next state. A
37
40
  * unit uninterested in an event MUST return the same state reference — an
@@ -40,13 +43,18 @@ interface ProjectionDefinition<K extends keyof SessionProjectionMap, S> {
40
43
  * @param event - the next committed session event.
41
44
  * @returns the next state (same reference when the event is not the unit's).
42
45
  */
43
- apply(state: S, event: SessionEvent): S
44
- /**
45
- * State wire payload (the read-side projection).
46
- * @param state - the current state.
47
- * @returns the whole current value for this unit's key.
48
- */
49
- view(state: S): SessionProjectionMap[K]
46
+ apply(state: NoInfer<S>, event: SessionEvent): NoInfer<S>
47
+ /** Client view. Omit for host-only units. */
48
+ wire?: K extends keyof SessionProjectionMap ? {
49
+ /** Validates the wire payload before it leaves the host. */
50
+ viewSchema: ZodType<SessionProjectionMap[K]>
51
+ /**
52
+ * State → wire payload (the read-side projection).
53
+ * @param state - the current state.
54
+ * @returns the whole current value for this unit's key.
55
+ */
56
+ view(state: NoInfer<S>): SessionProjectionMap[K]
57
+ } : never
50
58
  /**
51
59
  * Persisted-cache invalidation version: bump whenever the serialized state fields or the
52
60
  * fold semantics change, so persisted `(sessionId, key, ver, seq, val)`
@@ -63,14 +71,14 @@ interface ProjectionDefinition<K extends keyof SessionProjectionMap, S> {
63
71
 
64
72
  ```ts type-equiv
65
73
  /**
66
- * One consistent read cut over every registered unit for one session.
74
+ * One consistent read cut over every registered client-visible unit for one session.
67
75
  * `asOfSeq` is the shared watermark — the seq of the last event every value
68
76
  * reflects (`-1` for an empty log, mirroring `session/subscribed.lastSeq`).
69
77
  */
70
78
  interface ProjectionSnapshot {
71
79
  /** Seq of the last event the values reflect; -1 for an empty log. */
72
80
  asOfSeq: number
73
- /** Whole current value per registered key. */
81
+ /** Whole current client value per registered key. */
74
82
  values: Partial<SessionProjectionMap>
75
83
  }
76
84
  ```
@@ -89,7 +97,7 @@ type ProjectionChangeListener = (
89
97
  ) => void
90
98
  ```
91
99
 
92
- `snapshot(session)` 完全同步:载体在切出页面切片的同一 tick 内读取它,因此 `asOfSeq` 使两次读取使用同一个序号。每个值在返回前都会通过其单元的 schema 校验;如果 `view` 被误写为异步函数,它会返回 Promise,schema 校验将拒绝该值。对于每个已提交事件,变更流会为每个状态*引用*已变化的单元触发一次;状态未变时,`apply` 必须返回同一引用。
100
+ `snapshot(session)` 完全同步:载体在切出页面切片的同一 tick 内读取它,因此 `asOfSeq` 使两次读取使用同一个序号。它只返回客户端视图,并在返回前通过各单元的 `viewSchema` 校验。`stateOf(session, key)` 可在不计算无关视图的情况下读取一份实时 host 状态;调用方不得修改这一借用引用。对于每个已提交事件,变更流会为每个状态*引用*已变化的客户端可见单元触发一次;状态未变时,`apply` 必须返回同一引用。
93
101
 
94
102
  ## 注册表:`ctx.sessionProjections`
95
103
 
@@ -101,7 +109,7 @@ type ProjectionChangeListener = (
101
109
 
102
110
  ## Cordis API
103
111
 
104
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
112
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
105
113
 
106
114
  <a id="ctxsessionprojectioncache--sessionprojectioncache"></a>
107
115
 
@@ -151,13 +159,13 @@ async coldSnapshot(id: SessionId, signal?: AbortSignal): Promise<ProjectionSnaps
151
159
 
152
160
  Types: [Session](./session.md) · [SessionHeader](./persistence.md) · [SessionId](./core.md)
153
161
 
154
- Source: [`packages/session/session-projection-cache/src/index.ts:71`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-projection-cache/src/index.ts)
162
+ Source: [`packages/session/session-projection-cache/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-projection-cache/src/index.ts)
155
163
 
156
164
  <a id="ctxsessionprojections--sessionprojectionregistry"></a>
157
165
 
158
166
  ### `ctx.sessionProjections` — `SessionProjectionRegistry`
159
167
 
160
- `ctx.sessionProjections`: the projection unit table and its drive. The service subscribes to `session/event` once; every committed event passes every registered unit's `apply` (eager drive), and a changed state reference notifies the change feed with the schema-validated view. Cells build lazily — a unit registered after events flowed, or a session older than the registry, folds `init` over the in-memory log on first touch (event or read). Registration is an effect (disposer rides the calling fiber): an unloaded domain plugin's key disappears from snapshots and clients read it as capability absence. Domain plugins register under `ctx.inject(['sessionProjections'], …)` so headless assemblies without the registry stay unaffected. Registrants sharing a key share one unit and are counted: the same tool package mounted in N agent presets registers N times, and the key survives until the last one unloads.
168
+ `ctx.sessionProjections`: the projection unit table and its drive. The service subscribes to `session/event` once; every committed event passes every registered unit's `apply` (eager drive), and a changed state reference in a client-visible unit notifies the change feed with the schema-validated view. Cells build lazily — a unit registered after events flowed, or a session older than the registry, folds `init` over the in-memory log on first touch (event or read). Registration is an effect (disposer rides the calling fiber): an unloaded domain plugin's key disappears from snapshots and clients read it as capability absence. Domain plugins register under `ctx.inject(['sessionProjections'], …)` so headless assemblies without the registry stay unaffected. Registrants sharing a key share one unit and are counted: the same tool package mounted in N agent presets registers N times, and the key survives until the last one unloads.
161
169
 
162
170
  ```ts cordis-catalog
163
171
  /**
@@ -168,28 +176,45 @@ Source: [`packages/session/session-projection-cache/src/index.ts:71`](https://gi
168
176
  * @param definition - key, state schema, pure unit functions, and stateVersion.
169
177
  * @returns the exact disposer that unregisters this unit.
170
178
  */
171
- register<K extends keyof SessionProjectionMap, S>(definition: ProjectionDefinition<K, S>): () => void
179
+ register< K extends keyof SessionProjectionMap, S extends SessionProjectionStateMap[K], >( definition: Omit<ProjectionDefinition<K, S>, 'wire'> & { wire: NonNullable<ProjectionDefinition<K, S>['wire']> }, ): () => void
180
+
181
+ /**
182
+ * Register one host-only unit. Its state is omitted from client snapshots
183
+ * and always checkpointed like every other unit.
184
+ * @param definition - key, state schema, pure unit functions, and stateVersion.
185
+ * @returns the exact disposer that unregisters this unit.
186
+ */
187
+ register< K extends Exclude<keyof SessionProjectionStateMap, keyof SessionProjectionMap>, S extends SessionProjectionStateMap[K], >( definition: Omit<ProjectionDefinition<K, S>, 'wire'>, ): () => void
172
188
 
173
189
  /**
174
190
  * Subscribe to the change feed. The registration is an effect on the
175
191
  * calling context's fiber.
176
- * @param listener - called once per unit whose state reference changed, per committed event.
192
+ * @param listener - called once per client-visible unit whose state reference changed, per committed event.
177
193
  * @returns the exact disposer that unsubscribes.
178
194
  */
179
195
  onChanged(listener: ProjectionChangeListener): () => void
180
196
 
181
197
  /**
182
- * One consistent cut over every registered unit for one session, read from
198
+ * Read one unit's current host state without computing unrelated views.
199
+ * The returned value is live; callers must not mutate it.
200
+ * @param session - the session whose state is read.
201
+ * @param key - the registered unit key.
202
+ * @returns current state, or `undefined` when the key is not registered.
203
+ */
204
+ stateOf<K extends keyof SessionProjectionStateMap>( session: Session, key: K, ): SessionProjectionStateMap[K] | undefined
205
+
206
+ /**
207
+ * One consistent cut over every registered client-visible unit for one session, read from
183
208
  * the watermark cache (missing cells fold lazily over the in-memory log).
184
209
  * Fully synchronous — every value and `asOfSeq` reflect the same log
185
- * position. Each value passes its unit's schema before leaving.
210
+ * position. Each value passes its unit's `viewSchema` before leaving.
186
211
  * @param session - the session whose projection values are read.
187
- * @returns the snapshot; `values` is empty when no unit is registered.
212
+ * @returns the snapshot; `values` is empty when no client-visible unit is registered.
188
213
  */
189
214
  snapshot(session: Session): ProjectionSnapshot
190
215
 
191
216
  /**
192
- * State-level checkpoint of every registered unit for one session, read
217
+ * State-level checkpoint of every persisted unit for one session, read
193
218
  * from the watermark cache (missing cells fold lazily over the in-memory
194
219
  * log). This is the write side of the persisted projection cache: the
195
220
  * returned rows are the `(key → {ver, seq, val})` part of the durable
@@ -200,7 +225,7 @@ snapshot(session: Session): ProjectionSnapshot
200
225
  * every subsequent snapshot and frame through it (plain JSON by the unit
201
226
  * contract, so the clone is total).
202
227
  * @param session - the session whose unit states are checkpointed.
203
- * @returns one row per registered key; empty when no unit is registered.
228
+ * @returns one row per registered key.
204
229
  */
205
230
  checkpoint(session: Session): ProjectionCheckpoint
206
231
 
@@ -224,8 +249,8 @@ restoreFloor(checkpoint: ProjectionCheckpoint): number | undefined
224
249
 
225
250
  /**
226
251
  * View a checkpoint's rows without any log read: for every registered
227
- * unit whose row's `ver` matches, serve the schema-validated
228
- * `view` of the stored state; mismatched or absent rows leave their key
252
+ * client-visible unit whose row's `ver` matches, serve the schema-validated
253
+ * `view` of the schema-validated stored state; mismatched, malformed, or absent rows leave their key
229
254
  * absent (a cold or listing consumer treats it as not-yet-available and a
230
255
  * fuller read path refolds it). The zero-I/O rung of the read ladder —
231
256
  * values are as stale as their rows, never wrong.
@@ -235,7 +260,7 @@ restoreFloor(checkpoint: ProjectionCheckpoint): number | undefined
235
260
  viewCheckpoint(checkpoint: ProjectionCheckpoint): Partial<SessionProjectionMap>
236
261
 
237
262
  /**
238
- * Cold read: fold every registered unit over a stored log suffix, seeding
263
+ * Cold read: fold every persisted unit over a stored log suffix, seeding
239
264
  * each from its checkpoint row when usable — the one read recipe (cached
240
265
  * state + forward tail replay + `view`) applied without a live `Session`.
241
266
  * Call with the events returned by a persistence
@@ -256,10 +281,10 @@ viewCheckpoint(checkpoint: ProjectionCheckpoint): Partial<SessionProjectionMap>
256
281
  * supplied event's seq, `baseSeq - 1` for an empty tail) plus the
257
282
  * refreshed checkpoint rows at that cut, ready for a durable write-back.
258
283
  */
259
- restore(checkpoint: ProjectionCheckpoint, events: readonly SessionEvent[], baseSeq: number): { snapshot: ProjectionSnapshot; checkpoint: ProjectionCheckpoint }
284
+ restore( checkpoint: ProjectionCheckpoint, events: readonly SessionEvent[], baseSeq: number, ): { snapshot: ProjectionSnapshot; checkpoint: ProjectionCheckpoint }
260
285
  ```
261
286
 
262
287
  Types: [Session](./session.md) · [SessionEvent](./session.md)
263
288
 
264
- Source: [`packages/session/session-projection/src/index.ts:171`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-projection/src/index.ts)
289
+ Source: [`packages/session/session-projection/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-projection/src/index.ts)
265
290
  <!-- END GENERATED cordis-surface -->
@@ -365,7 +365,7 @@ type SessionQueryErrorCode =
365
365
 
366
366
  ## Cordis API
367
367
 
368
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
368
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
369
369
 
370
370
  <a id="ctxsessionquery--sessionqueryengine-abstract-seam"></a>
371
371
 
@@ -494,5 +494,5 @@ async readEvent(request: SessionEventReadRequest, signal?: AbortSignal): Promise
494
494
 
495
495
  Types: [SessionId](./core.md) · [SessionTitleSnapshot](./session-title.md)
496
496
 
497
- Source: [`packages/session-query/session-query/src/index.ts:81`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session-query/session-query/src/index.ts)
497
+ Source: [`packages/session-query/session-query/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session-query/session-query/src/index.ts)
498
498
  <!-- END GENERATED cordis-surface -->
@@ -99,7 +99,7 @@ type SessionReferenceErrorCode =
99
99
 
100
100
  ## Cordis API
101
101
 
102
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
102
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
103
103
 
104
104
  <a id="ctxfilereferences--filereferenceservice-abstract-seam"></a>
105
105
 
@@ -130,7 +130,7 @@ abstract list( agent: Agent, query: string, signal: AbortSignal, ): Promise<File
130
130
 
131
131
  Types: [Agent](./core.md)
132
132
 
133
- Source: [`packages/context/file-reference/src/index.ts:27`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/context/file-reference/src/index.ts)
133
+ Source: [`packages/context/file-reference/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/context/file-reference/src/index.ts)
134
134
 
135
135
  <a id="ctxsessionreferenceresolver--sessionreferenceresolver"></a>
136
136
 
@@ -173,5 +173,5 @@ async prepare( agent: Agent, content: ContentBlock[], references: SessionReferen
173
173
 
174
174
  Types: [Agent](./core.md) · [ContentBlock](./llm-streaming.md)
175
175
 
176
- Source: [`packages/context/session-reference/src/index.ts:75`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/context/session-reference/src/index.ts)
176
+ Source: [`packages/context/session-reference/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/context/session-reference/src/index.ts)
177
177
  <!-- END GENERATED cordis-surface -->
@@ -5,7 +5,7 @@ outline: [2,3]
5
5
 
6
6
  # 遥测(telemetry)
7
7
 
8
- 对外的会话上报拆分为一项[能力 seam](../capability-seams.md):Service Definition 与捕获协调器([dsh-session-telemetry](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/session/session-telemetry),`ctx.sessionTelemetry`)拥有捕获点、固定分片投影、`session-telemetry/record` 脱敏 waterfall(瀑布式事件)、handoff 游标与最小后端约定;部署方加载的 Service Provider([dsh-session-telemetry-otel](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/session/session-telemetry-otel))则是原样配置的 OpenTelemetry JS SDK 日志流水线。它是一项可选能力,不属于 agent loop(智能体循环)主干,这里也没有任何内容会进入模型请求。边界公理(harness 的职责止于 `emit()`;批处理、重试、排队与丢失策略都属于上报 SDK)连同被否决的替代方案,均已在[复活 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.md)中定案;捕获点、游标与投影的约定见 [Service Definition README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-telemetry/README.md)。
8
+ 对外的会话上报拆分为一项[能力 seam](../capability-seams.md):Service Definition 与捕获协调器([dsh-session-telemetry](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/session/session-telemetry),`ctx.sessionTelemetry`)拥有捕获点、固定分片投影、`session-telemetry/record` 脱敏 waterfall(瀑布式事件)、handoff 游标与最小后端约定;部署方加载的 Service Provider([dsh-session-telemetry-otel](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/session/session-telemetry-otel))则是原样配置的 OpenTelemetry JS SDK 日志流水线。它是一项可选能力,不属于 agent loop(智能体循环)主干,这里也没有任何内容会进入模型请求。边界公理(harness 的职责止于 `emit()`;批处理、重试、排队与丢失策略都属于上报 SDK)连同被否决的替代方案,均已在[复活 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.zh.md)中定案;捕获点、游标与投影的约定见 [Service Definition README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-telemetry/README.zh.md)。
9
9
 
10
10
  源码:[`packages/session/session-telemetry/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-telemetry/src/index.ts)
11
11
 
@@ -61,7 +61,7 @@ interface SessionTelemetryRecord {
61
61
 
62
62
  ## 共享披露
63
63
 
64
- 该 seam 的确认契约(归属 [Service Definition README 的共享披露段](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-telemetry/README.md#the-sharing-disclosure)):每个后端都通过 `ctx.sessionTelemetry` 上必需的抽象 `sharing` 成员披露其部署级共享策略,消费方只有在未挂载任何遥测服务时才渲染「未配置」。披露只陈述当前策略,绝不承诺投递或留存——交接是非阻塞入队,批处理、重试与丢失策略仍归上报 SDK。
64
+ 该 seam 的确认契约(归属 [Service Definition README 的共享披露段](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-telemetry/README.zh.md#the-sharing-disclosure)):每个后端都通过 `ctx.sessionTelemetry` 上必需的抽象 `sharing` 成员披露其部署级共享策略,消费方只有在未挂载任何遥测服务时才渲染「未配置」。披露只陈述当前策略,绝不承诺投递或留存——交接是非阻塞入队,批处理、重试与丢失策略仍归上报 SDK。
65
65
 
66
66
  ```ts type-equiv
67
67
  /**
@@ -134,7 +134,7 @@ interface SessionTelemetrySink {
134
134
 
135
135
  ## Cordis API
136
136
 
137
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
137
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
138
138
 
139
139
  <a id="ctxsessiontelemetry--sessiontelemetrybackend-abstract-seam"></a>
140
140
 
@@ -159,7 +159,7 @@ flush?(): void
159
159
  abstract shutdown(): Promise<void>
160
160
  ```
161
161
 
162
- Source: [`packages/session/session-telemetry/src/index.ts:148`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-telemetry/src/index.ts)
162
+ Source: [`packages/session/session-telemetry/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-telemetry/src/index.ts)
163
163
 
164
164
  <a id="session-telemetry-events"></a>
165
165
 
@@ -193,5 +193,5 @@ Transform one outbound record before it reaches the backend. This waterfall is t
193
193
  'session-telemetry/record'(record: SessionTelemetryRecord, next: () => SessionTelemetryRecord): SessionTelemetryRecord
194
194
  ```
195
195
 
196
- Source: [`packages/session/session-telemetry/src/index.ts:43`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-telemetry/src/index.ts)
196
+ Source: [`packages/session/session-telemetry/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-telemetry/src/index.ts)
197
197
  <!-- END GENERATED cordis-surface -->
@@ -154,7 +154,7 @@ interface SessionTitleProvider {
154
154
 
155
155
  ## Cordis API
156
156
 
157
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
157
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
158
158
 
159
159
  <a id="ctxsessiontitle--sessiontitleservice"></a>
160
160
 
@@ -203,5 +203,5 @@ register(provider: SessionTitleProvider): () => Promise<void>
203
203
 
204
204
  Types: [Session](./session.md)
205
205
 
206
- Source: [`packages/session/session-title/src/index.ts:261`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-title/src/index.ts)
206
+ Source: [`packages/session/session-title/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-title/src/index.ts)
207
207
  <!-- END GENERATED cordis-surface -->
@@ -135,7 +135,7 @@ interface SessionEventMap {
135
135
 
136
136
  ### `TodoItem`:一条待办项
137
137
 
138
- 这是 `todo/write` 事件全量列表快照中的单元。它有意保持精简:一行 `content` 加一个三态 `status`(没有 id、优先级或 `activeForm`);列表在每次写入时整体替换,因此条目无需稳定标识。见 [todo_write Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-29-todo-write-tool.md)。
138
+ 这是 `todo/write` 事件全量列表快照中的单元。它有意保持精简:一行 `content` 加一个三态 `status`(没有 id、优先级或 `activeForm`);列表在每次写入时整体替换,因此条目无需稳定标识。见 [todo_write Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-29-todo-write-tool.zh.md)。
139
139
 
140
140
  ```ts type-equiv
141
141
  /**
@@ -255,9 +255,11 @@ type SessionEvent<T extends SessionEventType = SessionEventType> = {
255
255
 
256
256
  对于 `assistant/message`,存在的 `sourceEventSeqs: []` 表示提供方流已知且完整地为空;旧格式或外部事件缺少该字段时,没有记录这条消息由哪些早期事件产生。agent loop 会为每次成功的模型调用写入该字段;其他 surface 事件只要包含该字段,其列表就必须非空。
257
257
 
258
+ <a id="surface-types"></a>
259
+
258
260
  ## Surface 类型
259
261
 
260
- 三种产生消息的类型(`SurfaceEventType`:`user/message`、`assistant/message`、`tool/result`)携带 surface 元数据,用来声明它们如何加入有序的派生 surface。见 [session surface Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-18-session-surface.md)。
262
+ 三种产生消息的类型(`SurfaceEventType`:`user/message`、`assistant/message`、`tool/result`)携带 surface 元数据,用来声明它们如何加入有序的派生 surface。见 [session surface Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-18-session-surface.zh.md)。
261
263
 
262
264
  ### `SurfaceEventType`:事件类型中产生消息的子集
263
265
 
@@ -315,7 +317,7 @@ interface SurfaceIntent {
315
317
  }
316
318
  ```
317
319
 
318
- 对 `SurfaceEventType` 事件必填:每个产生消息的事件都必须声明它如何加入 surface(派生模型历史的唯一来源)。面向人类的 transcript(文本记录)是另一个投影,读取的是日志中追加来源的事件,因为 surface 会有意遮蔽替换所概括的范围(见 [dsh-session](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/session/README.md) 的 `isAppendSurfaceEvent`)。非 surface 类型在编译期拒绝此参数。
320
+ 对 `SurfaceEventType` 事件必填:每个产生消息的事件都必须声明它如何加入 surface(派生模型历史的唯一来源)。面向人类的 transcript(文本记录)是另一个投影,读取的是日志中追加来源的事件,因为 surface 会有意遮蔽替换所概括的范围(见 [dsh-session](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/session/README.zh.md) 的 `isAppendSurfaceEvent`)。非 surface 类型在编译期拒绝此参数。
319
321
 
320
322
  只有 `assistant/message` 可以携带存在但为空的 `sourceEventSeqs`;字段不存在时,该事件没有记录这条消息由哪些早期事件产生,但提供方仍可能发出过分片。
321
323
 
@@ -587,7 +589,7 @@ interface TurnEndReasonMap {
587
589
 
588
590
  一个轮次包围一次模型循环执行,而不是整个会话日志。AgentLoop 只会在轮次内进入 pre-step 批次时记录注入的 `user/message` 事件;插件所属的纯日志事件仍可出现在 `turn/end` 与下一个 `turn/start` 之间,占用事件 seq 但不递增轮次编号。持久化会将每个连续且已接受的事件纳入有界持久化批次,而崩溃修复只关闭确实仍处于开放状态的尾部轮次。需要即时持久性屏障的生产方会显式等待 `ctx.sessions.flush(session)`。
589
591
 
590
- 可选的 `dsh-session/invariant` 配套插件会强制核心拥有的关系:轮次与步骤编号、执行事件封闭,以及同一步骤内的工具调用/结果配对。可合并扩展事件的关系由声明它的插件拥有,因此核心不会仅因没有开放轮次就拒绝未知事件。见[独立事件决策](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.md)。
592
+ 可选的 `dsh-session/invariant` 配套插件会强制核心拥有的关系:轮次与步骤编号、执行事件封闭,以及同一步骤内的工具调用/结果配对。可合并扩展事件的关系由声明它的插件拥有,因此核心不会仅因没有开放轮次就拒绝未知事件。见[独立事件决策](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.zh.md)。
591
593
 
592
594
  ## 种子结束边界:`session/end-seed`
593
595
 
@@ -605,7 +607,7 @@ interface TurnEndReasonMap {
605
607
 
606
608
  如果同一个插件事件族中的多条事件要组装成一个 Web Client Conversation Node,该事件族中的每条 start、update、result、resource 或 interruption 事件都必须携带或独立推导出同一个稳定业务 id。此要求只约束需要关联的 Node 事件族,并不要求每条 Session 事件都有业务 id;Client 因此无须根据相邻关系猜测归属,也无须扫描历史。参见 [Conversation Node 实操手册](../cookbook/adding-a-conversation-node.md)。
607
609
 
608
- 钩子桥接层的 `hook/invoked` / `hook/result` 对(来自 `@deepseek-ai/dsh-hook-protocol`)通过 `handlerId` 关联。`UserPromptSubmit`、`PreToolUse`、`PostToolUse` 与 `Stop` 在 loop 已打开的轮次内触发,因此其 `hook/*` 记录天然位于轮次之内。`SessionStart` 不生成 `hook/*` 记录,因为它在轮次 1 之前运行;其上下文会在 inbox 中保持待处理,直到唤醒交付打开一个轮次(见[钩子桥接 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-30-hook-bridges.md))。
610
+ 钩子桥接层的 `hook/invoked` / `hook/result` 对(来自 `@deepseek-ai/dsh-hook-protocol`)通过 `handlerId` 关联。`UserPromptSubmit`、`PreToolUse`、`PostToolUse` 与 `Stop` 在 loop 已打开的轮次内触发,因此其 `hook/*` 记录天然位于轮次之内。`SessionStart` 不生成 `hook/*` 记录,因为它在轮次 1 之前运行;其上下文会在 inbox 中保持待处理,直到唤醒交付打开一个轮次(见[钩子桥接 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-30-hook-bridges.zh.md))。
609
611
 
610
612
  ## 持久性约定
611
613
 
@@ -619,7 +621,7 @@ interface TurnEndReasonMap {
619
621
 
620
622
  ## Cordis API
621
623
 
622
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
624
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
623
625
 
624
626
  <a id="ctxsessions--sessionstore"></a>
625
627
 
@@ -755,7 +757,7 @@ fork(source: SessionForkSource, boundary?: number, childSessionId?: SessionId):
755
757
 
756
758
  Types: [CreateSessionOptions](./persistence.md) · [PrepareSessionOptions](./persistence.md) · [SessionId](./core.md)
757
759
 
758
- Source: [`packages/core/session/src/index.ts:792`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/session/src/index.ts)
760
+ Source: [`packages/core/session/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/session/src/index.ts)
759
761
 
760
762
  <a id="session-events"></a>
761
763
 
@@ -784,7 +786,7 @@ Creation announcement during session publication. A synchronous throw vetoes and
784
786
 
785
787
  Types: [Scoped](./scope.md)
786
788
 
787
- Source: [`packages/core/session/src/index.ts:54`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/session/src/index.ts)
789
+ Source: [`packages/core/session/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/session/src/index.ts)
788
790
 
789
791
  <a id="sessiondisposed--emit"></a>
790
792
 
@@ -807,7 +809,7 @@ Emitted once when an announced session leaves the store, including publication r
807
809
 
808
810
  Types: [Scoped](./scope.md)
809
811
 
810
- Source: [`packages/core/session/src/index.ts:64`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/session/src/index.ts)
812
+ Source: [`packages/core/session/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/session/src/index.ts)
811
813
 
812
814
  <a id="sessionevent--emit"></a>
813
815
 
@@ -832,7 +834,7 @@ Post-commit, fire-and-forget append feed. The listener snapshot resolves before
832
834
 
833
835
  Types: [Scoped](./scope.md)
834
836
 
835
- Source: [`packages/core/session/src/index.ts:76`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/session/src/index.ts)
837
+ Source: [`packages/core/session/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/session/src/index.ts)
836
838
 
837
839
  <a id="sessionflush--parallel"></a>
838
840
 
@@ -854,5 +856,5 @@ Awaited parallel durability checkpoint: every listener runs and the caller await
854
856
 
855
857
  Types: [Scoped](./scope.md)
856
858
 
857
- Source: [`packages/core/session/src/index.ts:85`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/session/src/index.ts)
859
+ Source: [`packages/core/session/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/session/src/index.ts)
858
860
  <!-- END GENERATED cordis-surface -->
@@ -170,7 +170,7 @@ type SettingsUpdateSource = 'update' | 'provider'
170
170
 
171
171
  ## Cordis API
172
172
 
173
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
173
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
174
174
 
175
175
  <a id="ctxsettings--settingsprovider-abstract-seam"></a>
176
176
 
@@ -255,7 +255,7 @@ async replace(ns: SettingsNamespace, section: object, expectedRevision?: number)
255
255
  async mutate(ns: SettingsNamespace, ops: readonly SettingsPathOp[], expectedRevision?: number): Promise<void>
256
256
  ```
257
257
 
258
- Source: [`packages/settings/settings/src/index.ts:350`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/settings/settings/src/index.ts)
258
+ Source: [`packages/settings/settings/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/settings/settings/src/index.ts)
259
259
 
260
260
  <a id="settings-events"></a>
261
261
 
@@ -282,7 +282,7 @@ One registered namespace's RAW user section changed, whether or not the resolved
282
282
  'settings/document-updated'(ns: SettingsNamespace, revision: number): void
283
283
  ```
284
284
 
285
- Source: [`packages/settings/settings/src/types.ts:48`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/settings/settings/src/types.ts)
285
+ Source: [`packages/settings/settings/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/settings/settings/src/types.ts)
286
286
 
287
287
  <a id="settingsupdated--emit"></a>
288
288
 
@@ -309,5 +309,5 @@ Committed change to one registered namespace's resolved value. Emitted after the
309
309
  'settings/updated'(ns: SettingsNamespace, next: unknown, prev: unknown, source: SettingsUpdateSource): void
310
310
  ```
311
311
 
312
- Source: [`packages/settings/settings/src/types.ts:35`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/settings/settings/src/types.ts)
312
+ Source: [`packages/settings/settings/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/settings/settings/src/types.ts)
313
313
  <!-- END GENERATED cordis-surface -->
@@ -101,7 +101,7 @@ interface ShellExecSpec {
101
101
  }
102
102
  ```
103
103
 
104
- `stdin` 和 `env` 是受信任的进程内插件输入,不由 `dsh-tool-bash` 暴露。本地执行器会先清除环境中的凭据,再合并调用方显式提供的 env。见 [bash-stdin-env Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-30-bash-stdin-env-trusted-plugin-api.md)。
104
+ `stdin` 和 `env` 是受信任的进程内插件输入,不由 `dsh-tool-bash` 暴露。本地执行器会先清除环境中的凭据,再合并调用方显式提供的 env。见 [bash-stdin-env Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-30-bash-stdin-env-trusted-plugin-api.zh.md)。
105
105
 
106
106
  `stdoutMaxBytes` 同样仅供受信任插件使用。它让前台消费方能在有界解析预算内请求完整 stdout,而不会改变 stderr、后台任务或面向模型的 bash 工具的常规输出上限。
107
107
 
@@ -143,7 +143,7 @@ interface ShellRunResult {
143
143
 
144
144
  ## 文件沙箱:`ShellSandboxInfo`
145
145
 
146
- 使用沙箱的执行器通过 `ShellExecutor.sandboxMode` 暴露其已配置的模式回退值。工具层请求 [`@deepseek-ai/dsh-sandbox-policy`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/sandbox/sandbox-policy/README.md),把每个调用会话的持久 `sandbox/mode` 覆盖值与不可变 cwd 解析为 `ShellExecRequest.sandboxPolicy`;经用户批准、严格更宽松的调用只替换模式。模式/root/enforcement 词汇归 [`@deepseek-ai/dsh-sandbox` 沙箱 seam](./sandbox.md) 所有;模式仅管辖文件效果。
146
+ 使用沙箱的执行器通过 `ShellExecutor.sandboxMode` 暴露其已配置的模式回退值。工具层请求 [`@deepseek-ai/dsh-sandbox-policy`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/sandbox/sandbox-policy/README.zh.md),把每个调用会话的持久 `sandbox/mode` 覆盖值与不可变 cwd 解析为 `ShellExecRequest.sandboxPolicy`;经用户批准、严格更宽松的调用只替换模式。模式/root/enforcement 词汇归 [`@deepseek-ai/dsh-sandbox` 沙箱 seam](./sandbox.md) 所有;模式仅管辖文件效果。
147
147
 
148
148
  沙箱化运行会报告其模式、保守的拒绝分类与强制执行完整度。`runnerFailed` 标记命令运行前沙箱 runner 已失败;前台执行会抛出 `SANDBOX_UNAVAILABLE`,而已结束的后台进程只能通过其事实通道报告。
149
149
 
@@ -165,7 +165,7 @@ interface ShellSandboxInfo {
165
165
  }
166
166
  ```
167
167
 
168
- 当受限模式没有可用后端时,`ctx.sandbox` 提供方会抛出、执行器会传播由[沙箱 seam](./sandbox.md)所有的 `SANDBOX_UNAVAILABLE` 错误码。选定的 runner 拒绝其 profile 时会触达同一个故障关闭的前台错误;已结束的后台任务则记录 `runnerFailed`。模型会在结果中收到拒绝/runner 事实,仅当拒绝标记指出生效模式时才得知该模式,并可通过 `sandbox_permissions` 加 `justification` 请求一次性、严格更宽松的重试;执行任何操作前,`ctx.approval` 必须批准该次确切调用。完整的策略与切换设计见[沙箱 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-06-sandbox.md)。
168
+ 当受限模式没有可用后端时,`ctx.sandbox` 提供方会抛出、执行器会传播由[沙箱 seam](./sandbox.md)所有的 `SANDBOX_UNAVAILABLE` 错误码。选定的 runner 拒绝其 profile 时会触达同一个故障关闭的前台错误;已结束的后台任务则记录 `runnerFailed`。模型会在结果中收到拒绝/runner 事实,仅当拒绝标记指出生效模式时才得知该模式,并可通过 `sandbox_permissions` 加 `justification` 请求一次性、严格更宽松的重试;执行任何操作前,`ctx.approval` 必须批准该次确切调用。完整的策略与切换设计见[沙箱 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-06-sandbox.zh.md)。
169
169
 
170
170
  ## 后台进程:`ShellProcess`
171
171
 
@@ -229,7 +229,7 @@ interface ShellProcessRead {
229
229
 
230
230
  ## Cordis API
231
231
 
232
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
232
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
233
233
 
234
234
  <a id="ctxshell--shellexecutor-abstract-seam"></a>
235
235
 
@@ -269,7 +269,7 @@ abstract run(spec: ShellExecSpec): Promise<ShellRunResult>
269
269
  abstract start(spec: ShellExecSpec): ShellProcess
270
270
  ```
271
271
 
272
- Source: [`packages/shell/shell/src/index.ts:65`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/shell/shell/src/index.ts)
272
+ Source: [`packages/shell/shell/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/shell/shell/src/index.ts)
273
273
 
274
274
  <a id="ctxshellenv--shellenvregistry"></a>
275
275
 
@@ -302,5 +302,5 @@ list(): BashEnvVariableInfo[]
302
302
 
303
303
  Types: [DshEnvironment](./subprocess.md) · [ToolExecution](./tools.md)
304
304
 
305
- Source: [`packages/shell/shell-env/src/index.ts:89`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/shell/shell-env/src/index.ts)
305
+ Source: [`packages/shell/shell-env/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/shell/shell-env/src/index.ts)
306
306
  <!-- END GENERATED cordis-surface -->
@@ -243,7 +243,7 @@ interface Config {
243
243
 
244
244
  ## Cordis API
245
245
 
246
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
246
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
247
247
 
248
248
  <a id="ctxskills--skillregistry"></a>
249
249
 
@@ -307,7 +307,7 @@ async snapshot(options: SkillViewOptions = {}): Promise<SkillCatalogSnapshot>
307
307
  async get(name: string, options: SkillViewOptions = {}): Promise<SkillDefinition | undefined>
308
308
  ```
309
309
 
310
- Source: [`packages/skill/skill/src/index.ts:357`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/skill/skill/src/index.ts)
310
+ Source: [`packages/skill/skill/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/skill/skill/src/index.ts)
311
311
 
312
312
  <a id="skills-events"></a>
313
313
 
@@ -330,5 +330,5 @@ A skill provider, runtime contribution, or provider-backed catalog may have chan
330
330
  'skills/change'(): void
331
331
  ```
332
332
 
333
- Source: [`packages/skill/skill/src/index.ts:297`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/skill/skill/src/index.ts)
333
+ Source: [`packages/skill/skill/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/skill/skill/src/index.ts)
334
334
  <!-- END GENERATED cordis-surface -->
@@ -5,7 +5,7 @@ outline: [2,3]
5
5
 
6
6
  # spill 存储
7
7
 
8
- spill 存储 seam 是一项[能力 seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.md),它持久保存工具的超大文本,并返回面向模型的定位符与检索指引;该能力拆分到三个包:Service Definition([dsh-spill](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill),`ctx.spillStore`)、Service Provider([dsh-spill-local](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill-local),宿主文件系统中会话作用域的私有文件)和 Consumer([dsh-spill-policy](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill-policy),`tools/post-execute` 策略)。spill 是**一项可选能力**,不属于 agent loop(智能体循环)主干,因此其词汇记录在此处,而不在 [core.md](./core.md) 中。预览机制仍归 [dsh-output-retention](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/util/output-retention) 所有;该 seam 只保存策略交给它的最终文本。
8
+ spill 存储 seam 是一项[能力 seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.zh.md),它持久保存工具的超大文本,并返回面向模型的定位符与检索指引;该能力拆分到三个包:Service Definition([dsh-spill](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill),`ctx.spillStore`)、Service Provider([dsh-spill-local](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill-local),宿主文件系统中会话作用域的私有文件)和 Consumer([dsh-spill-policy](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill-policy),`tools/post-execute` 策略)。spill 是**一项可选能力**,不属于 agent loop(智能体循环)主干,因此其词汇记录在此处,而不在 [core.md](./core.md) 中。预览机制仍归 [dsh-output-retention](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/util/output-retention) 所有;该 seam 只保存策略交给它的最终文本。
9
9
 
10
10
  源码:[`packages/spill/spill/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/spill/spill/src/types.ts)
11
11
 
@@ -93,7 +93,7 @@ type SpillLocator = Branded<'SpillLocator'>
93
93
 
94
94
  ## Cordis API
95
95
 
96
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
96
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
97
97
 
98
98
  <a id="ctxspillstore--spillstore-abstract-seam"></a>
99
99
 
@@ -116,5 +116,5 @@ Semantics every implementation must honor:
116
116
  abstract saveText(input: SaveTextSpill): Promise<SpillRef>
117
117
  ```
118
118
 
119
- Source: [`packages/spill/spill/src/index.ts:45`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/spill/spill/src/index.ts)
119
+ Source: [`packages/spill/spill/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/spill/spill/src/index.ts)
120
120
  <!-- END GENERATED cordis-surface -->