dsh-plugin-dev-kb 1.0.8 → 1.1.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 (188) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.en.md +6 -6
  3. package/README.md +6 -6
  4. package/kb/INDEX.md +21 -5
  5. package/kb/README.md +11 -10
  6. package/kb/extra/AGENTS.md +4 -4
  7. package/kb/extra/cookbook/adding-a-remote-api.md +197 -0
  8. package/kb/extra/cookbook/adding-a-remote-api.zh.md +197 -0
  9. package/kb/extra/cookbook/adding-a-vendored-package.md +2 -2
  10. package/kb/extra/cookbook/adding-a-vendored-package.zh.md +2 -2
  11. package/kb/extra/deepseek-llm-api-wire-extensions.md +163 -0
  12. package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +163 -0
  13. package/kb/extra/development.md +8 -14
  14. package/kb/extra/development.zh.md +8 -14
  15. package/kb/extra/event-producer-consumer.md +55 -48
  16. package/kb/extra/event-producer-consumer.zh.md +58 -51
  17. package/kb/extra/glossary.md +1 -1
  18. package/kb/extra/glossary.zh.md +1 -1
  19. package/kb/extra/graph-atlas.md +0 -2
  20. package/kb/extra/graph-atlas.zh.md +0 -2
  21. package/kb/extra/i18n/README.md +4 -4
  22. package/kb/extra/i18n/README.zh.md +4 -4
  23. package/kb/extra/i18n/style-samples.md +2 -2
  24. package/kb/extra/module-graph.md +646 -926
  25. package/kb/extra/module-graph.zh.md +648 -928
  26. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.md +2 -2
  27. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +2 -2
  28. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.md +2 -2
  29. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +2 -2
  30. package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.md +2 -2
  31. package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.zh.md +2 -2
  32. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +1 -1
  33. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +1 -1
  34. package/kb/extra/rescope.md +2 -2
  35. package/kb/extra/rescope.zh.md +2 -2
  36. package/kb/extra/subsystems/agent-team.md +28 -4
  37. package/kb/extra/subsystems/agent-team.zh.md +28 -4
  38. package/kb/extra/subsystems/attachment.md +168 -7
  39. package/kb/extra/subsystems/attachment.zh.md +168 -7
  40. package/kb/extra/subsystems/extensions.md +18 -0
  41. package/kb/extra/subsystems/extensions.zh.md +18 -0
  42. package/kb/extra/subsystems/feedback.md +4 -4
  43. package/kb/extra/subsystems/feedback.zh.md +4 -4
  44. package/kb/extra/subsystems/todo.md +32 -0
  45. package/kb/extra/subsystems/todo.zh.md +32 -0
  46. package/kb/extra/subsystems/webhook.md +70 -0
  47. package/kb/extra/subsystems/webhook.zh.md +70 -0
  48. package/kb/extra/testing.md +15 -10
  49. package/kb/extra/testing.zh.md +13 -8
  50. package/kb/extra/web-styling.md +4 -0
  51. package/kb/extra/web-styling.zh.md +4 -0
  52. package/kb/meta/search-index.json +309 -177
  53. package/kb/meta/site-pages.txt +183 -167
  54. package/kb/meta/source.json +5 -5
  55. package/kb/meta/topics.md +14 -6
  56. package/kb/site/develop/basic/publish.md +2 -2
  57. package/kb/site/develop/basic/tool.md +1 -1
  58. package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +5 -4
  59. package/kb/site/develop/framework/events.md +1 -1
  60. package/kb/site/develop/practice/dynamic-cordis.md +17 -0
  61. package/kb/site/develop/practice/llm-adapter.md +4 -3
  62. package/kb/site/en/develop/basic/publish.md +2 -2
  63. package/kb/site/en/develop/basic/tool.md +1 -1
  64. package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +5 -4
  65. package/kb/site/en/develop/framework/events.md +1 -1
  66. package/kb/site/en/develop/practice/dynamic-cordis.md +17 -0
  67. package/kb/site/en/develop/practice/llm-adapter.md +4 -3
  68. package/kb/site/en/guide/github-review.md +104 -0
  69. package/kb/site/en/guide/mcp-memory.md +103 -0
  70. package/kb/site/en/guide/network-proxy.md +87 -0
  71. package/kb/site/en/guide/providers.md +70 -17
  72. package/kb/site/en/guide/python-sdk.md +80 -34
  73. package/kb/site/en/guide/schedule.md +23 -0
  74. package/kb/site/en/reference/agent-lifecycle.md +6 -4
  75. package/kb/{extra → site/en/reference}/api-gateway.md +12 -10
  76. package/kb/site/en/reference/capability-seams.md +128 -73
  77. package/kb/site/en/reference/config-catalog.md +481 -360
  78. package/kb/site/en/reference/cookbook/adding-a-package.md +3 -4
  79. package/kb/site/en/reference/cookbook/adding-a-settings-card.md +12 -10
  80. package/kb/site/en/reference/cookbook/adding-a-tool.md +11 -4
  81. package/kb/site/en/reference/cookbook/adding-an-llm-adapter.md +1 -1
  82. package/kb/site/en/reference/cookbook/extension-cookbook.md +20 -17
  83. package/kb/site/en/reference/cordis-api/inherited.md +1 -1
  84. package/kb/site/en/reference/cordis-primer.md +2 -1
  85. package/kb/site/en/reference/index.md +30 -11
  86. package/kb/site/en/reference/persistence-catalog.md +148 -80
  87. package/kb/site/en/reference/subsystems/approval.md +10 -10
  88. package/kb/site/en/reference/subsystems/client-modules.md +58 -16
  89. package/kb/site/en/reference/subsystems/code-runtime.md +10 -6
  90. package/kb/site/en/reference/subsystems/commands.md +25 -16
  91. package/kb/site/en/reference/subsystems/compaction.md +11 -11
  92. package/kb/site/en/reference/{cookbook/adding-a-conversation-node.md → subsystems/conversation.md} +50 -24
  93. package/kb/site/en/reference/subsystems/core.md +156 -17
  94. package/kb/site/en/reference/subsystems/credentials.md +44 -3
  95. package/kb/site/en/reference/subsystems/filesystem.md +12 -2
  96. package/kb/site/en/reference/subsystems/goal.md +1 -1
  97. package/kb/site/en/reference/subsystems/index.md +7 -2
  98. package/kb/site/en/reference/subsystems/jobs.md +1 -1
  99. package/kb/site/en/reference/subsystems/llm-streaming.md +154 -12
  100. package/kb/site/en/reference/subsystems/permission-presets.md +6 -6
  101. package/kb/site/en/reference/subsystems/persistence.md +185 -175
  102. package/kb/site/en/reference/subsystems/plan.md +2 -2
  103. package/kb/site/en/reference/subsystems/sandbox.md +2 -0
  104. package/kb/site/en/reference/subsystems/schedule.md +9 -3
  105. package/kb/site/en/reference/subsystems/session-projection.md +115 -48
  106. package/kb/site/en/reference/subsystems/session-query.md +28 -14
  107. package/kb/site/en/reference/subsystems/session-reference.md +53 -8
  108. package/kb/site/en/reference/subsystems/session-telemetry.md +8 -8
  109. package/kb/site/en/reference/subsystems/session-title.md +6 -6
  110. package/kb/site/en/reference/subsystems/session.md +401 -99
  111. package/kb/site/en/reference/subsystems/settings.md +101 -6
  112. package/kb/site/en/reference/subsystems/skills.md +23 -0
  113. package/kb/site/en/reference/subsystems/slots.md +178 -0
  114. package/kb/site/en/reference/subsystems/spill.md +2 -2
  115. package/kb/site/en/reference/subsystems/storage.md +34 -3
  116. package/kb/site/en/reference/subsystems/subagent.md +122 -109
  117. package/kb/site/en/reference/subsystems/system-prompt.md +17 -4
  118. package/kb/site/en/reference/subsystems/token-meter.md +27 -12
  119. package/kb/site/en/reference/subsystems/tools.md +39 -39
  120. package/kb/site/en/reference/subsystems/typert.md +62 -55
  121. package/kb/site/en/reference/subsystems/user-questions.md +33 -33
  122. package/kb/site/en/reference/subsystems/web-client.md +98 -0
  123. package/kb/site/en/reference/subsystems/web-server.md +11 -5
  124. package/kb/site/en/reference/subsystems/web.md +7 -1
  125. package/kb/site/en/reference/subsystems/workspace.md +102 -9
  126. package/kb/site/en/reference/tool-catalog.md +86 -82
  127. package/kb/site/en/reference/tool-execution-pipeline.md +1 -1
  128. package/kb/site/guide/github-review.md +104 -0
  129. package/kb/site/guide/mcp-memory.md +103 -0
  130. package/kb/site/guide/network-proxy.md +87 -0
  131. package/kb/site/guide/providers.md +70 -17
  132. package/kb/site/guide/python-sdk.md +87 -41
  133. package/kb/site/guide/schedule.md +23 -0
  134. package/kb/site/reference/agent-lifecycle.md +6 -4
  135. package/kb/{extra/api-gateway.zh.md → site/reference/api-gateway.md} +12 -10
  136. package/kb/site/reference/capability-seams.md +128 -73
  137. package/kb/site/reference/config-catalog.md +481 -360
  138. package/kb/site/reference/cookbook/adding-a-package.md +3 -4
  139. package/kb/site/reference/cookbook/adding-a-settings-card.md +12 -10
  140. package/kb/site/reference/cookbook/adding-a-tool.md +11 -4
  141. package/kb/site/reference/cookbook/adding-an-llm-adapter.md +1 -1
  142. package/kb/site/reference/cookbook/extension-cookbook.md +20 -17
  143. package/kb/site/reference/cordis-api/inherited.md +1 -1
  144. package/kb/site/reference/cordis-primer.md +2 -1
  145. package/kb/site/reference/index.md +30 -11
  146. package/kb/site/reference/persistence-catalog.md +148 -80
  147. package/kb/site/reference/subsystems/approval.md +10 -10
  148. package/kb/site/reference/subsystems/client-modules.md +58 -16
  149. package/kb/site/reference/subsystems/code-runtime.md +10 -6
  150. package/kb/site/reference/subsystems/commands.md +25 -16
  151. package/kb/site/reference/subsystems/compaction.md +11 -11
  152. package/kb/site/reference/{cookbook/adding-a-conversation-node.md → subsystems/conversation.md} +50 -24
  153. package/kb/site/reference/subsystems/core.md +156 -17
  154. package/kb/site/reference/subsystems/credentials.md +44 -3
  155. package/kb/site/reference/subsystems/filesystem.md +12 -2
  156. package/kb/site/reference/subsystems/goal.md +1 -1
  157. package/kb/site/reference/subsystems/index.md +7 -2
  158. package/kb/site/reference/subsystems/jobs.md +1 -1
  159. package/kb/site/reference/subsystems/llm-streaming.md +154 -12
  160. package/kb/site/reference/subsystems/permission-presets.md +5 -5
  161. package/kb/site/reference/subsystems/persistence.md +184 -174
  162. package/kb/site/reference/subsystems/plan.md +2 -2
  163. package/kb/site/reference/subsystems/schedule.md +9 -3
  164. package/kb/site/reference/subsystems/session-projection.md +115 -48
  165. package/kb/site/reference/subsystems/session-query.md +28 -14
  166. package/kb/site/reference/subsystems/session-reference.md +53 -8
  167. package/kb/site/reference/subsystems/session-telemetry.md +8 -8
  168. package/kb/site/reference/subsystems/session-title.md +6 -6
  169. package/kb/site/reference/subsystems/session.md +401 -99
  170. package/kb/site/reference/subsystems/settings.md +101 -6
  171. package/kb/site/reference/subsystems/skills.md +23 -0
  172. package/kb/site/reference/subsystems/slots.md +178 -0
  173. package/kb/site/reference/subsystems/spill.md +2 -2
  174. package/kb/site/reference/subsystems/storage.md +34 -3
  175. package/kb/site/reference/subsystems/subagent.md +122 -109
  176. package/kb/site/reference/subsystems/system-prompt.md +17 -4
  177. package/kb/site/reference/subsystems/token-meter.md +27 -12
  178. package/kb/site/reference/subsystems/tools.md +39 -39
  179. package/kb/site/reference/subsystems/typert.md +62 -55
  180. package/kb/site/reference/subsystems/user-questions.md +33 -33
  181. package/kb/site/reference/subsystems/web-client.md +98 -0
  182. package/kb/site/reference/subsystems/web-server.md +11 -5
  183. package/kb/site/reference/subsystems/web.md +7 -1
  184. package/kb/site/reference/subsystems/workspace.md +102 -9
  185. package/kb/site/reference/tool-catalog.md +85 -81
  186. package/kb/site/reference/tool-execution-pipeline.md +1 -1
  187. package/package.json +2 -2
  188. package/skills/dsh-plugin-dev-kb.md +8 -6
