@fishwithcat/dsh-subagent 0.2.2-alpha.2 → 0.2.2-alpha.3

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.
@@ -4,7 +4,7 @@
4
4
  * @module @deepseek-ai/dsh-subagent/continuation-messages
5
5
  */
6
6
  import { boundContextSummary, createUserMessage } from '@deepseek-ai/dsh-llm';
7
- /** Build durable attribution for one adjacent-Agent message. */
7
+ /** Build durable attribution for one Agent message. */
8
8
  function agentMessageSource(sender) {
9
9
  return {
10
10
  kind: 'agent-message',
@@ -13,7 +13,7 @@ function agentMessageSource(sender) {
13
13
  };
14
14
  }
15
15
  /**
16
- * Build the model-visible and durable representation of one adjacent-Agent message.
16
+ * Build the model-visible and durable representation of one Agent message.
17
17
  * @param sender - exact live Agent that authored the message.
18
18
  * @param content - model-visible message blocks supplied by the sender.
19
19
  * @returns the durable user-message representation delivered to the recipient.
@@ -28,22 +28,19 @@ export function createAgentMessage(sender, content) {
28
28
  });
29
29
  }
30
30
  /**
31
- * Append adjacent-Agent return guidance to a continuable child's initial task.
32
- * @param parentId - durable parent session id named in the guidance.
31
+ * Append automatic result-delivery guidance to a parent-delivered child's initial task.
33
32
  * @param prompt - initial model-visible task blocks.
34
- * @returns task blocks followed by the continuable return guidance.
33
+ * @returns task blocks followed by the result-delivery guidance.
35
34
  */
36
- export function withContinuableReturnGuidance(parentId, prompt) {
37
- const encodedParentId = JSON.stringify(parentId);
35
+ export function withResultDeliveryGuidance(prompt) {
38
36
  return [
39
37
  ...prompt,
40
38
  {
41
39
  type: 'text',
42
- text: `Your parent agent id is ${encodedParentId}. Before you finish, send your result to that agent with `
43
- + `send_message({ agent_id: ${encodedParentId}, message: "<self-contained result>" }). The parent shares `
44
- + 'your workspace but does not automatically receive your transcript, tool output, or reasoning. Send '
45
- + 'earlier messages as well when a finding changes what the parent should do next; sending a message '
46
- + 'does not end your turn.',
40
+ text: 'Your final answer is delivered automatically if your '
41
+ + 'parent is still online. Include the result and relevant evidence in that answer; the parent does not '
42
+ + 'receive your full transcript, tool output, or reasoning. If your last action is a message to your '
43
+ + 'parent, the completion notice omits your final answer; include the result and relevant evidence in that message.',
47
44
  },
48
45
  ];
49
46
  }
@@ -84,8 +81,8 @@ function settlementSummary(childId, stopReason, continuable) {
84
81
  * @param childId - durable child session id named in the notice.
85
82
  * @param terminal - recorded terminal state for the settled Activation.
86
83
  * @param continuable - whether the child can accept another task.
87
- * @param omitClosingText - replace the closing text with a note that the child's
88
- * last message to the parent already carries it.
84
+ * @param omitClosingText - replace the closing text when the child's last action
85
+ * was a message to its direct parent.
89
86
  * @returns the durable user-message representation delivered to the parent.
90
87
  */
91
88
  export function createSettlementMessage(childId, terminal, continuable = true, omitClosingText = false) {
@@ -111,6 +108,7 @@ export function createSettlementMessage(childId, terminal, continuable = true, o
111
108
  kind: 'subagent-settled',
112
109
  form: 'notice',
113
110
  summary: boundContextSummary(summary),
111
+ stopReason: terminal.stopReason,
114
112
  senderSessionId: childId,
115
113
  },
116
114
  });
@@ -8,6 +8,7 @@ import type { PromptContentPart } from '@deepseek-ai/dsh-attachment/types';
8
8
  import type { Branded } from '@deepseek-ai/dsh-brand';
9
9
  import type { MessageId } from '@deepseek-ai/dsh-llm/brand';
10
10
  import type { SessionId } from '@deepseek-ai/dsh-session/types';
11
+ import type { KnownSubagentCatalogFields } from './projection-types.ts';
11
12
  /**
12
13
  * Client-minted identity of one browser prompt, persisted on the exact accepted
13
14
  * message. It carries the Session Controller's `session-request-id` brand so a
@@ -25,22 +26,7 @@ export type SubagentCatalogRow = {
25
26
  * does not encode a durable outcome or guarantee continuation delivery.
26
27
  */
27
28
  readonly activity: 'running' | 'inactive';
28
- } & ({
29
- /** A terminal one-shot child. */
30
- readonly mode: 'one-shot';
31
- /** Optional durable creation label from the parent catalog. */
32
- readonly label?: string;
33
- } | {
34
- /** An external execution without a local child Session. */
35
- readonly mode: 'external';
36
- /** Optional durable creation label from the parent catalog. */
37
- readonly label?: string;
38
- } | {
39
- /** A resumable conversation. */
40
- readonly mode: 'continuable';
41
- /** Durable creation label from the parent catalog. */
42
- readonly label: string;
43
- });
29
+ } & KnownSubagentCatalogFields;
44
30
  /**
45
31
  * One recursive catalog row. Traversal may also return diagnostics for
46
32
  * unknown catalog modes or unreadable child catalogs.
@@ -72,18 +58,15 @@ export type SubagentAddress = {
72
58
  } | {
73
59
  readonly mode: 'unknown';
74
60
  });
75
- /** One Agent inbox destination, as the prompt request selects it. */
76
- export type SubagentDelivery = SubagentPromptRequest['delivery'];
77
- /** One human message addressed to a continuable direct child. */
61
+ /** One Agent inbox destination for a continuation message. */
62
+ export type SubagentDelivery = 'queue' | 'steer';
63
+ /** One human message addressed to a continuable subagent. */
78
64
  export interface SubagentPromptRequest {
79
65
  /** Identity persisted on the accepted message, minted before the call. */
80
66
  readonly requestId: SubagentPromptRequestId;
81
- readonly parentSessionId: SessionId;
82
67
  readonly childSessionId: SessionId;
83
- /** Required discriminator retained from the browser control address. */
84
- readonly mode: 'continuable';
85
68
  /** Whether this message queues a later turn or targets the nearest step. */
86
- readonly delivery: 'queue' | 'steer';
69
+ readonly delivery: SubagentDelivery;
87
70
  /**
88
71
  * Browser prompt parts delivered as the child's user message. The Host
89
72
  * admits and persists image parts before delivery, so the wire never
@@ -117,15 +100,11 @@ declare module '@deepseek-ai/dsh-typert-protocol' {
117
100
  'subagent/invalid-time-zone': {
118
101
  readonly value: string;
119
102
  };
120
- /** No live Agent carries the addressed parent session. */
121
- 'subagent/parent-unavailable': {
122
- readonly parentSessionId: SessionId;
123
- };
124
103
  /** The addressed child cannot take a continuation. */
125
104
  'subagent/not-resumable': {
126
105
  readonly childSessionId: SessionId;
127
106
  };
128
- /** The claimed parent does not own the addressed child. */
107
+ /** The supplied address or live subagent-tree identity could not be verified. */
129
108
  'subagent/unauthorized': {
130
109
  readonly childSessionId: SessionId;
131
110
  };
@@ -8,18 +8,14 @@ import type { SessionId } from '@deepseek-ai/dsh-session';
8
8
  import { z } from 'zod';
9
9
  declare const CONTROL_ID_SCHEMAS: {
10
10
  readonly 'subagent.prompt': z.ZodObject<{
11
- parentSessionId: z.ZodString;
12
11
  childSessionId: z.ZodString;
13
- mode: z.ZodLiteral<"continuable">;
14
12
  delivery: z.ZodEnum<{
15
13
  queue: "queue";
16
14
  steer: "steer";
17
15
  }>;
18
16
  }, z.core.$strip>;
19
17
  readonly 'subagent.interrupt': z.ZodObject<{
20
- parentSessionId: z.ZodString;
21
18
  childSessionId: z.ZodString;
22
- mode: z.ZodLiteral<"continuable">;
23
19
  }, z.core.$strip>;
24
20
  };
25
21
  /**
@@ -11,15 +11,11 @@ import { SubagentError } from "./error.js";
11
11
  const SESSION_ID_SCHEMA = z.string().min(1);
12
12
  const CONTROL_ID_SCHEMAS = {
13
13
  'subagent.prompt': z.object({
14
- parentSessionId: SESSION_ID_SCHEMA,
15
14
  childSessionId: SESSION_ID_SCHEMA,
16
- mode: z.literal('continuable'),
17
15
  delivery: z.enum(['queue', 'steer']),
18
16
  }),
19
17
  'subagent.interrupt': z.object({
20
- parentSessionId: SESSION_ID_SCHEMA,
21
18
  childSessionId: SESSION_ID_SCHEMA,
22
- mode: z.literal('continuable'),
23
19
  }),
24
20
  };
25
21
  /**
@@ -59,7 +55,7 @@ export function rejectPrompt(error, childSessionId, signal) {
59
55
  case 'NOT_RESUMABLE':
60
56
  throw new RemoteError('subagent/not-resumable', 'subagent cannot be resumed', { childSessionId }, { cause: error });
61
57
  case 'UNAUTHORIZED':
62
- throw new RemoteError('subagent/unauthorized', 'subagent does not belong to this parent', { childSessionId }, { cause: error });
58
+ throw new RemoteError('subagent/unauthorized', 'subagent membership in the active tree could not be verified', { childSessionId }, { cause: error });
63
59
  case 'DRAINING':
64
60
  case 'ACTIVATION_CLOSING':
65
61
  case 'ACTIVATION_LIMIT_REACHED':
@@ -14,7 +14,7 @@
14
14
  * to one activation's result contract rather than durable child composition.
15
15
  * Per-activation knobs such as `maxTokens` are omitted for the same reason as
16
16
  * `outputSchema`: they budget one activation. Cold resume requires the exact
17
- * live parent for authorization but reconstructs child options only from the
17
+ * live subagent tree root for authorization but reconstructs child options only from the
18
18
  * durable descriptor, so it neither restores the prior budget nor inherits
19
19
  * the parent's current one; the resumed route's defaults apply instead.
20
20
  *
@@ -14,7 +14,7 @@
14
14
  * to one activation's result contract rather than durable child composition.
15
15
  * Per-activation knobs such as `maxTokens` are omitted for the same reason as
16
16
  * `outputSchema`: they budget one activation. Cold resume requires the exact
17
- * live parent for authorization but reconstructs child options only from the
17
+ * live subagent tree root for authorization but reconstructs child options only from the
18
18
  * durable descriptor, so it neither restores the prior budget nor inherits
19
19
  * the parent's current one; the resumed route's defaults apply instead.
20
20
  *
@@ -14,7 +14,7 @@
14
14
  * `startActivation` establishes every child under the activation manager, which
15
15
  * owns execution, result delivery, and resource release. Local providers seed
16
16
  * resumable Agents; external providers return a single execution handle.
17
- * `sendMessage` steers between adjacent local Agents without exposing
17
+ * `sendMessage` steers between local Agents in one subagent tree without exposing
18
18
  * whether a child is resident. Discovery combines real child Sessions with
19
19
  * parent-owned records for external executions.
20
20
  * Direct discovery reads parent catalogs; descendants recursively read reachable
@@ -38,10 +38,9 @@ import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
38
38
  import type { SubagentInterruptReceipt, SubagentPromptReceipt, SubagentPromptRequest } from './control-types.ts';
39
39
  import type { SubagentActivation, SubagentActivationSpec, SubagentInterruptAuthority, SubagentProvider, SubagentRunEndInfo, SubagentRunInfo, SubagentSendMessageOptions } from './types.ts';
40
40
  import type { SubagentDescendantListEntry } from './list-children.ts';
41
- import type { SubagentCatalogEntry } from './projection-types.ts';
42
- import { deliverSubagentPrompt } from './internal.ts';
43
41
  import type { DelegatedApprovalPolicy } from './child-agent.ts';
44
42
  export type {} from './catalog.ts';
43
+ export type {} from './projection.ts';
45
44
  export * from './out-of-process.ts';
46
45
  export { AssistantOutputFold, finalAssistantOutput } from './assistant-output.ts';
47
46
  export { SubagentRunId } from './types.ts';
@@ -78,18 +77,18 @@ declare module '@deepseek-ai/cordis' {
78
77
  /**
79
78
  * A provider established a published child. For in-process providers,
80
79
  * `ctx.agents.get(info.id)` resolves during this notification.
81
- * Scope-filtered dispatch keys the carrier by the delegating parent, so a
82
- * parent-scoped listener observes only its own delegations. Paired with
80
+ * Scope-filtered dispatch keys the carrier by the subagent tree root, so a
81
+ * root-scoped listener observes all subagent tree activations. Paired with
83
82
  * `subagent/end`.
84
- * @param info - the provider and published child identity.
83
+ * @param info - provider, child identity, and durable direct creator `parentSessionId`.
85
84
  * @mode emit
86
85
  */
87
86
  'subagent/start'(this: Scoped<SubagentRuntime>, info: SubagentRunInfo): void;
88
87
  /**
89
- * A published child settled. Scope-filtered dispatch uses the same delegating
90
- * parent carrier as `subagent/start`, so the lifecycle pair reaches the
88
+ * A published child settled. Scope-filtered dispatch uses the same subagent tree-root
89
+ * carrier as `subagent/start`, so the lifecycle pair reaches the
91
90
  * same scoped audience.
92
- * @param info - the run identity and terminal outcome.
91
+ * @param info - run identity, durable direct creator `parentSessionId`, and terminal outcome.
93
92
  * @mode emit
94
93
  */
95
94
  'subagent/end'(this: Scoped<SubagentRuntime>, info: SubagentRunEndInfo): void;
@@ -156,43 +155,36 @@ export declare class SubagentRuntime extends TypertRemoteService {
156
155
  */
157
156
  startActivation(spec: SubagentActivationSpec): Promise<SubagentActivation>;
158
157
  /**
159
- * Join progressing descendants without cancelling them. Idle descendants whose
160
- * inboxes require a later wake stay resident and do not delay host completion.
161
- * @param parent - the exact parent whose descendant work is observed.
162
- * @returns whether work was joined; hosts recheck parent idle after true.
158
+ * Resolve the root shared by an Agent and its other agents in its subagent tree.
159
+ * @param caller - exact live Agent whose subagent ancestry selects the tree.
160
+ * @returns the live root; ordinary Session forks lead independent trees.
161
+ * @throws when the caller or its runtime owner is unavailable.
163
162
  */
164
- waitForChildren(parent: Agent): Promise<boolean>;
163
+ rootOf(caller: Agent): Agent;
165
164
  /**
166
- * Steer one model-authored message to the sender's direct parent or direct
167
- * continuable child. A running target admits it at the nearest step boundary;
168
- * an idle target starts a turn, and an absent direct child cold-resumes from
169
- * persistence. The service derives durable sender attribution from the exact
170
- * live sender. Caller cancellation stops only pre-acceptance work.
171
- * @param sender - exact live Agent authorizing and originating the message.
172
- * @param targetId - durable direct-parent or direct-child session id.
165
+ * Join progressing subagent tree work for its root. Idle members with parked input
166
+ * stay resident without delaying host completion. Ordinary members return false.
167
+ * @param root - exact live subagent tree root whose member work is awaited.
168
+ * @returns whether work was joined; hosts recheck root idle after true.
169
+ */
170
+ waitForTreeWork(root: Agent): Promise<boolean>;
171
+ /**
172
+ * Steer one model-authored message to another member of the same subagent tree.
173
+ * A running target receives it at its next step; an idle target starts a turn.
174
+ * A cold target resumes under its runtime subagent tree root without restoring
175
+ * its creation ancestors. Sender identity is rechecked before inbox acceptance; cancellation
176
+ * stops only pre-acceptance work and never retracts an accepted message.
177
+ * @param sender - exact live root or resident continuable Agent originating the message.
178
+ * @param targetId - another root or continuable member's durable Session id.
173
179
  * @param content - model-authored content to deliver.
174
180
  * @param options - caller cancellation before inbox acceptance.
175
181
  * @returns the accepted message's inbox id.
176
- * @throws when continuation services are unavailable, adjacency is rejected,
177
- * or the message was not admitted.
182
+ * @throws when the target is outside the tree, cannot resume, or rejects input.
178
183
  */
179
184
  sendMessage(sender: Agent, targetId: SessionId, content: ContentBlock[], options: SubagentSendMessageOptions): Promise<MessageId>;
180
185
  /**
181
- * Deliver one host-protocol message to a direct continuable child.
182
- * Symbol-keyed so host adapters can preserve their own source descriptors without
183
- * widening the public Service Definition or impersonating an Agent sender.
184
- * @param parent - exact live direct parent authorizing delivery.
185
- * @param childId - durable direct-child session id.
186
- * @param content - host-authored content to deliver.
187
- * @param source - durable host-protocol source descriptor.
188
- * @param signal - caller cancellation before inbox acceptance.
189
- * @param delivery - Queue as a distinct turn or Steer at the nearest step.
190
- * @returns the accepted message's inbox id.
191
- */
192
- private [deliverSubagentPrompt];
193
- /**
194
- * Interrupt one live child's current execution under a human parent
195
- * address or an exact live ancestor Agent. Fire-and-return: the cancel
186
+ * Interrupt one live child's current execution under a trusted user
187
+ * operation or an exact live ancestor Agent. Fire-and-return: the cancel
196
188
  * signal is issued before this returns, but the target may keep running
197
189
  * until it observes the signal. Unclaimed pending inbox work, the Activation,
198
190
  * and published descendants are preserved; claimed work is not requeued.
@@ -201,43 +193,20 @@ export declare class SubagentRuntime extends TypertRemoteService {
201
193
  * is an accepted no-op, as is a manager-less composition, which cannot own a
202
194
  * live Activation.
203
195
  * @param targetSessionId - the durable child session id to interrupt.
204
- * @param authority - the human parent address or exact live ancestor Agent.
196
+ * @param authority - a trusted user operation or exact live ancestor Agent.
205
197
  * @throws {SubagentError} `UNAUTHORIZED` when the authority does not own the
206
198
  * live target.
207
199
  */
208
200
  interrupt(targetSessionId: SessionId, authority: SubagentInterruptAuthority): void;
209
201
  /**
210
- * Close subagent admission below exact live parent Agents, stop only their
211
- * visible descendant Activations synchronously, then await admitted scoped
212
- * materializations and release those forests child-first. The scoped cutoff
213
- * lasts until each exact parent leaves the registry; unrelated parent trees
214
- * remain live.
215
- * @param parents - exact host-owned parent Agents entering teardown.
216
- * @returns once every retained descendant activation released its execution handle.
202
+ * Close admission and stop all instances in the selected subagent trees, then await
203
+ * pending startup and cleanup. Ordinary members are ignored. The cutoff lasts
204
+ * until each exact root leaves the registry; unrelated subagent trees remain live.
205
+ * @param parents - exact live subagent tree roots entering teardown.
206
+ * @returns once all admitted startup and member cleanup have settled.
217
207
  * @throws an aggregate error after all branches settle when any failed.
218
208
  */
219
209
  drainDescendants(parents: readonly Agent[]): Promise<void>;
220
- /**
221
- * Release selected resident direct children of one exact live
222
- * parent. Other children of the same parent remain admitted and resident.
223
- * Absent targets and a manager-less composition are accepted no-ops.
224
- * @param parent - exact live direct parent authorizing the selected release.
225
- * @param childIds - durable direct-child ids to release when resident.
226
- * @returns once every selected activation released its execution handle.
227
- * @throws {SubagentError} `UNAUTHORIZED` when a resident target belongs to a
228
- * different parent or the supplied parent identity is stale.
229
- */
230
- drainChildren(parent: Agent, childIds: readonly SessionId[]): Promise<void>;
231
- /**
232
- * Read the parent's durable direct-child catalog without loading or resuming an Agent.
233
- * The service owns and releases the live-preferred Session observation.
234
- * @param parentSessionId - parent whose direct children are requested.
235
- * @param signal - cancellation forwarded to the Session query.
236
- * @returns catalog children in parent event order.
237
- * @throws {@link SubagentError} when query or catalog projection is unavailable.
238
- * @throws SessionQueryError when the parent cannot be read or the query is cancelled.
239
- */
240
- listChildren(parentSessionId: SessionId, signal?: AbortSignal): Promise<SubagentCatalogEntry[]>;
241
210
  /**
242
211
  * Recursively list reachable parent catalogs in stable pre-order, preserving
243
212
  * each catalog's event order. Each row carries its catalog parent and depth;
@@ -256,8 +225,8 @@ export declare class SubagentRuntime extends TypertRemoteService {
256
225
  */
257
226
  listDescendants(rootSessionId: SessionId, signal?: AbortSignal): Promise<SubagentDescendantListEntry[]>;
258
227
  /**
259
- * Deliver one browser-authored message to a continuable child through the
260
- * exact live direct parent, retaining the caller-minted request identity and
228
+ * Deliver one browser-authored message to a continuable child through its
229
+ * live subagent tree root, retaining the caller-minted request identity and
261
230
  * validated browser zone on the accepted message. Success identifies the
262
231
  * message the child's inbox accepted; later execution is independent of this
263
232
  * call. Queue delivery targets a later turn; steer delivery targets the
@@ -265,30 +234,26 @@ export declare class SubagentRuntime extends TypertRemoteService {
265
234
  * Image parts are admitted and persisted through the attachment store
266
235
  * before delivery, and the child's model must accept image input.
267
236
  * Cold resume at capacity rejects with `subagent/delivery-unavailable`.
268
- * @param request - durable address, delivery, minted identity, content, and optional browser zone.
237
+ * Access is checked on the target Session before attachment admission or restoration.
238
+ * @param request - target id, delivery, minted identity, content, and optional browser zone.
269
239
  * @param signal - carrier cancellation, owning the call until inbox acceptance.
270
240
  * @returns the accepted message's inbox identity.
271
241
  * @throws {RemoteError} `gateway/bad-request`, `subagent/attachment-invalid`,
272
- * `subagent/invalid-time-zone`, `subagent/parent-unavailable`,
242
+ * `subagent/invalid-time-zone`,
273
243
  * `subagent/not-resumable`, `subagent/unauthorized`,
274
244
  * `subagent/delivery-unavailable`, `gateway/cancelled`, or `gateway/internal`.
275
245
  */
276
246
  prompt(request: SubagentPromptRequest, signal: AbortSignal): Promise<SubagentPromptReceipt>;
277
247
  /**
278
- * Remote face of {@link interrupt} under one durable parent address. No
279
- * catalog, history, persistence, or parent Agent lookup runs: the core
280
- * primitive alone authorizes the address against the live Activation, which
281
- * is what keeps a live child interruptible while its parent Agent is offline.
248
+ * Remote face of {@link interrupt}, authorized on the target Session by the Gateway.
249
+ * No catalog, history, persistence, or parent Agent lookup runs.
282
250
  * Absent, idle, and already-completed targets are accepted no-ops there.
283
251
  * @param childSessionId - durable child session id to interrupt.
284
- * @param parentSessionId - durable direct parent whose authority is claimed.
285
- * @param mode - required continuable-address discriminator.
286
252
  * @returns acknowledgement that the cancel signal was admitted, not that the target is quiescent.
287
253
  * @throws {RemoteError} `gateway/bad-request` for an empty id,
288
- * `subagent/unauthorized` when the address does not own the live target,
289
254
  * otherwise `gateway/internal`.
290
255
  */
291
- interruptByParent(childSessionId: SessionId, parentSessionId: SessionId, mode: 'continuable'): SubagentInterruptReceipt;
256
+ interruptByUser(childSessionId: SessionId): SubagentInterruptReceipt;
292
257
  /**
293
258
  * Register a provider under its name. Registration is effect-scoped and HMR
294
259
  * safe; removing a provider blocks new starts but does not revoke runs that
@@ -304,26 +269,12 @@ export declare class SubagentRuntime extends TypertRemoteService {
304
269
  * @returns the provider, or undefined when absent.
305
270
  */
306
271
  getProvider(name: string): SubagentProvider | undefined;
307
- /**
308
- * List registered provider names in insertion order.
309
- * @returns the registered names.
310
- */
311
- list(): string[];
312
- /**
313
- * Resolve one provider's detached continuable-creation contribution. Method
314
- * presence on the provider IS the capability, so a provider without it is
315
- * rejected before the manager reserves any child resources.
316
- */
317
- private prepareContinuable;
272
+ /** A pending start must use the exact provider whose capabilities were checked. */
273
+ private assertProviderCurrent;
318
274
  /** Look up a provider for dispatch or fail loud. */
319
275
  private expectProvider;
320
276
  /** Resolve the subagent manager or fail loud. */
321
277
  private requireManager;
322
- /**
323
- * Build the lifecycle observer for one continuable Activation's residency
324
- * epoch, so the manager publishes its edges without owning event dispatch.
325
- */
326
- private observeActivation;
327
278
  /** Reject the first requested capability that the provider lacks. */
328
279
  private assertCapabilities;
329
280
  }