dsh-plugin-dev-kb 1.0.0

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 (234) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +56 -0
  3. package/cordis.patch.yml +12 -0
  4. package/kb/INDEX.md +210 -0
  5. package/kb/README.md +69 -0
  6. package/kb/extra/AGENTS.md +75 -0
  7. package/kb/extra/api-gateway.md +164 -0
  8. package/kb/extra/api-gateway.zh.md +164 -0
  9. package/kb/extra/cookbook/adding-a-vendored-package.md +59 -0
  10. package/kb/extra/cookbook/adding-a-vendored-package.zh.md +59 -0
  11. package/kb/extra/cookbook/maintaining-dsh-code-review.md +64 -0
  12. package/kb/extra/cookbook/maintaining-dsh-code-review.zh.md +64 -0
  13. package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.md +32 -0
  14. package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.zh.md +32 -0
  15. package/kb/extra/defensive-patterns.md +33 -0
  16. package/kb/extra/defensive-patterns.zh.md +33 -0
  17. package/kb/extra/development.md +171 -0
  18. package/kb/extra/development.zh.md +171 -0
  19. package/kb/extra/event-producer-consumer.md +76 -0
  20. package/kb/extra/event-producer-consumer.zh.md +78 -0
  21. package/kb/extra/glossary.md +45 -0
  22. package/kb/extra/glossary.zh.md +45 -0
  23. package/kb/extra/graph-atlas.md +24 -0
  24. package/kb/extra/graph-atlas.zh.md +26 -0
  25. package/kb/extra/i18n/README.md +60 -0
  26. package/kb/extra/i18n/README.zh.md +60 -0
  27. package/kb/extra/i18n/style-samples.md +87 -0
  28. package/kb/extra/i18n/terminology.md +214 -0
  29. package/kb/extra/i18n/translation-prompt.md +263 -0
  30. package/kb/extra/i18n/translation-rules.md +69 -0
  31. package/kb/extra/i18n/translation-rules.zh.md +69 -0
  32. package/kb/extra/module-graph.md +1641 -0
  33. package/kb/extra/module-graph.zh.md +1643 -0
  34. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.md +113 -0
  35. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +113 -0
  36. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.md +47 -0
  37. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +47 -0
  38. package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.md +53 -0
  39. package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.zh.md +53 -0
  40. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +55 -0
  41. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +55 -0
  42. package/kb/extra/postmortem/README.md +18 -0
  43. package/kb/extra/postmortem/README.zh.md +18 -0
  44. package/kb/extra/rescope.md +53 -0
  45. package/kb/extra/rescope.zh.md +53 -0
  46. package/kb/extra/subsystems/attachment.md +125 -0
  47. package/kb/extra/subsystems/attachment.zh.md +125 -0
  48. package/kb/extra/subsystems/extensions.md +364 -0
  49. package/kb/extra/subsystems/extensions.zh.md +364 -0
  50. package/kb/extra/subsystems/feedback.md +266 -0
  51. package/kb/extra/subsystems/feedback.zh.md +266 -0
  52. package/kb/extra/testing.md +49 -0
  53. package/kb/extra/testing.zh.md +49 -0
  54. package/kb/extra/web-styling.md +25 -0
  55. package/kb/extra/web-styling.zh.md +25 -0
  56. package/kb/meta/search-index.json +1328 -0
  57. package/kb/meta/site-pages.txt +168 -0
  58. package/kb/meta/source.json +13 -0
  59. package/kb/meta/topics.md +75 -0
  60. package/kb/site/develop/basic/config.md +108 -0
  61. package/kb/site/develop/basic/index.md +146 -0
  62. package/kb/site/develop/basic/publish.md +185 -0
  63. package/kb/site/develop/basic/tool.md +54 -0
  64. package/kb/site/develop/cordis-tutorial/01-first-plugin.md +95 -0
  65. package/kb/site/develop/cordis-tutorial/02-lifecycle-and-effects.md +98 -0
  66. package/kb/site/develop/cordis-tutorial/03-services.md +98 -0
  67. package/kb/site/develop/cordis-tutorial/04-events.md +144 -0
  68. package/kb/site/develop/cordis-tutorial/05-config.md +84 -0
  69. package/kb/site/develop/cordis-tutorial/06-composition-and-hmr.md +113 -0
  70. package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +107 -0
  71. package/kb/site/develop/cordis-tutorial/index.md +62 -0
  72. package/kb/site/develop/framework/events.md +145 -0
  73. package/kb/site/develop/framework/index.md +139 -0
  74. package/kb/site/develop/framework/service.md +152 -0
  75. package/kb/site/develop/practice/index.md +157 -0
  76. package/kb/site/develop/practice/llm-adapter.md +190 -0
  77. package/kb/site/en/develop/basic/config.md +108 -0
  78. package/kb/site/en/develop/basic/index.md +146 -0
  79. package/kb/site/en/develop/basic/publish.md +185 -0
  80. package/kb/site/en/develop/basic/tool.md +54 -0
  81. package/kb/site/en/develop/cordis-tutorial/01-first-plugin.md +95 -0
  82. package/kb/site/en/develop/cordis-tutorial/02-lifecycle-and-effects.md +98 -0
  83. package/kb/site/en/develop/cordis-tutorial/03-services.md +98 -0
  84. package/kb/site/en/develop/cordis-tutorial/04-events.md +144 -0
  85. package/kb/site/en/develop/cordis-tutorial/05-config.md +84 -0
  86. package/kb/site/en/develop/cordis-tutorial/06-composition-and-hmr.md +113 -0
  87. package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +107 -0
  88. package/kb/site/en/develop/cordis-tutorial/index.md +60 -0
  89. package/kb/site/en/develop/framework/events.md +145 -0
  90. package/kb/site/en/develop/framework/index.md +139 -0
  91. package/kb/site/en/develop/framework/service.md +150 -0
  92. package/kb/site/en/develop/practice/index.md +157 -0
  93. package/kb/site/en/develop/practice/llm-adapter.md +190 -0
  94. package/kb/site/en/guide/providers-custom-form.png +0 -0
  95. package/kb/site/en/guide/providers-models-page.png +0 -0
  96. package/kb/site/en/guide/providers.md +100 -0
  97. package/kb/site/en/guide/python-sdk.md +106 -0
  98. package/kb/site/en/guide/quickstart.md +32 -0
  99. package/kb/site/en/index.md +8 -0
  100. package/kb/site/en/reference/agent-lifecycle.md +86 -0
  101. package/kb/site/en/reference/capability-seams.md +475 -0
  102. package/kb/site/en/reference/config-catalog.md +3155 -0
  103. package/kb/site/en/reference/cookbook/adding-a-conversation-node.md +235 -0
  104. package/kb/site/en/reference/cookbook/adding-a-package.md +120 -0
  105. package/kb/site/en/reference/cookbook/adding-a-settings-card.md +102 -0
  106. package/kb/site/en/reference/cookbook/adding-a-tool.md +96 -0
  107. package/kb/site/en/reference/cookbook/adding-an-llm-adapter.md +45 -0
  108. package/kb/site/en/reference/cookbook/extension-cookbook.md +131 -0
  109. package/kb/site/en/reference/cordis-api/context.md +368 -0
  110. package/kb/site/en/reference/cordis-api/events.md +211 -0
  111. package/kb/site/en/reference/cordis-api/fiber.md +379 -0
  112. package/kb/site/en/reference/cordis-api/inherited.md +43 -0
  113. package/kb/site/en/reference/cordis-api/registry.md +156 -0
  114. package/kb/site/en/reference/cordis-api/service.md +106 -0
  115. package/kb/site/en/reference/cordis-primer.md +46 -0
  116. package/kb/site/en/reference/index.md +131 -0
  117. package/kb/site/en/reference/persistence-catalog.md +949 -0
  118. package/kb/site/en/reference/subsystems/approval.md +173 -0
  119. package/kb/site/en/reference/subsystems/client-modules.md +121 -0
  120. package/kb/site/en/reference/subsystems/code-runtime.md +194 -0
  121. package/kb/site/en/reference/subsystems/commands.md +190 -0
  122. package/kb/site/en/reference/subsystems/compaction.md +241 -0
  123. package/kb/site/en/reference/subsystems/core.md +1073 -0
  124. package/kb/site/en/reference/subsystems/credentials.md +136 -0
  125. package/kb/site/en/reference/subsystems/filesystem.md +498 -0
  126. package/kb/site/en/reference/subsystems/goal.md +280 -0
  127. package/kb/site/en/reference/subsystems/index.md +58 -0
  128. package/kb/site/en/reference/subsystems/invariants.md +91 -0
  129. package/kb/site/en/reference/subsystems/jobs.md +293 -0
  130. package/kb/site/en/reference/subsystems/llm-streaming.md +920 -0
  131. package/kb/site/en/reference/subsystems/lsp.md +205 -0
  132. package/kb/site/en/reference/subsystems/permission-presets.md +134 -0
  133. package/kb/site/en/reference/subsystems/persistence.md +388 -0
  134. package/kb/site/en/reference/subsystems/plan.md +90 -0
  135. package/kb/site/en/reference/subsystems/sandbox.md +221 -0
  136. package/kb/site/en/reference/subsystems/schedule.md +189 -0
  137. package/kb/site/en/reference/subsystems/scope.md +62 -0
  138. package/kb/site/en/reference/subsystems/session-projection.md +265 -0
  139. package/kb/site/en/reference/subsystems/session-query.md +498 -0
  140. package/kb/site/en/reference/subsystems/session-reference.md +111 -0
  141. package/kb/site/en/reference/subsystems/session-telemetry.md +197 -0
  142. package/kb/site/en/reference/subsystems/session-title.md +207 -0
  143. package/kb/site/en/reference/subsystems/session.md +852 -0
  144. package/kb/site/en/reference/subsystems/settings.md +313 -0
  145. package/kb/site/en/reference/subsystems/shell.md +306 -0
  146. package/kb/site/en/reference/subsystems/skills.md +334 -0
  147. package/kb/site/en/reference/subsystems/spill.md +120 -0
  148. package/kb/site/en/reference/subsystems/storage.md +232 -0
  149. package/kb/site/en/reference/subsystems/subagent.md +737 -0
  150. package/kb/site/en/reference/subsystems/subprocess.md +327 -0
  151. package/kb/site/en/reference/subsystems/system-prompt.md +210 -0
  152. package/kb/site/en/reference/subsystems/terminal.md +187 -0
  153. package/kb/site/en/reference/subsystems/token-meter.md +93 -0
  154. package/kb/site/en/reference/subsystems/tools.md +723 -0
  155. package/kb/site/en/reference/subsystems/typert.md +339 -0
  156. package/kb/site/en/reference/subsystems/user-questions.md +181 -0
  157. package/kb/site/en/reference/subsystems/web-server.md +111 -0
  158. package/kb/site/en/reference/subsystems/web.md +202 -0
  159. package/kb/site/en/reference/subsystems/workflow.md +281 -0
  160. package/kb/site/en/reference/subsystems/workspace.md +231 -0
  161. package/kb/site/en/reference/tool-catalog.md +1877 -0
  162. package/kb/site/en/reference/tool-execution-pipeline.md +66 -0
  163. package/kb/site/guide/providers-custom-form.zh.png +0 -0
  164. package/kb/site/guide/providers-models-page.zh.png +0 -0
  165. package/kb/site/guide/providers.md +100 -0
  166. package/kb/site/guide/python-sdk.md +106 -0
  167. package/kb/site/guide/quickstart.md +32 -0
  168. package/kb/site/index.md +8 -0
  169. package/kb/site/reference/agent-lifecycle.md +86 -0
  170. package/kb/site/reference/capability-seams.md +475 -0
  171. package/kb/site/reference/config-catalog.md +3154 -0
  172. package/kb/site/reference/cookbook/adding-a-conversation-node.md +235 -0
  173. package/kb/site/reference/cookbook/adding-a-package.md +120 -0
  174. package/kb/site/reference/cookbook/adding-a-settings-card.md +102 -0
  175. package/kb/site/reference/cookbook/adding-a-tool.md +98 -0
  176. package/kb/site/reference/cookbook/adding-an-llm-adapter.md +45 -0
  177. package/kb/site/reference/cookbook/extension-cookbook.md +133 -0
  178. package/kb/site/reference/cordis-api/context.md +368 -0
  179. package/kb/site/reference/cordis-api/events.md +211 -0
  180. package/kb/site/reference/cordis-api/fiber.md +379 -0
  181. package/kb/site/reference/cordis-api/inherited.md +43 -0
  182. package/kb/site/reference/cordis-api/registry.md +156 -0
  183. package/kb/site/reference/cordis-api/service.md +106 -0
  184. package/kb/site/reference/cordis-primer.md +52 -0
  185. package/kb/site/reference/index.md +135 -0
  186. package/kb/site/reference/persistence-catalog.md +949 -0
  187. package/kb/site/reference/subsystems/approval.md +173 -0
  188. package/kb/site/reference/subsystems/client-modules.md +121 -0
  189. package/kb/site/reference/subsystems/code-runtime.md +194 -0
  190. package/kb/site/reference/subsystems/commands.md +190 -0
  191. package/kb/site/reference/subsystems/compaction.md +241 -0
  192. package/kb/site/reference/subsystems/core.md +1081 -0
  193. package/kb/site/reference/subsystems/credentials.md +136 -0
  194. package/kb/site/reference/subsystems/filesystem.md +498 -0
  195. package/kb/site/reference/subsystems/goal.md +280 -0
  196. package/kb/site/reference/subsystems/index.md +58 -0
  197. package/kb/site/reference/subsystems/invariants.md +91 -0
  198. package/kb/site/reference/subsystems/jobs.md +293 -0
  199. package/kb/site/reference/subsystems/llm-streaming.md +926 -0
  200. package/kb/site/reference/subsystems/lsp.md +205 -0
  201. package/kb/site/reference/subsystems/permission-presets.md +134 -0
  202. package/kb/site/reference/subsystems/persistence.md +388 -0
  203. package/kb/site/reference/subsystems/plan.md +90 -0
  204. package/kb/site/reference/subsystems/sandbox.md +221 -0
  205. package/kb/site/reference/subsystems/schedule.md +189 -0
  206. package/kb/site/reference/subsystems/scope.md +62 -0
  207. package/kb/site/reference/subsystems/session-projection.md +265 -0
  208. package/kb/site/reference/subsystems/session-query.md +498 -0
  209. package/kb/site/reference/subsystems/session-reference.md +111 -0
  210. package/kb/site/reference/subsystems/session-telemetry.md +197 -0
  211. package/kb/site/reference/subsystems/session-title.md +207 -0
  212. package/kb/site/reference/subsystems/session.md +854 -0
  213. package/kb/site/reference/subsystems/settings.md +313 -0
  214. package/kb/site/reference/subsystems/shell.md +306 -0
  215. package/kb/site/reference/subsystems/skills.md +334 -0
  216. package/kb/site/reference/subsystems/spill.md +120 -0
  217. package/kb/site/reference/subsystems/storage.md +232 -0
  218. package/kb/site/reference/subsystems/subagent.md +739 -0
  219. package/kb/site/reference/subsystems/subprocess.md +327 -0
  220. package/kb/site/reference/subsystems/system-prompt.md +210 -0
  221. package/kb/site/reference/subsystems/terminal.md +187 -0
  222. package/kb/site/reference/subsystems/token-meter.md +93 -0
  223. package/kb/site/reference/subsystems/tools.md +723 -0
  224. package/kb/site/reference/subsystems/typert.md +339 -0
  225. package/kb/site/reference/subsystems/user-questions.md +181 -0
  226. package/kb/site/reference/subsystems/web-server.md +111 -0
  227. package/kb/site/reference/subsystems/web.md +202 -0
  228. package/kb/site/reference/subsystems/workflow.md +281 -0
  229. package/kb/site/reference/subsystems/workspace.md +231 -0
  230. package/kb/site/reference/tool-catalog.md +1880 -0
  231. package/kb/site/reference/tool-execution-pipeline.md +66 -0
  232. package/package.json +40 -0
  233. package/scripts/rebuild-index.mjs +88 -0
  234. package/skills/dsh-plugin-dev-kb.md +66 -0
