refactor(subagent): drop host-user authority and split lifecycle publication
Remove the host-user continuation capability and the public residency query, then separate the seam's public event payloads from its internal lifecycle control interfaces. `followup()` now takes the exact live direct parent `Agent` instead of a `SubagentAuthority` union. No production adapter ever supplied user authority, so the `UserAuthorityGrant` brand token existed only to stop a forged discriminant from bypassing the direct-parent check — deleting the branch retires the token, its mint method, and that attack surface together. Narrowing `parent` from `Agent | undefined` to `Agent` removes three special cases, including the path where a parentless epoch dispatched its lifecycle events unscoped. Scoped-versus-global dispatch is now decided by the event, not by whether a caller happened to have a parent. `activationState()` had no caller; `ActivationState`, `ActivationObserver`, and `ContinuationHost` are package-private. New `src/lifecycle.ts` owns the contained emitter, the one-shot run observer, and the Activation observer, while `SubagentRunInfo`/`SubagentRunEndInfo` move to `src/types.ts` beside the other consumer-facing contracts. Those payloads are public API — dsh-jsonrpc, hooks-claude, and the package invariant all consume them — whereas the observer is a contract between two in-package collaborators, so they no longer share a home merely for both being lifecycle-shaped. The service keeps ownership of the scope carrier: `scopeTarget()` composes the service's own context filter, so a narrowed stand-in would silently change scope filtering. Also drops now-unused dsh-tasks-local and dsh-tool-tasks dev dependencies, and corrects the README claim that a pre-residency failure emits a terminal edge — that path only ever rethrew.
This commit is contained in:
@@ -794,7 +794,7 @@ A ready child settled. Scope-filtered dispatch uses the same delegating parent c
|
||||
|
||||
Types: [Scoped](../core-data-structures/scope.md) · [SubagentService](../core-data-structures/subagent.md)
|
||||
|
||||
Source: [`packages/subagent/subagent/src/index.ts:143`](../../packages/subagent/subagent/src/index.ts)
|
||||
Source: [`packages/subagent/subagent/src/index.ts:136`](../../packages/subagent/subagent/src/index.ts)
|
||||
|
||||
### `subagent/provider-added` — emit
|
||||
|
||||
@@ -811,7 +811,7 @@ A provider became resolvable in the registry.
|
||||
|
||||
Types: [SubagentProvider](../core-data-structures/subagent.md)
|
||||
|
||||
Source: [`packages/subagent/subagent/src/index.ts:117`](../../packages/subagent/subagent/src/index.ts)
|
||||
Source: [`packages/subagent/subagent/src/index.ts:110`](../../packages/subagent/subagent/src/index.ts)
|
||||
|
||||
### `subagent/provider-removed` — emit
|
||||
|
||||
@@ -826,7 +826,7 @@ A provider left the registry. Accepted runs remain holder-owned.
|
||||
'subagent/provider-removed'(name: string): void
|
||||
```
|
||||
|
||||
Source: [`packages/subagent/subagent/src/index.ts:123`](../../packages/subagent/subagent/src/index.ts)
|
||||
Source: [`packages/subagent/subagent/src/index.ts:116`](../../packages/subagent/subagent/src/index.ts)
|
||||
|
||||
### `subagent/start` — emit
|
||||
|
||||
@@ -848,7 +848,7 @@ A provider established a ready child. For in-process providers, `ctx.agents.get(
|
||||
|
||||
Types: [Scoped](../core-data-structures/scope.md) · [SubagentService](../core-data-structures/subagent.md)
|
||||
|
||||
Source: [`packages/subagent/subagent/src/index.ts:134`](../../packages/subagent/subagent/src/index.ts)
|
||||
Source: [`packages/subagent/subagent/src/index.ts:127`](../../packages/subagent/subagent/src/index.ts)
|
||||
|
||||
## `system-prompt/*`
|
||||
|
||||
|
||||
@@ -1967,35 +1967,18 @@ async startContinuable(spec: ContinuableStartSpec): Promise<ContinuableStart>
|
||||
* Deliver one later message to a continuable child as its next FIFO turn. A
|
||||
* resident child's Agent inbox accepts it directly (waking a `waiting`
|
||||
* Activation), while an absent one is cold-resumed from its persisted
|
||||
* Session. The Agent inbox is the only queue, so parent and user messages
|
||||
* share one observable order.
|
||||
* @param authority - trusted parent or user authority for this delivery.
|
||||
* Session. The Agent inbox is the only queue, so every accepted message has
|
||||
* one observable order.
|
||||
* @param parent - the exact live direct parent authorizing this delivery.
|
||||
* @param childId - durable child session id.
|
||||
* @param content - user-role content to deliver.
|
||||
* @param options - durable provenance and caller cancellation, which stops the
|
||||
* operation only before inbox acceptance.
|
||||
* @returns the accepted message's inbox id.
|
||||
* @throws when continuation services are unavailable, authority is rejected,
|
||||
* or the message was not admitted.
|
||||
* @throws when continuation services are unavailable, parent authority is
|
||||
* rejected, or the message was not admitted.
|
||||
*/
|
||||
async followup( authority: SubagentAuthority, childId: SessionId, content: ContentBlock[], options: SubagentFollowupOptions, ): Promise<MessageId>
|
||||
|
||||
/**
|
||||
* Host-user authority for continuable operations, which may continue any
|
||||
* durable child without its parent. A composition passes this only to a
|
||||
* trusted host adapter carrying real human interaction; a model-facing tool
|
||||
* uses `{ kind: 'parent', agent }` from its own execution context instead.
|
||||
* @returns the authority a host adapter supplies to {@link followup}.
|
||||
*/
|
||||
userAuthority(): SubagentAuthority
|
||||
|
||||
/**
|
||||
* Read one durable child's live residency state.
|
||||
* @param childId - durable child session id.
|
||||
* @returns its Activation state, or `undefined` when no Activation is live.
|
||||
* @throws when continuation services are unavailable.
|
||||
*/
|
||||
activationState(childId: SessionId): ActivationState | undefined
|
||||
async followup( parent: Agent, childId: SessionId, content: ContentBlock[], options: SubagentFollowupOptions, ): Promise<MessageId>
|
||||
|
||||
/**
|
||||
* Close continuable admission synchronously, then dispose every live
|
||||
@@ -2040,9 +2023,9 @@ list(): string[]
|
||||
async start(name: string, request: SubagentStartRequest): Promise<SubagentRun>
|
||||
```
|
||||
|
||||
Types: [ActivationState](../core-data-structures/subagent.md) · [ContentBlock](../core-data-structures/core.md) · [ContinuableStart](../core-data-structures/subagent.md) · [ContinuableStartSpec](../core-data-structures/subagent.md) · [MessageId](../core-data-structures/core.md) · [SessionId](../core-data-structures/core.md) · [SubagentAuthority](../core-data-structures/subagent.md) · [SubagentFollowupOptions](../core-data-structures/subagent.md) · [SubagentProvider](../core-data-structures/subagent.md) · [SubagentRun](../core-data-structures/subagent.md) · [SubagentStartRequest](../core-data-structures/subagent.md)
|
||||
Types: [Agent](../core-data-structures/core.md) · [ContentBlock](../core-data-structures/core.md) · [ContinuableStart](../core-data-structures/subagent.md) · [ContinuableStartSpec](../core-data-structures/subagent.md) · [MessageId](../core-data-structures/core.md) · [SessionId](../core-data-structures/core.md) · [SubagentFollowupOptions](../core-data-structures/subagent.md) · [SubagentProvider](../core-data-structures/subagent.md) · [SubagentRun](../core-data-structures/subagent.md) · [SubagentStartRequest](../core-data-structures/subagent.md)
|
||||
|
||||
Source: [`packages/subagent/subagent/src/index.ts:176`](../../packages/subagent/subagent/src/index.ts)
|
||||
Source: [`packages/subagent/subagent/src/index.ts:141`](../../packages/subagent/subagent/src/index.ts)
|
||||
|
||||
## `ctx.subprocess` — `SubprocessService` (abstract seam)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user