@@ -7,7 +7,7 @@ outline: [2,3]
7
7
 
8
8
  The subagent seam lets an agent delegate work to a child agent. Like [bash](./shell.md), it is **one optional capability**, not part of the agent loop, so its types live here rather than in [core.md](./core.md). It differs from the other capability seams because **multiple provider implementations coexist** in one context, registered by name (`ctx.subagents`), while bash allows only one executor. Its registry follows the [LLM adapter registry](./llm-streaming.md), not the single-service bash executor.
9
9
 
10
- Service Definition: [dsh-subagent](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/subagent) (`ctx.subagents` + the vocabulary below). Service Providers are sibling packages (`dsh-subagent-spawn-in-process`, `-fork`, `-acp`, `-codex`, `-claude-code`, `-dsh-sdk`); the model-facing Consumers are [dsh-tool-subagent](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent) (per-provider delegation), [dsh-tool-subagent-control](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-control) (the optional global `send_message`, `interrupt_agent`, and `list_agents` controls), and [dsh-tool-subagent-report](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-report) (the optional child-scoped `report` return channel). The same `ctx.subagents` service owns continuable-child orchestration through an internal activation manager and read-only child and descendant discovery straight from the session store and optional session persistence. Product-provider rationale lives in [the Codex and Claude Code Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.md); common-seam rationale lives in [the subagent Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.md), [the continuable subagents Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.md), [the report-tool Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-30-continuable-subagent-report-tool.md), [the durable catalog Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-22-durable-subagent-catalog-and-list-agents.md), [the list-identity-projection Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-06-subagent-list-identity-projection.md), and [the merged-service Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/simplification/2026-07-26-merge-subagent-control-service.md).
10
+ Service Definition: [dsh-subagent](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/subagent) (`ctx.subagents` + the vocabulary below). Service Providers are sibling packages (`dsh-subagent-spawn-in-process`, `dsh-subagent-fork-in-process`, `dsh-subagent-acp`, `dsh-subagent-codex`, `dsh-subagent-claude-code`, `dsh-subagent-dsh-sdk`); the model-facing Consumers are [dsh-tool-subagent](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent) (per-provider delegation) and [dsh-tool-subagent-control](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-control) (the optional global `send_message`, `interrupt_agent`, and `list_agents` controls). The same `ctx.subagents` service owns continuable-child orchestration through an internal activation manager and read-only child and descendant discovery straight from the session store and optional session persistence. Product-provider rationale lives in [the Codex and Claude Code Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.md); common-seam rationale lives in [the subagent Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.md), [the continuable subagents Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.md), [the adjacent-Agent messaging Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-27-adjacent-agent-steer-messaging.md), [the durable catalog Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-22-durable-subagent-catalog-and-list-agents.md), [the list-identity-projection Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-06-subagent-list-identity-projection.md), and [the merged-service Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/simplification/2026-07-26-merge-subagent-control-service.md).
11
11
 