@@ -0,0 +1,173 @@
1
+ ---
2
+ editSource: "docs/subsystems/approval.zh.md"
3
+ outline: [2,3]
4
+ ---
5
+
6
+ # 用户审批
7
+
8
+ [dsh-user-approval](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/interaction/user-approval) 的用户审批 seam 回答一个问题:这个具体操作是否可以继续?它拥有共享的请求/结果词汇、`ctx.approval` 分发服务、`approval/request` 应答者 waterfall(瀑布式事件)、仅记录日志的审计事件对,以及按会话的 `ask`/`never` 策略。UI 通道可以提供人类应答者;[ACP(Agent Client Protocol)自动化桥接层](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/acp/acp)为其拥有的 agent(智能体)提供一次性机器决策。调用方如 [dsh-tools](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/core/tools) 和 [dsh-tool-bash](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/shell/tool-bash) 消费闭合的结果,除非结果为 `allowed-once`,否则一律拒绝。
9
+
10
+ 源码:[`packages/interaction/user-approval/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/user-approval/src/index.ts)
11
+
12
+ ## 标识与结果
13
+
14
+ 每个请求都会获得一个全新的 `ApprovalRequestId`。该品牌类型将 `approval/asked` 与 `approval/decided` 审计事件配对,同时不会让审批 id 与工具调用 id 或 agent/会话 id 互换。
15
+
16
+ ```ts type-equiv
17
+ /**
18
+ * Pairs one `approval/asked` audit event with its `approval/decided`.
19
+ * Service-issued (one fresh id per {@link ApprovalService.request} call).
20
+ */
21
+ type ApprovalRequestId = Branded<'ApprovalRequestId'>
22
+ ```
23
+
24
+ `ApprovalOutcome` 是闭合的,且失败时拒绝。`allowed-once` 仅授权所询问的那一个操作;调用方对 `rejected`、`cancelled` 和 `unavailable` 均执行拒绝。缺失、不负责该请求、抛异常或不合规的应答者会产生 `unavailable`,而非放行。
25
+
26
+ ```ts type-equiv
27
+ /**
28
+ * Closed approval outcomes: a one-shot grant, explicit rejection, withdrawn
29
+ * request, or unavailable answerer. Callers fail closed on `unavailable`.
30
+ */
31
+ type ApprovalOutcome = 'allowed-once' | 'rejected' | 'cancelled' | 'unavailable'
32
+ ```
33
+
34
+ ## 按会话策略
35
+
36
+ `ApprovalPolicy` 决定在交互式应答者运行之前发生什么。`ask` 委托给组合的应答者链,链的无应答默认值为 `unavailable`;`never` 确定性地返回 `rejected`,不分发任何应答者。生效值为会话日志中最后一条 `approval/policy` 事件,回退到服务配置。`setApprovalPolicy(session, policy)` 是唯一的写入路径,因此回放能重建覆盖值。
37
+
38
+ ```ts type-equiv
39
+ /**
40
+ * A session's approval policy — what happens to an {@link ApprovalService}
41
+ * ask BEFORE any interactive answerer sees it:
42
+ *
43
+ * - `'ask'` (the default) — delegate to the composed answerers; with none
44
+ * composed the chain falls through to the fail-closed `'unavailable'`.
45
+ * - `'never'` — never prompt anyone: every ask resolves `'rejected'`
46
+ * deterministically. The strict headless stance (CI, unattended runs) and
47
+ * the policy whose outcome is knowable without asking.
48
+ */
49
+ type ApprovalPolicy = 'ask' | 'never'
50
+ ```
51
+
52
+ 两种策略都会将各自完整的当前含义贡献给缓存安全的运行时上下文快照。带来源的 `user/message` 是持久化且模型可见的输入;审批状态变化时,会在保留的历史后追加一份新的完整快照,而不改写请求头中的系统提示词。
53
+
54
+ ## 审批请求
55
+
56
+ `ApprovalRequest` 以足够精确的方式标识 agent 和工具操作,以便路由和审计该问题。它有意省略工具参数:应答者通过 `callId` 将提示附加到已流式输出的工具调用上,而非渲染另一份可能漂移的副本。
57
+
58
+ ```ts type-equiv
59
+ /**
60
+ * Readonly same-process permission question. `callId` links to an already
61
+ * presented tool call, so arguments are not duplicated here.
62
+ */
63
+ interface ApprovalRequest {
64
+ /**
65
+ * The agent on whose behalf the question is asked. Routes the question (a
66
+ * UI answerer only answers for agents it owns) and receives the audit
67
+ * events on its session log.
68
+ */
69
+ readonly agent: Agent
70
+ /** The tool the question is about (presentation and audit). */
71
+ readonly toolName: string
72
+ /**
73
+ * The exact tool call being decided, when the asker has one — lets a UI
74
+ * attach the prompt to the tool call it already streamed.
75
+ */
76
+ readonly callId?: CallId
77
+ /** The asker's human-readable explanation of WHY it is asking. */
78
+ readonly reason?: string
79
+ /**
80
+ * Aborting withdraws the question: the request settles `'cancelled'`
81
+ * immediately and a late answer from a still-pending answerer is discarded.
82
+ */
83
+ readonly signal?: AbortSignal
84
+ }
85
+ ```
86
+
87
+ ## 分发与审计
88
+
89
+ `ctx.approval.request(req)` 要求发起请求的会话处于一个尚未结束的轮次内。它追加 `approval/asked`,获取一个结果,追加对应的 `approval/decided`,然后以该结果完成。`never` 策略在服务内部、waterfall 分发之前强制执行,因此即使后来以 `prepend` 注册的应答者也无法绕过它。应答者在负责处理该请求时返回结果,否则调用 `next()` 委托;第一个应答占据唯一的决策槽位。
90
+
91
+ 审计事件仅写入日志,不进入模型 transcript(文本记录)。模型可见的行为是调用方派生的工具结果与当前运行时上下文快照。服务 dispose(资源释放)时会移除其上下文贡献;应答者监听器独立地通过 effect 绑定到其所属插件。
92
+
93
+ <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
94
+
95
+ <a id="cordis-surface"></a>
96
+
97
+ ## Cordis API
98
+
99
+ 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).
100
+
101
+ <a id="ctxapproval--approvalservice"></a>
102
+
103
+ ### `ctx.approval` — `ApprovalService`
104
+
105
+ Approval service that applies session policy before answerers and logs every ask/outcome pair to the requesting session. It exposes deterministic policy changes to the model through the runtime-context snapshot and switch notices.
106
+
107
+ ```ts cordis-catalog
108
+ /**
109
+ * Switch one live agent's policy and queue the transition for its next model
110
+ * step. Session initialization uses {@link setApprovalPolicy} directly
111
+ * because there is no previously visible policy to change.
112
+ * @param agent - the live agent whose policy is changing.
113
+ * @param policy - the new effective policy.
114
+ */
115
+ setPolicy(agent: Agent, policy: ApprovalPolicy): void
116
+
117
+ /**
118
+ * Ask the composed answerers to decide one readonly same-process request.
119
+ * The service borrows the request, agent, session, and live signal directly.
120
+ * The request requires an open turn because the audit pair must be enclosed
121
+ * by the durable log's commit/replay boundary; an idle ask rejects before
122
+ * appending anything. The answerer phase always produces an outcome: an
123
+ * aborted signal yields `'cancelled'`, a missing or throwing answerer yields
124
+ * `'unavailable'` (fail closed), and a rogue non-vocabulary return value is
125
+ * normalized to `'unavailable'`. A failure that prevents either audit append
126
+ * from committing still rejects because returning an unlogged decision would
127
+ * violate the pair. Session contains post-commit observer failures, so an
128
+ * authoritative append cannot reject the request or suppress its matching
129
+ * audit event.
130
+ * @param req - the pending decision (agent, tool identity, reason, signal).
131
+ * @returns the closed outcome; `'allowed-once'` is the only grant.
132
+ * @throws when no turn is open or either audit event fails before the session
133
+ * append commit point.
134
+ */
135
+ async request(req: ApprovalRequest): Promise<ApprovalOutcome>
136
+
137
+ /**
138
+ * Read the session override without applying the configured default.
139
+ * @param session - session whose log supplies the override.
140
+ * @returns the last logged policy, or `undefined` without one.
141
+ */
142
+ overrideOf(session: Session): ApprovalPolicy | undefined
143
+ ```
144
+
145
+ Types: [Agent](./core.md) · [Session](./session.md)
146
+
147
+ Source: [`packages/interaction/user-approval/src/index.ts:192`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/user-approval/src/index.ts)
148
+
149
+ <a id="approval-events"></a>
150
+
151
+ ### `approval/*` events
152
+
153
+ <a id="approvalrequest--waterfall"></a>
154
+
155
+ #### `approval/request` — waterfall
156
+
157
+ Ask composed answerers for one decision. Return an outcome to claim the request or call `next()`; failure yields the fail-closed default. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
158
+
159
+ ```ts cordis-catalog
160
+ /**
161
+ * Ask composed answerers for one decision. Return an outcome to claim the
162
+ * request or call `next()`; failure yields the fail-closed default.
163
+ * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
164
+ * @param req - the pending decision (agent, tool identity, reason, signal).
165
+ * @mode waterfall
166
+ */
167
+ 'approval/request'(this: Scoped<ApprovalService>, req: ApprovalRequest, next: () => Promise<ApprovalOutcome>): Promise<ApprovalOutcome>
168
+ ```
169
+
170
+ Types: [Scoped](./scope.md)
171
+
172
+ Source: [`packages/interaction/user-approval/src/index.ts:30`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/user-approval/src/index.ts)
173
+ <!-- END GENERATED cordis-surface -->
@@ -0,0 +1,121 @@
1
+ ---
2
+ editSource: "docs/subsystems/client-modules.zh.md"
3
+ outline: [2,3]
4
+ ---
5
+
6
+ # Client 模块
7
+
8
+ Web 插件表:[dsh-client-modules](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/client/modules) 中 client 模块系统的 Node 半,以 `ctx.clientModules`(`ClientModuleRegistry`)形式提供。它扫描宿主 Loader 的 entry,找出声明了 `dsh.client` 的包,组合出 `window.__DSH_BOOT__` entry 图,在 `/plugins/<id>/client.js` 提供各个 bundle,并经 index 转换(index tap)注入启动 manifest(元数据清单)——这是同一个服务的四个面。它是 Web GUI 栈的一项可选能力,不属于 agent loop(智能体循环)主干,并且是 [dsh-host-webserver](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/host/webserver) 的消费方:[web-server.md](./web-server.md) 所述的载体提供本服务注册的前缀路由与 index 转换。同一个包的浏览器半(`ctx.modules`,即拉取并物化这些 bundle 的 lazy CJS 模块表)属于内核机件,记录在[包 README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/modules/README.md)中,不在本页。
9
+
10
+ 源码:[`packages/client/modules/src/client/manifest.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/modules/src/client/manifest.ts)
11
+
12
+ ## wire
13
+
14
+ 图是 Node 半与浏览器半之间协议层的唯一真源:宿主从扫描到的包组合出 `WebBootEntry` 行,把图作为 `<head>` 中的第一个脚本注入(`window.__DSH_BOOT__`,其中 `<` 已转义,插件可控的字符串因此无法逃出 script 元素),壳则在启动任何东西之前先解析它。没有有效 manifest 的页面无法启动——浏览器侧的解析器在图缺失或畸形时大声抛错。
15
+
16
+ ```ts type-equiv
17
+ /**
18
+ * One composed client entry pushed by the host (a graph row). Wire
19
+ * single source: the host node half (package root) produces this same shape.
20
+ * `immediately` marks stage-one prefetch; `inject` is informational graph
21
+ * metadata (the authoritative edges live in each package's `dsh.client`
22
+ * declaration and reach fibers through entry creation).
23
+ */
24
+ interface WebBootEntry {
25
+ /** Entry name == package name. */
26
+ id: string
27
+ /** Bundle endpoint, '/plugins/<id>/client.js?rev=<rev>'. */
28
+ url: string
29
+ /** Bundle content hash (cache-busting consistency anchor). */
30
+ rev: string
31
+ /** Package-name dependency edges, informational (preflight display / HMR diffing). */
32
+ inject?: string[]
33
+ /** Stage-one prefetch mark: load the script for factory registration during module-face boot. */
34
+ immediately?: boolean
35
+ }
36
+ ```
37
+
38
+ ```ts type-equiv
39
+ /** The composed client entry graph the host injects as `window.__DSH_BOOT__`. */
40
+ interface WebBootGraph {
41
+ /** Consistency anchor over the whole graph (content + bundle hashes). */
42
+ rev: string
43
+ /** Composed entries; order carries no semantics (activation order is fiber inject waiting). */
44
+ entries: WebBootEntry[]
45
+ }
46
+ ```
47
+
48
+ 每一行的 `rev` 是该 bundle 的内容哈希,并作为使缓存失效的查询参数附在 URL 上;图的 `rev` 对组合后的各行做哈希,因此任何一行的变化都会改变它。`immediately` 标记第一阶段预取档位(在模块面启动期间 fetch 并执行,只做登记);惰性行在首次 import 时才拉取。
49
+
50
+ ## 扫描
51
+
52
+ 包加入这张表的方式,是在自己的 package.json 中声明 `dsh.client`(`platform: 'web'`、可选的 `inject` 边、可选的 `immediately`),并在 `exports["./client"]` 导出构建好的 bundle。包解析锚定在配置树的 `ctx.baseUrl`——即 cordis.yml 所在目录,该目录的包把每个被组合的插件声明为依赖——这一锚点未设置时,构造即抛错。
53
+
54
+ 扫描是单包增量的;不存在全量重扫代码路径。fiber 构造或 dispose(资源释放)时的每次 cordis `internal/plugin` 发射都把该 fiber 的 entry 名标脏,一次微任务 flush 把每个脏名与实时 loader entry 对账。激活趟以全部当前 entry 灌入同一个脏集合并同步 flush,因此初扫与稳态共享一条实现——但失败姿态相反。激活时,已加载 entry 中的畸形声明或缺失 bundle 会聚合为一个大声的 `AggregateError`,列出每个损坏的包:该 fiber 进入 FAILED,由启动的大声失败 sweep 上报。稳态下,损坏的包只记录一条警告,且不得殃及其他包。
55
+
56
+ 包元数据——包括「非 client 包」这一否定结论——按名缓存且永不过期:插件集合的变更在重启后生效。fiber 重启原样复用其行与 rev;bundle 内容变更只经 `rebuilt()` 到达图。
57
+
58
+ ## bundle 路由与 index 转换
59
+
60
+ `GET`/`HEAD /plugins/<id>/client.js` 以 `no-cache` 从磁盘提供已注册的 bundle(锚定一致性的是 rev 查询参数,而非 HTTP 缓存);其他方法返回 405。未知 id——或已注册、但 bundle 因尚未构建而不可读的行——回应一个大声的 404,而不是让载体的 SPA 回退把 HTML 当作 JavaScript 发出。index 转换在每次 index 渲染时注入当前图,因此刷新页面总是针对实时组合启动。
61
+
62
+ ## 服务
63
+
64
+ `ClientModuleRegistry`(`ctx.clientModules`,定义于 [`packages/client/modules/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/modules/src/index.ts))暴露读取面与重建面;签名见生成的[服务目录](#ctxclientmodules--clientmoduleregistry)。`graph()` 返回当前组合出的图(两次变更之间是同一个稳定对象),`clientPath(id)` 返回该 bundle 的绝对路径。`rebuilt(id)` 是 bundle 内容到达图的唯一入口:它对文件重新哈希,只有 rev 真正变化才会重新组合图并发出通知。`onRebuilt` 按发生变化的 bundle 逐个触发并携带新 rev;`onGraphChanged` 在任何一次重新组合了图的 flush 之后触发(行的增删,或 rebuilt 带来的 rev 变化),并采用拉取模型——监听器自行重读 `graph()`。两条通知路径都会兜住监听器异常,因此一个抛错的订阅者既不能让后续订阅者被跳过,也不能杀死触发这次 flush 的一方。
65
+
66
+ 开发环境下,[dsh-client-hmr](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/hmr/README.md) 是注册表的监视驱动:它的 Node 半从同步取得的基线出发,对图中每一行的 bundle 做 stat 轮询,变化时调用 `rebuilt(id)`,经 `onGraphChanged` 重新同步监视集合,并通过 SSE(Server-Sent Events)把 rev 变化广播给浏览器半。生产环境的图完全不含 HMR(热模块替换)行;模块宿主自身从不监视文件。
67
+
68
+ <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
69
+
70
+ <a id="cordis-surface"></a>
71
+
72
+ ## Cordis API
73
+
74
+ 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).
75
+
76
+ <a id="ctxclientmodules--clientmoduleregistry"></a>
77
+
78
+ ### `ctx.clientModules` — `ClientModuleRegistry`
79
+
80
+ The web plugin table service: incremental `dsh.client` scan + wire composition + bundle route + index tap. Construction runs the activation scan synchronously — a malformed declaration or missing bundle among the already-loaded entries aggregates into one loud throw (FAILED fiber; the boot activation audit reports it).
81
+
82
+ ```ts cordis-catalog
83
+ /**
84
+ * Current composed entry graph (stable object between changes).
85
+ * @returns the graph served as `window.__DSH_BOOT__`.
86
+ */
87
+ graph(): WebBootGraph
88
+
89
+ /**
90
+ * Absolute path of an entry's client bundle.
91
+ * @param id - entry id (package name).
92
+ * @returns the path, or undefined for an unknown id.
93
+ */
94
+ clientPath(id: string): string | undefined
95
+
96
+ /**
97
+ * Re-hash one bundle (the HMR watch's registration hook — the only entry
98
+ * point through which bundle content changes reach the graph).
99
+ * @param id - entry id (package name).
100
+ * @returns the new rev, or undefined for an unknown id.
101
+ */
102
+ rebuilt(id: string): string | undefined
103
+
104
+ /**
105
+ * Subscribe to bundle rebuilds; fires only when the re-hash changed the rev.
106
+ * @param listener - receives the entry id and its new bundle rev.
107
+ * @returns the unsubscriber.
108
+ */
109
+ onRebuilt(listener: (id: string, rev: string) => void): () => void
110
+
111
+ /**
112
+ * Fires after any flush that recomposed the graph (row added/removed, or a
113
+ * rebuilt rev change). Pull model: listeners re-read {@link graph}.
114
+ * @param listener - notified with no payload.
115
+ * @returns the unsubscriber.
116
+ */
117
+ onGraphChanged(listener: () => void): () => void
118
+ ```
119
+
120
+ Source: [`packages/client/modules/src/index.ts:184`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/modules/src/index.ts)
121
+ <!-- END GENERATED cordis-surface -->
@@ -0,0 +1,194 @@
1
+ ---
2
+ editSource: "docs/subsystems/code-runtime.zh.md"
3
+ outline: [2,3]
4
+ ---
5
+
6
+ # 代码运行时
7
+
8
+ 代码执行 seam 是一个[能力 seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-13-capability-seams.md):其 Service Definition([dsh-code-runtime](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/code-runtime/code-runtime),`ctx.codeRuntime`)使用宿主提供的异步绑定运行一段模型编写的程序,并报告其打印内容与返回值。代码执行是**一项可选能力**,不属于 agent loop(智能体循环)主干,因此其词汇定义在此而非 [core.md](./core.md) 中。各后端的执行基底与源语言不同,这两项均为服务上的只读描述符;worker-thread Service Provider 与工具注册表 Consumer 的约定见 [Code Mode 基础设计](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-15-code-mode.md) 和[类型化返回约定](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-20-code-mode-typed-tool-returns.md)。
9
+
10
+ 源码:[`packages/code-runtime/code-runtime/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/code-runtime/code-runtime/src/types.ts)
11
+
12
+ ## 运行:请求进,结果出
13
+
14
+ `CodeRunRequest` 携带**运行时要处理的一切内容**。按照「包边界处显式优于隐式」的规则,默认值(时间预算、输出上限)来自实现的已校验配置,绝不是 `run()` 内部隐藏的 `??`:
15
+
16
+ ```ts type-equiv
17
+ /**
18
+ * One run: the program source plus everything the runtime acts on. Per the
19
+ * explicit-over-implicit convention, defaulting (time budgets, output caps)
20
+ * is the implementation's validated config — a request carries no optional
21
+ * tuning knobs for a hidden `??` to fill in.
22
+ */
23
+ interface CodeRunRequest {
24
+ /**
25
+ * The program source, in the runtime's {@link ../index.ts | language}. It
26
+ * runs as the body of an async function: top-level `await` and `return`
27
+ * are available, and the completion value becomes
28
+ * {@link CodeRunResult.value}.
29
+ */
30
+ program: string
31
+ /** Host functions exposed to the program, one global object per namespace. */
32
+ bindings: CodeBindingNamespace[]
33
+ /**
34
+ * Abort the run: the runtime stops the program (hard, even mid-loop) and
35
+ * resolves with a {@link CodeRunFailure} of kind `'abort'`. In-flight
36
+ * binding calls are the CALLER's to settle — the runtime only stops asking.
37
+ */
38
+ signal?: AbortSignal
39
+ }
40
+ ```
41
+
42
+ 结果将错误报告为一个**字段**,而不是让 `run()` 返回被拒绝的 Promise。报告程序失败是调用方的职责,不走异常路径(与 `ShellExecutor.run` 失败时仍正常完成的约定一致):
43
+
44
+ ```ts type-equiv
45
+ /**
46
+ * The outcome of one run. An error is a FIELD on a resolved result, never a
47
+ * rejection of `run()` — reporting a failed program is the caller's job, not
48
+ * an exception path.
49
+ */
50
+ interface CodeRunResult {
51
+ /**
52
+ * The program's completion value (its top-level `return`), when it ran to
53
+ * completion and the value crossed the runtime's lossless-JSON boundary.
54
+ * Invalid or over-limit completions fail the run instead of substituting a
55
+ * rendered string; a failed or value-less run leaves this absent.
56
+ */
57
+ value?: CodeJsonValue
58
+ /** Text the program emitted, in order, bounded only as part of the outer result. */
59
+ logs: string[]
60
+ /** Present iff the run failed; see {@link CodeRunFailure} for the taxonomy. */
61
+ error?: CodeRunFailure
62
+ }
63
+ ```
64
+
65
+ ## 绑定:宿主函数作为程序全局变量
66
+
67
+ 每个 `CodeBindingNamespace` 在程序内成为一个由异步可调用函数组成的全局对象(Code Mode Consumer 传入一个:`tools`)。参数与返回值必须是无损 JSON,且跨越边界时不受 seam 层字节上限约束;运行时可以通过结构化克隆桥接它们。命名空间可以声明程序可见的错误类,而无需让运行时知道 Consumer 的名称:运行时会注入真实构造函数,并将被拒绝的调用转为该类的实例。运行时也将绑定名视为不可信输入(`__proto__` 是普通自有属性,绝不会发生原型碰撞):
68
+
69
+ ```ts type-equiv
70
+ /**
71
+ * Program-visible typed rejection for one binding namespace. The runtime
72
+ * injects a real error constructor under `name`; rejected member calls become
73
+ * its instances and expose the exact member name through
74
+ * `memberNameProperty`. Both strings are runtime data rather than knowledge
75
+ * of a particular consumer such as Code Mode.
76
+ */
77
+ interface CodeBindingErrorClass {
78
+ /** Constructor global and resulting `Error.name`; same portable identifier rule as {@link CodeBindingNamespace.global}. */
79
+ name: string
80
+ /**
81
+ * Non-empty own property for the member name. The portable exclusion set is
82
+ * `RESERVED_ERROR_MEMBERS` plus dunder-form names (`__x__`, non-empty
83
+ * middle), enforced identically by every backend; any other name —
84
+ * identifiers or not — is accepted everywhere.
85
+ */
86
+ memberNameProperty: string
87
+ }
88
+ ```
89
+
90
+ ```ts type-equiv
91
+ /**
92
+ * A named group of {@link CodeBindingFunction}s the runtime exposes to the
93
+ * program as one global object (e.g. `tools`). Function names are arbitrary
94
+ * strings — a runtime must treat names like `__proto__` or `constructor` as
95
+ * ordinary own properties (null-prototype construction), never as prototype
96
+ * collisions.
97
+ */
98
+ interface CodeBindingNamespace {
99
+ /**
100
+ * The global identifier the program sees. Must match the LANGUAGE-PORTABLE
101
+ * identifier subset `[A-Za-z_][A-Za-z0-9_]*` and no language's reserved
102
+ * words, so the same namespace list works against every backend regardless
103
+ * of `language` — a JS-only spelling like `$tools` is rejected by design,
104
+ * not just by the Python backend. Names that satisfy the identifier rule but
105
+ * name a backend-owned slot (`RESERVED_BINDING_GLOBALS`, e.g. `console`,
106
+ * `__dsh_main__`) are also refused everywhere; see its declaration for the
107
+ * exact set and why each entry is reserved.
108
+ */
109
+ global: string
110
+ /** The callable members, keyed by the exact name the program calls. */
111
+ functions: Record<string, CodeBindingFunction>
112
+ /** Optional program-visible typed rejection contract for this namespace. */
113
+ errorClass?: CodeBindingErrorClass
114
+ }
115
+ ```
116
+
117
+ ```ts type-equiv
118
+ /** A lossless JSON value transferable through the dependency-light Service Definition. */
119
+ type CodeJsonValue = null | boolean | number | string | CodeJsonValue[] | { [key: string]: CodeJsonValue }
120
+ ```
121
+
122
+ ```ts type-equiv
123
+ /**
124
+ * One host-side function exposed to the program as an async callable. The
125
+ * runtime bridges calls to it (possibly across a serialization boundary), so
126
+ * `args` and the resolution value MUST be lossless JSON. A runtime rejects a
127
+ * lossy or non-cloneable value with a descriptive error rather than corrupting
128
+ * the run. No seam-level byte cap applies to a binding resolution. A rejection
129
+ * of this function surfaces inside the program as a rejection of the
130
+ * corresponding call.
131
+ */
132
+ type CodeBindingFunction = (args: unknown) => Promise<CodeJsonValue>
133
+ ```
134
+
135
+ ## 捕获的输出与失败分类体系
136
+
137
+ 日志是按发出顺序排列的纯字符串。运行时捕获程序的 console 与流输出,但通道和 console 方法的元数据不属于 seam,因为 Consumer 只渲染文本。实现会对序列化后的外层日志数组,以及完成值或失败消息的组合载荷设置上限;固定的结果封装语法与 Consumer 展示空白不计入这份可变载荷计量。超限会显式失败,而不会在值中插入替代内容。
138
+
139
+ 失败类型是**正交的结果,独立报告**(见 [defensive-patterns](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/defensive-patterns.md)):预算耗尽不是异常,中止不是超时,基底崩溃(如 OOM)也不是二者中的任何一个:
140
+
141
+ ```ts type-equiv
142
+ /**
143
+ * Why a run failed. The kinds are orthogonal outcomes reported independently
144
+ * (per docs/defensive-patterns.md): a budget expiry is not an exception, an
145
+ * abort is not a timeout, and a substrate death is neither.
146
+ *
147
+ * - `'exception'` — the program threw or failed to parse/transform.
148
+ * - `'timeout'` — an implementation-owned budget expired; the message says which.
149
+ * - `'abort'` — {@link CodeRunRequest.signal} fired.
150
+ * - `'worker-exit'` — the execution substrate died without settling (e.g. OOM).
151
+ * - `'invalid-output'` — the completion value was not lossless JSON.
152
+ * - `'output-limit'` — the serialized outer logs/value/diagnostic exceeded the configured cap.
153
+ */
154
+ interface CodeRunFailure {
155
+ /** The failure class (see the interface doc for each kind's meaning). */
156
+ kind: 'exception' | 'timeout' | 'abort' | 'worker-exit' | 'invalid-output' | 'output-limit'
157
+ /** Human-readable detail, suitable for feeding back to a model to self-correct. */
158
+ message: string
159
+ }
160
+ ```
161
+
162
+ ## 服务
163
+
164
+ `CodeRuntime`(`ctx.codeRuntime`,抽象服务,定义于 [`packages/code-runtime/code-runtime/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/code-runtime/code-runtime/src/index.ts))由 `run(request)` 加两个只读描述符组成:`language`(程序必须使用的语言,已知值为 `'typescript'` 与 `'python'`,即 `dsh-tools` 能呈现的那些,其中只有 `'typescript'` 有已发布的后端;生成语言相关展示的 Consumer 据此切换,遇到无法展示的语言时应显式报错)和 `isolation`(执行基底,`'worker-thread'`、`'process'`、`'container'`;仅为诊断标签,**不构成安全承诺**)。实现必须保证各次运行彼此隔离(无跨运行状态),并在 dispose(资源释放)时等待系统完全停稳:teardown 要等到所有进行中的运行均已终止并结算后才完成。
165
+
166
+ <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
167
+
168
+ <a id="cordis-surface"></a>
169
+
170
+ ## Cordis API
171
+
172
+ 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
+
174
+ <a id="ctxcoderuntime--coderuntime-abstract-seam"></a>
175
+
176
+ ### `ctx.codeRuntime` — `CodeRuntime` (abstract seam)
177
+
178
+ Registers one `ctx.codeRuntime` implementation. Program, budget, abort, and substrate failures resolve in CodeRunResult; only Service Definition contract misuse rejects. Implementations bridge structured-cloneable bindings, materialize each declared namespace rejection class, treat programs as hostile peers, isolate runs from one another, and terminate and await in-flight runs during disposal.
179
+
180
+ ```ts cordis-catalog
181
+ /**
182
+ * Execute one program against the request's bindings and capture what it
183
+ * emitted. See the class doc for the resolution contract (error is a result
184
+ * field; rejection means Service Definition contract misuse only).
185
+ * @param request - the program, its bindings, and the abort signal; the
186
+ * request carries everything the runtime acts on, with no hidden defaults.
187
+ * @returns the run's outcome: completion value (when transferable), the
188
+ * ordered log capture, and the failure (if any).
189
+ */
190
+ abstract run(request: CodeRunRequest): Promise<CodeRunResult>
191
+ ```
192
+
193
+ Source: [`packages/code-runtime/code-runtime/src/index.ts:102`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/code-runtime/code-runtime/src/index.ts)
194
+ <!-- END GENERATED cordis-surface -->