12
12
  Sources: [`packages/subagent/subagent/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/types.ts), [`packages/subagent/subagent/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts), and [`packages/subagent/subagent/src/continuation.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/continuation.ts)
13
13
 
@@ -28,6 +28,7 @@ A provider advertises its **start-time** features on a static descriptor the ser
28
28
  * to `maxDepth`; the other names match.
29
29
  */
30
30
  interface SubagentCapabilities {
31
+ readonly agentOptions: boolean
31
32
  readonly outputSchema: boolean
32
33
  readonly depthLimit: boolean
33
34
  readonly toolFilter: boolean
@@ -37,7 +38,7 @@ interface SubagentCapabilities {
37
38
 
38
39
  ## The one-shot start request
39
40
 
40
- The tool layer builds this request from the model input and its own config; the service validates it against the named provider before `start`. Required `parent` supplies the session cwd, lineage, and delegation depth. Optional output schema, depth, tool filter, and persona require matching capability flags. Unsupported schemas fail at start; in-process backends scope filters and personas to child creation and implement the supported object-rooted schema with a forced capture tool.
41
+ The tool layer builds this request from the model input and its own config; the service validates it against the named provider before `start`. Required `parent` supplies the session cwd, lineage, and delegation depth. Optional Agent provider, model, reasoning-effort, and token overrides, output schema, depth, tool filter, and persona require matching capability flags. In-process backends merge `agentOptions` over the parent Agent's options, scope filters and personas to child creation, and implement the supported object-rooted schema with a forced capture tool. The DSH SDK backend merges the four Agent route fields over its instance defaults and validates them in the child runtime's initialization; ACP, Codex, and Claude Code reject `agentOptions` before starting their transports.
41
42
 
42
43
  ```ts type-equiv
43
44
  /**
@@ -66,6 +67,13 @@ interface SubagentStartRequest {
66
67
  * remaining turn work when it fires afterward.
67
68
  */
68
69
  readonly signal: AbortSignal
70
+ /**
71
+ * Optional host-Agent provider, model, reasoning-effort, and output-token
72
+ * overrides. Requires {@link SubagentCapabilities.agentOptions}; in-process
73
+ * providers merge them over the parent Agent's options when they create the
74
+ * child, while the DSH SDK provider merges them over its instance defaults
75
+ * before initializing the separate child runtime.
76
+ */
69
77
  readonly agentOptions?: AgentOptions
70
78
  /**
71
79
  * Object-rooted JSON Schema within `assertObjectJsonSchema`'s enforced subset. Start rejects
@@ -128,21 +136,21 @@ persisted Session
128
136
 
129
137
  `SubagentRuntime.startContinuable()` reserves the stable child id, snapshots the versioned `subagent/descriptor` payload, asks the named provider for its detached `ContinuableCreateSpec`, creates the child Agent through a private activation-owner scope, establishes any continuable-parent ownership, and submits the initial prompt. It resolves with `{ childId, messageId }` when inbox acceptance yields the message id — without waiting for the turn to start or for the message to enter the Session log. Every failure before that acceptance rejects with neither id, disposing any created handle and rolling back the Activation and parent ownership.
130
138
 
131
- `SubagentRuntime.followup()` is the sole continuation-message operation, and routing depends only on Activation residency:
139
+ `SubagentRuntime.sendMessage()` is the sole model-authored message operation. It accepts the exact live sender plus a target id, permits only a direct parent or direct continuable child, derives sender attribution itself, and routes a direct-child target by Activation residency:
132
140
 
133
- | Activation state | `followup` |
141
+ | Target Activation state | `sendMessage` |
134
142
  |---|---|
135
- | `running` | enqueue in the same Activation |
136
- | `waiting` | wake the same Activation |
137
- | no Activation | cold-resume a new Activation |
143
+ | `running` | steer the nearest step in the same Activation |
144
+ | `waiting` | wake and steer the same Activation |
145
+ | no Activation | cold-resume a new Activation, then steer it |
138
146
 
139
147
  `running` means the Agent has an active admission or turn, or waking inbox work; `waiting` means it is quiescent but still owns at least one child Activation that has not completed disposal; `settled` means quiescent with every owned child disposed, at which point the manager disposes the [`AgentHandle`](./core.md#creation-and-ownership) and removes the Activation. The manager derives these internal conditions from Agent quiescence and the owned-child set rather than maintaining a second execution state machine.
140
148
 
141
- The Agent inbox is the only queue. Every continuation message becomes one `Agent.followup()` FIFO turn, so accepted messages have one observable order and a follow-up cannot redirect a turn already underway. Successful delivery returns the accepted `MessageId`; the existing `agent/inbox/inserted`, `agent/inbox/claimed`, and `agent/inbox/discarded` events remain the message-lifecycle observations, and the continuation layer defines no subagent-specific delivery route.
149
+ The Agent inbox is the only queue. Every Agent message uses `Agent.steer()`: an idle target starts a turn, while a running target claims it at the nearest step boundary. Successful delivery returns the accepted `MessageId`; the existing `agent/inbox/inserted`, `agent/inbox/claimed`, and `agent/inbox/discarded` events remain the message-lifecycle observations, and the continuation layer defines no subagent-specific delivery route.
142
150
 
143
- Follow-up authority comes from an exact live Agent tool context. The authenticated Agent must be the durable child's direct parent recorded in `SessionHeader.parentSession`. `MessageSource` and `senderSessionId` record who supplied an admitted message but grant no authority; the optional model-facing tool uses `CoordinatorMessageSource`.
151
+ Authority comes from the exact live sender. Parent-to-child delivery requires the target's `SessionHeader.parentSession` to name the sender; child-to-parent delivery requires the sender's resident Activation to name the target. Siblings, ancestors beyond one edge, self-targets, stale Agent objects, and one-shot children are rejected. Each accepted message is framed as `Agent <sender-id> sent a message:` and records `AgentMessageSource`; provenance records the sender but grants no authority.
144
152
 
145
- For both operations the caller signal owns lookup, materialization, and admission only until inbox acceptance. Afterwards the manager owns the Activation independently: later caller cancellation neither cancels the accepted turn nor disposes the child, and the seam exposes no steering operation.
153
+ For `startContinuable()` and `sendMessage()`, the caller signal owns lookup, materialization, and admission only until inbox acceptance. Afterwards the manager owns the Activation independently: later caller cancellation neither cancels the accepted turn nor disposes the child. Human browser prompts remain a separate private Queue adapter and therefore still produce distinct FIFO turns.
146
154
 
147
155
  `SubagentRuntime.interrupt(targetSessionId, authority)` is the one public stop: it authorizes synchronously, issues `Agent.cancel(cause, { keepInbox: true })` on the live target, and returns without awaiting quiescence. The Activation, its unclaimed pending inbox work, and published descendants are untouched; work already claimed into the interrupted turn is not requeued. Once the interrupted driver is idle, a waking send resumes the parked FIFO queue. An absent target — unknown, one-shot, or already settled — and a manager-less composition are accepted no-ops. For a live target, a mismatched parent address or caller outside its live ancestry rejects with `UNAUTHORIZED`; stale ancestor objects and self-targeting ancestor requests reject before target lookup.
148
156
 
@@ -162,21 +170,19 @@ Every Activation owns its `AgentHandle` and an `ownedChildren: Set<SessionId>`;
162
170
  Final settlement awaits `ctx.sessions.flush(session)` but ignores its participation boolean because an arbitrary listener cannot prove that a persistence backend stored the state. Rejection is logged without failing the Activation, and the manager still disposes the handle and releases ownership; the persisted child state may then be missing or stale on a later resume. Manager unload invokes an internal manager-wide drain that closes admission and disposes every live forest; `drainContinuableDescendants(parents)` closes admission only below exact live host-owned Agents and disposes their continuable descendants while unrelated forests remain live. Both await already-admitted materializations in their scope, propagate cancellation top-down, release handles child-first, and await every selected branch despite individual failures. Durable child Sessions survive that process-local teardown.
163
171
 
164
172
  ```ts type-equiv
165
- /** Attribution for a model coordinator's follow-up to one of its children. */
166
- interface CoordinatorMessageSource {
167
- readonly kind: 'coordinator'
173
+ /** Durable attribution for one model-authored message between adjacent Agents. */
174
+ interface AgentMessageSource {
175
+ readonly kind: 'agent-message'
168
176
  /** A message another agent addressed to this one (`relay` context form). */
169
177
  readonly form: 'relay'
170
- /** Session id of the agent whose tool call produced the follow-up. */
178
+ /** Session id of the Agent whose tool call produced the message. */
171
179
  readonly senderSessionId: SessionId
172
180
  }
173
181
  ```
174
182
 
175
183
  ```ts type-equiv
176
- /** Options for following up with one continuable child. */
177
- interface SubagentFollowupOptions {
178
- /** Durable attribution retained on the delivered message; it grants no authority. */
179
- readonly source: MessageSource
184
+ /** Options for one model-authored message between adjacent Agents. */
185
+ interface SubagentSendMessageOptions {
180
186
  /** Caller cancellation, owning the operation only until inbox acceptance. */
181
187
  readonly signal: AbortSignal
182
188
  }
@@ -192,33 +198,13 @@ interface ContinuableStart {
192
198
  }
193
199
  ```
194
200
 
195
- An optional continuable-child setup contribution can install scope-local capabilities after base child composition and before Activation publication. The registry is ordered and transactional: a failed or revoked setup rolls back the unpublished Activation, child-scope disposal releases every installation, new registrations affect the next Activation, and registration removal revokes every resident installation immediately.
196
-
197
- `SubagentRuntime.reportFrom()` uses that extension point without adding a second queue or a result-bearing child wrapper. The exact live child Agent authorizes the call; callers cannot name a recipient. The manager derives the only recipient from the child's durable `parentSession`, requires that parent Agent to be live, frames the selected content as one `subagent-report` user message, and returns the message's stable `MessageId`. Quiet delivery uses `Agent.inject()` and does not wake the parent; next-step delivery uses `Agent.steer()`, waking an idle parent or joining a running parent's nearest step boundary. Neither mode concludes the child's turn, and no final answer reports implicitly.
198
-
199
- ```ts type-equiv
200
- /** Durable attribution for a continuable child's explicit parent report. */
201
- interface SubagentReportMessageSource {
202
- readonly kind: 'subagent-report'
203
- /** A message another agent addressed to this one (`relay` context form). */
204
- readonly form: 'relay'
205
- /** Session id of the reporting child. */
206
- readonly senderSessionId: SessionId
207
- }
208
- ```
209
-
210
- ```ts type-equiv
211
- /** Deployment scheduling policy for accepted child reports. */
212
- type SubagentReportDelivery = 'quiet' | 'next-step'
213
- ```
214
-
215
- Reporting is the child's own choice, so the manager keeps a separate account of its own: when a resident Activation settles, it delivers one notice to the child's durable direct parent describing how that epoch ended and carrying its final assistant content. That delivery is unconditional for every child whose id a caller received, happens before the ownership release that would let the parent be judged settled, and reaches a resident parent through the same waking-admission accounting as a report. A parent whose own lineage is already tearing down receives it without a wake, because waking a quiescent Agent starts a turn rather than queueing work. Its provenance is a distinct kind so a transcript never presents a runtime account as something the child wrote.
201
+ When a resident Activation settles, the manager delivers one notice to the child's durable direct parent describing how that epoch ended and carrying its final assistant content. That delivery is unconditional for every child whose id a caller received, happens before the ownership release that would let the parent be judged settled, and reaches a resident parent through the same waking-admission accounting as an Agent message. A parent whose own lineage is already tearing down receives it without a wake, because waking a quiescent Agent starts a turn rather than queueing work. Its provenance is a distinct kind so a transcript never presents a runtime account as something the child wrote.
216
202
 
217
203
  ```ts type-equiv
218
204
  /**
219
205
  * Durable attribution for the runtime's own account of a continuable child
220
206
  * settling. Deliberately a different kind from
221
- * {@link SubagentReportMessageSource}: a report is content the child chose,
207
+ * {@link AgentMessageSource}: an Agent message is content the sender chose,
222
208
  * while this message is the manager stating what became of the child, and a
223
209
  * transcript that merged them would credit the child with words it never wrote.
224
210
  */
@@ -233,17 +219,7 @@ interface SubagentSettledMessageSource {
233
219
  }
234
220
  ```
235
221
 
236
- ```ts type-equiv
237
- /** Options for one continuable child's report to its direct parent. */
238
- interface SubagentReportOptions {
239
- /** Already-resolved parent scheduling policy. */
240
- readonly delivery: SubagentReportDelivery
241
- /** Caller cancellation, owning authorization and admission until acceptance. */
242
- readonly signal: AbortSignal
243
- }
244
- ```
245
-
246
- The provider participates only in preparing the initial creation spec, where `spawn` and `fork` differ. Its returned spec carries only detached provider-specific creation inputs — today the optional parent-history seed — and no Agent, `AgentHandle`, prompt delivery, result, disposal, or resume operation. Cold resume does not dispatch through a provider at all: the manager folds the generic descriptor, calls `ctx.agents.resume()` through the same activation-owner scope, and submits the waiting turn.
222
+ The provider participates only in preparing the initial creation spec, where `spawn` and `fork` differ. Its returned spec carries only detached provider-specific creation inputs — the optional parent-history seed — and no Agent, `AgentHandle`, prompt delivery, result, disposal, or resume operation. Cold resume does not dispatch through a provider at all: the manager folds the generic descriptor, calls `ctx.agents.resume()` through the same activation-owner scope, and submits the waiting turn.
247
223
 
248
224
  ```ts type-equiv
249
225
  /**
@@ -283,13 +259,13 @@ interface ContinuableCreateSpec {
283
259
  }
284
260
  ```
285
261
 
286
- The descriptor (`SubagentDescriptorData` in [descriptor.ts](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/descriptor.ts)) is a mode-discriminated durable identity for every session-backed subagent. Both modes carry the provider name. A `one-shot` descriptor optionally carries a caller-owned display `label`; a `continuable` descriptor requires the delegation `description` as its durable creation label and additionally snapshots resolved child `agentOptions.provider`/`model` and optional `persona`/`toolFilter` for cold resume. It never snapshots the merge-extensible `AgentOptions` object, so an unrelated extension value cannot break continuation and a later composition input is a deliberate version change. It omits `subagentDepth` (cold resume trusts the persisted header's `delegationDepth` as the monotone floor) and `outputSchema` (one run or Activation's result contract, not durable identity).
262
+ The descriptor (`SubagentDescriptorData` in [descriptor.ts](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/descriptor.ts)) is a mode-discriminated durable identity for every session-backed subagent. Both modes carry the provider name. A `one-shot` descriptor optionally carries a caller-owned display `label`; a `continuable` descriptor requires the delegation `description` as its durable creation label and additionally snapshots resolved child `agentOptions.provider`/`model`/`reasoningEffort` and optional `persona`/`toolFilter` for cold resume. It never snapshots the merge-extensible `AgentOptions` object, so an unrelated extension value cannot break continuation and a later composition input is a deliberate version change. It omits `subagentDepth` (cold resume trusts the persisted header's `delegationDepth` as the monotone floor) and `outputSchema` (one run or Activation's result contract, not durable identity).
287
263
 
288
- A local one-shot provider appends the descriptor inside the child's initial turn before its first request. The continuation manager appends the descriptor after any provider-supplied lineage and before the initial prompt is admitted; `header.seedLength` remains the fork-lineage boundary: resume-time descriptor authority reads the child's own suffix, while the list-serving identity projection folds `subagent/descriptor` last-wins so the child's own descriptor overrides a fork-seeded ancestor's. The event is log-only: no `surfaceOp`, never in model history, and retained across compaction by the append-only log. Malformed current-version descriptors are corrupt; unsupported versions cannot be classified by this runtime.
264
+ A local one-shot provider appends the descriptor inside the child's initial turn before its first request. The continuation manager appends the descriptor after any provider-supplied lineage and before the initial prompt is admitted; `Session.inheritedEventCount` remains the fork-lineage boundary: resume-time descriptor authority reads the child's own suffix, while the list-serving identity projection folds `subagent/descriptor` last-wins so the child's own descriptor overrides a fork-seeded ancestor's. A seeded cold list skips a cache hint until an authoritative observation supplies that exact cut. The event is log-only: no `surfaceOp`, never in model history, and retained across compaction by the append-only log. Malformed current-version descriptors are corrupt; unsupported versions cannot be classified by this runtime.
289
265
 
290
266
  ## Durable enumeration: `listChildren()`, `listDescendants()`, and their entries
291
267
 
292
- `SubagentRuntime.listChildren(parentSessionId)` enumerates the parent's direct session-backed subagents from the live-preferred merge of `ctx.sessions.list()` and optional `ctx.sessionPersistence.list()` — no query service, and no Agent is loaded or resumed. Candidates are the direct children whose durable header carries `origin: 'subagent'`; the marker classifies enumeration and coarse generic-route denial but cannot establish a valid descriptor, resumability, or authorization — the projection fold owns identity, and the Activation contract owns resume. Each row's `mode`/`label` is the registered `subagent` projection unit's value, served through a three-rung ladder: the registry's watermark cache for a live child (zero log reads); the optional projection checkpoint cache for a cold one (`cachedSnapshot` — an identity passing the own-suffix seq gate is final, because an own descriptor is immutable once appended); otherwise one `persistence.inspect()` reading folded through the registry (bounded concurrency, recomputed per listing). The cache is a pure optional accelerator: absent, serving the `null` sentinel or missing the key, failing the seq gate, or faulting, it falls silently through to the authoritative refold. The fold is `subagent/descriptor` last-wins with no failure channel: the child's own descriptor overrides a fork-seeded ancestor's, and a malformed or unknown-version payload folds to a serializable `null` sentinel, treated as no value. The result is one `SubagentListEntry[]` in `createdAt`-then-id order: a served identity yields a `child` entry with `mode: 'one-shot' | 'continuable'` and `activity: 'running' | 'inactive'`; continuable entries always carry `label`, while one-shot entries carry it only when the start caller supplied presentation metadata. A settled candidate whose fold served no identity yields a `corrupt` diagnostic — missing, malformed, and unknown-version descriptors deliberately undistinguished (`unsupported` remains in the type but is never produced); a running candidate without an identity is omitted (the creation window before its descriptor lands); a failed cold inspection yields one `unavailable` diagnostic retried on the next listing, so one damaged sibling cannot hide healthy children. `hasChildren` marks a direct descendant with durable subagent origin, read from the same merged material. Activity snapshots only whether the logical record is live in `ctx.sessions`, not outcome or resumability. Absent persistence, enumeration is live-only rather than an error — a cold child cannot be resumed then either. `listChildren()` throws `SubagentError` with code `SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE` when the `ctx.sessionProjections` registry is absent and `SUBAGENT_CONTROL_SESSION_STORE_UNAVAILABLE` when the session store is, both checked before any read so a deployment with zero children still fails deterministically; the list tool requires `ctx.subagents` and `ctx.agents` at plugin load. A service consumer such as a UI can display both modes and choose an unlabeled one-shot fallback, while the model-facing `list_agents` adapter (the separately loadable `/list-agents` plugin of [dsh-tool-subagent-control](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-control)) keeps only continuable entries and refines status through the live Agent registry into its own `running`/`idle`/`ready` vocabulary, whose `ready` names a storage-only child as resumable rather than terminal. Listing does not consult the continuation manager's Activation map, Agent registry, or provider availability; `send_message` remains the authoritative delivery-time operation, and a listed running continuable child may still reject delivery as an ownership conflict. The read-path rationale lives in [the list-identity-projection Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-06-subagent-list-identity-projection.md).
268
+ `SubagentRuntime.listChildren(parentSessionId)` enumerates the parent's direct session-backed subagents from the live-preferred merge of `ctx.sessions` and the session-query engine's `listSessions()` — no Agent is loaded or resumed. Candidates are the direct children whose durable header carries `origin: 'subagent'`; the marker classifies enumeration and coarse generic-route denial but cannot establish a valid descriptor, resumability, or authorization — the projection fold owns identity, and the Activation contract owns resume. Each row's `mode`/`label` is the registered `subagent` projection unit's value, served through a three-rung ladder: the registry's watermark cache for a live child (zero log reads); the optional projection checkpoint cache for a cold one (`cachedSnapshot` — an identity passing the own-suffix seq gate is final, because an own descriptor is immutable once appended); otherwise one `query.observeSession()` cold observation folded through the registry (bounded concurrency, recomputed per listing). The cache is a pure optional accelerator: absent, serving the `null` sentinel or missing the key, failing the seq gate, or faulting, it falls silently through to the authoritative refold. The fold is `subagent/descriptor` last-wins with no failure channel: the child's own descriptor overrides a fork-seeded ancestor's, and a malformed or unknown-version payload folds to a serializable `null` sentinel, treated as no value. The result is one `SubagentListEntry[]` in `createdAt`-then-id order: a served identity yields a `child` entry with `mode: 'one-shot' | 'continuable'` and `activity: 'running' | 'inactive'`; continuable entries always carry `label`, while one-shot entries carry it only when the start caller supplied presentation metadata. A settled candidate whose fold served no identity yields a `corrupt` diagnostic — missing, malformed, and unknown-version descriptors deliberately undistinguished (`unsupported` remains in the type but is never produced); a running candidate without an identity is omitted (the creation window before its descriptor lands); a failed cold inspection yields one `unavailable` diagnostic retried on the next listing, so one damaged sibling cannot hide healthy children. `hasChildren` marks a direct descendant with durable subagent origin, read from the same merged material. Activity snapshots only whether the logical record is live in `ctx.sessions`, not outcome or resumability. Absent persistence, enumeration is live-only rather than an error — a cold child cannot be resumed then either. `listChildren()` throws `SubagentError` with code `SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE` when the `ctx.sessionProjections` registry is absent and `SUBAGENT_CONTROL_SESSION_STORE_UNAVAILABLE` when the session store is, both checked before any read so a deployment with zero children still fails deterministically; the list tool requires `ctx.subagents` and `ctx.agents` at plugin load. A service consumer such as a UI can display both modes and choose an unlabeled one-shot fallback, while the model-facing `list_agents` adapter (the separately loadable `/list-agents` plugin of [dsh-tool-subagent-control](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-control)) keeps only continuable entries and refines status through the live Agent registry into its own `running`/`idle`/`ready` vocabulary, whose `ready` names a storage-only child as resumable rather than terminal. Listing does not consult the continuation manager's Activation map, Agent registry, or provider availability; `send_message` remains the authoritative delivery-time operation, and a listed running continuable child may still reject delivery as an ownership conflict. The read-path rationale lives in [the list-identity-projection Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-06-subagent-list-identity-projection.md).
293
269
 
294
270
  `SubagentRuntime.listDescendants(rootSessionId)` applies the same live-preferred corpus and projection-backed interpretation to the root's complete descendant tree in stable pre-order. Ordinary sessions and one-shot children remain traversal nodes, so continuable descendants below them are discovered; only `origin: 'subagent'` candidates produce rows. Each returned child or diagnostic adds its position from the enumerated durable header, while a cold inspection revalidates that complete lifecycle before serving identity:
295
271
 
@@ -415,7 +391,7 @@ A local one-shot run MUST publish an ordinary child agent/session before `start(
415
391
 
416
392
  ## The provider contract: `SubagentProvider`
417
393
 
418
- Each provider is a named child-agent transport, and multiple providers may coexist. The service validates requested start-time capabilities before `start()`, and rejects a continuable start on a provider without `prepareContinuable`. `inheritsParentContext` describes only conversation seeding (`fork`: true; `spawn` and `acp`: false), allowing consumers to generate accurate model-facing wording without implying inherited tools, services, or authority.
394
+ Each provider is a named child-agent transport, and multiple providers may coexist. The service validates requested start-time capabilities before `start()`, and rejects a continuable start on a provider without `prepareContinuable`. `inheritsParentContext` describes only conversation seeding (`fork`: true; `spawn` and `acp`: false), allowing consumers to generate accurate model-facing wording without implying inherited tools, services, or authority. A provider whose one-shot route has static provider-owned defaults publishes optional immutable `agentRouteDefaults`, allowing a Consumer to merge model/tool overrides against the correct baseline before preflight.
419
395
 
420
396
  ```ts type-equiv
421
397
  /**
@@ -437,6 +413,13 @@ interface SubagentProvider {
437
413
  * It says nothing about tool registration, injected services, or authority inheritance.
438
414
  */
439
415
  readonly inheritsParentContext: boolean
416
+ /**
417
+ * Optional static provider-owned provider/model route for one-shot Agent
418
+ * options. Consumers merge tool/model overrides over these values before
419
+ * preflight; providers whose route derives from the parent omit it. The value
420
+ * is detached immutable data and requires `agentOptions` support.
421
+ */
422
+ readonly agentRouteDefaults?: Readonly<{ provider: string; model: string }>
440
423
  /**
441
424
  * Establish a ONE-SHOT child and return its handle after publication.
442
425
  * The service has already validated that every requested start-time
@@ -485,6 +468,22 @@ The spawn and fork backends create an ordinary one-shot agent through `parent.ct
485
468
 
486
469
  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).
487
470
 
471
+ <a id="ctxsubagentmodelselection--subagentmodelselectionconfig"></a>
472
+
473
+ ### `ctx.subagentModelSelection` — `SubagentModelSelectionConfig`
474
+
475
+ Singleton settings owner read by delegation tools when an Agent is published.
476
+
477
+ ```ts cordis-catalog
478
+ /**
479
+ * Read a detached selection preference for the next eligible Agent publication.
480
+ * @returns the enabled state and exact allowed routes.
481
+ */
482
+ current(): SubagentModelSelectionSettings
483
+ ```
484
+
485
+ Source: [`packages/subagent/tool-subagent/src/model-selection-settings.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/tool-subagent/src/model-selection-settings.ts)
486
+
488
487
  <a id="ctxsubagents--subagentruntime"></a>
489
488
 
490
489
  ### `ctx.subagents` — `SubagentRuntime`
@@ -504,21 +503,20 @@ Named provider registry with one-shot runs, durable discovery, and continuable-c
504
503
  async startContinuable(spec: ContinuableStartSpec): Promise<ContinuableStart>
505
504
 
506
505
  /**
507
- * Deliver one later message to a continuable child as its next FIFO turn. A
508
- * resident child's Agent inbox accepts it directly (waking a `waiting`
509
- * Activation), while an absent one is cold-resumed from its persisted
510
- * Session. The Agent inbox is the only queue, so every accepted message has
511
- * one observable order.
512
- * @param parent - the exact live direct parent authorizing this delivery.
513
- * @param childId - durable child session id.
514
- * @param content - user-role content to deliver.
515
- * @param options - the message source fields and caller cancellation, which stops the
516
- * operation only before inbox acceptance.
506
+ * Steer one model-authored message to the sender's direct parent or direct
507
+ * continuable child. A running target admits it at the nearest step boundary;
508
+ * an idle target starts a turn, and an absent direct child cold-resumes from
509
+ * persistence. The service derives durable sender attribution from the exact
510
+ * live sender. Caller cancellation stops only pre-acceptance work.
511
+ * @param sender - exact live Agent authorizing and originating the message.
512
+ * @param targetId - durable direct-parent or direct-child session id.
513
+ * @param content - model-authored content to deliver.
514
+ * @param options - caller cancellation before inbox acceptance.
517
515
  * @returns the accepted message's inbox id.
518
- * @throws when continuation services are unavailable, parent authority is
519
- * rejected, or the message was not admitted.
516
+ * @throws when continuation services are unavailable, adjacency is rejected,
517
+ * or the message was not admitted.
520
518
  */
521
- async followup( parent: Agent, childId: SessionId, content: ContentBlock[], options: SubagentFollowupOptions, ): Promise<MessageId>
519
+ async sendMessage( sender: Agent, targetId: SessionId, content: ContentBlock[], options: SubagentSendMessageOptions, ): Promise<MessageId>
522
520
 
523
521
  /**
524
522
  * Interrupt one live continuable child's current turn under a human parent
@@ -537,29 +535,6 @@ async followup( parent: Agent, childId: SessionId, content: ContentBlock[], opti
537
535
  */
538
536
  interrupt(targetSessionId: SessionId, authority: SubagentInterruptAuthority): void
539
537
 
540
- /**
541
- * Deliver selected content from one live continuable child to its durable
542
- * direct parent. The child is the authority credential; callers cannot name a
543
- * recipient. Reporting does not conclude the child's turn or Activation.
544
- * @param child - exact live reporting child.
545
- * @param content - selected model-facing content.
546
- * @param options - parent scheduling and pre-acceptance cancellation.
547
- * @returns the stable identity of the parent-accepted message.
548
- * @throws when continuation services are unavailable, sender authorization
549
- * fails, or the direct parent is not live.
550
- */
551
- async reportFrom( child: Agent, content: ContentBlock[], options: SubagentReportOptions, ): Promise<MessageId>
552
-
553
- /**
554
- * Compose one deployment capability into every continuable child's
555
- * unpublished creation context on fresh creation and cold resume. Grants wait
556
- * for the next Activation; removing the contribution revokes every resident
557
- * installation immediately.
558
- * @param contribution - synchronous child-scope installer.
559
- * @returns the exact Cordis effect disposer.
560
- */
561
- registerContinuableSetup(contribution: ContinuableSetupContribution): () => void
562
-
563
538
  /**
564
539
  * Close continuable admission below exact live parent Agents, stop only their
565
540
  * visible descendant Activations synchronously, then await admitted scoped
@@ -586,27 +561,16 @@ async drainContinuableChildren(parent: Agent, childIds: readonly SessionId[]): P
586
561
 
587
562
  /**
588
563
  * Enumerate the parent's direct session-backed subagents without loading or
589
- * resuming an Agent and without any query service: the listing merges the live
590
- * session store with optional session persistence (live-preferred) and
591
- * serves each child's durable mode/label from the registered `subagent`
592
- * projection unit down a three-rung ladder — the registry's watermark
593
- * snapshot for a live child; for a cold one, a durable projection-cache
594
- * row when the optional cache serves an own-suffix identity (its `seq`
595
- * gate proves the value postdates the fork seed, where a child's own
596
- * descriptor is immutable once appended), else one persistence inspection
597
- * folded through the registry. The
598
- * projection fold is the single classification authority; per-child
599
- * diagnostics relay a fold that served no identity or a failed inspection,
600
- * never a list-time descriptor parse. Absent persistence, enumeration is
601
- * live-only (a cold child cannot be resumed then either, so its absence is
602
- * capability absence, not an error). This service consults no Agent
603
- * registrations, Activations, or providers.
564
+ * resuming an Agent. The Session query service supplies one live-preferred
565
+ * corpus and shared point observations; the projection cache supplies
566
+ * immutable descriptor hits without opening cold logs. The registered
567
+ * `subagent` projection remains the sole mode/label classifier.
604
568
  *
605
- * Every persistence read receives `signal`, and the listing rechecks
606
- * cancellation around each of those awaits. Read rejections that settle
569
+ * Every query receives `signal`, and the listing rechecks cancellation
570
+ * around each await. Read rejections that settle
607
571
  * after an abort become a stable `SubagentError` with code `CANCELLED`.
608
572
  * @param parentSessionId - parent session whose direct children are listed.
609
- * @param signal - caller-owned cancellation forwarded to persistence reads
573
+ * @param signal - caller-owned cancellation forwarded to Session queries
610
574
  * and observed around every read await.
611
575
  * @returns children and per-child diagnostics ordered by `createdAt`, then id.
612
576
  * @throws {@link SubagentError} when the projection registry or the session
@@ -631,6 +595,55 @@ listChildren(parentSessionId: SessionId, signal?: AbortSignal): Promise<Subagent
631
595
  */
632
596
  listDescendants(rootSessionId: SessionId, signal?: AbortSignal): Promise<SubagentDescendantListEntry[]>
633
597
 
598
+ /**
599
+ * Remote face of {@link listChildren} for one browser: the durable listing
600
+ * plus live Agent activity and the delivery-time parent availability hint.
601
+ * Parent availability is a hint; {@link prompt} performs the authoritative
602
+ * check. Named apart from the provider-name {@link list}, which owns the
603
+ * member.
604
+ * @param parentSessionId - parent session whose direct children are listed.
605
+ * @param signal - carrier cancellation forwarded to Session queries.
606
+ * @returns the catalog view for that parent.
607
+ * @throws {RemoteError} `gateway/bad-request` for an empty parent id,
608
+ * `gateway/cancelled` for an aborted read, `subagent/projections-unavailable` when
609
+ * the deployment has no projection registry, otherwise `gateway/internal`.
610
+ */
611
+ @Remote('list') async remoteExportList(parentSessionId: SessionId, signal: AbortSignal): Promise<SubagentCatalog>
612
+
613
+ /**
614
+ * Deliver one browser-authored message to a continuable child through the
615
+ * exact live direct parent, retaining the caller-minted request identity and
616
+ * validated browser zone on the accepted message. Success identifies the
617
+ * message the child's FIFO inbox accepted; later execution is independent of
618
+ * this call.
619
+ * Image parts are admitted and persisted through the attachment store
620
+ * before delivery, and the child's model must accept image input.
621
+ * @param request - durable address, minted identity, content, and optional browser zone.
622
+ * @param signal - carrier cancellation, owning the call until inbox acceptance.
623
+ * @returns the accepted message's inbox identity.
624
+ * @throws {RemoteError} `gateway/bad-request`, `subagent/attachment-invalid`,
625
+ * `subagent/invalid-time-zone`, `subagent/parent-unavailable`,
626
+ * `subagent/not-resumable`, `subagent/unauthorized`,
627
+ * `subagent/delivery-unavailable`, `gateway/cancelled`, or `gateway/internal`.
628
+ */
629
+ @Remote('prompt') async prompt(request: SubagentPromptRequest, signal: AbortSignal): Promise<SubagentPromptReceipt>
630
+
631
+ /**
632
+ * Remote face of {@link interrupt} under one durable parent address. No
633
+ * catalog, history, persistence, or parent Agent lookup runs: the core
634
+ * primitive alone authorizes the address against the live Activation, which
635
+ * is what keeps a live child interruptible while its parent Agent is offline.
636
+ * Absent, idle, and already-completed targets are accepted no-ops there.
637
+ * @param childSessionId - durable child session id to interrupt.
638
+ * @param parentSessionId - durable direct parent whose authority is claimed.
639
+ * @param mode - required continuable-address discriminator.
640
+ * @returns acknowledgement that the cancel signal was admitted, not that the target is quiescent.
641
+ * @throws {RemoteError} `gateway/bad-request` for an empty id,
642
+ * `subagent/unauthorized` when the address does not own the live target,
643
+ * otherwise `gateway/internal`.
644
+ */
645
+ @Remote('interruptByParent') interruptByParent( childSessionId: SessionId, parentSessionId: SessionId, mode: 'continuable', ): SubagentInterruptReceipt
646
+
634
647
  /**
635
648
  * Register a provider under its name. Registration is effect-scoped and HMR
636
649
  * safe; removing a provider blocks new starts but does not revoke runs that
@@ -42,7 +42,7 @@ interface ToolProviderResult {
42
42
 
43
43
  ## Prompt sections
44
44
 
45
- `PromptSection` is a readonly same-process registration contract. Its text may be static or resolved from the current assembly context. One effective `complete` section becomes the sole prompt section after cooperative assembly.
45
+ `PromptSection` is a readonly same-process registration contract. Its text may be static or resolved from the current assembly context. Sections sort by ascending order and then code-unit name; repository contributors resolve the service-owned named allocation through `getSectionOrder()`. Runtime-context contributors resolve their independent allocation through `getContextOrder()`. One effective `complete` section becomes the sole prompt section after cooperative assembly.
46
46
 
47
47
  ```ts type-equiv
48
48
  /** One contributed section of the system prompt (registry input). */
@@ -50,9 +50,8 @@ interface PromptSection {
50
50
  /** Unique name — a duplicate registration throws (see {@link SystemPrompt.section}). */
51
51
  readonly name: string
52
52
  /**
53
- * Sections are concatenated in ascending order. Convention: `-100` is the
54
- * harness identity, `0` the deployment persona, tool guidance uses 100–199;
55
- * other negative orders also render before the persona.
53
+ * Sections are concatenated in ascending order. Equal orders use code-unit
54
+ * name order.
56
55
  */
57
56
  readonly order: number
58
57
  /**
@@ -112,6 +111,20 @@ Registry service for the prompt inputs assembled before each model step.
112
111
  */
113
112
  section(section: PromptSection): () => void
114
113
 
114
+ /**
115
+ * Resolve the centrally owned placement of a repository prompt section.
116
+ * @param name - stable section placement name.
117
+ * @returns the section's numeric sort order.
118
+ */
119
+ getSectionOrder(name: PromptSectionOrderName): number
120
+
121
+ /**
122
+ * Resolve the centrally owned placement of a repository runtime context.
123
+ * @param name - stable context placement name.
124
+ * @returns the context's numeric sort order.
125
+ */
126
+ getContextOrder(name: PromptContextOrderName): number
127
+
115
128
  /**
116
129
  * Register ordered dynamic context in the calling context's scope. Scoped
117
130
  * entries shadow global entries with the same name.
@@ -15,21 +15,21 @@ Source: [`packages/llm/token-meter/src/types.ts`](https://github.com/deepseek-ai
15
15
  /** Detached immutable request-pressure and surface snapshot at one consumed log revision. */
16
16
  interface TokenMeasurement {
17
17
  /** Number of durable events consumed; equal to the next unread event seq. */
18
- readonly logRevision: number
18
+ readonly logRevision: SessionLogOffset
19
19
  /** Provider or heuristic anchor used for this measurement. */
20
20
  readonly baseline: TokenMeasurementBaseline
21
21
  /** Signed repricing of current surface content relative to the baseline anchor. */
22
22
  readonly surfaceDeltaTokens: number
23
23
  /** Non-negative current request-and-response pressure. */
24
24
  readonly totalTokens: number
25
- /** Total heuristic tokens across the current surface. */
25
+ /** Total route-priced request tokens across the current surface; equals the sum of the node prices. */
26
26
  readonly surfaceTokens: number
27
27
  /** Current surface nodes in positional head-to-tail order. */
28
28
  readonly nodes: readonly TokenSurfaceNode[]
29
29
  }
30
30
  ```
31
31
 
32
- `baseline.kind === 'usage'` means the latest successful provider call has the same canonical request envelope and its total is no lower than that call's full heuristic anchor. `estimated` means no reusable conservative usage anchor exists, so the service priced the complete envelope and surface with its fixed heuristic. A later successful request replaces the earlier anchor; signed `surfaceDeltaTokens` preserves growth and shrinkage relative to a matching anchor. `totalTokens` remains request-and-response pressure, while `surfaceTokens` is the surface-only heuristic total and equals the sum of the node prices.
32
+ Every measurement resolves the effective envelope's routed provider/model to that route's declared request-image pricing through `ctx.llm`, so image occurrences are priced as the visual tokens plus model-visible text the request actually sends; routes and compositions without declared pricing keep the fixed heuristic. `baseline.kind === 'usage'` means the latest successful provider call has the same canonical request envelope and its total is no lower than that call's full route-priced anchor. `estimated` means no reusable conservative usage anchor exists, so the service priced the complete envelope and surface itself. A later successful request replaces the earlier anchor; signed `surfaceDeltaTokens` preserves growth and shrinkage relative to a matching anchor, repricing both sides under the same route. `totalTokens` remains request-and-response pressure, while `surfaceTokens` is the surface-only route-priced total and equals the sum of the node prices.
33
33
 
34
34
  ## `TokenSurfaceNode`
35
35
 
@@ -37,9 +37,20 @@ interface TokenMeasurement {
37
37
  /** One token-priced node in the current ordered session surface. */
38
38
  interface TokenSurfaceNode {
39
39
  /** Durable sequence number of the surface event. */
40
- readonly seq: number
41
- /** Heuristic tokens for the exact message projected by this node. */
40
+ readonly seq: SessionSeq
41
+ /**
42
+ * Request-pressure tokens for the exact message projected by this node under
43
+ * the measured route: image occurrences carry the route's declared visual
44
+ * price when the routed adapter declares one, and the fixed heuristic
45
+ * otherwise. Trigger, retention, and range selection all read this price.
46
+ */
42
47
  readonly tokens: number
48
+ /**
49
+ * Fixed-heuristic tokens for the same message, independent of any route.
50
+ * The shadow-price protocol prices replacements with this value so the O(1)
51
+ * projection fold stays in agreement with its own appends.
52
+ */
53
+ readonly heuristicTokens: number
43
54
  }
44
55
  ```
45
56
 
@@ -63,14 +74,18 @@ Replay owner for one service-wide estimator and isolated per-session folds.
63
74
  /**
64
75
  * Measure current request pressure and surface through the durable tail.
65
76
  *
66
- * Provider usage is reused only when the latest successful call's canonical
67
- * request envelope matches `requestHeader` and its total is no lower than
68
- * that call's full heuristic anchor; otherwise the complete envelope and
69
- * surface are heuristically repriced.
77
+ * The effective envelope's routed provider/model selects the request-image
78
+ * pricing every node is priced under: a route whose adapter declares image
79
+ * pricing charges each retained image its visual tokens plus its
80
+ * model-visible text, while other routes keep the fixed heuristic. Provider
81
+ * usage is reused only when the latest successful call's canonical request
82
+ * envelope matches `requestHeader` and its total is no lower than that
83
+ * call's full route-priced anchor; otherwise the complete envelope and
84
+ * surface are repriced.
70
85
  *
71
- * `requestHeader` affects request pressure only; surface fields always
72
- * describe the current session surface. Every call clones those positional
73
- * nodes, so measurement is O(surface).
86
+ * `requestHeader` replaces the latest logged envelope for pressure and node
87
+ * pricing; the node set always describes the current session surface. Every
88
+ * call clones those positional nodes, so measurement is O(surface).
74
89
  *
75
90
  * @param session - session to replay through its current durable tail.
76
91
  * @param requestHeader - optional effective request envelope replacing the latest logged header.