diff --git a/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.i18n.yaml
new file mode 100644
index 0000000000..d85dec23a0
--- /dev/null
+++ b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.i18n.yaml
@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md
+2026-09-01-parent-owned-subagent-catalog.md: 7b2082bb6c8e046d3083ab95abffb739895d13b8
+2026-09-01-parent-owned-subagent-catalog.zh.md: 5f8413a3b88a747de6308b1220bb3139543ba83c
diff --git a/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md
new file mode 100644
index 0000000000..7b2082bb6c
--- /dev/null
+++ b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md
@@ -0,0 +1,43 @@
+# Agent Note: Parent-owned subagent catalog events
+
+Status: implemented
+
+English | [中文](2026-09-01-parent-owned-subagent-catalog.zh.md)
+
+## Problem
+
+Direct-child discovery once reconstructed a catalog from the global Session corpus and each selected child's log. Creation already knows the direct parent, child id, mode, and label, so repository-wide enumeration and child-log reads duplicated an owned fact and made browser refresh cost depend on unrelated Sessions.
+
+The child descriptor remains necessary for recovery and composition, but it cannot be the discovery source because a reader must find and open the child before it can read the descriptor. Forks add a separate requirement: a seeded copy of a parent log must not inherit the original Session's children.
+
+## Decision
+
+The parent Session's required `subagent/catalog` events are the persistent authority for direct-child discovery. Each event is one successful creation fact containing `childId`, `childCreatedAt`, mode, and the mode-discriminated label. Remote one-shot runs without a local Session remain outside this catalog.
+
+Creation publishes only successful facts. A one-shot run appends the catalog event after its provider returns a local child and before the run reaches its caller. A continuable run admits the initial prompt, appends the catalog event, then returns the child id. If admission or catalog append fails, creation fails and releases the activation; there is no compensating catalog event or rollback protocol.
+
+The child header and `subagent/descriptor` remain authoritative for recovery and composition. An Activation and the exact parent relationship remain authoritative for authorization and delivery. Mode and label are snapshotted once and the same detached values reach the parent catalog fact and child descriptor.
+
+The registered host-only `subagentCatalog` projection materializes the parent facts. It stores facts in a persistent stack of 64-entry chunks, so an append copies at most the head chunk in bounded O(1) work. Materialization visits D facts and sorts them by `childCreatedAt`, then child id, in O(D log D). A projection checkpoint clones the state once in O(D); projection-cache writes remain asynchronous and use the existing mandatory creation, turn-end, and disposal points.
+
+Fork isolation uses the exact `Session.inheritedEventCount` supplied to projection initialization. The fold ignores `subagent/catalog` events below that offset. The state stores the inherited offset but not each event seq because acceptance is decided during folding.
+
+Snapshot normalizers zero `childCreatedAt` because it originates from the process clock. The TypeScript normalizer also sorts adjacent catalog facts by distinct child id because parallel successful creations may append in either order. Non-catalog events remain ordering barriers.
+
+## Alternatives considered
+
+**A flat immutable array.** Appending with `[...facts, fact]` copies D facts, so creation is O(D). Mutating a shared array would violate projection state ownership and checkpoint safety.
+
+**A node-per-fact linked list.** It provides O(1) append and O(D) read, but persisted projection checkpoints form JSON nested D levels deep. Sixty-four-entry chunks preserve the asymptotic costs while reducing nesting.
+
+**A client-visible projection.** Publishing the complete catalog after every creation would turn constant-time folding into O(D²) cumulative materialization. The Session Controller already owns the observation needed for a cold read.
+
+**A durable SQLite child index.** An index would create another write path, reconciliation protocol, schema, and corruption surface for a fact already ordered in the parent Session log.
+
+**A compensating failure event.** Recording catalog membership before initial prompt admission requires a second operation, pairing rules, rollback cleanup, and client reconciliation. Delaying the success fact until admission completes removes that protocol.
+
+## Consequences
+
+A caller can request `projectionStateKeys: ['subagentCatalog']` from `observeSession`. Live observations clone the maintained registry state; cold observations hydrate their prepared Session and detach the same state at the observation cursor. Direct-child and descendant listing still use the Session corpus and child identity projection.
+
+Backends that do not know the required event refuse the log under the existing Session event mechanism. Pre-release format policy requires no fallback scan for old logs.
diff --git a/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.zh.md b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.zh.md
new file mode 100644
index 0000000000..5f8413a3b8
--- /dev/null
+++ b/.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.zh.md
@@ -0,0 +1,43 @@
+# Agent Note: parent 自有的 subagent 目录事件
+
+Status: implemented
+
+[English](2026-09-01-parent-owned-subagent-catalog.md) | 中文
+
+## 问题
+
+直接 child discovery 曾从全局 Session 语料与每个入选 child 的日志重建目录。创建过程已经知道直接 parent、child id、mode 与 label,因此仓库范围枚举和 child 日志读取重复推导了已有归属的事实,并让浏览器刷新成本取决于无关 Session。
+
+child descriptor 对恢复与 composition 仍然必要,但它不能作为 discovery 来源,因为读取方必须先找到并打开 child 才能读取 descriptor。fork 还有独立要求:从 parent 日志播种的副本不能继承原 Session 的 child。
+
+## 决策
+
+parent Session 的 required `subagent/catalog` 事件是直接 child discovery 的持久化权威。每个事件都是一条成功创建事实,包含 `childId`、`childCreatedAt`、mode 与按 mode 区分的 label。没有本地 Session 的远程 one-shot run 不进入该目录。
+
+创建只发布成功事实。one-shot run 在 provider 返回本地 child 后、run 到达调用方前追加目录事件。continuable run 先准入初始 prompt,再追加目录事件,最后返回 child id。准入或目录追加失败时,创建失败并释放 activation;不存在补偿目录事件或 rollback 协议。
+
+child header 与 `subagent/descriptor` 继续拥有恢复与 composition 权威。Activation 与精确 parent 关系继续拥有授权与投递权威。mode 与 label 只快照一次,同一份分离值写入 parent catalog fact 与 child descriptor。
+
+注册的 host-only `subagentCatalog` projection 物化 parent fact。它以每块 64 项的持久 stack 保存事实,因此 append 最多复制 head chunk,以有界 O(1) 工作完成。materialization 访问 D 条事实,再按 `childCreatedAt` 与 child id 以 O(D log D) 排序。projection checkpoint 以 O(D) 克隆 state;projection-cache 继续异步写入,并使用既有创建、turn-end 与 disposal 强制点。
+
+fork 隔离使用 projection 初始化时提供的精确 `Session.inheritedEventCount`。fold 忽略该 offset 之前的 `subagent/catalog` 事件。state 保存 inherited offset,但不保存每条 event seq,因为接受判定已在 fold 时完成。
+
+snapshot normalizer 会把 `childCreatedAt` 归零,因为它来自 process clock。TypeScript normalizer 还会按不同 child id 排序相邻 catalog fact,因为并行成功创建的 append 顺序可能不同。非 catalog event 继续作为顺序 barrier。
+
+## 考虑过的替代方案
+
+**扁平不可变数组。** 用 `[...facts, fact]` append 会复制 D 个 fact,因此创建是 O(D)。修改共享数组会违反 projection state ownership 与 checkpoint 安全。
+
+**每 fact 一个 node 的 linked list。** 它提供 O(1) append 与 O(D) read,但持久 projection checkpoint 会形成 D 层 JSON 嵌套。每块 64 项保留渐进复杂度,同时降低嵌套深度。
+
+**client-visible projection。** 每次创建后发布完整 catalog 会把常数时间 fold 变成 O(D²) 累积 materialization。Session Controller 已经拥有 cold read 所需的 observation。
+
+**持久 SQLite child index。** index 会为 parent Session 日志中已有顺序的 fact 增加另一套写路径、reconciliation protocol、schema 与 corruption surface。
+
+**补偿失败事件。** 在初始 prompt 准入前记录 catalog membership 会引入第二种 operation、配对规则、rollback 清理与 client reconciliation。把成功事实推迟到准入完成后即可删除该协议。
+
+## 后果
+
+调用方可以向 `observeSession` 请求 `projectionStateKeys: ['subagentCatalog']`。实时观察克隆 registry 维护中的 state;冷观察 hydrate 已准备的 Session,并在观察 cursor 处分离出同一 state。直接子级和后代列表仍使用 Session 语料库与子级身份 projection。
+
+不认识该 required event 的 backend 会按既有 Session event 机制拒绝日志。pre-release format policy 不要求为旧日志保留 fallback scan。
diff --git a/docs/event-producer-consumer.i18n.yaml b/docs/event-producer-consumer.i18n.yaml
index f0492f3a9f..1e314eaacc 100644
--- a/docs/event-producer-consumer.i18n.yaml
+++ b/docs/event-producer-consumer.i18n.yaml
@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write docs/event-producer-consumer.md
-event-producer-consumer.md: 7c33981cb58d4bad7c1b410fcf61d4649f6322c1
+event-producer-consumer.md: 81b6fc83f0c3922df402106789c5788b4c0a6b3e
event-producer-consumer.zh.md: d857561a7d9dbdf4c4d971a1854d43d3ecc4fd2a
diff --git a/docs/event-producer-consumer.md b/docs/event-producer-consumer.md
index 7c33981cb5..81b6fc83f0 100644
--- a/docs/event-producer-consumer.md
+++ b/docs/event-producer-consumer.md
@@ -55,10 +55,10 @@ This matrix shows which packages dispatch each harness-owned event and which pac
| `settings/document-updated` | `emit` | [`packages/settings/settings/src/types.ts:105`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | `remotes` |
| `settings/updated` | `emit` | [`packages/settings/settings/src/types.ts:92`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | [`settings`](../packages/settings/settings) |
| `skills/change` | `emit` | [`packages/skill/skill/src/index.ts:298`](../packages/skill/skill/src/index.ts) | [`skill`](../packages/skill/skill) (`events.dispatch`) | - |
-| `subagent/end` | `emit` | [`packages/subagent/subagent/src/index.ts:168`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), `server`, [`subagent`](../packages/subagent/subagent) |
-| `subagent/provider-added` | `emit` | [`packages/subagent/subagent/src/index.ts:142`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`emit`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) |
-| `subagent/provider-removed` | `emit` | [`packages/subagent/subagent/src/index.ts:148`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) |
-| `subagent/start` | `emit` | [`packages/subagent/subagent/src/index.ts:159`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`subagent`](../packages/subagent/subagent) |
+| `subagent/end` | `emit` | [`packages/subagent/subagent/src/index.ts:169`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), `server`, [`subagent`](../packages/subagent/subagent) |
+| `subagent/provider-added` | `emit` | [`packages/subagent/subagent/src/index.ts:143`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`emit`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) |
+| `subagent/provider-removed` | `emit` | [`packages/subagent/subagent/src/index.ts:149`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) |
+| `subagent/start` | `emit` | [`packages/subagent/subagent/src/index.ts:160`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`subagent`](../packages/subagent/subagent) |
| `system-prompt/assemble` | `waterfall` | [`packages/core/system-prompt/src/index.ts:31`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`waterfall`) | [`agent`](../packages/core/agent), [`agent-presets`](../packages/preset/agent-presets), [`session-reference`](../packages/context/session-reference), [`system-prompt`](../packages/core/system-prompt) |
| `system-prompt/change` | `emit` | [`packages/core/system-prompt/src/index.ts:37`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`emit`) | - |
| `tools/change` | `emit` | [`packages/core/tools/src/index.ts:199`](../packages/core/tools/src/index.ts) | [`agent-presets`](../packages/preset/agent-presets) (`emit`), [`tools`](../packages/core/tools) (`emit`) | [`tool-subagent`](../packages/subagent/tool-subagent) |
diff --git a/docs/persistence-catalog.i18n.yaml b/docs/persistence-catalog.i18n.yaml
index 1e60882ff3..ab3b610505 100644
--- a/docs/persistence-catalog.i18n.yaml
+++ b/docs/persistence-catalog.i18n.yaml
@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write docs/persistence-catalog.md
-persistence-catalog.md: b239204810f92d866d309214678a22901e6f3ef6
-persistence-catalog.zh.md: 86d81a5a64322c98ea288c0aa0289550153eedf0
+persistence-catalog.md: 1859ca37bec3ba06033a209103d4471eaa3fa3c7
+persistence-catalog.zh.md: d967b46c9e60df10a60d4599640b58f5e8b97bf5
diff --git a/docs/persistence-catalog.md b/docs/persistence-catalog.md
index b239204810..1859ca37be 100644
--- a/docs/persistence-catalog.md
+++ b/docs/persistence-catalog.md
@@ -761,6 +761,20 @@ Source: [`packages/core/session/src/types.ts:287`](../packages/core/session/src/
### `subagent/*`
+
+
+#### `subagent/catalog` — log-only
+
+```ts persistence-catalog
+/**
+ * A direct child's complete discovery fact.
+ * @param data - versioned parent-owned catalog entry.
+ */
+'subagent/catalog': SubagentCatalogEvent
+```
+
+Source: [`packages/subagent/subagent/src/catalog.ts:37`](../packages/subagent/subagent/src/catalog.ts)
+
#### `subagent/descriptor` — log-only
diff --git a/docs/persistence-catalog.zh.md b/docs/persistence-catalog.zh.md
index 86d81a5a64..d967b46c9e 100644
--- a/docs/persistence-catalog.zh.md
+++ b/docs/persistence-catalog.zh.md
@@ -763,6 +763,20 @@ export type SessionEvent = {
### `subagent/*`
+
+
+#### `subagent/catalog` — log-only
+
+```ts persistence-catalog
+/**
+ * A direct child's complete discovery fact.
+ * @param data - versioned parent-owned catalog entry.
+ */
+'subagent/catalog': SubagentCatalogEvent
+```
+
+来源:[`packages/subagent/subagent/src/catalog.ts:37`](../packages/subagent/subagent/src/catalog.ts)
+
#### `subagent/descriptor` — log-only
diff --git a/packages/core/session/src/known-event-types.ts b/packages/core/session/src/known-event-types.ts
index b21b7ec576..decb838cb5 100644
--- a/packages/core/session/src/known-event-types.ts
+++ b/packages/core/session/src/known-event-types.ts
@@ -54,6 +54,7 @@ export const KNOWN_SESSION_EVENT_TYPES: ReadonlySet = new Set([
'session/title-llm-request',
'step/end',
'step/start',
+ 'subagent/catalog',
'subagent/descriptor',
'subagent/model-selection-policy',
'system/message',
diff --git a/packages/extensions/tool-cordis/src/api-catalog.ts b/packages/extensions/tool-cordis/src/api-catalog.ts
index f74e1d9e51..de254c190b 100644
--- a/packages/extensions/tool-cordis/src/api-catalog.ts
+++ b/packages/extensions/tool-cordis/src/api-catalog.ts
@@ -5213,11 +5213,11 @@ export const TYPE_API: readonly TypeApiEntry[] = [
},
{
name: 'SessionObservation',
- declaration: 'export interface SessionObservation extends Disposable {\n readonly source: \'live\' | \'prepared\';\n readonly header: SessionHeader;\n readonly inheritedEventCount: SessionLogOffsetType;\n readonly events: readonly SessionEvent[];\n readonly cursor: SessionSeqCursor;\n readonly revision?: SessionPersistenceRevision;\n readonly projections?: ProjectionSnapshot;\n retain(): SessionObservation;\n}',
+ declaration: 'export interface SessionObservation extends Disposable {\n readonly source: \'live\' | \'prepared\';\n readonly header: SessionHeader;\n readonly inheritedEventCount: SessionLogOffsetType;\n readonly events: readonly SessionEvent[];\n readonly cursor: SessionSeqCursor;\n readonly revision?: SessionPersistenceRevision;\n readonly projections?: ProjectionSnapshot;\n readonly projectionStates?: Partial;\n retain(): SessionObservation;\n}',
},
{
name: 'SessionObservationOptions',
- declaration: 'export interface SessionObservationOptions {\n readonly signal?: AbortSignal;\n readonly projectionMode?: \'all\' | \'none\';\n}',
+ declaration: 'export interface SessionObservationOptions {\n readonly signal?: AbortSignal;\n readonly projectionMode?: \'all\' | \'none\';\n readonly projectionStateKeys?: readonly Extract[];\n}',
},
{
name: 'SessionOpenWorkspacePathRequest',
diff --git a/packages/session-query/session-query/README.i18n.yaml b/packages/session-query/session-query/README.i18n.yaml
index 122ec31432..e5ac8d1d9b 100644
--- a/packages/session-query/session-query/README.i18n.yaml
+++ b/packages/session-query/session-query/README.i18n.yaml
@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write packages/session-query/session-query/README.md
-README.md: cbd7379b290397101ab3178e9d742c87a4afab08
-README.zh.md: 02bf708e4e8dc0104f5f031c8b963f29a5675b75
+README.md: 52c6870fed7f39c2e2c5a49c1aa43c7e498488ea
+README.zh.md: e062d0a2a37252378ae32431d8ae8d1a264ec200
diff --git a/packages/session-query/session-query/README.md b/packages/session-query/session-query/README.md
index cbd7379b29..52c6870fed 100644
--- a/packages/session-query/session-query/README.md
+++ b/packages/session-query/session-query/README.md
@@ -108,7 +108,7 @@ The decision history lives in the [unified service decision](../../../.agents/no
### Observation cache
-`observeSession` builds point observations without a listing preflight. A live observation fixes its cut as the current log length and materializes `events` on first read, so header-, cursor-, or projection-only consumers never copy the log; the log only appends, so a late first read still yields exactly that prefix. The cold path stats the stored session first and consults an own bounded cache keyed by the persistence instance and the `stat` revision: an unchanged revision reuses the restored unpublished Session without re-reading the log; a changed revision, or a replaced persistence instance, reloads through the handle seam and replaces the entry. The cache holds `preparedSessionCacheSize` entries with least-recently-used eviction, entries pinned by active observation leases are never evicted, and a session that goes live mid-read retries the live path.
+`observeSession` builds point observations without a listing preflight. A live observation fixes its cut as the current log length and materializes `events` on first read, so header-, cursor-, or projection-only consumers never copy the log; the log only appends, so a late first read still yields exactly that prefix. The cold path stats the stored session first and consults an own bounded cache keyed by the persistence instance and the `stat` revision: an unchanged revision reuses the restored unpublished Session without re-reading the log; a changed revision, or a replaced persistence instance, reloads through the handle seam and replaces the entry. The cache holds `preparedSessionCacheSize` entries with least-recently-used eviction, entries pinned by active observation leases are never evicted, and a session that goes live mid-read retries the live path. `projectionStateKeys` detaches named host projection states at the same cut independently of `projectionMode`: a live observation clones the registry's maintained cells, and a cold observation hydrates its prepared Session's cells once so states and any views share one cut; unregistered keys are omitted and an absent registry leaves `projectionStates` undefined.
### Reads and traces
diff --git a/packages/session-query/session-query/README.zh.md b/packages/session-query/session-query/README.zh.md
index 02bf708e4e..e062d0a2a3 100644
--- a/packages/session-query/session-query/README.zh.md
+++ b/packages/session-query/session-query/README.zh.md
@@ -108,7 +108,7 @@ kind: "package-reference"
### 观察缓存
-`observeSession` 不经过列表预检直接构建定点观察。实时观察以当前日志长度固定 cut,并在首次读取时才物化 `events`,因此只需要 header、cursor 或 projection 的消费者永远不会复制日志;日志只会追加,所以延后的首次读取得到的仍然正好是该前缀。冷路径先对存储会话执行 `stat`,再查询自有的有界缓存,缓存键为持久化实例加 `stat` 修订:修订未变则复用已恢复的未发布 Session,不再重读日志;修订变化或持久化实例被替换则经 handle 缝重新加载并替换条目。缓存保留 `preparedSessionCacheSize` 个条目并按最久未用淘汰,被活跃观察租约钉住的条目从不被淘汰;读取中途转为实时的会话会重试实时路径。
+`observeSession` 不经过列表预检直接构建定点观察。实时观察以当前日志长度固定 cut,并在首次读取时才物化 `events`,因此只需要 header、cursor 或 projection 的消费者永远不会复制日志;日志只会追加,所以延后的首次读取得到的仍然正好是该前缀。冷路径先对存储会话执行 `stat`,再查询自有的有界缓存,缓存键为持久化实例加 `stat` 修订:修订未变则复用已恢复的未发布 Session,不再重读日志;修订变化或持久化实例被替换则经 handle 缝重新加载并替换条目。缓存保留 `preparedSessionCacheSize` 个条目并按最久未用淘汰,被活跃观察租约钉住的条目从不被淘汰;读取中途转为实时的会话会重试实时路径。 `projectionStateKeys` 在同一 cut 上分离出指定的 host projection state,与 `projectionMode` 无关:实时观察克隆 registry 维护中的 cell,冷观察则一次性 hydrate 其已准备 Session 的 cell,使 state 与任何 view 共享同一 cut;未注册的 key 被省略,registry 缺失时 `projectionStates` 为 undefined。
### 读取与追踪
diff --git a/packages/session-query/session-query/src/observation.ts b/packages/session-query/session-query/src/observation.ts
index 7ef86cebd4..7ba5951710 100644
--- a/packages/session-query/session-query/src/observation.ts
+++ b/packages/session-query/session-query/src/observation.ts
@@ -9,6 +9,7 @@ import type {
SessionPersistenceSnapshot,
} from '@deepseek-ai/dsh-session-persistence'
import type { ProjectionSnapshot } from '@deepseek-ai/dsh-session-projection'
+import type { SessionProjectionStateMap } from '@deepseek-ai/dsh-session-projection/types'
import type {} from '@deepseek-ai/dsh-session-projection-cache'
import { SESSION_QUERY_DEFAULT_PREPARED_SESSION_CACHE_SIZE, SessionQueryError } from './config.ts'
import { readColdSessionLog, type ColdSessionLog } from './cold-read.ts'
@@ -33,6 +34,11 @@ export interface SessionObservation extends Disposable {
readonly revision?: SessionPersistenceRevision
/** Exact projection baseline at {@link cursor}, when the registry is mounted. */
readonly projections?: ProjectionSnapshot
+ /**
+ * Requested host projection states detached at {@link cursor}; present only
+ * when the registry is mounted, and contains only the registered keys.
+ */
+ readonly projectionStates?: Partial
/**
* Retain the same immutable cut for another Host owner.
* @returns an independently disposable lease over this observation.
@@ -46,6 +52,12 @@ export interface SessionObservationOptions {
readonly signal?: AbortSignal
/** Whether to compute every projection or leave projection state untouched. */
readonly projectionMode?: 'all' | 'none'
+ /**
+ * Host projection states to detach from the same exact cut, independent of
+ * {@link projectionMode}. A cold observation hydrates its registry cells to
+ * serve them.
+ */
+ readonly projectionStateKeys?: readonly Extract[]
}
/**
@@ -98,23 +110,25 @@ export class SessionObservationReader {
sessionId: SessionId,
options: SessionObservationOptions = {},
): Promise {
- const { signal, projectionMode = 'all' } = options
+ const { signal, projectionMode = 'all', projectionStateKeys } = options
for (;;) {
throwIfObservationAborted(signal)
const live = this.ctx.sessions.get(sessionId)
- if (live !== undefined) return this.live(live, projectionMode)
+ if (live !== undefined) return this.live(live, projectionMode, projectionStateKeys)
const persistence = this.ctx.get('sessionPersistence')
if (persistence === undefined) throw notFound(sessionId)
const snapshot = await this.statSource(persistence, sessionId, signal)
const attachedDuringStat = this.ctx.sessions.get(sessionId)
- if (attachedDuringStat !== undefined) return this.live(attachedDuringStat, projectionMode)
+ if (attachedDuringStat !== undefined) {
+ return this.live(attachedDuringStat, projectionMode, projectionStateKeys)
+ }
let entry = this.cachedEntry(persistence, sessionId, snapshot.revision)
if (entry === undefined) {
const loaded = await this.loadSource(persistence, sessionId, signal)
throwIfObservationAborted(signal)
const attached = this.ctx.sessions.get(sessionId)
- if (attached !== undefined) return this.live(attached, projectionMode)
+ if (attached !== undefined) return this.live(attached, projectionMode, projectionStateKeys)
// The handle marks persisted events as adoptable; synthetic closers
// are owned by this read, so the combined seed needs no copy.
const seed = loaded.events
@@ -148,8 +162,15 @@ export class SessionObservationReader {
}
let projections: ProjectionSnapshot | undefined
+ let projectionStates: Partial | undefined
try {
- projections = projectionMode === 'none' ? undefined : this.preparedProjections(entry)
+ if (projectionMode === 'all' || projectionStateKeys !== undefined) {
+ // Hydration installs every unit's cell on the prepared Session, so a
+ // requested host state reads the same cut the views were taken from.
+ const snapshot = this.preparedProjections(entry)
+ projections = projectionMode === 'all' ? snapshot : undefined
+ projectionStates = this.projectionStates(entry.session, projectionStateKeys)
+ }
} catch (error: unknown) {
throw new SessionQueryError(
`failed to project session "${sessionId}": ${errorMessage(error)}`,
@@ -157,7 +178,7 @@ export class SessionObservationReader {
{ cause: error },
)
}
- return this.preparedLease(sessionId, entry, projections)
+ return this.preparedLease(sessionId, entry, projections, projectionStates)
}
}
@@ -243,6 +264,7 @@ export class SessionObservationReader {
sessionId: SessionId,
entry: PreparedEntry,
projections: ProjectionSnapshot | undefined,
+ projectionStates: Partial | undefined,
): SessionObservation {
entry.refs += 1
const lease = (): SessionObservation => {
@@ -255,6 +277,7 @@ export class SessionObservationReader {
cursor: entry.events.at(-1)?.seq ?? -1,
revision: entry.revision,
...projections === undefined ? {} : { projections },
+ ...projectionStates === undefined ? {} : { projectionStates },
retain: () => {
if (disposed) throw new Error(`session observation "${sessionId}" is disposed`)
entry.refs += 1
@@ -274,6 +297,7 @@ export class SessionObservationReader {
private live(
session: Session,
projectionMode: NonNullable,
+ projectionStateKeys: SessionObservationOptions['projectionStateKeys'],
): SessionObservation {
// The cut is the log length now. The log only appends, so the prefix
// below `seq` is the same array whenever a consumer first reads `events`.
@@ -282,6 +306,7 @@ export class SessionObservationReader {
const projections = projectionMode === 'none'
? undefined
: this.ctx.get('sessionProjections')?.snapshot(session)
+ const projectionStates = this.projectionStates(session, projectionStateKeys)
const lease = (): SessionObservation => {
let disposed = false
return {
@@ -294,6 +319,7 @@ export class SessionObservationReader {
},
cursor: seq === 0 ? -1 : SessionSeq(seq - 1),
...projections === undefined ? {} : { projections },
+ ...projectionStates === undefined ? {} : { projectionStates },
retain: () => {
if (disposed) throw new Error(`session observation "${session.id}" is disposed`)
return lease()
@@ -312,6 +338,26 @@ export class SessionObservationReader {
? registry.hydrate(entry.session, {}, entry.events, SessionLogOffset(0))
: cache.hydratePrepared(entry.session, entry.events)
}
+
+ /**
+ * Detach the requested host states from the registry cells already at this
+ * Session's cut. Registry cells are live references that later drives
+ * advance, so each state is cloned into the immutable observation.
+ */
+ private projectionStates(
+ session: Session,
+ keys: SessionObservationOptions['projectionStateKeys'],
+ ): Partial | undefined {
+ if (keys === undefined) return undefined
+ const registry = this.ctx.get('sessionProjections')
+ if (registry === undefined) return undefined
+ const states: Record = {}
+ for (const key of keys) {
+ const state = registry.stateOf(session, key)
+ if (state !== undefined) states[key] = structuredClone(state)
+ }
+ return states
+ }
}
function throwIfObservationAborted(signal: AbortSignal | undefined): void {
diff --git a/packages/session-query/session-query/tests/observation.spec.ts b/packages/session-query/session-query/tests/observation.spec.ts
index 8e2879ca14..106f3453e1 100644
--- a/packages/session-query/session-query/tests/observation.spec.ts
+++ b/packages/session-query/session-query/tests/observation.spec.ts
@@ -17,6 +17,7 @@ import type {
SessionPersistenceStatOptions,
} from '@deepseek-ai/dsh-session-persistence'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
+import { titleProjectionDefinition } from '@deepseek-ai/dsh-session-title'
import { describe, expect, it, vi } from 'vitest'
import { SessionObservationReader } from '../src/observation.ts'
@@ -36,6 +37,15 @@ function messageEvent(seq: number, text: string): SessionEvent {
}
}
+function titleEvent(seq: number, title: string): SessionEvent {
+ return {
+ type: 'session/title',
+ seq: SessionSeq(seq),
+ time: seq + 1,
+ data: { title, messageSeqs: [], source: { kind: 'user' } },
+ }
+}
+
/** A log whose writer crashed mid-turn: read-only viewing must balance it in memory. */
function interruptedLog(text: string): SessionEvent[] {
return [
@@ -786,3 +796,67 @@ describe('SessionObservationReader cold projections', () => {
await ctx.fiber.dispose()
})
})
+
+describe('SessionObservationReader host projection states', () => {
+ it('detaches a live registry state at the observed cut without computing views', async () => {
+ const ctx = await readerContext()
+ await ctx.plugin(SessionProjectionRegistry)
+ ctx.sessionProjections.register(titleProjectionDefinition)
+ const session = ctx.sessions.create(SessionId('live-host-state'))
+ session.append('session/title', { title: 'Live title', messageSeqs: [], source: { kind: 'user' } })
+ const reader = new SessionObservationReader(ctx)
+
+ using observed = await reader.read(session.id, { projectionMode: 'none', projectionStateKeys: ['title'] })
+ session.append('session/title', { title: 'Later title', messageSeqs: [], source: { kind: 'user' } })
+ using later = await reader.read(session.id, { projectionMode: 'none', projectionStateKeys: ['title'] })
+
+ expect(observed.projections).toBeUndefined()
+ expect(observed.projectionStates).toEqual({ title: 'Live title' })
+ expect(later.projectionStates).toEqual({ title: 'Later title' })
+ await ctx.fiber.dispose()
+ })
+
+ it('hydrates a prepared Session once and serves the requested state from its cells', async () => {
+ const ctx = await readerContext()
+ await ctx.plugin(SessionProjectionRegistry)
+ ctx.sessionProjections.register(titleProjectionDefinition)
+ const meta = header('cold-host-state')
+ const store = new Map([[meta.id, { header: meta, events: [titleEvent(0, 'Cold title')], revision: 'r1' }]])
+ ctx.provide('sessionPersistence', stubPersistence(store, { stat: 0, open: 0, read: 0 }))
+ const hydrate = vi.spyOn(ctx.sessionProjections, 'hydrate')
+
+ using observed = await new SessionObservationReader(ctx).read(meta.id, {
+ projectionMode: 'none',
+ projectionStateKeys: ['title'],
+ })
+
+ expect(observed.source).toBe('prepared')
+ expect(observed.projections).toBeUndefined()
+ expect(observed.projectionStates).toEqual({ title: 'Cold title' })
+ expect(hydrate).toHaveBeenCalledOnce()
+ await ctx.fiber.dispose()
+ })
+
+ it('omits unregistered keys and the whole map when no registry is mounted', async () => {
+ const withRegistry = await readerContext()
+ await withRegistry.plugin(SessionProjectionRegistry)
+ const registered = withRegistry.sessions.create(SessionId('unregistered-key'))
+ using partial = await new SessionObservationReader(withRegistry).read(registered.id, {
+ projectionMode: 'none',
+ projectionStateKeys: ['title'],
+ })
+ expect(partial.projectionStates).toEqual({})
+ await withRegistry.fiber.dispose()
+
+ const withoutRegistry = await readerContext()
+ const meta = header('no-registry')
+ const store = new Map([[meta.id, { header: meta, events: [titleEvent(0, 'Cold title')], revision: 'r1' }]])
+ withoutRegistry.provide('sessionPersistence', stubPersistence(store, { stat: 0, open: 0, read: 0 }))
+ using absent = await new SessionObservationReader(withoutRegistry).read(meta.id, {
+ projectionMode: 'none',
+ projectionStateKeys: ['title'],
+ })
+ expect(absent.projectionStates).toBeUndefined()
+ await withoutRegistry.fiber.dispose()
+ })
+})
diff --git a/packages/subagent/subagent/README.i18n.yaml b/packages/subagent/subagent/README.i18n.yaml
index f9edd9b52a..7ff5a6a616 100644
--- a/packages/subagent/subagent/README.i18n.yaml
+++ b/packages/subagent/subagent/README.i18n.yaml
@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write packages/subagent/subagent/README.md
-README.md: 6b58f36fcd4d6e8a198ddc86e80ccc28491a0a34
-README.zh.md: be99e7c91f13c6d83a6375047ec5f21d55b21053
+README.md: 1b57a43bbd565e46bd738fe94e0d324fd1310684
+README.zh.md: f3e49584f3b40984d616ddc6f269d0adacc424de
diff --git a/packages/subagent/subagent/README.md b/packages/subagent/subagent/README.md
index 6b58f36fcd..1b57a43bbd 100644
--- a/packages/subagent/subagent/README.md
+++ b/packages/subagent/subagent/README.md
@@ -96,6 +96,8 @@ A request is validated against the provider's advertised capabilities, a durable
The manager reserves a child identity, resolves the durable descriptor, creates (or cold-resumes) the child Agent, installs it in an Activation, and submits the prompt. Model-authored messages cross one parent/child edge through fixed Steer scheduling; browser human prompts choose Queue or best-effort Steer through an internal adapter, while other host protocols may retain Queue for distinct turns. A Session queue command admits a live subagent-owned Agent only from its own continuable descriptor. Settlement waits for Agent activity to finish, an empty Inbox, and no owned children, then flushes final Session state with admission open. Under the child lock, the manager revalidates the wake generation, Session sequence, Inbox, and owned children; the synchronous task entry of `Agent.runMaintenance()` claims the idle phase and closes the private subagent Inbox in the same JavaScript turn before handle disposal. An absent direct-child Activation cold-resumes from the persisted session. When a resident Activation settles, the manager tells the child's direct parent in the parent's own turn stream.
+Successful local child creation appends a `subagent/catalog` fact to the parent Session. One-shot creation records it after the provider returns; continuable creation records it after initial inbox admission and before returning the child id. Failure releases the child without publishing a compensating catalog event. The host-only `subagentCatalog` projection excludes fork-inherited facts and can be read through an observation's requested projection state. [The parent-catalog decision](../../../.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.md) owns ordering, persistence costs, and alternatives.
+
### Ownership and invariants
- **Publication is the boundary** — before it the provider owns the setup and must roll back on failure; after it the caller owns the run and must dispose it.
diff --git a/packages/subagent/subagent/README.zh.md b/packages/subagent/subagent/README.zh.md
index be99e7c91f..f3e49584f3 100644
--- a/packages/subagent/subagent/README.zh.md
+++ b/packages/subagent/subagent/README.zh.md
@@ -96,6 +96,8 @@ kind: "package-reference"
管理器预留 child 身份、解析持久化描述符、创建(或冷恢复)child、把它安装进 Activation 并提交提示词。模型编写的消息通过固定 Steer 调度跨一条 parent/child 边;浏览器人类 prompt 通过内部适配器选择 Queue 或 best-effort Steer,其他 host 协议仍可保留 Queue 以创建独立轮次。Session queue command 仅根据 child 自身的 continuable descriptor 准入在线 subagent-owned Agent。Settlement 会等待 Agent 活动结束、Inbox 为空且没有所拥有子级,再在准入开放时 flush 最终 Session 状态。管理器随后在 child lock 内重新验证 wake generation、Session 序号、Inbox 与所拥有子级;`Agent.runMaintenance()` 的同步 task 入口会占用 idle 阶段,并在同一个 JavaScript turn 内关闭私有 subagent Inbox,然后才 dispose handle。直接 child 不存在 Activation 时会从持久化会话冷恢复。当驻留 Activation 结算时,管理器会在 parent 自身的轮次流中告知该 child 的直接 parent。
+本地子级创建成功时,父 Session 追加一条 `subagent/catalog` 事实。一次性创建在 provider 返回后记录;可继续创建在初始 inbox 准入后、返回子级 id 前记录。失败会释放子级,不发布补偿性目录事件。仅 host 使用的 `subagentCatalog` projection 排除 fork 继承的事实,并可通过观察请求的 projection state 读取。[父目录决策](../../../.agents/notes/implemented/architecture/2026-09-01-parent-owned-subagent-catalog.zh.md) 说明排序、持久化成本和替代方案。
+
### 所有权与不变式
- **发布即边界**——发布前提供方拥有设置并须在失败时回滚;发布后调用方拥有运行并须 dispose(资源释放)它。
diff --git a/packages/subagent/subagent/src/catalog.ts b/packages/subagent/subagent/src/catalog.ts
new file mode 100644
index 0000000000..1ea5f86d9c
--- /dev/null
+++ b/packages/subagent/subagent/src/catalog.ts
@@ -0,0 +1,186 @@
+/**
+ * Parent-owned durable subagent catalog events and their chunked projection.
+ *
+ * @module @deepseek-ai/dsh-subagent/catalog
+ */
+
+import { z } from 'zod'
+import type {
+ Session,
+ SessionEvent,
+ SessionHeader,
+ SessionId,
+ SessionLogOffset,
+} from '@deepseek-ai/dsh-session'
+import type { ProjectionDefinition } from '@deepseek-ai/dsh-session-projection'
+
+/** Current payload version for `subagent/catalog` events. */
+export const SUBAGENT_CATALOG_VERSION = 0
+
+/** One complete parent-owned catalog fact. */
+export type SubagentCatalogEvent =
+ & {
+ readonly version: 0
+ readonly childId: SessionId
+ readonly childCreatedAt: number
+ } & (
+ | { readonly mode: 'one-shot'; readonly label?: string }
+ | { readonly mode: 'continuable'; readonly label: string }
+ )
+
+declare module '@deepseek-ai/dsh-session/types' {
+ interface SessionEventMap {
+ /**
+ * A direct child's complete discovery fact.
+ * @param data - versioned parent-owned catalog entry.
+ */
+ 'subagent/catalog': SubagentCatalogEvent
+ }
+}
+
+/** One current direct-child discovery row materialized from parent facts. */
+export type SubagentCatalogEntry =
+ & {
+ readonly id: SessionId
+ readonly createdAt: number
+ }
+ & (
+ | { readonly mode: 'one-shot'; readonly label?: string }
+ | { readonly mode: 'continuable'; readonly label: string }
+ )
+
+/** A fixed-size persistent stack node; newest facts occupy the head chunk. */
+interface CatalogChunk {
+ readonly facts: readonly SubagentCatalogEvent[]
+ readonly previous?: CatalogChunk | undefined
+}
+
+/**
+ * Host fold state for one parent catalog. A cold reader detaches it from a
+ * Session observation for direct-child materialization.
+ */
+export interface SubagentCatalogState {
+ readonly inheritedEventCount: SessionLogOffset
+ readonly head?: CatalogChunk | undefined
+}
+
+const sessionIdSchema = z.string() as unknown as z.ZodType
+const oneShotCatalogSchema = z.object({
+ version: z.literal(SUBAGENT_CATALOG_VERSION),
+ childId: sessionIdSchema,
+ childCreatedAt: z.number().int().nonnegative(),
+ mode: z.literal('one-shot'),
+ label: z.string().optional(),
+}).strict()
+const continuableCatalogSchema = z.object({
+ version: z.literal(SUBAGENT_CATALOG_VERSION),
+ childId: sessionIdSchema,
+ childCreatedAt: z.number().int().nonnegative(),
+ mode: z.literal('continuable'),
+ label: z.string(),
+}).strict()
+const eventDataSchema = z.union([
+ oneShotCatalogSchema,
+ continuableCatalogSchema,
+]) as unknown as z.ZodType
+const chunkSchema: z.ZodType = z.lazy(() => z.object({
+ facts: z.array(eventDataSchema).min(1).max(64),
+ previous: chunkSchema.optional(),
+}).strict())
+const stateSchema: z.ZodType = z.object({
+ inheritedEventCount: z.number().int().nonnegative() as unknown as z.ZodType,
+ head: chunkSchema.optional(),
+}).strict()
+
+declare module '@deepseek-ai/dsh-session-projection/types' {
+ interface SessionProjectionStateMap {
+ subagentCatalog: SubagentCatalogState
+ }
+}
+
+/** Append one fact to the persistent chunk stack in constant bounded work. */
+function appendFact(state: SubagentCatalogState, fact: SubagentCatalogEvent): SubagentCatalogState {
+ const head = state.head
+ if (head === undefined || head.facts.length === 64) {
+ return { ...state, head: { facts: [fact], ...head === undefined ? {} : { previous: head } } }
+ }
+ return {
+ ...state,
+ head: {
+ facts: [...head.facts, fact],
+ ...head.previous === undefined ? {} : { previous: head.previous },
+ },
+ }
+}
+
+/**
+ * Materialize direct children from their parent's successful creation facts.
+ * @param state - parent catalog fold state.
+ * @returns current direct-child rows in creation order.
+ */
+export function subagentCatalogEntries(state: SubagentCatalogState): SubagentCatalogEntry[] {
+ const entries: SubagentCatalogEntry[] = []
+ for (let chunk = state.head; chunk !== undefined; chunk = chunk.previous) {
+ for (const data of chunk.facts) {
+ entries.push(data.mode === 'one-shot'
+ ? {
+ id: data.childId,
+ createdAt: data.childCreatedAt,
+ mode: data.mode,
+ ...data.label === undefined ? {} : { label: data.label },
+ }
+ : {
+ id: data.childId,
+ createdAt: data.childCreatedAt,
+ mode: data.mode,
+ label: data.label,
+ })
+ }
+ }
+ entries.sort((left, right) => left.createdAt - right.createdAt || left.id.localeCompare(right.id))
+ return entries
+}
+
+/** Parent-owned direct-child catalog projection. */
+export const subagentCatalogProjectionDefinition = {
+ key: 'subagentCatalog',
+ stateSchema,
+ init: (_header: SessionHeader, inheritedEventCount: SessionLogOffset) => ({ inheritedEventCount }),
+ apply: (state, event: SessionEvent) => {
+ if (event.type !== 'subagent/catalog' || event.seq < state.inheritedEventCount) return state
+ const parsed = eventDataSchema.safeParse(event.data)
+ if (!parsed.success) return state
+ return appendFact(state, parsed.data)
+ },
+ stateVersion: 1,
+} satisfies ProjectionDefinition<'subagentCatalog', SubagentCatalogState>
+
+/**
+ * Append a complete direct-child discovery fact to its parent Session.
+ * @param parent - durable direct parent receiving the discovery fact.
+ * @param child - established child's immutable Session metadata.
+ * @param descriptor - mode-discriminated creation label frozen with the child.
+ */
+export function establishCatalogChild(
+ parent: Session,
+ child: SessionHeader,
+ descriptor:
+ | { readonly mode: 'one-shot'; readonly label?: string }
+ | { readonly mode: 'continuable'; readonly label: string },
+): void {
+ parent.append('subagent/catalog', descriptor.mode === 'one-shot'
+ ? {
+ version: SUBAGENT_CATALOG_VERSION,
+ childId: child.id,
+ childCreatedAt: child.createdAt,
+ mode: descriptor.mode,
+ ...descriptor.label === undefined ? {} : { label: descriptor.label },
+ }
+ : {
+ version: SUBAGENT_CATALOG_VERSION,
+ childId: child.id,
+ childCreatedAt: child.createdAt,
+ mode: descriptor.mode,
+ label: descriptor.label,
+ })
+}
diff --git a/packages/subagent/subagent/src/continuation-activation.ts b/packages/subagent/subagent/src/continuation-activation.ts
index 2579e4aa5b..df2b6da439 100644
--- a/packages/subagent/subagent/src/continuation-activation.ts
+++ b/packages/subagent/subagent/src/continuation-activation.ts
@@ -499,7 +499,6 @@ export class ContinuableActivationRegistry {
} finally {
this.wake(activation)
}
- activation.announced = true
return message.id
}
diff --git a/packages/subagent/subagent/src/continuation.ts b/packages/subagent/subagent/src/continuation.ts
index b5ffced75e..b86d5cd836 100644
--- a/packages/subagent/subagent/src/continuation.ts
+++ b/packages/subagent/subagent/src/continuation.ts
@@ -39,6 +39,7 @@ import {
} from './continuation-messages.ts'
import { assertSubagentMaxDepth } from './depth.ts'
import { foldSubagentDescriptor, snapshotSubagentDescriptor } from './descriptor.ts'
+import { establishCatalogChild } from './catalog.ts'
import { SubagentError } from './error.ts'
import { isAdjacentAgentSendMessageTool } from './internal.ts'
import type { ActivationObserver } from './lifecycle.ts'
@@ -170,13 +171,15 @@ export class SubagentContinuationManager {
composition: { persona: request.persona, toolFilter: request.toolFilter },
signal: spec.signal,
})
- return this.submitMaterialized(
+ const childHeader = activation.handle.agent.session.header
+ return await this.submitMaterialized(
activation,
isAdjacentAgentSendMessageTool(this.ctx.get('tools')?.get('send_message', activation.handle.agent))
? withContinuableReturnGuidance(parent.id, request.prompt)
: request.prompt,
{ source: { kind: 'user' }, signal: spec.signal, delivery: 'queue' },
parent,
+ () => { establishCatalogChild(parent.session, childHeader, descriptor) },
)
})
return { childId, messageId }
@@ -307,7 +310,9 @@ export class SubagentContinuationManager {
return undefined
}
}
- return this.submitAdmitted(activation, content, options, parent)
+ const messageId = this.submitAdmitted(activation, content, options, parent)
+ activation.announced = true
+ return messageId
})
/* v8 ignore start -- only a delivery that lost the disposal cutoff retries. */
if (live !== undefined) return live
@@ -448,12 +453,13 @@ export class SubagentContinuationManager {
return await this.submitMaterialized(activation, content, options, parent)
}
- /** Submit to a freshly materialized Activation or roll it back completely. */
+ /** Admit a materialized child, commit its creation fact, and release it on failure. */
private async submitMaterialized(
activation: Activation,
content: ContentBlock[],
options: ChildDeliveryOptions,
parent: Agent,
+ commit?: () => void,
): Promise {
try {
if (contentHasImage(content)) {
@@ -462,11 +468,18 @@ export class SubagentContinuationManager {
throw new SubagentError(`subagent "${activation.childId}" is closing`, 'ACTIVATION_CLOSING')
}
}
- return this.submitAdmitted(activation, content, options, parent)
+ const messageId = this.submitAdmitted(activation, content, options, parent)
+ commit?.()
+ activation.announced = true
+ return messageId
} catch (error: unknown) {
- /* v8 ignore next -- rollback disposal failures must not mask the
- * pre-acceptance signal, drain, or lifecycle failure. */
- await this.activations.dispose(activation).catch(() => undefined)
+ try {
+ await this.activations.dispose(activation)
+ } catch (cleanupError: unknown) {
+ this.ctx.logger.warn(
+ `subagent continuation: disposal after admission or catalog append failure also failed: ${String(cleanupError)}`,
+ )
+ }
throw error
}
}
diff --git a/packages/subagent/subagent/src/index.ts b/packages/subagent/subagent/src/index.ts
index 88977cdcae..aa11318ec3 100644
--- a/packages/subagent/subagent/src/index.ts
+++ b/packages/subagent/subagent/src/index.ts
@@ -74,6 +74,7 @@ import { listChildren as listSubagentChildren, listDescendants as listSubagentDe
import type { SubagentDescendantListEntry, SubagentListEntry } from './list-children.ts'
import { snapshotSubagentDescriptor } from './descriptor.ts'
import { subagentIdentityProjectionDefinition, subagentTimingProjectionDefinition } from './projection.ts'
+import { establishCatalogChild, subagentCatalogProjectionDefinition } from './catalog.ts'
import { deliverSubagentPrompt } from './internal.ts'
export * from './out-of-process.ts'
@@ -208,6 +209,7 @@ export class SubagentRuntime extends TypertRemoteService {
}, 'subagents.continuationBinding()')
})
ctx.inject(['sessionProjections'], (projectionCtx) => {
+ projectionCtx.sessionProjections.register(subagentCatalogProjectionDefinition)
projectionCtx.sessionProjections.register(subagentTimingProjectionDefinition)
projectionCtx.sessionProjections.register(subagentIdentityProjectionDefinition)
})
@@ -559,7 +561,23 @@ export class SubagentRuntime extends TypertRemoteService {
...request.label !== undefined ? { label: request.label } : {},
})
const resolved: ResolvedSubagentStartRequest = { ...request, descriptor }
- return observeRun(this.emitLifecycle, name, request.parent, await provider.start(resolved))
+ const run = await provider.start(resolved)
+ const child = run.localAgent?.session
+ if (child !== undefined) {
+ try {
+ establishCatalogChild(request.parent.session, child.header, descriptor)
+ } catch (error: unknown) {
+ try {
+ await run.dispose()
+ } catch (cleanupError: unknown) {
+ this.ctx.logger.warn(
+ `subagent: disposal after catalog append failure also failed: ${String(cleanupError)}`,
+ )
+ }
+ throw error
+ }
+ }
+ return observeRun(this.emitLifecycle, name, request.parent, run)
}
/**
diff --git a/packages/subagent/subagent/tests/catalog.spec.ts b/packages/subagent/subagent/tests/catalog.spec.ts
new file mode 100644
index 0000000000..9fb134f4b8
--- /dev/null
+++ b/packages/subagent/subagent/tests/catalog.spec.ts
@@ -0,0 +1,117 @@
+import { describe, expect, it } from 'vitest'
+import {
+ SessionLogOffset,
+ SessionSeq,
+ SESSION_FORMAT_VERSION,
+ SessionId,
+} from '@deepseek-ai/dsh-session'
+import type { SessionEvent, SessionHeader } from '@deepseek-ai/dsh-session'
+import {
+ subagentCatalogEntries,
+ subagentCatalogProjectionDefinition,
+} from '../src/catalog.ts'
+import type { SubagentCatalogState } from '../src/catalog.ts'
+
+const header: SessionHeader = {
+ version: SESSION_FORMAT_VERSION,
+ id: SessionId('catalog-parent'),
+ createdAt: 0,
+ isSeeded: false,
+}
+
+/** Fold one event list through the pure definition, as the registry does for a log. */
+function fold(events: readonly SessionEvent[]): SubagentCatalogState {
+ let state = subagentCatalogProjectionDefinition.init(header, SessionLogOffset(0))
+ for (const event of events) state = subagentCatalogProjectionDefinition.apply(state, event)
+ return state
+}
+
+function fact(
+ seq: number,
+ childId: string,
+ childCreatedAt: number,
+ descriptor:
+ | { readonly mode: 'one-shot'; readonly label?: string }
+ | { readonly mode: 'continuable'; readonly label: string },
+): SessionEvent<'subagent/catalog'> {
+ return {
+ type: 'subagent/catalog',
+ seq: SessionSeq(seq),
+ time: 0,
+ data: {
+ version: 0,
+ childId: SessionId(childId),
+ childCreatedAt,
+ ...descriptor,
+ },
+ }
+}
+
+describe('subagent catalog projection', () => {
+ it('preserves earlier checkpoints across chunk rollover and restores every fact', () => {
+ const first = fold(Array.from({ length: 64 }, (_, i) =>
+ fact(i, `child-${i}`, i, { mode: 'one-shot' })))
+ const checkpoint = JSON.stringify(first)
+ let state = first
+ for (let i = 64; i < 130; i += 1) {
+ state = subagentCatalogProjectionDefinition.apply(
+ state, fact(i, `child-${i}`, i, { mode: 'one-shot' }),
+ )
+ }
+ const restored = subagentCatalogProjectionDefinition.stateSchema.parse(
+ JSON.parse(JSON.stringify(state)),
+ )
+
+ expect(JSON.stringify(first)).toBe(checkpoint)
+ expect(subagentCatalogEntries(first)).toHaveLength(64)
+ expect(subagentCatalogEntries(restored).map(entry => entry.id))
+ .toEqual(Array.from({ length: 130 }, (_, i) => SessionId(`child-${i}`)))
+ })
+
+ it('validates recursive chunk state and materializes every label variant in stable order', () => {
+ const events: SessionEvent[] = [
+ fact(0, 'child-b', 1, { mode: 'one-shot' }),
+ fact(1, 'child-a', 1, { mode: 'one-shot', label: 'once' }),
+ {
+ type: 'subagent/catalog',
+ seq: SessionSeq(2),
+ time: 0,
+ data: {
+ version: 0,
+ childId: SessionId('child-c'),
+ childCreatedAt: 2,
+ mode: 'continuable',
+ },
+ } as unknown as SessionEvent,
+ fact(3, 'child-d', 3, { mode: 'continuable', label: 'later' }),
+ ]
+ const state = fold(events)
+
+ expect(subagentCatalogProjectionDefinition.stateSchema.parse(JSON.parse(JSON.stringify(state))))
+ .toEqual(state)
+ expect(subagentCatalogEntries(state)).toEqual([
+ { id: SessionId('child-a'), createdAt: 1, mode: 'one-shot', label: 'once' },
+ { id: SessionId('child-b'), createdAt: 1, mode: 'one-shot' },
+ { id: SessionId('child-d'), createdAt: 3, mode: 'continuable', label: 'later' },
+ ])
+ })
+
+ it('ignores unrelated, inherited, and malformed events without changing state', () => {
+ const seededHeader = { ...header, isSeeded: true }
+ const initial = subagentCatalogProjectionDefinition.init(seededHeader, SessionLogOffset(2))
+ const unrelated = subagentCatalogProjectionDefinition.apply(initial, {
+ type: 'turn/start', seq: SessionSeq(2), time: 0, data: { turn: 1 },
+ })
+ const inherited = subagentCatalogProjectionDefinition.apply(
+ unrelated,
+ fact(1, 'inherited', 1, { mode: 'one-shot' }),
+ )
+ const malformed = subagentCatalogProjectionDefinition.apply(inherited, {
+ type: 'subagent/catalog', seq: SessionSeq(2), time: 0, data: { version: 9 },
+ } as unknown as SessionEvent)
+
+ expect(unrelated).toBe(initial)
+ expect(inherited).toBe(initial)
+ expect(malformed).toBe(initial)
+ })
+})
diff --git a/packages/subagent/subagent/tests/continuation.spec.ts b/packages/subagent/subagent/tests/continuation.spec.ts
index 298183cdc1..f2bbd16ef5 100644
--- a/packages/subagent/subagent/tests/continuation.spec.ts
+++ b/packages/subagent/subagent/tests/continuation.spec.ts
@@ -7,7 +7,7 @@ import type { Agent } from '@deepseek-ai/dsh-agent'
import AgentLoop from '@deepseek-ai/dsh-agent-loop'
import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit'
import { SessionId } from '@deepseek-ai/dsh-session'
-import type { SessionEvent } from '@deepseek-ai/dsh-session'
+import type { SessionEvent, SessionEventMap } from '@deepseek-ai/dsh-session'
import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl'
import * as toolSchedule from '@deepseek-ai/dsh-schedule'
import * as SubagentSpawn from '@deepseek-ai/dsh-subagent-spawn-in-process'
@@ -421,6 +421,67 @@ describe('SubagentRuntime.startContinuable', () => {
})
})
+ it('releases the Activation when the parent catalog append fails', async () => {
+ const { ctx, parent } = await setup([textResponse('unused')])
+ const childId = SessionId('00000000-0000-4000-8000-000000000321')
+ const catalogFailure = new Error('catalog append failed')
+ const cleanupFailure = new Error('activation disposal also failed')
+ const appendCatalog = parent.session.append.bind(parent.session) as (
+ type: 'subagent/catalog',
+ data: SessionEventMap['subagent/catalog'],
+ ) => SessionEvent<'subagent/catalog'>
+ vi.spyOn(parent.session, 'append').mockImplementation(((type: string, data: unknown) => {
+ if (type === 'subagent/catalog') {
+ const activation = continuationActivations(ctx).get(childId)
+ if (activation === undefined) throw new Error('expected live Activation')
+ const dispose = activation.handle.dispose.bind(activation.handle)
+ vi.spyOn(activation.handle, 'dispose').mockImplementation(async () => {
+ await dispose()
+ throw cleanupFailure
+ })
+ throw catalogFailure
+ }
+ return appendCatalog('subagent/catalog', data as SessionEventMap['subagent/catalog'])
+ }) as typeof parent.session.append)
+
+ await expect(ctx.subagents.startContinuable({
+ ...startSpec(parent),
+ childId,
+ })).rejects.toBe(catalogFailure)
+
+ await vi.waitFor(() => { expect(ctx.agents.get(childId)).toBeUndefined() })
+ expect(parent.session.snapshotEvents().filter(event => event.type === 'subagent/catalog')).toEqual([])
+ })
+
+ it('preserves prompt admission failure when Activation disposal also fails', async () => {
+ const { ctx, parent } = await setup([textResponse('unused')])
+ const childId = SessionId('00000000-0000-4000-8000-000000000322')
+ const admissionFailure = new Error('prompt admission failed')
+ const cleanupFailure = new Error('activation disposal also failed')
+ const controller = new AbortController()
+ const warnings: string[] = []
+ ctx.logger.warn = (message: string) => { warnings.push(message) }
+ ctx.on('subagent/start', () => {
+ const activation = continuationActivations(ctx).get(childId)
+ if (activation === undefined) throw new Error('expected live Activation')
+ const dispose = activation.handle.dispose.bind(activation.handle)
+ vi.spyOn(activation.handle, 'dispose').mockImplementation(async () => {
+ await dispose()
+ throw cleanupFailure
+ })
+ controller.abort(admissionFailure)
+ })
+
+ await expect(ctx.subagents.startContinuable({
+ ...startSpec(parent, 'spawn', controller.signal),
+ childId,
+ })).rejects.toBe(admissionFailure)
+ await vi.waitFor(() => { expect(ctx.agents.get(childId)).toBeUndefined() })
+ expect(warnings.some(warning => warning.startsWith(
+ 'subagent continuation: disposal after admission or catalog append failure also failed:',
+ ))).toBe(true)
+ })
+
it('rolls an unpublished Activation back when lifecycle publication fails', async () => {
const { ctx, parent } = await setup([textResponse('unused')])
const ends: SubagentRunEndInfo[] = []
diff --git a/packages/subagent/subagent/tests/service.spec.ts b/packages/subagent/subagent/tests/service.spec.ts
index e74c684405..899f34eb9b 100644
--- a/packages/subagent/subagent/tests/service.spec.ts
+++ b/packages/subagent/subagent/tests/service.spec.ts
@@ -18,7 +18,7 @@ import SubagentRuntime, {
type SubagentRunEndInfo,
type SubagentStartRequest,
} from '@deepseek-ai/dsh-subagent'
-import { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session'
+import { Session, SessionId, type SessionEvent } from '@deepseek-ai/dsh-session'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
function fakeParent(id = 'parent-1'): Agent {
@@ -73,6 +73,24 @@ async function service(): Promise<{ ctx: Context; subagents: SubagentRuntime }>
}
describe('SubagentRuntime', () => {
+ it('releases its catalog projection binding with the service fiber', async () => {
+ const ctx = new Context()
+ await ctx.plugin(SessionProjectionRegistry)
+ const fiber = await ctx.plugin(SubagentRuntime)
+ const parent = Session.create(SessionId('catalog-parent'))
+ parent.append('subagent/catalog', {
+ version: 0,
+ childId: SessionId('catalog-child'),
+ childCreatedAt: 1,
+ mode: 'one-shot',
+ })
+ expect(ctx.sessionProjections.stateOf(parent, 'subagentCatalog')?.head?.facts).toHaveLength(1)
+
+ await fiber.dispose()
+
+ expect(ctx.sessionProjections.stateOf(parent, 'subagentCatalog')).toBeUndefined()
+ })
+
it('registers, lists, looks up, starts, and removes providers', async () => {
const { ctx, subagents } = await service()
const added: string[] = []
@@ -252,6 +270,36 @@ describe('SubagentRuntime', () => {
expect(lifecycle).not.toHaveBeenCalled()
})
+ it('quiesces a local run when the parent catalog append fails', async () => {
+ const { subagents } = await service()
+ const parentSession = Session.create(SessionId('catalog-parent'))
+ const childSession = Session.create(SessionId('catalog-child'))
+ const parent = { id: parentSession.id, session: parentSession } as Agent
+ const localAgent = { id: childSession.id, session: childSession } as Agent
+ const cleanupFailure = new Error('dispose also failed')
+ const dispose = vi.fn().mockRejectedValue(cleanupFailure)
+ subagents.registerProvider({
+ name: 'catalog-failure',
+ capabilities: NO_CAPS,
+ inheritsParentContext: false,
+ start: () => Promise.resolve({
+ id: childSession.id,
+ localAgent,
+ result: Promise.resolve({ output: [], stopReason: 'completed' }),
+ dispose,
+ }),
+ })
+ const catalogFailure = new Error('catalog unavailable')
+ const append = vi.spyOn(parentSession, 'append').mockImplementation(() => {
+ throw catalogFailure
+ })
+
+ await expect(subagents.start('catalog-failure', baseRequest({ parent })))
+ .rejects.toBe(catalogFailure)
+ expect(append).toHaveBeenCalledOnce()
+ expect(dispose).toHaveBeenCalledOnce()
+ })
+
it('emits an enriched end event and maps result rejection to error telemetry', async () => {
const { ctx, subagents } = await service()
const completed = new StubProvider('completed', NO_CAPS, {
diff --git a/packages/test-support/session-snapshot/README.i18n.yaml b/packages/test-support/session-snapshot/README.i18n.yaml
index 7eeb15e7c5..9f145f4ecb 100644
--- a/packages/test-support/session-snapshot/README.i18n.yaml
+++ b/packages/test-support/session-snapshot/README.i18n.yaml
@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write packages/test-support/session-snapshot/README.md
-README.md: 533baf73e4913d1c64ea018e7c99099da1a1348b
-README.zh.md: c3926c3e7d7ec53064a5d3dac3048e0d934b4c5c
+README.md: 55580faef36cd99b2179371e50b8a8ac680056c6
+README.zh.md: 9c23a09a75e3ba37305a3209098039623011a0f3
diff --git a/packages/test-support/session-snapshot/README.md b/packages/test-support/session-snapshot/README.md
index 533baf73e4..55580faef3 100644
--- a/packages/test-support/session-snapshot/README.md
+++ b/packages/test-support/session-snapshot/README.md
@@ -70,7 +70,7 @@ defineAcpSnapshotSuite({
Each recorded-session directory carries a closed `snapshot.yml` manifest plus canonical parent and contiguous child roles. Parent filenames are `session[.vN].jsonl`; children are `session.[.vN].jsonl`; v0 omits `.v0`, positive versions use lowercase `.vN`, and every filename agrees with its header. A role may retain older generations, but the harness selects the numerically highest one. An owning manifest may declare `sessionFormat.version` plus one or more closed `coverage` names to keep that historical generation as an explicit migration fixture; absence tracks the current writer. The manifest also names the scenario, shipped profile, composition/header class, recording source, and only the replay, platform, permission, environment, workspace, or input facts the completed Session cannot reconstruct. Storage guards check tool results and portable paths in every selected parent and child role. Prompt/schema scrubbing, message identity, and prompt-before-request ordering apply to current generations; retained predecessors keep their historical representation. The adapter registers expected-output, Session-log, and optional `workspace.expected/` comparisons; guards reject orphan directories, missing roles, noncanonical names, absolute paths, malformed manifests, and platform-specific separators.
-`normalizeSessionSnapshot` retains the complete Session header and event payloads but omits top-level `seq`/`time` envelopes from committed fixtures after normalizing paths and scrubbing system-prompt text and tool schemas; it also normalizes embedded stream clocks and historical packed-row `seq0`/`time0` envelopes. Replay synthesizes the top-level envelopes in memory, while runtime persistence continues to write complete logs. Multi-session comparison validates expected and harvested logs through the strict build-static Session format catalog before identity redaction and normalization; source filenames cannot alter format validation. A retained historical replay input is not the native V3 writer-output oracle: structural migration preserves request meaning but can produce a different event layout. Normalization preserves unexpected request-header fields, including `system`, so regressions remain visible. Versionless protocol-adapter unit fixtures remain outside the released Session format corpus. Current v3 fixtures use one row per event; retained v0/v1 fixtures may use canonical packed rows. The [temporary repository migrator](../../../scripts/migrate-packed-session-fixtures.ts) (`pnpm run migrate:packed-session-fixtures`) rewrites older historical layouts, and its [removal proposal](../../../.agents/notes/proposed/process/2026-07-26-remove-packed-session-fixture-migrator.md) owns its deletion.
+`normalizeSessionSnapshot` retains the complete Session header and event payloads but omits top-level `seq`/`time` envelopes from committed fixtures after normalizing paths and scrubbing system-prompt text and tool schemas; it also normalizes embedded stream clocks and historical packed-row `seq0`/`time0` envelopes, and catalog child-creation clocks. Replay synthesizes the top-level envelopes in memory, while runtime persistence continues to write complete logs. Multi-session comparison validates expected and harvested logs through the strict build-static Session format catalog before identity redaction and normalization; source filenames cannot alter format validation. A retained historical replay input is not the native V3 writer-output oracle: structural migration preserves request meaning but can produce a different event layout. Normalization preserves unexpected request-header fields, including `system`, so regressions remain visible. Versionless protocol-adapter unit fixtures remain outside the released Session format corpus. Current v3 fixtures use one row per event; retained v0/v1 fixtures may use canonical packed rows. The [temporary repository migrator](../../../scripts/migrate-packed-session-fixtures.ts) (`pnpm run migrate:packed-session-fixtures`) rewrites older historical layouts, and its [removal proposal](../../../.agents/notes/proposed/process/2026-07-26-remove-packed-session-fixture-migrator.md) owns its deletion.
Spill scenarios save through the real local provider under a private temporary root. Their fixture adapter exposes fixed-length logical locators and maps only this run’s saved locators back to real files for retrieval, preserving preview budgets without writing into a shared logical path. Known snapshot spill paths normalize to stable locator tokens, including paths quoted inside JSON omission notices with JSON-escaped Windows separators. Refresh extraction preserves the matched serialized path spelling for literal replacement. Normalization changes only the locator: saved byte lengths and omission counts remain comparison evidence.
diff --git a/packages/test-support/session-snapshot/README.zh.md b/packages/test-support/session-snapshot/README.zh.md
index c3926c3e7d..9c23a09a75 100644
--- a/packages/test-support/session-snapshot/README.zh.md
+++ b/packages/test-support/session-snapshot/README.zh.md
@@ -70,7 +70,7 @@ defineAcpSnapshotSuite({
每个已记录 Session 目录携带封闭的 `snapshot.yml` manifest,以及规范 parent 与连续 child 角色。parent 文件名是 `session[.vN].jsonl`;child 是 `session.[.vN].jsonl`;v0 省略 `.v0`,正版本使用小写 `.vN`,且每个文件名与其 header 一致。一个角色可以保留旧 generation,但 harness 会选择数值最高的一项。拥有 fixture 的 manifest 可以声明 `sessionFormat.version` 与一个或多个封闭 `coverage` 名称,把该历史 generation 保留为显式迁移 fixture;省略此字段时跟随当前 writer。manifest 还会指名场景、随附 profile、组合/header 类别、录制来源,以及已完成 Session 无法重建的 replay、平台、权限、环境、workspace 或输入事实。存储保护检查每个选定 parent 与 child 角色的工具结果和可移植路径。提示词/schema 擦除、消息身份及提示词先于请求的顺序检查适用于当前 generation;保留的前代维持其历史表示。适配器注册预期输出、Session 日志与可选 `workspace.expected/` 比较;保护会拒绝遗留目录、缺失角色、非规范名称、绝对路径、malformed manifest 与平台专用分隔符。
-`normalizeSessionSnapshot` 在规范化路径并擦除系统提示文本与工具 schema 后,会保留完整 Session header 与事件 payload,但从已提交 fixture 中省略顶层 `seq`/`time` envelope;它还会规范化嵌入式 stream clock 与历史 packed-row 的 `seq0`/`time0` envelope。Replay 只在内存中合成顶层 envelope,而运行时持久化仍写入完整日志。多 Session 比较会先通过严格的构建期静态 Session 格式目录校验预期日志与收集日志,再进行身份脱敏与规范化;来源文件名不能改变格式校验。保留的历史 replay 输入不是原生 V3 writer 输出的比较基准:结构迁移保留请求含义,但可以产生不同的事件布局。归一化保留意外的 request-header 字段(包括 `system`),使回归保持可见。无版本的协议适配器单元测试 fixture 不属于已发布 Session 格式语料。当前 v3 fixture 每个事件占一行;保留的 v0/v1 fixture 可以使用规范 packed row。[临时仓库迁移器](../../../scripts/migrate-packed-session-fixtures.ts)(`pnpm run migrate:packed-session-fixtures`)会改写更旧的历史布局,由其[移除提案](../../../.agents/notes/proposed/process/2026-07-26-remove-packed-session-fixture-migrator.zh.md)负责删除该迁移器。
+`normalizeSessionSnapshot` 在规范化路径并擦除系统提示文本与工具 schema 后,会保留完整 Session header 与事件 payload,但从已提交 fixture 中省略顶层 `seq`/`time` envelope;它还会规范化嵌入式 stream clock 与历史 packed-row 的 `seq0`/`time0` envelope 与 catalog child 创建时钟。Replay 只在内存中合成顶层 envelope,而运行时持久化仍写入完整日志。多 Session 比较会先通过严格的构建期静态 Session 格式目录校验预期日志与收集日志,再进行身份脱敏与规范化;来源文件名不能改变格式校验。保留的历史 replay 输入不是原生 V3 writer 输出的比较基准:结构迁移保留请求含义,但可以产生不同的事件布局。归一化保留意外的 request-header 字段(包括 `system`),使回归保持可见。无版本的协议适配器单元测试 fixture 不属于已发布 Session 格式语料。当前 v3 fixture 每个事件占一行;保留的 v0/v1 fixture 可以使用规范 packed row。[临时仓库迁移器](../../../scripts/migrate-packed-session-fixtures.ts)(`pnpm run migrate:packed-session-fixtures`)会改写更旧的历史布局,由其[移除提案](../../../.agents/notes/proposed/process/2026-07-26-remove-packed-session-fixture-migrator.zh.md)负责删除该迁移器。
Spill 场景通过真实本地 provider 保存到私有临时根目录。夹具适配器提供固定长度的逻辑定位符,并仅将本次运行已保存的定位符映射回实际文件以供检索,在不写入共享逻辑路径的情况下保留预览预算。已知的快照 spill 路径会规范化为稳定的定位信息 token,包括 JSON 省略通知中带引号、使用 JSON 转义 Windows 分隔符的路径。刷新提取会保留匹配路径的序列化写法,以便进行字面替换。规范化只改变定位信息:保存字节数与省略计数仍作为比较证据。
diff --git a/packages/test-support/session-snapshot/src/index.ts b/packages/test-support/session-snapshot/src/index.ts
index 1b53cccfe2..eb4d900a74 100644
--- a/packages/test-support/session-snapshot/src/index.ts
+++ b/packages/test-support/session-snapshot/src/index.ts
@@ -44,6 +44,7 @@ export {
normalizeSessionSnapshot,
normalizeSessionSnapshots,
normalizeStdout,
+ omitSubagentCatalogForHistoricalComparison,
scrubModelRequestBulk,
scrubSessionSnapshot,
scrubSystemPrompts,
diff --git a/packages/test-support/session-snapshot/src/normalize.ts b/packages/test-support/session-snapshot/src/normalize.ts
index c0624918f3..2a4145fe80 100644
--- a/packages/test-support/session-snapshot/src/normalize.ts
+++ b/packages/test-support/session-snapshot/src/normalize.ts
@@ -33,6 +33,31 @@ function omitFixtureEnvelope(record: Record): void {
delete record.time0
}
+/** Return a catalog event's child id, or undefined for every ordering barrier. */
+function catalogChildId(event: { readonly type: string; readonly data?: unknown }): string | undefined {
+ if (event.type !== 'subagent/catalog' || event.data === null || typeof event.data !== 'object') return undefined
+ const data = event.data as { childId?: unknown }
+ return typeof data.childId === 'string' ? data.childId : undefined
+}
+
+/** Sort commutative adjacent catalog facts without crossing another event. */
+function canonicalizeCatalogRuns(events: readonly T[]): T[] {
+ const canonical = [...events]
+ let start = 0
+ while (start < canonical.length) {
+ if (catalogChildId(canonical[start] as T) === undefined) {
+ start += 1
+ continue
+ }
+ let end = start + 1
+ while (end < canonical.length && catalogChildId(canonical[end] as T) !== undefined) end += 1
+ canonical.splice(start, end - start, ...canonical.slice(start, end).sort((left, right) =>
+ (catalogChildId(left) as string).localeCompare(catalogChildId(right) as string)))
+ start = end
+ }
+ return canonical
+}
+
/** A cwd-rooted path after volatile cwd replacement, through its last separator-delimited segment. */
const CWD_ROOTED_PATH_RE = /\{\{cwd\}\}(?:[\\/][^\s<>"'`]+)+/g
const PATH_TAG_RE = /()([^<]*)(<\/path>)/g
@@ -325,8 +350,9 @@ export function normalizeStdout(
/**
* Normalize a session JSONL log into a stable expected output: the header line's
* volatile fields (`createdAt`, `id`, `cwd`) are zeroed/scrubbed; event,
- * historical packed-row, embedded Assistant-stream, and goal lifecycle clocks
- * are zeroed; and all volatile strings are scrubbed. Projected inputs remain
+ * historical packed-row, embedded Assistant-stream, goal lifecycle, and
+ * catalog child-creation clocks are zeroed; and all volatile strings are
+ * scrubbed. Projected inputs remain
* projected. Packed `data.dt` gaps are normalized even when the projected row
* omits its `time0` anchor.
* Output is JSONL in the same shape as the input — one compact record per
@@ -381,6 +407,10 @@ export function normalizeSessionLog(
if ('createdAt' in data) data.createdAt = 0
if ('updatedAt' in data) data.updatedAt = 0
}
+ if (record.type === 'subagent/catalog' && record.data !== null && typeof record.data === 'object') {
+ const data = record.data as Record
+ if ('childCreatedAt' in data) data.childCreatedAt = 0
+ }
if (Object.hasOwn(record, 'sourceEventSeqs')) {
record.sourceEventSeqs = decodeSeqRanges(record.sourceEventSeqs)
}
@@ -397,8 +427,10 @@ function projectSessionSnapshot(rawLog: string): string {
const lines = rawLog.split('\n').filter(line => line.trim().length > 0)
const header = lines.shift() as string
- const body = lines.map((line) => {
- const record = JSON.parse(line) as Record
+ const records = canonicalizeCatalogRuns(lines.map((line) => {
+ return JSON.parse(line) as Record & { type: string }
+ }))
+ const body = records.map((record) => {
const projected = { ...record }
omitFixtureEnvelope(projected)
return JSON.stringify(projected)
@@ -450,6 +482,44 @@ export function normalizeSessionSnapshots(
))
}
+/**
+ * Omit current subagent discovery facts when comparing a fresh run with an
+ * immutable historical Session generation. The remaining source-event
+ * references are rebased to the projected stream and refuse to cite an
+ * omitted catalog event.
+ *
+ * @param rawLog - normalized current-format snapshot JSONL.
+ * @returns the snapshot without `subagent/catalog` events.
+ */
+export function omitSubagentCatalogForHistoricalComparison(rawLog: string): string {
+ const lines = rawLog.split('\n').filter(line => line.trim().length > 0)
+ const header = lines.shift()
+ if (header === undefined) throw new Error('session snapshot must start with a session header')
+ const events = lines.map(line => JSON.parse(line) as Record)
+ const omitted = new Set(events.flatMap((event, seq) => event.type === 'subagent/catalog' ? [seq] : []))
+ if (omitted.size === 0) return `${[header, ...lines].join('\n')}\n`
+
+ const retained = events.flatMap((event, seq) => {
+ if (omitted.has(seq)) return []
+ if (!Array.isArray(event.sourceEventSeqs)) return [event]
+ const sourceEventSeqs = event.sourceEventSeqs.map((source) => {
+ if (typeof source !== 'number' || !Number.isSafeInteger(source) || source < 0) {
+ throw new Error('normalized sourceEventSeqs must contain non-negative safe integers')
+ }
+ if (omitted.has(source)) {
+ throw new Error(`historical comparison cannot omit cited catalog event ${source}`)
+ }
+ let preceding = 0
+ for (const omittedSeq of omitted) {
+ if (omittedSeq < source) preceding += 1
+ }
+ return source - preceding
+ })
+ return [{ ...event, sourceEventSeqs }]
+ })
+ return [header, ...retained.map(event => JSON.stringify(event)), ''].join('\n')
+}
+
/**
* Omit the artifact header generation after official migration for comparison.
* Delivery and captured-source generations retain their opaque recorded values.
diff --git a/packages/test-support/session-snapshot/tests/normalize.spec.ts b/packages/test-support/session-snapshot/tests/normalize.spec.ts
index ffd6d2f24e..cfc02aaeab 100644
--- a/packages/test-support/session-snapshot/tests/normalize.spec.ts
+++ b/packages/test-support/session-snapshot/tests/normalize.spec.ts
@@ -7,6 +7,7 @@ import {
normalizeSessionSnapshot,
normalizeSessionSnapshots,
normalizeStdout,
+ omitSubagentCatalogForHistoricalComparison,
scrubModelRequestBulk,
scrubSessionSnapshot,
scrubSystemPrompts,
@@ -523,12 +524,35 @@ describe('normalizeSessionLog', () => {
expect(out).toContain('"operation":"resume"')
})
+ it('normalizes subagent catalog child creation clocks', () => {
+ const catalog = JSON.stringify({
+ type: 'subagent/catalog',
+ seq: 2,
+ time: 5,
+ data: {
+ version: 0,
+ childId: 'child',
+ childCreatedAt: 123,
+ mode: 'one-shot',
+ },
+ })
+ const out = normalizeSessionLog(`${header({})}\n${catalog}\n`, ctx)
+ expect(out).toContain('"childCreatedAt":0')
+ })
+
it('handles complete envelopes when optional normalized fields are absent', () => {
const bareHeader = JSON.stringify({ type: 'session', id: 's' })
const bareHook = JSON.stringify({ type: 'hook/result', seq: 2, time: 5, data: { decision: 'allow' } })
const nullDataHook = JSON.stringify({ type: 'hook/result', seq: 3, time: 6, data: null })
- const out = normalizeSessionLog(`${bareHeader}\n${bareHook}\n${nullDataHook}\n`, ctx)
+ const bareCatalog = JSON.stringify({
+ type: 'subagent/catalog',
+ seq: 4,
+ time: 7,
+ data: { version: 0 },
+ })
+ const out = normalizeSessionLog(`${bareHeader}\n${bareHook}\n${nullDataHook}\n${bareCatalog}\n`, ctx)
expect(out).toContain('"decision":"allow"')
+ expect(out).toContain('"version":0')
expect(out).not.toContain('durationMs')
})
})
@@ -597,6 +621,69 @@ describe('normalizeSessionSnapshot', () => {
].join('\n'))
})
+ it('orders adjacent catalog facts by child id', () => {
+ const raw = [
+ JSON.stringify({ type: 'session', version: 0 }),
+ JSON.stringify({ type: 'tool/call', data: { callId: 'parallel' } }),
+ JSON.stringify({
+ type: 'subagent/catalog',
+ data: { version: 0, childId: '{{session:3}}', childCreatedAt: 123, mode: 'one-shot' },
+ }),
+ JSON.stringify({
+ type: 'subagent/catalog',
+ data: { version: 0, childId: '{{session:2}}', childCreatedAt: 124, mode: 'one-shot' },
+ }),
+ JSON.stringify({ type: 'tool/result', data: { callId: 'parallel' } }),
+ ].join('\n') + '\n'
+ const normalized = normalizeSessionSnapshot(raw, ctx)
+ expect(normalized.indexOf('{{session:2}}')).toBeLessThan(normalized.indexOf('{{session:3}}'))
+ expect(normalized).toContain('"childCreatedAt":0')
+ })
+
+ it('treats malformed catalog facts as ordering barriers', () => {
+ const raw = [
+ JSON.stringify({ type: 'session', version: 0 }),
+ JSON.stringify({
+ type: 'subagent/catalog',
+ data: { version: 0, childId: '{{session:2}}', childCreatedAt: 1, mode: 'one-shot' },
+ }),
+ JSON.stringify({
+ type: 'subagent/catalog',
+ data: { version: 0, childId: 3, childCreatedAt: 3, mode: 'one-shot' },
+ }),
+ ].join('\n') + '\n'
+ const normalized = normalizeSessionSnapshot(raw, ctx)
+ expect(normalized).toContain('{{session:2}}')
+ expect(normalized).toContain('"childId":3')
+ })
+
+ it('omits current catalog facts and rebases source references for historical comparison', () => {
+ const normalized = [
+ JSON.stringify({ type: 'session', id: '{{session:1}}' }),
+ JSON.stringify({ type: 'tool/call', data: { callId: 'first' } }),
+ JSON.stringify({
+ type: 'subagent/catalog',
+ data: { version: 0, childId: '{{session:2}}', childCreatedAt: 0, mode: 'one-shot' },
+ }),
+ JSON.stringify({ type: 'tool/result', data: { callId: 'first' }, sourceEventSeqs: [0] }),
+ JSON.stringify({ type: 'tool/call', data: { callId: 'second' } }),
+ JSON.stringify({
+ type: 'subagent/catalog',
+ data: { version: 0, childId: '{{session:3}}', childCreatedAt: 0, mode: 'one-shot' },
+ }),
+ JSON.stringify({ type: 'tool/result', data: { callId: 'second' }, sourceEventSeqs: [3] }),
+ '',
+ ].join('\n')
+ expect(omitSubagentCatalogForHistoricalComparison(normalized)).toBe([
+ JSON.stringify({ type: 'session', id: '{{session:1}}' }),
+ JSON.stringify({ type: 'tool/call', data: { callId: 'first' } }),
+ JSON.stringify({ type: 'tool/result', data: { callId: 'first' }, sourceEventSeqs: [0] }),
+ JSON.stringify({ type: 'tool/call', data: { callId: 'second' } }),
+ JSON.stringify({ type: 'tool/result', data: { callId: 'second' }, sourceEventSeqs: [2] }),
+ '',
+ ].join('\n'))
+ })
+
it('migrates and re-packs multi-session fixtures after relationship-preserving id redaction', () => {
const raw = [
JSON.stringify({ type: 'session', version: 0, id: '{{session:1}}', createdAt: 0, delegationDepth: 0 }),
diff --git a/python/sdk/tests/test_smoke_model.py b/python/sdk/tests/test_smoke_model.py
index 37d584f76e..5b950f98e3 100644
--- a/python/sdk/tests/test_smoke_model.py
+++ b/python/sdk/tests/test_smoke_model.py
@@ -223,6 +223,27 @@ def test_mcp_smoke_accepts_the_external_server_result() -> None:
)
+def test_advanced_snapshot_normalizes_catalog_child_creation_time() -> None:
+ value = {
+ "type": "subagent/catalog",
+ "data": {
+ "childCreatedAt": 1788246207176,
+ },
+ }
+
+ assert SMOKE["normalize_snapshot_value"](value, []) == {
+ "type": "subagent/catalog",
+ "data": {
+ "childCreatedAt": 0,
+ },
+ }
+
+ assert SMOKE["normalize_snapshot_value"](
+ {"type": "fixture/event", "data": {"childCreatedAt": 1788246207176}},
+ [],
+ ) == {"type": "fixture/event", "data": {"childCreatedAt": 1788246207176}}
+
+
def test_snapshot_comparison_preserves_opaque_generation_provenance() -> None:
normalize = SMOKE["normalize_session_format_comparison"]
expected = {
diff --git a/scripts/smoke-python-runtime.py b/scripts/smoke-python-runtime.py
index 760e6c7bae..e8719f0709 100644
--- a/scripts/smoke-python-runtime.py
+++ b/scripts/smoke-python-runtime.py
@@ -2158,6 +2158,10 @@ def normalize_snapshot_value(
}
if normalized.get("type") == "session" and "createdAt" in normalized:
normalized["createdAt"] = 0
+ if normalized.get("type") == "subagent/catalog":
+ data = normalized.get("data")
+ if isinstance(data, dict) and "childCreatedAt" in data:
+ data["childCreatedAt"] = 0
if "seq" in normalized and "time" in normalized:
normalized["time"] = 0
if normalized.get("type") in ("assistant/message", "assistant/attempt"):
diff --git a/scripts/snapshots/python-sdk-single-exe/advanced/session.v2.jsonl b/scripts/snapshots/python-sdk-single-exe/advanced/session.v2.jsonl
index 651f662c19..a3c3e49f68 100644
--- a/scripts/snapshots/python-sdk-single-exe/advanced/session.v2.jsonl
+++ b/scripts/snapshots/python-sdk-single-exe/advanced/session.v2.jsonl
@@ -35,27 +35,29 @@
{"type":"session-log-deepseek/delivery-accepted","data":{"sessionId":"{{parent}}","sessionFormatVersion":2,"throughSeq":32}}
{"type":"assistant/message","data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\": \"Check direct child\", \"prompt\": \"Reply with exactly DIRECT_CHILD_OK and nothing else.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"smoke-model"},"id":"{{messageId}}"},"usage":{"inputTokens":3,"outputTokens":3,"totalTokens":6},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":0,"index":0,"dt":[],"id":"advanced-direct-child","name":"subagent","args":["{\"description\": \"Check direct child\", \"prompt\": \"Reply with exactly DIRECT_CHILD_OK and nothing else.\"}"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\": \"Check direct child\", \"prompt\": \"Reply with exactly DIRECT_CHILD_OK and nothing else.\"}"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3,"totalTokens":6}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":4,"callId":"advanced-direct-child","name":"subagent","arguments":"{\"description\": \"Check direct child\", \"prompt\": \"Reply with exactly DIRECT_CHILD_OK and nothing else.\"}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{child-1}}","childCreatedAt":0,"mode":"one-shot","label":"Check direct child"}}
{"type":"tool/result","data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"advanced-direct-child"},"content":[{"type":"tool-result","toolCallId":"advanced-direct-child","content":[{"type":"text","text":"DIRECT_CHILD_OK"}],"isError":false}],"role":"user","id":"{{messageId}}"}},"sourceEventSeqs":[35],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":4}}
{"type":"step/start","data":{"turn":1,"step":5}}
-{"type":"session-log-deepseek/delivery-accepted","data":{"sessionId":"{{parent}}","sessionFormatVersion":2,"throughSeq":38}}
+{"type":"session-log-deepseek/delivery-accepted","data":{"sessionId":"{{parent}}","sessionFormatVersion":2,"throughSeq":39}}
{"type":"assistant/message","data":{"turn":1,"step":5,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\": \"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\", \"meta\": {\"name\": \"advanced-exe-snapshot\", \"description\": \"exercise one packaged workflow child\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"smoke-model"},"id":"{{messageId}}"},"usage":{"inputTokens":3,"outputTokens":3,"totalTokens":6},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":0,"index":0,"dt":[],"id":"advanced-workflow","name":"workflow","args":["{\"script\": \"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\", \"meta\": {\"name\": \"advanced-exe-snapshot\", \"description\": \"exercise one packaged workflow child\"}}"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\": \"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\", \"meta\": {\"name\": \"advanced-exe-snapshot\", \"description\": \"exercise one packaged workflow child\"}}"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3,"totalTokens":6}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":5,"callId":"advanced-workflow","name":"workflow","arguments":"{\"script\": \"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\", \"meta\": {\"name\": \"advanced-exe-snapshot\", \"description\": \"exercise one packaged workflow child\"}}"}}
{"type":"tool-workflow/run-start","data":{"runId":"{{workflow-run}}","name":"advanced-exe-snapshot"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{child-2}}","childCreatedAt":0,"mode":"one-shot"}}
{"type":"tool-workflow/agent-start","data":{"runId":"{{workflow-run}}","seq":1,"label":"workflow-child","phase":"Delegate","childId":"{{child-2}}"}}
{"type":"tool-workflow/agent-end","data":{"runId":"{{workflow-run}}","seq":1,"outcome":"completed"}}
{"type":"tool-workflow/run-end","data":{"runId":"{{workflow-run}}","stopReason":"completed"}}
-{"type":"tool/result","data":{"turn":1,"step":5,"message":{"source":{"kind":"tool","callId":"advanced-workflow"},"content":[{"type":"tool-result","toolCallId":"advanced-workflow","content":[{"type":"text","text":"workflow \"advanced-exe-snapshot\" completed (1 agent).\nReturn value:\n{\n \"reply\": \"WORKFLOW_CHILD_OK\"\n}"}],"isError":false}],"role":"user","id":"{{messageId}}"}},"sourceEventSeqs":[41],"surfaceOp":"append"}
+{"type":"tool/result","data":{"turn":1,"step":5,"message":{"source":{"kind":"tool","callId":"advanced-workflow"},"content":[{"type":"tool-result","toolCallId":"advanced-workflow","content":[{"type":"text","text":"workflow \"advanced-exe-snapshot\" completed (1 agent).\nReturn value:\n{\n \"reply\": \"WORKFLOW_CHILD_OK\"\n}"}],"isError":false}],"role":"user","id":"{{messageId}}"}},"sourceEventSeqs":[42],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":5}}
{"type":"step/start","data":{"turn":1,"step":6}}
-{"type":"session-log-deepseek/delivery-accepted","data":{"sessionId":"{{parent}}","sessionFormatVersion":2,"throughSeq":48}}
+{"type":"session-log-deepseek/delivery-accepted","data":{"sessionId":"{{parent}}","sessionFormatVersion":2,"throughSeq":50}}
{"type":"assistant/message","data":{"turn":1,"step":6,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\": \"snap-1\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"smoke-model"},"id":"{{messageId}}"},"usage":{"inputTokens":3,"outputTokens":3,"totalTokens":6},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":0,"index":0,"dt":[],"id":"advanced-undefine","name":"cordis_undefine","args":["{\"pluginId\": \"snap-1\"}"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\": \"snap-1\"}"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3,"totalTokens":6}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":6,"callId":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\": \"snap-1\"}"}}
-{"type":"tool/result","data":{"turn":1,"step":6,"message":{"source":{"kind":"tool","callId":"advanced-undefine"},"content":[{"type":"tool-result","toolCallId":"advanced-undefine","content":[{"type":"text","text":"Removed dynamic Plugin snap-1 and all of its Packages."}],"isError":false}],"role":"user","id":"{{messageId}}"}},"sourceEventSeqs":[51],"surfaceOp":"append"}
+{"type":"tool/result","data":{"turn":1,"step":6,"message":{"source":{"kind":"tool","callId":"advanced-undefine"},"content":[{"type":"tool-result","toolCallId":"advanced-undefine","content":[{"type":"text","text":"Removed dynamic Plugin snap-1 and all of its Packages."}],"isError":false}],"role":"user","id":"{{messageId}}"}},"sourceEventSeqs":[53],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":6}}
{"type":"step/start","data":{"turn":1,"step":7}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"smoke-model","maxTokens":256000,"reasoningEffort":"high"},"adapterDefaults":{"reasoningEffort":true,"maxTokens":true},"system":"{{system}}","tools":["cordis_define","cordis_inspect_list","cordis_inspect_query","cordis_inspect_self","cordis_run","cordis_stop","cordis_undefine","job_kill","job_list","job_output","run_code","subagent","workflow"]},"reason":"change"}}
-{"type":"session-log-deepseek/delivery-accepted","data":{"sessionId":"{{parent}}","sessionFormatVersion":2,"throughSeq":55}}
+{"type":"session-log-deepseek/delivery-accepted","data":{"sessionId":"{{parent}}","sessionFormatVersion":2,"throughSeq":57}}
{"type":"assistant/message","data":{"turn":1,"step":7,"message":{"role":"assistant","content":[{"type":"text","text":"ADVANCED_EXECUTABLE_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"smoke-model"},"id":"{{message:1}}"},"usage":{"inputTokens":3,"outputTokens":3,"totalTokens":6},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":0,"index":0,"dt":[],"texts":["ADVANCED_EXECUTABLE_OK"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"ADVANCED_EXECUTABLE_OK"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3,"totalTokens":6}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":7}}
{"type":"command/run","data":{"commandId":"{{command:1}}","name":"feedback","source":{"kind":"user"}}}
diff --git a/snapshots/sdk/subagent-continuable-inheritance/session.v2.jsonl b/snapshots/sdk/subagent-continuable-inheritance/session.v2.jsonl
index a4d9939d8d..53e7059320 100644
--- a/snapshots/sdk/subagent-continuable-inheritance/session.v2.jsonl
+++ b/snapshots/sdk/subagent-continuable-inheritance/session.v2.jsonl
@@ -12,12 +12,13 @@
{"type":"session/title","data":{"title":"Follow these steps exactly, then","messageSeqs":[8],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788199056889,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788199056889,"index":0,"dt":[],"id":"call_bg_start","name":"subagent","args":["{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"]},{"type":"chunk","time":1788199056889,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}}},{"type":"chunk","time":1788199056889,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788199056889,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500533971,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500533971,"index":0,"dt":[],"id":"call_bg_start","name":"subagent","args":["{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"]},{"type":"chunk","time":1788500533971,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}}},{"type":"chunk","time":1788500533971,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500533971,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500533982,"mode":"continuable","label":"Reply with CHILD_OK"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_bg_start"},"content":[{"type":"tool-result","toolCallId":"call_bg_start","content":[{"type":"text","text":"started subagent {{session:2}}"}],"isError":false}],"role":"user","id":"{{message:4}}"}},"sourceEventSeqs":[14],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788199056914,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788199056914,"index":0,"dt":[],"texts":["SUBAGENT_SETTLED_NOTED"]},{"type":"chunk","time":1788199056914,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}}},{"type":"chunk","time":1788199056914,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788199056914,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500534017,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500534017,"index":0,"dt":[],"texts":["SUBAGENT_SETTLED_NOTED"]},{"type":"chunk","time":1788500534017,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}}},{"type":"chunk","time":1788500534017,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500534017,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Background subagent {{session:2}} finished and will do no further work unless you send it more."},{"type":"text","text":"Its closing message:"},{"type":"text","text":"CHILD_OK"}],"source":{"kind":"subagent-settled","form":"notice","summary":"Background subagent {{session:2}} finished and will do no further work unless you send it more.","senderSessionId":"{{session:2}}"},"role":"user","id":"{{message:6}}"}]}}
@@ -25,6 +26,6 @@
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","data":{"turn":2,"step":1}}
{"type":"user/message","data":{"content":[{"type":"text","text":"Background subagent {{session:2}} finished and will do no further work unless you send it more."},{"type":"text","text":"Its closing message:"},{"type":"text","text":"CHILD_OK"}],"source":{"kind":"subagent-settled","form":"notice","summary":"Background subagent {{session:2}} finished and will do no further work unless you send it more.","senderSessionId":"{{session:2}}"},"role":"user","id":"{{message:6}}"},"surfaceOp":"append"}
-{"type":"assistant/attempt","data":{"turn":2,"step":1,"stream":[{"type":"chunk","time":1788199056967,"chunk":{"type":"finish","reason":{"kind":"error","failure":{"message":"llm-replay: script exhausted — session requested model call #4 but its script has only 3; re-record the scenario","code":"UNKNOWN"}}}}]}}
+{"type":"assistant/attempt","data":{"turn":2,"step":1,"stream":[{"type":"chunk","time":1788500534037,"chunk":{"type":"finish","reason":{"kind":"error","failure":{"message":"llm-replay: script exhausted — session requested model call #4 but its script has only 3; re-record the scenario","code":"UNKNOWN"}}}}]}}
{"type":"step/end","data":{"turn":2,"step":1}}
{"type":"turn/end","data":{"turn":2,"reason":{"kind":"error","error":{"message":"llm-replay: script exhausted — session requested model call #4 but its script has only 3; re-record the scenario","code":"UNKNOWN"}}}}
diff --git a/snapshots/sdk/subagent-continuable/session.v2.jsonl b/snapshots/sdk/subagent-continuable/session.v2.jsonl
index 99fa92dba8..fe561fdf71 100644
--- a/snapshots/sdk/subagent-continuable/session.v2.jsonl
+++ b/snapshots/sdk/subagent-continuable/session.v2.jsonl
@@ -11,27 +11,28 @@
{"type":"session/title","data":{"title":"Follow these steps exactly, then","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788269696592,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788269696592,"index":0,"dt":[],"id":"call_bg_start","name":"subagent","args":["{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"]},{"type":"chunk","time":1788269696592,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}}},{"type":"chunk","time":1788269696592,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788269696592,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500520579,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500520579,"index":0,"dt":[],"id":"call_bg_start","name":"subagent","args":["{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"]},{"type":"chunk","time":1788500520579,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}}},{"type":"chunk","time":1788500520579,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500520579,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500520585,"mode":"continuable","label":"Reply with CHILD_OK"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_bg_start"},"content":[{"type":"tool-result","toolCallId":"call_bg_start","content":[{"type":"text","text":"started subagent {{session:2}}"}],"isError":false}],"role":"user","id":"{{message:4}}"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_followup_1","name":"send_message","arguments":"{\"agent_id\": \"{{session:2}}\", \"message\": \"Now reply with exactly SECOND_OK.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788269696618,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788269696618,"index":0,"dt":[],"id":"call_followup_1","name":"send_message","args":["{\"agent_id\": \"{{session:2}}\", \"message\": \"Now reply with exactly SECOND_OK.\"}"]},{"type":"chunk","time":1788269696618,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_followup_1","name":"send_message","arguments":"{\"agent_id\": \"{{session:2}}\", \"message\": \"Now reply with exactly SECOND_OK.\"}"}}},{"type":"chunk","time":1788269696618,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788269696618,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_followup_1","name":"send_message","arguments":"{\"agent_id\": \"{{session:2}}\", \"message\": \"Now reply with exactly SECOND_OK.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500520615,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500520615,"index":0,"dt":[],"id":"call_followup_1","name":"send_message","args":["{\"agent_id\": \"{{session:2}}\", \"message\": \"Now reply with exactly SECOND_OK.\"}"]},{"type":"chunk","time":1788500520615,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_followup_1","name":"send_message","arguments":"{\"agent_id\": \"{{session:2}}\", \"message\": \"Now reply with exactly SECOND_OK.\"}"}}},{"type":"chunk","time":1788500520615,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500520615,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":2,"callId":"call_followup_1","name":"send_message","arguments":"{\"agent_id\": \"{{session:2}}\", \"message\": \"Now reply with exactly SECOND_OK.\"}"}}
-{"type":"tool/result","data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"call_followup_1"},"content":[{"type":"tool-result","toolCallId":"call_followup_1","content":[{"type":"text","text":"message delivered to agent {{session:2}}"}],"isError":false}],"role":"user","id":"{{message:6}}"}},"sourceEventSeqs":[18],"surfaceOp":"append"}
+{"type":"tool/result","data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"call_followup_1"},"content":[{"type":"tool-result","toolCallId":"call_followup_1","content":[{"type":"text","text":"message delivered to agent {{session:2}}"}],"isError":false}],"role":"user","id":"{{message:6}}"}},"sourceEventSeqs":[19],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"step/start","data":{"turn":1,"step":3}}
-{"type":"assistant/message","data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_followup_2","name":"send_message","arguments":"{\"agent_id\": \"{{session:2}}\", \"message\": \"Now reply with exactly THIRD_OK.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788269696641,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788269696642,"index":0,"dt":[],"id":"call_followup_2","name":"send_message","args":["{\"agent_id\": \"{{session:2}}\", \"message\": \"Now reply with exactly THIRD_OK.\"}"]},{"type":"chunk","time":1788269696642,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_followup_2","name":"send_message","arguments":"{\"agent_id\": \"{{session:2}}\", \"message\": \"Now reply with exactly THIRD_OK.\"}"}}},{"type":"chunk","time":1788269696642,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788269696642,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_followup_2","name":"send_message","arguments":"{\"agent_id\": \"{{session:2}}\", \"message\": \"Now reply with exactly THIRD_OK.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500520635,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500520635,"index":0,"dt":[],"id":"call_followup_2","name":"send_message","args":["{\"agent_id\": \"{{session:2}}\", \"message\": \"Now reply with exactly THIRD_OK.\"}"]},{"type":"chunk","time":1788500520635,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_followup_2","name":"send_message","arguments":"{\"agent_id\": \"{{session:2}}\", \"message\": \"Now reply with exactly THIRD_OK.\"}"}}},{"type":"chunk","time":1788500520635,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500520635,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":3,"callId":"call_followup_2","name":"send_message","arguments":"{\"agent_id\": \"{{session:2}}\", \"message\": \"Now reply with exactly THIRD_OK.\"}"}}
-{"type":"tool/result","data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"call_followup_2"},"content":[{"type":"tool-result","toolCallId":"call_followup_2","content":[{"type":"text","text":"message delivered to agent {{session:2}}"}],"isError":false}],"role":"user","id":"{{message:8}}"}},"sourceEventSeqs":[23],"surfaceOp":"append"}
+{"type":"tool/result","data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"call_followup_2"},"content":[{"type":"tool-result","toolCallId":"call_followup_2","content":[{"type":"text","text":"message delivered to agent {{session:2}}"}],"isError":false}],"role":"user","id":"{{message:8}}"}},"sourceEventSeqs":[24],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":3}}
{"type":"step/start","data":{"turn":1,"step":4}}
-{"type":"assistant/message","data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_followup_unknown","name":"send_message","arguments":"{\"agent_id\": \"22222222-2222-4222-8222-222222222222\", \"message\": \"Please continue.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:9}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788269696663,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788269696664,"index":0,"dt":[],"id":"call_followup_unknown","name":"send_message","args":["{\"agent_id\": \"22222222-2222-4222-8222-222222222222\", \"message\": \"Please continue.\"}"]},{"type":"chunk","time":1788269696664,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_followup_unknown","name":"send_message","arguments":"{\"agent_id\": \"22222222-2222-4222-8222-222222222222\", \"message\": \"Please continue.\"}"}}},{"type":"chunk","time":1788269696664,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788269696664,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_followup_unknown","name":"send_message","arguments":"{\"agent_id\": \"22222222-2222-4222-8222-222222222222\", \"message\": \"Please continue.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:9}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500520648,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500520648,"index":0,"dt":[],"id":"call_followup_unknown","name":"send_message","args":["{\"agent_id\": \"22222222-2222-4222-8222-222222222222\", \"message\": \"Please continue.\"}"]},{"type":"chunk","time":1788500520648,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_followup_unknown","name":"send_message","arguments":"{\"agent_id\": \"22222222-2222-4222-8222-222222222222\", \"message\": \"Please continue.\"}"}}},{"type":"chunk","time":1788500520648,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500520648,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":4,"callId":"call_followup_unknown","name":"send_message","arguments":"{\"agent_id\": \"22222222-2222-4222-8222-222222222222\", \"message\": \"Please continue.\"}"}}
-{"type":"tool/result","data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"call_followup_unknown"},"content":[{"type":"tool-result","toolCallId":"call_followup_unknown","content":[{"type":"text","text":"Error: subagent \"22222222-2222-4222-8222-222222222222\" is unavailable"}],"isError":true}],"role":"user","id":"{{message:10}}"},"error":{"name":"SubagentError","code":"NOT_RESUMABLE"}},"sourceEventSeqs":[28],"surfaceOp":"append"}
+{"type":"tool/result","data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"call_followup_unknown"},"content":[{"type":"tool-result","toolCallId":"call_followup_unknown","content":[{"type":"text","text":"Error: subagent \"22222222-2222-4222-8222-222222222222\" is unavailable"}],"isError":true}],"role":"user","id":"{{message:10}}"},"error":{"name":"SubagentError","code":"NOT_RESUMABLE"}},"sourceEventSeqs":[29],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":4}}
{"type":"step/start","data":{"turn":1,"step":5}}
-{"type":"assistant/message","data":{"turn":1,"step":5,"message":{"role":"assistant","content":[{"type":"text","text":"DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:11}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788269696680,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788269696680,"index":0,"dt":[],"texts":["DONE"]},{"type":"chunk","time":1788269696681,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DONE"}}},{"type":"chunk","time":1788269696681,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788269696681,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":5,"message":{"role":"assistant","content":[{"type":"text","text":"DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:11}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500520662,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500520662,"index":0,"dt":[],"texts":["DONE"]},{"type":"chunk","time":1788500520662,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DONE"}}},{"type":"chunk","time":1788500520662,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500520662,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":5}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Background subagent {{session:2}} finished and will do no further work unless you send it more."},{"type":"text","text":"Its closing message:"},{"type":"text","text":"SECOND_OK"}],"source":{"kind":"subagent-settled","form":"notice","summary":"Background subagent {{session:2}} finished and will do no further work unless you send it more.","senderSessionId":"{{session:2}}"},"role":"user","id":"{{message:12}}"}]}}
@@ -39,6 +40,6 @@
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","data":{"turn":2,"step":1}}
{"type":"user/message","data":{"content":[{"type":"text","text":"Background subagent {{session:2}} finished and will do no further work unless you send it more."},{"type":"text","text":"Its closing message:"},{"type":"text","text":"SECOND_OK"}],"source":{"kind":"subagent-settled","form":"notice","summary":"Background subagent {{session:2}} finished and will do no further work unless you send it more.","senderSessionId":"{{session:2}}"},"role":"user","id":"{{message:12}}"},"surfaceOp":"append"}
-{"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:13}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788269696729,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788269696729,"index":0,"dt":[],"texts":["SUBAGENT_SETTLED_NOTED"]},{"type":"chunk","time":1788269696729,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}}},{"type":"chunk","time":1788269696729,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788269696729,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:13}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500520702,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500520702,"index":0,"dt":[],"texts":["SUBAGENT_SETTLED_NOTED"]},{"type":"chunk","time":1788500520702,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}}},{"type":"chunk","time":1788500520702,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500520702,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":2,"step":1}}
{"type":"turn/end","data":{"turn":2,"reason":{"kind":"completed"}}}
diff --git a/snapshots/sdk/subagent-fork-in-process/session.v2.jsonl b/snapshots/sdk/subagent-fork-in-process/session.v2.jsonl
index 5f0fdd60e1..f9f4398bfc 100644
--- a/snapshots/sdk/subagent-fork-in-process/session.v2.jsonl
+++ b/snapshots/sdk/subagent-fork-in-process/session.v2.jsonl
@@ -11,7 +11,7 @@
{"type":"session/title","data":{"title":"Remember this fact for later:","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to remember the codeword \"MARMALADE\" and reply with just \"OK\"."},{"type":"text","text":"OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":2885,"outputTokens":25,"cacheReadTokens":0,"reasoningTokens":23},"stream":[{"type":"chunk","time":1788199063113,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788199063113,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," user"," wants"," me"," to"," remember"," the"," cod","ew","ord"," \"","M","ARM","AL","ADE","\""," and"," reply"," with"," just"," \"","OK","\"."]},{"type":"chunk","time":1788199063113,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788199063113,"index":1,"dt":[],"texts":["OK"]},{"type":"chunk","time":1788199063113,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to remember the codeword \"MARMALADE\" and reply with just \"OK\"."}}},{"type":"chunk","time":1788199063113,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"OK"}}},{"type":"chunk","time":1788199063113,"chunk":{"type":"usage","usage":{"inputTokens":2885,"outputTokens":25,"cacheReadTokens":0,"reasoningTokens":23}}},{"type":"chunk","time":1788199063113,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to remember the codeword \"MARMALADE\" and reply with just \"OK\"."},{"type":"text","text":"OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":2885,"outputTokens":25,"cacheReadTokens":0,"reasoningTokens":23},"stream":[{"type":"chunk","time":1788500537271,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788500537272,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," user"," wants"," me"," to"," remember"," the"," cod","ew","ord"," \"","M","ARM","AL","ADE","\""," and"," reply"," with"," just"," \"","OK","\"."]},{"type":"chunk","time":1788500537272,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788500537272,"index":1,"dt":[],"texts":["OK"]},{"type":"chunk","time":1788500537272,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to remember the codeword \"MARMALADE\" and reply with just \"OK\"."}}},{"type":"chunk","time":1788500537272,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"OK"}}},{"type":"chunk","time":1788500537272,"chunk":{"type":"usage","usage":{"inputTokens":2885,"outputTokens":25,"cacheReadTokens":0,"reasoningTokens":23}}},{"type":"chunk","time":1788500537272,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Use the subagent_fork tool exactly once to delegate this subtask to a forked child agent: 'What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else.' The forked child inherits this conversation, so it can answer. After the subagent returns, reply with the single word PARENT_DONE and stop. Do not use the bash tool."}],"source":{"kind":"user"},"role":"user","id":"{{message:4}}"}]}}
@@ -19,11 +19,12 @@
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","data":{"turn":2,"step":1}}
{"type":"user/message","data":{"content":[{"type":"text","text":"Use the subagent_fork tool exactly once to delegate this subtask to a forked child agent: 'What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else.' The forked child inherits this conversation, so it can answer. After the subagent returns, reply with the single word PARENT_DONE and stop. Do not use the bash tool."}],"source":{"kind":"user"},"role":"user","id":"{{message:4}}"},"surfaceOp":"append"}
-{"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to use subagent_fork to delegate a question to a child agent. The child agent inherits this conversation and should be able to answer: the project codeword is MARMALADE. After the subagent returns, I should reply with PARENT_DONE."},{"type":"tool-call","id":"call_00_sAtKUseRzHRBvL4CF7XF1334","name":"subagent_fork","arguments":"{\"description\": \"Recall project codeword\", \"prompt\": \"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":158,"outputTokens":147,"cacheReadTokens":2816,"reasoningTokens":59},"stream":[{"type":"chunk","time":1788199063133,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788199063133,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," user"," wants"," me"," to"," use"," sub","agent","_f","ork"," to"," delegate"," a"," question"," to"," a"," child"," agent","."," The"," child"," agent"," inher","its"," this"," conversation"," and"," should"," be"," able"," to"," answer",":"," the"," project"," cod","ew","ord"," is"," MAR","M","AL","ADE","."," After"," the"," sub","agent"," returns",","," I"," should"," reply"," with"," PAR","ENT","_D","ONE","."]},{"type":"chunk","time":1788199063133,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788199063133,"index":1,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"id":"call_00_sAtKUseRzHRBvL4CF7XF1334","name":"subagent_fork","args":["","{","\"","description","\"",": ","\"","Recall"," project"," cod","ew","ord","\"",", ","\"","prom","pt","\"",": ","\"","What"," is"," the"," project"," cod","ew","ord"," mentioned"," earlier"," in"," this"," conversation","?"," Reply"," with"," exactly"," that"," one"," word"," and"," nothing"," else",".","\"","}"]},{"type":"chunk","time":1788199063133,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to use subagent_fork to delegate a question to a child agent. The child agent inherits this conversation and should be able to answer: the project codeword is MARMALADE. After the subagent returns, I should reply with PARENT_DONE."}}},{"type":"chunk","time":1788199063133,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_sAtKUseRzHRBvL4CF7XF1334","name":"subagent_fork","arguments":"{\"description\": \"Recall project codeword\", \"prompt\": \"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else.\"}"}}},{"type":"chunk","time":1788199063133,"chunk":{"type":"usage","usage":{"inputTokens":158,"outputTokens":147,"cacheReadTokens":2816,"reasoningTokens":59}}},{"type":"chunk","time":1788199063133,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to use subagent_fork to delegate a question to a child agent. The child agent inherits this conversation and should be able to answer: the project codeword is MARMALADE. After the subagent returns, I should reply with PARENT_DONE."},{"type":"tool-call","id":"call_00_sAtKUseRzHRBvL4CF7XF1334","name":"subagent_fork","arguments":"{\"description\": \"Recall project codeword\", \"prompt\": \"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":158,"outputTokens":147,"cacheReadTokens":2816,"reasoningTokens":59},"stream":[{"type":"chunk","time":1788500537291,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788500537291,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," user"," wants"," me"," to"," use"," sub","agent","_f","ork"," to"," delegate"," a"," question"," to"," a"," child"," agent","."," The"," child"," agent"," inher","its"," this"," conversation"," and"," should"," be"," able"," to"," answer",":"," the"," project"," cod","ew","ord"," is"," MAR","M","AL","ADE","."," After"," the"," sub","agent"," returns",","," I"," should"," reply"," with"," PAR","ENT","_D","ONE","."]},{"type":"chunk","time":1788500537291,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500537291,"index":1,"dt":[0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"id":"call_00_sAtKUseRzHRBvL4CF7XF1334","name":"subagent_fork","args":["","{","\"","description","\"",": ","\"","Recall"," project"," cod","ew","ord","\"",", ","\"","prom","pt","\"",": ","\"","What"," is"," the"," project"," cod","ew","ord"," mentioned"," earlier"," in"," this"," conversation","?"," Reply"," with"," exactly"," that"," one"," word"," and"," nothing"," else",".","\"","}"]},{"type":"chunk","time":1788500537292,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to use subagent_fork to delegate a question to a child agent. The child agent inherits this conversation and should be able to answer: the project codeword is MARMALADE. After the subagent returns, I should reply with PARENT_DONE."}}},{"type":"chunk","time":1788500537292,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_sAtKUseRzHRBvL4CF7XF1334","name":"subagent_fork","arguments":"{\"description\": \"Recall project codeword\", \"prompt\": \"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else.\"}"}}},{"type":"chunk","time":1788500537292,"chunk":{"type":"usage","usage":{"inputTokens":158,"outputTokens":147,"cacheReadTokens":2816,"reasoningTokens":59}}},{"type":"chunk","time":1788500537292,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":2,"step":1,"callId":"call_00_sAtKUseRzHRBvL4CF7XF1334","name":"subagent_fork","arguments":"{\"description\": \"Recall project codeword\", \"prompt\": \"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else.\"}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500537300,"mode":"one-shot","label":"Recall project codeword"}}
{"type":"tool/result","data":{"turn":2,"step":1,"message":{"source":{"kind":"tool","callId":"call_00_sAtKUseRzHRBvL4CF7XF1334"},"content":[{"type":"tool-result","toolCallId":"call_00_sAtKUseRzHRBvL4CF7XF1334","content":[{"type":"text","text":"MARMALADE"}],"isError":false}],"role":"user","id":"{{message:6}}"}},"sourceEventSeqs":[21],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":2,"step":1}}
{"type":"step/start","data":{"turn":2,"step":2}}
-{"type":"assistant/message","data":{"turn":2,"step":2,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The forked child agent correctly returned \"MARMALADE\". Now I need to reply with \"PARENT_DONE\"."},{"type":"text","text":"PARENT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"usage":{"inputTokens":65,"outputTokens":30,"cacheReadTokens":3072,"reasoningTokens":25},"stream":[{"type":"chunk","time":1788199063200,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788199063200,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," for","ked"," child"," agent"," correctly"," returned"," \"","M","ARM","AL","ADE","\"."," Now"," I"," need"," to"," reply"," with"," \"","PAR","ENT","_D","ONE","\"."]},{"type":"chunk","time":1788199063200,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788199063200,"index":1,"dt":[0,0,0],"texts":["PAR","ENT","_D","ONE"]},{"type":"chunk","time":1788199063200,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The forked child agent correctly returned \"MARMALADE\". Now I need to reply with \"PARENT_DONE\"."}}},{"type":"chunk","time":1788199063200,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"PARENT_DONE"}}},{"type":"chunk","time":1788199063200,"chunk":{"type":"usage","usage":{"inputTokens":65,"outputTokens":30,"cacheReadTokens":3072,"reasoningTokens":25}}},{"type":"chunk","time":1788199063200,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":2,"step":2,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The forked child agent correctly returned \"MARMALADE\". Now I need to reply with \"PARENT_DONE\"."},{"type":"text","text":"PARENT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"usage":{"inputTokens":65,"outputTokens":30,"cacheReadTokens":3072,"reasoningTokens":25},"stream":[{"type":"chunk","time":1788500537363,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788500537363,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," for","ked"," child"," agent"," correctly"," returned"," \"","M","ARM","AL","ADE","\"."," Now"," I"," need"," to"," reply"," with"," \"","PAR","ENT","_D","ONE","\"."]},{"type":"chunk","time":1788500537363,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788500537363,"index":1,"dt":[0,0,0],"texts":["PAR","ENT","_D","ONE"]},{"type":"chunk","time":1788500537363,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The forked child agent correctly returned \"MARMALADE\". Now I need to reply with \"PARENT_DONE\"."}}},{"type":"chunk","time":1788500537363,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"PARENT_DONE"}}},{"type":"chunk","time":1788500537363,"chunk":{"type":"usage","usage":{"inputTokens":65,"outputTokens":30,"cacheReadTokens":3072,"reasoningTokens":25}}},{"type":"chunk","time":1788500537363,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":2,"step":2}}
{"type":"turn/end","data":{"turn":2,"reason":{"kind":"completed"}}}
diff --git a/snapshots/sdk/subagent-list-agents/session.v2.jsonl b/snapshots/sdk/subagent-list-agents/session.v2.jsonl
index bc0a67bfad..685bafd019 100644
--- a/snapshots/sdk/subagent-list-agents/session.v2.jsonl
+++ b/snapshots/sdk/subagent-list-agents/session.v2.jsonl
@@ -11,12 +11,13 @@
{"type":"session/title","data":{"title":"Call the subagent tool once","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788199064253,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788199064253,"index":0,"dt":[],"id":"call_bg_start","name":"subagent","args":["{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"]},{"type":"chunk","time":1788199064253,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}}},{"type":"chunk","time":1788199064253,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788199064253,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500537942,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500537942,"index":0,"dt":[],"id":"call_bg_start","name":"subagent","args":["{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"]},{"type":"chunk","time":1788500537942,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}}},{"type":"chunk","time":1788500537942,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500537942,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500537949,"mode":"continuable","label":"Reply with CHILD_OK"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_bg_start"},"content":[{"type":"tool-result","toolCallId":"call_bg_start","content":[{"type":"text","text":"started subagent {{session:2}}"}],"isError":false}],"role":"user","id":"{{message:4}}"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"STARTED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788199064280,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788199064280,"index":0,"dt":[],"texts":["STARTED"]},{"type":"chunk","time":1788199064280,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"STARTED"}}},{"type":"chunk","time":1788199064280,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788199064280,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"STARTED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500537988,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500537988,"index":0,"dt":[],"texts":["STARTED"]},{"type":"chunk","time":1788500537988,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"STARTED"}}},{"type":"chunk","time":1788500537988,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500537988,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Background subagent {{session:2}} finished and will do no further work unless you send it more."},{"type":"text","text":"Its closing message:"},{"type":"text","text":"CHILD_OK"}],"source":{"kind":"subagent-settled","form":"notice","summary":"Background subagent {{session:2}} finished and will do no further work unless you send it more.","senderSessionId":"{{session:2}}"},"role":"user","id":"{{message:6}}"}]}}
@@ -24,7 +25,7 @@
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","data":{"turn":2,"step":1}}
{"type":"user/message","data":{"content":[{"type":"text","text":"Background subagent {{session:2}} finished and will do no further work unless you send it more."},{"type":"text","text":"Its closing message:"},{"type":"text","text":"CHILD_OK"}],"source":{"kind":"subagent-settled","form":"notice","summary":"Background subagent {{session:2}} finished and will do no further work unless you send it more.","senderSessionId":"{{session:2}}"},"role":"user","id":"{{message:6}}"},"surfaceOp":"append"}
-{"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788199064342,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788199064342,"index":0,"dt":[],"texts":["SUBAGENT_SETTLED_NOTED"]},{"type":"chunk","time":1788199064342,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}}},{"type":"chunk","time":1788199064342,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788199064342,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500538018,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500538018,"index":0,"dt":[],"texts":["SUBAGENT_SETTLED_NOTED"]},{"type":"chunk","time":1788500538018,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}}},{"type":"chunk","time":1788500538018,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500538018,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":2,"step":1}}
{"type":"turn/end","data":{"turn":2,"reason":{"kind":"completed"}}}
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Call list_agents once with scope set to descendants and observe the subagent you started. Then call interrupt_agent once with agent_id set to {{session:2}}. Then reply with the single word DONE. Do not call any other tool."}],"source":{"kind":"user"},"role":"user","id":"{{message:8}}"}]}}
@@ -32,11 +33,11 @@
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","data":{"turn":3,"step":1}}
{"type":"user/message","data":{"content":[{"type":"text","text":"Call list_agents once with scope set to descendants and observe the subagent you started. Then call interrupt_agent once with agent_id set to {{session:2}}. Then reply with the single word DONE. Do not call any other tool."}],"source":{"kind":"user"},"role":"user","id":"{{message:8}}"},"surfaceOp":"append"}
-{"type":"assistant/message","data":{"turn":3,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_list","name":"list_agents","arguments":"{}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:9}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788199064368,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788199064368,"index":0,"dt":[],"id":"call_list","name":"list_agents","args":["{}"]},{"type":"chunk","time":1788199064368,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_list","name":"list_agents","arguments":"{}"}}},{"type":"chunk","time":1788199064368,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788199064368,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":3,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_list","name":"list_agents","arguments":"{}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:9}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500538040,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500538040,"index":0,"dt":[],"id":"call_list","name":"list_agents","args":["{}"]},{"type":"chunk","time":1788500538040,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_list","name":"list_agents","arguments":"{}"}}},{"type":"chunk","time":1788500538040,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500538040,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":3,"step":1,"callId":"call_list","name":"list_agents","arguments":"{}"}}
-{"type":"tool/result","data":{"turn":3,"step":1,"message":{"source":{"kind":"tool","callId":"call_list"},"content":[{"type":"tool-result","toolCallId":"call_list","content":[{"type":"text","text":"{{session:2}} [ready] — Reply with CHILD_OK"}],"isError":false}],"role":"user","id":"{{message:10}}"}},"sourceEventSeqs":[34],"surfaceOp":"append"}
+{"type":"tool/result","data":{"turn":3,"step":1,"message":{"source":{"kind":"tool","callId":"call_list"},"content":[{"type":"tool-result","toolCallId":"call_list","content":[{"type":"text","text":"{{session:2}} [ready] — Reply with CHILD_OK"}],"isError":false}],"role":"user","id":"{{message:10}}"}},"sourceEventSeqs":[35],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":3,"step":1}}
{"type":"step/start","data":{"turn":3,"step":2}}
-{"type":"assistant/message","data":{"turn":3,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:11}}"},"usage":{"inputTokens":10,"outputTokens":2},"stream":[{"type":"chunk","time":1788199064389,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788199064389,"index":0,"dt":[],"texts":["DONE"]},{"type":"chunk","time":1788199064389,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DONE"}}},{"type":"chunk","time":1788199064389,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}},{"type":"chunk","time":1788199064389,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":3,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:11}}"},"usage":{"inputTokens":10,"outputTokens":2},"stream":[{"type":"chunk","time":1788500538061,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500538061,"index":0,"dt":[],"texts":["DONE"]},{"type":"chunk","time":1788500538061,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DONE"}}},{"type":"chunk","time":1788500538061,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}},{"type":"chunk","time":1788500538061,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":3,"step":2}}
{"type":"turn/end","data":{"turn":3,"reason":{"kind":"completed"}}}
diff --git a/snapshots/sdk/subagent-mixed/session.v2.jsonl b/snapshots/sdk/subagent-mixed/session.v2.jsonl
index b221888a97..312dad21c5 100644
--- a/snapshots/sdk/subagent-mixed/session.v2.jsonl
+++ b/snapshots/sdk/subagent-mixed/session.v2.jsonl
@@ -11,7 +11,7 @@
{"type":"session/title","data":{"title":"Remember this fact for later:","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to remember a codeword and just reply with \"OK\"."},{"type":"text","text":"OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":2883,"outputTokens":19,"cacheReadTokens":0,"reasoningTokens":17},"stream":[{"type":"chunk","time":1788199065455,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788199065455,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," user"," wants"," me"," to"," remember"," a"," cod","ew","ord"," and"," just"," reply"," with"," \"","OK","\"."]},{"type":"chunk","time":1788199065455,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788199065455,"index":1,"dt":[],"texts":["OK"]},{"type":"chunk","time":1788199065456,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to remember a codeword and just reply with \"OK\"."}}},{"type":"chunk","time":1788199065456,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"OK"}}},{"type":"chunk","time":1788199065456,"chunk":{"type":"usage","usage":{"inputTokens":2883,"outputTokens":19,"cacheReadTokens":0,"reasoningTokens":17}}},{"type":"chunk","time":1788199065456,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to remember a codeword and just reply with \"OK\"."},{"type":"text","text":"OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":2883,"outputTokens":19,"cacheReadTokens":0,"reasoningTokens":17},"stream":[{"type":"chunk","time":1788500538590,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788500538590,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," user"," wants"," me"," to"," remember"," a"," cod","ew","ord"," and"," just"," reply"," with"," \"","OK","\"."]},{"type":"chunk","time":1788500538590,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788500538590,"index":1,"dt":[],"texts":["OK"]},{"type":"chunk","time":1788500538590,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to remember a codeword and just reply with \"OK\"."}}},{"type":"chunk","time":1788500538590,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"OK"}}},{"type":"chunk","time":1788500538590,"chunk":{"type":"usage","usage":{"inputTokens":2883,"outputTokens":19,"cacheReadTokens":0,"reasoningTokens":17}}},{"type":"chunk","time":1788500538590,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Do these two delegations, once at a time. First, use the subagent tool (fresh child) exactly once: 'Reply with exactly the word ALPHA and nothing else.' Then, after it returns, use the subagent_fork tool (forked child that inherits this conversation) exactly once: 'What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else.' After both subagents return, reply with the single word PARENT_DONE and stop. Do not use the bash tool."}],"source":{"kind":"user"},"role":"user","id":"{{message:4}}"}]}}
@@ -19,16 +19,18 @@
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","data":{"turn":2,"step":1}}
{"type":"user/message","data":{"content":[{"type":"text","text":"Do these two delegations, once at a time. First, use the subagent tool (fresh child) exactly once: 'Reply with exactly the word ALPHA and nothing else.' Then, after it returns, use the subagent_fork tool (forked child that inherits this conversation) exactly once: 'What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else.' After both subagents return, reply with the single word PARENT_DONE and stop. Do not use the bash tool."}],"source":{"kind":"user"},"role":"user","id":"{{message:4}}"},"surfaceOp":"append"}
-{"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"Let me do these two delegations one at a time as requested.\n\nFirst, I'll use the subagent tool (fresh child) to reply with \"ALPHA\"."},{"type":"tool-call","id":"call_00_YvHr2bGomk5HhpgDTvE81896","name":"subagent","arguments":"{\"description\": \"Reply ALPHA only\", \"prompt\": \"Reply with exactly the word ALPHA and nothing else.\", \"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":185,"outputTokens":110,"cacheReadTokens":2816,"reasoningTokens":35},"stream":[{"type":"chunk","time":1788199065477,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788199065477,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["Let"," me"," do"," these"," two"," deleg","ations"," one"," at"," a"," time"," as"," requested",".\n\n","First",","," I","'ll"," use"," the"," sub","agent"," tool"," (","fresh"," child",")"," to"," reply"," with"," \"","AL","P","HA","\"."]},{"type":"chunk","time":1788199065477,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788199065477,"index":1,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"id":"call_00_YvHr2bGomk5HhpgDTvE81896","name":"subagent","args":["","{","\"","description","\"",": ","\"","Reply"," AL","P","HA"," only","\"",", ","\"","prom","pt","\"",": ","\"","Reply"," with"," exactly"," the"," word"," AL","P","HA"," and"," nothing"," else",".","\"",", \"run_in_background\":false}"]},{"type":"chunk","time":1788199065477,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"Let me do these two delegations one at a time as requested.\n\nFirst, I'll use the subagent tool (fresh child) to reply with \"ALPHA\"."}}},{"type":"chunk","time":1788199065477,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_YvHr2bGomk5HhpgDTvE81896","name":"subagent","arguments":"{\"description\": \"Reply ALPHA only\", \"prompt\": \"Reply with exactly the word ALPHA and nothing else.\", \"run_in_background\":false}"}}},{"type":"chunk","time":1788199065477,"chunk":{"type":"usage","usage":{"inputTokens":185,"outputTokens":110,"cacheReadTokens":2816,"reasoningTokens":35}}},{"type":"chunk","time":1788199065477,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"Let me do these two delegations one at a time as requested.\n\nFirst, I'll use the subagent tool (fresh child) to reply with \"ALPHA\"."},{"type":"tool-call","id":"call_00_YvHr2bGomk5HhpgDTvE81896","name":"subagent","arguments":"{\"description\": \"Reply ALPHA only\", \"prompt\": \"Reply with exactly the word ALPHA and nothing else.\", \"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":185,"outputTokens":110,"cacheReadTokens":2816,"reasoningTokens":35},"stream":[{"type":"chunk","time":1788500538608,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788500538608,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["Let"," me"," do"," these"," two"," deleg","ations"," one"," at"," a"," time"," as"," requested",".\n\n","First",","," I","'ll"," use"," the"," sub","agent"," tool"," (","fresh"," child",")"," to"," reply"," with"," \"","AL","P","HA","\"."]},{"type":"chunk","time":1788500538608,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500538608,"index":1,"dt":[0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"id":"call_00_YvHr2bGomk5HhpgDTvE81896","name":"subagent","args":["","{","\"","description","\"",": ","\"","Reply"," AL","P","HA"," only","\"",", ","\"","prom","pt","\"",": ","\"","Reply"," with"," exactly"," the"," word"," AL","P","HA"," and"," nothing"," else",".","\"",", \"run_in_background\":false}"]},{"type":"chunk","time":1788500538609,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"Let me do these two delegations one at a time as requested.\n\nFirst, I'll use the subagent tool (fresh child) to reply with \"ALPHA\"."}}},{"type":"chunk","time":1788500538609,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_YvHr2bGomk5HhpgDTvE81896","name":"subagent","arguments":"{\"description\": \"Reply ALPHA only\", \"prompt\": \"Reply with exactly the word ALPHA and nothing else.\", \"run_in_background\":false}"}}},{"type":"chunk","time":1788500538609,"chunk":{"type":"usage","usage":{"inputTokens":185,"outputTokens":110,"cacheReadTokens":2816,"reasoningTokens":35}}},{"type":"chunk","time":1788500538609,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":2,"step":1,"callId":"call_00_YvHr2bGomk5HhpgDTvE81896","name":"subagent","arguments":"{\"description\": \"Reply ALPHA only\", \"prompt\": \"Reply with exactly the word ALPHA and nothing else.\", \"run_in_background\":false}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500538615,"mode":"one-shot","label":"Reply ALPHA only"}}
{"type":"tool/result","data":{"turn":2,"step":1,"message":{"source":{"kind":"tool","callId":"call_00_YvHr2bGomk5HhpgDTvE81896"},"content":[{"type":"tool-result","toolCallId":"call_00_YvHr2bGomk5HhpgDTvE81896","content":[{"type":"text","text":"ALPHA"}],"isError":false}],"role":"user","id":"{{message:6}}"}},"sourceEventSeqs":[21],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":2,"step":1}}
{"type":"step/start","data":{"turn":2,"step":2}}
-{"type":"assistant/message","data":{"turn":2,"step":2,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The first subagent returned \"ALPHA\". Now I need to use the subagent_fork tool (forked child that inherits this conversation) to ask about the project codeword."},{"type":"tool-call","id":"call_00_JSr5rhREq23wSmwSkCP77184","name":"subagent_fork","arguments":"{\"description\": \"Recall project codeword\", \"prompt\": \"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"usage":{"inputTokens":54,"outputTokens":128,"cacheReadTokens":3072,"reasoningTokens":40},"stream":[{"type":"chunk","time":1788199065535,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788199065535,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," first"," sub","agent"," returned"," \"","AL","P","HA","\"."," Now"," I"," need"," to"," use"," the"," sub","agent","_f","ork"," tool"," (","fork","ed"," child"," that"," inher","its"," this"," conversation",")"," to"," ask"," about"," the"," project"," cod","ew","ord","."]},{"type":"chunk","time":1788199065535,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788199065535,"index":1,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"id":"call_00_JSr5rhREq23wSmwSkCP77184","name":"subagent_fork","args":["","{","\"","description","\"",": ","\"","Recall"," project"," cod","ew","ord","\"",", ","\"","prom","pt","\"",": ","\"","What"," is"," the"," project"," cod","ew","ord"," mentioned"," earlier"," in"," this"," conversation","?"," Reply"," with"," exactly"," that"," one"," word"," and"," nothing"," else",".","\"","}"]},{"type":"chunk","time":1788199065535,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The first subagent returned \"ALPHA\". Now I need to use the subagent_fork tool (forked child that inherits this conversation) to ask about the project codeword."}}},{"type":"chunk","time":1788199065535,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_JSr5rhREq23wSmwSkCP77184","name":"subagent_fork","arguments":"{\"description\": \"Recall project codeword\", \"prompt\": \"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else.\"}"}}},{"type":"chunk","time":1788199065535,"chunk":{"type":"usage","usage":{"inputTokens":54,"outputTokens":128,"cacheReadTokens":3072,"reasoningTokens":40}}},{"type":"chunk","time":1788199065535,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":2,"step":2,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The first subagent returned \"ALPHA\". Now I need to use the subagent_fork tool (forked child that inherits this conversation) to ask about the project codeword."},{"type":"tool-call","id":"call_00_JSr5rhREq23wSmwSkCP77184","name":"subagent_fork","arguments":"{\"description\": \"Recall project codeword\", \"prompt\": \"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"usage":{"inputTokens":54,"outputTokens":128,"cacheReadTokens":3072,"reasoningTokens":40},"stream":[{"type":"chunk","time":1788500538670,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788500538670,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," first"," sub","agent"," returned"," \"","AL","P","HA","\"."," Now"," I"," need"," to"," use"," the"," sub","agent","_f","ork"," tool"," (","fork","ed"," child"," that"," inher","its"," this"," conversation",")"," to"," ask"," about"," the"," project"," cod","ew","ord","."]},{"type":"chunk","time":1788500538670,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500538670,"index":1,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0],"id":"call_00_JSr5rhREq23wSmwSkCP77184","name":"subagent_fork","args":["","{","\"","description","\"",": ","\"","Recall"," project"," cod","ew","ord","\"",", ","\"","prom","pt","\"",": ","\"","What"," is"," the"," project"," cod","ew","ord"," mentioned"," earlier"," in"," this"," conversation","?"," Reply"," with"," exactly"," that"," one"," word"," and"," nothing"," else",".","\"","}"]},{"type":"chunk","time":1788500538671,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The first subagent returned \"ALPHA\". Now I need to use the subagent_fork tool (forked child that inherits this conversation) to ask about the project codeword."}}},{"type":"chunk","time":1788500538671,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_JSr5rhREq23wSmwSkCP77184","name":"subagent_fork","arguments":"{\"description\": \"Recall project codeword\", \"prompt\": \"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else.\"}"}}},{"type":"chunk","time":1788500538671,"chunk":{"type":"usage","usage":{"inputTokens":54,"outputTokens":128,"cacheReadTokens":3072,"reasoningTokens":40}}},{"type":"chunk","time":1788500538671,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":2,"step":2,"callId":"call_00_JSr5rhREq23wSmwSkCP77184","name":"subagent_fork","arguments":"{\"description\": \"Recall project codeword\", \"prompt\": \"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else.\"}"}}
-{"type":"tool/result","data":{"turn":2,"step":2,"message":{"source":{"kind":"tool","callId":"call_00_JSr5rhREq23wSmwSkCP77184"},"content":[{"type":"tool-result","toolCallId":"call_00_JSr5rhREq23wSmwSkCP77184","content":[{"type":"text","text":"SAFFRON"}],"isError":false}],"role":"user","id":"{{message:8}}"}},"sourceEventSeqs":[26],"surfaceOp":"append"}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:3}}","childCreatedAt":1788500538677,"mode":"one-shot","label":"Recall project codeword"}}
+{"type":"tool/result","data":{"turn":2,"step":2,"message":{"source":{"kind":"tool","callId":"call_00_JSr5rhREq23wSmwSkCP77184"},"content":[{"type":"tool-result","toolCallId":"call_00_JSr5rhREq23wSmwSkCP77184","content":[{"type":"text","text":"SAFFRON"}],"isError":false}],"role":"user","id":"{{message:8}}"}},"sourceEventSeqs":[27],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":2,"step":2}}
{"type":"step/start","data":{"turn":2,"step":3}}
-{"type":"assistant/message","data":{"turn":2,"step":3,"message":{"role":"assistant","content":[{"type":"reasoning","text":"Both subagents returned:\n1. First (fresh child): \"ALPHA\"\n2. Second (forked child): \"SAFFRON\" - correctly inherited the conversation context where I was asked to remember the codeword \"SAFFRON\".\n\nNow I reply with \"PARENT_DONE\" as instructed."},{"type":"text","text":"PARENT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:9}}"},"usage":{"inputTokens":69,"outputTokens":69,"cacheReadTokens":3200,"reasoningTokens":64},"stream":[{"type":"chunk","time":1788199065598,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788199065598,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["Both"," sub","agents"," returned",":\n","1","."," First"," (","fresh"," child","):"," \"","AL","P","HA","\"\n","2","."," Second"," (","fork","ed"," child","):"," \"","SA","FF","RON","\""," -"," correctly"," inherited"," the"," conversation"," context"," where"," I"," was"," asked"," to"," remember"," the"," cod","ew","ord"," \"","SA","FF","RON","\".\n\n","Now"," I"," reply"," with"," \"","PAR","ENT","_D","ONE","\""," as"," instructed","."]},{"type":"chunk","time":1788199065598,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788199065598,"index":1,"dt":[0,0,0],"texts":["PAR","ENT","_D","ONE"]},{"type":"chunk","time":1788199065598,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"Both subagents returned:\n1. First (fresh child): \"ALPHA\"\n2. Second (forked child): \"SAFFRON\" - correctly inherited the conversation context where I was asked to remember the codeword \"SAFFRON\".\n\nNow I reply with \"PARENT_DONE\" as instructed."}}},{"type":"chunk","time":1788199065598,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"PARENT_DONE"}}},{"type":"chunk","time":1788199065598,"chunk":{"type":"usage","usage":{"inputTokens":69,"outputTokens":69,"cacheReadTokens":3200,"reasoningTokens":64}}},{"type":"chunk","time":1788199065598,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":2,"step":3,"message":{"role":"assistant","content":[{"type":"reasoning","text":"Both subagents returned:\n1. First (fresh child): \"ALPHA\"\n2. Second (forked child): \"SAFFRON\" - correctly inherited the conversation context where I was asked to remember the codeword \"SAFFRON\".\n\nNow I reply with \"PARENT_DONE\" as instructed."},{"type":"text","text":"PARENT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:9}}"},"usage":{"inputTokens":69,"outputTokens":69,"cacheReadTokens":3200,"reasoningTokens":64},"stream":[{"type":"chunk","time":1788500538725,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788500538725,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["Both"," sub","agents"," returned",":\n","1","."," First"," (","fresh"," child","):"," \"","AL","P","HA","\"\n","2","."," Second"," (","fork","ed"," child","):"," \"","SA","FF","RON","\""," -"," correctly"," inherited"," the"," conversation"," context"," where"," I"," was"," asked"," to"," remember"," the"," cod","ew","ord"," \"","SA","FF","RON","\".\n\n","Now"," I"," reply"," with"," \"","PAR","ENT","_D","ONE","\""," as"," instructed","."]},{"type":"chunk","time":1788500538725,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788500538725,"index":1,"dt":[0,0,0],"texts":["PAR","ENT","_D","ONE"]},{"type":"chunk","time":1788500538725,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"Both subagents returned:\n1. First (fresh child): \"ALPHA\"\n2. Second (forked child): \"SAFFRON\" - correctly inherited the conversation context where I was asked to remember the codeword \"SAFFRON\".\n\nNow I reply with \"PARENT_DONE\" as instructed."}}},{"type":"chunk","time":1788500538725,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"PARENT_DONE"}}},{"type":"chunk","time":1788500538725,"chunk":{"type":"usage","usage":{"inputTokens":69,"outputTokens":69,"cacheReadTokens":3200,"reasoningTokens":64}}},{"type":"chunk","time":1788500538725,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":2,"step":3}}
{"type":"turn/end","data":{"turn":2,"reason":{"kind":"completed"}}}
diff --git a/snapshots/sdk/subagent-send-message/session.v2.jsonl b/snapshots/sdk/subagent-send-message/session.v2.jsonl
index d80daddee2..6de97f0e4c 100644
--- a/snapshots/sdk/subagent-send-message/session.v2.jsonl
+++ b/snapshots/sdk/subagent-send-message/session.v2.jsonl
@@ -11,12 +11,13 @@
{"type":"session/title","data":{"title":"Follow these steps exactly, then","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Send a finding\", \"prompt\": \"Send exactly CHILD_MESSAGE_OK to your parent with send_message, then stop.\", \"run_in_background\": true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788269697328,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788269697328,"index":0,"dt":[],"id":"call_bg_start","name":"subagent","args":["{\"description\": \"Send a finding\", \"prompt\": \"Send exactly CHILD_MESSAGE_OK to your parent with send_message, then stop.\", \"run_in_background\": true}"]},{"type":"chunk","time":1788269697328,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Send a finding\", \"prompt\": \"Send exactly CHILD_MESSAGE_OK to your parent with send_message, then stop.\", \"run_in_background\": true}"}}},{"type":"chunk","time":1788269697328,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788269697328,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Send a finding\", \"prompt\": \"Send exactly CHILD_MESSAGE_OK to your parent with send_message, then stop.\", \"run_in_background\": true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500539308,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500539308,"index":0,"dt":[],"id":"call_bg_start","name":"subagent","args":["{\"description\": \"Send a finding\", \"prompt\": \"Send exactly CHILD_MESSAGE_OK to your parent with send_message, then stop.\", \"run_in_background\": true}"]},{"type":"chunk","time":1788500539308,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Send a finding\", \"prompt\": \"Send exactly CHILD_MESSAGE_OK to your parent with send_message, then stop.\", \"run_in_background\": true}"}}},{"type":"chunk","time":1788500539308,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500539308,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Send a finding\", \"prompt\": \"Send exactly CHILD_MESSAGE_OK to your parent with send_message, then stop.\", \"run_in_background\": true}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500539315,"mode":"continuable","label":"Send a finding"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_bg_start"},"content":[{"type":"tool-result","toolCallId":"call_bg_start","content":[{"type":"text","text":"started subagent {{session:2}}"}],"isError":false}],"role":"user","id":"{{message:4}}"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"STARTED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788269697354,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788269697354,"index":0,"dt":[],"texts":["STARTED"]},{"type":"chunk","time":1788269697354,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"STARTED"}}},{"type":"chunk","time":1788269697354,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788269697354,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"STARTED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500539349,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500539349,"index":0,"dt":[],"texts":["STARTED"]},{"type":"chunk","time":1788500539349,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"STARTED"}}},{"type":"chunk","time":1788500539349,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500539349,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
{"type":"agent/inbox/spliced","data":{"target":"next-step","start":0,"inserted":[{"content":[{"type":"text","text":"Agent {{session:2}} sent a message: "},{"type":"text","text":"CHILD_MESSAGE_OK"}],"source":{"kind":"agent-message","form":"relay","senderSessionId":"{{session:2}}"},"role":"user","id":"{{message:6}}"}]}}
@@ -27,7 +28,7 @@
{"type":"step/start","data":{"turn":2,"step":1}}
{"type":"user/message","data":{"content":[{"type":"text","text":"Agent {{session:2}} sent a message: "},{"type":"text","text":"CHILD_MESSAGE_OK"}],"source":{"kind":"agent-message","form":"relay","senderSessionId":"{{session:2}}"},"role":"user","id":"{{message:6}}"},"surfaceOp":"append"}
{"type":"user/message","data":{"content":[{"type":"text","text":"Background subagent {{session:2}} finished and will do no further work unless you send it more."},{"type":"text","text":"Its closing message:"},{"type":"text","text":"Message sent."}],"source":{"kind":"subagent-settled","form":"notice","summary":"Background subagent {{session:2}} finished and will do no further work unless you send it more.","senderSessionId":"{{session:2}}"},"role":"user","id":"{{message:7}}"},"surfaceOp":"append"}
-{"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:8}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788269697428,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788269697428,"index":0,"dt":[],"texts":["SUBAGENT_SETTLED_NOTED"]},{"type":"chunk","time":1788269697428,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}}},{"type":"chunk","time":1788269697428,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788269697428,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:8}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500539403,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500539403,"index":0,"dt":[],"texts":["SUBAGENT_SETTLED_NOTED"]},{"type":"chunk","time":1788500539403,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"SUBAGENT_SETTLED_NOTED"}}},{"type":"chunk","time":1788500539403,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500539403,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":2,"step":1}}
{"type":"turn/end","data":{"turn":2,"reason":{"kind":"completed"}}}
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Repeat back, verbatim, the exact message the background subagent sent you. Reply with only that text. Do not use any tools."}],"source":{"kind":"user"},"role":"user","id":"{{message:9}}"}]}}
@@ -35,6 +36,6 @@
{"type":"agent/inbox/spliced","data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","data":{"turn":3,"step":1}}
{"type":"user/message","data":{"content":[{"type":"text","text":"Repeat back, verbatim, the exact message the background subagent sent you. Reply with only that text. Do not use any tools."}],"source":{"kind":"user"},"role":"user","id":"{{message:9}}"},"surfaceOp":"append"}
-{"type":"assistant/message","data":{"turn":3,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"CHILD_MESSAGE_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:10}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788269697454,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788269697454,"index":0,"dt":[],"texts":["CHILD_MESSAGE_OK"]},{"type":"chunk","time":1788269697454,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"CHILD_MESSAGE_OK"}}},{"type":"chunk","time":1788269697454,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788269697454,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":3,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"CHILD_MESSAGE_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:10}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500539428,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500539428,"index":0,"dt":[],"texts":["CHILD_MESSAGE_OK"]},{"type":"chunk","time":1788500539428,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"CHILD_MESSAGE_OK"}}},{"type":"chunk","time":1788500539428,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500539428,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":3,"step":1}}
{"type":"turn/end","data":{"turn":3,"reason":{"kind":"completed"}}}
diff --git a/snapshots/sdk/subagent-spawn-in-process/session.v2.jsonl b/snapshots/sdk/subagent-spawn-in-process/session.v2.jsonl
index 8b6c5fc4f6..16cecfc4e6 100644
--- a/snapshots/sdk/subagent-spawn-in-process/session.v2.jsonl
+++ b/snapshots/sdk/subagent-spawn-in-process/session.v2.jsonl
@@ -11,11 +11,12 @@
{"type":"session/title","data":{"title":"Use the subagent tool exactly","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to:\n1. Use the subagent tool exactly once with description 'echo probe' and prompt 'Reply with exactly: child answer 42.'\n2. Then reply with the subagent's final answer verbatim.\n\nLet me do this step by step."},{"type":"tool-call","id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","arguments":"{\"description\": \"echo probe\", \"prompt\": \"Reply with exactly: child answer 42.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":135,"outputTokens":124,"cacheReadTokens":1664,"reasoningTokens":55},"stream":[{"type":"chunk","time":1788199067994,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788199067994,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," user"," wants"," me"," to",":\n","1","."," Use"," the"," sub","agent"," tool"," exactly"," once"," with"," description"," '","echo"," probe","'"," and"," prompt"," '","Reply"," with"," exactly",":"," child"," answer"," ","42",".'\n","2","."," Then"," reply"," with"," the"," sub","agent","'s"," final"," answer"," verb","atim",".\n\n","Let"," me"," do"," this"," step"," by"," step","."]},{"type":"chunk","time":1788199067994,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788199067994,"index":1,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","args":["","{","\"","description","\"",": ","\"","echo"," probe","\"",", ","\"","prom","pt","\"",": ","\"","Reply"," with"," exactly",":"," child"," answer"," ","42",".","\"","}"]},{"type":"chunk","time":1788199067994,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to:\n1. Use the subagent tool exactly once with description 'echo probe' and prompt 'Reply with exactly: child answer 42.'\n2. Then reply with the subagent's final answer verbatim.\n\nLet me do this step by step."}}},{"type":"chunk","time":1788199067994,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","arguments":"{\"description\": \"echo probe\", \"prompt\": \"Reply with exactly: child answer 42.\"}"}}},{"type":"chunk","time":1788199067994,"chunk":{"type":"usage","usage":{"inputTokens":135,"outputTokens":124,"cacheReadTokens":1664,"reasoningTokens":55}}},{"type":"chunk","time":1788199067994,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to:\n1. Use the subagent tool exactly once with description 'echo probe' and prompt 'Reply with exactly: child answer 42.'\n2. Then reply with the subagent's final answer verbatim.\n\nLet me do this step by step."},{"type":"tool-call","id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","arguments":"{\"description\": \"echo probe\", \"prompt\": \"Reply with exactly: child answer 42.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":135,"outputTokens":124,"cacheReadTokens":1664,"reasoningTokens":55},"stream":[{"type":"chunk","time":1788500539940,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788500539940,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," user"," wants"," me"," to",":\n","1","."," Use"," the"," sub","agent"," tool"," exactly"," once"," with"," description"," '","echo"," probe","'"," and"," prompt"," '","Reply"," with"," exactly",":"," child"," answer"," ","42",".'\n","2","."," Then"," reply"," with"," the"," sub","agent","'s"," final"," answer"," verb","atim",".\n\n","Let"," me"," do"," this"," step"," by"," step","."]},{"type":"chunk","time":1788500539940,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500539940,"index":1,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","args":["","{","\"","description","\"",": ","\"","echo"," probe","\"",", ","\"","prom","pt","\"",": ","\"","Reply"," with"," exactly",":"," child"," answer"," ","42",".","\"","}"]},{"type":"chunk","time":1788500539940,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to:\n1. Use the subagent tool exactly once with description 'echo probe' and prompt 'Reply with exactly: child answer 42.'\n2. Then reply with the subagent's final answer verbatim.\n\nLet me do this step by step."}}},{"type":"chunk","time":1788500539940,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","arguments":"{\"description\": \"echo probe\", \"prompt\": \"Reply with exactly: child answer 42.\"}"}}},{"type":"chunk","time":1788500539940,"chunk":{"type":"usage","usage":{"inputTokens":135,"outputTokens":124,"cacheReadTokens":1664,"reasoningTokens":55}}},{"type":"chunk","time":1788500539940,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","arguments":"{\"description\": \"echo probe\", \"prompt\": \"Reply with exactly: child answer 42.\"}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500539946,"mode":"one-shot","label":"echo probe"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_00_oHPNQ1nLoakoaAGXIxCM7404"},"content":[{"type":"tool-result","toolCallId":"call_00_oHPNQ1nLoakoaAGXIxCM7404","content":[{"type":"text","text":"Error: subagent run failed"}],"isError":true}],"role":"user","id":"{{message:4}}"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The subagent replied with \"child answer 42.\" Now I need to reply with the subagent's final answer verbatim."},{"type":"text","text":"child answer 42."}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":19,"outputTokens":32,"cacheReadTokens":1920,"reasoningTokens":26},"stream":[{"type":"chunk","time":1788199068048,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788199068048,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],"texts":["The"," sub","agent"," replied"," with"," \"","child"," answer"," ","42",".\""," Now"," I"," need"," to"," reply"," with"," the"," sub","agent","'s"," final"," answer"," verb","atim","."]},{"type":"chunk","time":1788199068049,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788199068049,"index":1,"dt":[0,0,0,0],"texts":["child"," answer"," ","42","."]},{"type":"chunk","time":1788199068049,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The subagent replied with \"child answer 42.\" Now I need to reply with the subagent's final answer verbatim."}}},{"type":"chunk","time":1788199068049,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"child answer 42."}}},{"type":"chunk","time":1788199068049,"chunk":{"type":"usage","usage":{"inputTokens":19,"outputTokens":32,"cacheReadTokens":1920,"reasoningTokens":26}}},{"type":"chunk","time":1788199068049,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The subagent replied with \"child answer 42.\" Now I need to reply with the subagent's final answer verbatim."},{"type":"text","text":"child answer 42."}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":19,"outputTokens":32,"cacheReadTokens":1920,"reasoningTokens":26},"stream":[{"type":"chunk","time":1788500540000,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788500540000,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," sub","agent"," replied"," with"," \"","child"," answer"," ","42",".\""," Now"," I"," need"," to"," reply"," with"," the"," sub","agent","'s"," final"," answer"," verb","atim","."]},{"type":"chunk","time":1788500540000,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788500540000,"index":1,"dt":[0,0,0,0],"texts":["child"," answer"," ","42","."]},{"type":"chunk","time":1788500540000,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The subagent replied with \"child answer 42.\" Now I need to reply with the subagent's final answer verbatim."}}},{"type":"chunk","time":1788500540000,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"child answer 42."}}},{"type":"chunk","time":1788500540000,"chunk":{"type":"usage","usage":{"inputTokens":19,"outputTokens":32,"cacheReadTokens":1920,"reasoningTokens":26}}},{"type":"chunk","time":1788500540000,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
diff --git a/snapshots/session/advanced-toolchain-runtime/session.v2.jsonl b/snapshots/session/advanced-toolchain-runtime/session.v2.jsonl
index b3772f0156..31a014ede7 100644
--- a/snapshots/session/advanced-toolchain-runtime/session.v2.jsonl
+++ b/snapshots/session/advanced-toolchain-runtime/session.v2.jsonl
@@ -11,30 +11,32 @@
{"type":"session/title","data":{"title":"Run this advanced flow exactly","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-define","name":"cordis_define","arguments":"{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788233482630,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233482630,"index":0,"dt":[],"id":"advanced-define","name":"cordis_define","args":["{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"]},{"type":"chunk","time":1788233482630,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-define","name":"cordis_define","arguments":"{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"}}},{"type":"chunk","time":1788233482630,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788233482630,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-define","name":"cordis_define","arguments":"{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788500543707,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500543708,"index":0,"dt":[],"id":"advanced-define","name":"cordis_define","args":["{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"]},{"type":"chunk","time":1788500543708,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-define","name":"cordis_define","arguments":"{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"}}},{"type":"chunk","time":1788500543708,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788500543708,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"advanced-define","name":"cordis_define","arguments":"{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"advanced-define"},"content":[{"type":"tool-result","toolCallId":"advanced-define","content":[{"type":"text","text":"Defined snap-1/pkg-1 (Snapshot Marker); it is not running yet. Use cordis_run to activate this Package."}],"isError":false}],"role":"user","id":"{{message:4}}"},"meta":{"pluginId":"snap-1","packageId":"pkg-1"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788233482656,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233482656,"index":0,"dt":[],"id":"advanced-direct-child","name":"subagent","args":["{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"]},{"type":"chunk","time":1788233482656,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}}},{"type":"chunk","time":1788233482656,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788233482656,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788500543727,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500543727,"index":0,"dt":[],"id":"advanced-direct-child","name":"subagent","args":["{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"]},{"type":"chunk","time":1788500543727,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}}},{"type":"chunk","time":1788500543727,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788500543727,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":2,"callId":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500543732,"mode":"one-shot","label":"Check direct child"}}
{"type":"tool/result","data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"advanced-direct-child"},"content":[{"type":"tool-result","toolCallId":"advanced-direct-child","content":[{"type":"text","text":"DIRECT_CHILD_OK"}],"isError":false}],"role":"user","id":"{{message:6}}"}},"sourceEventSeqs":[18],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"step/start","data":{"turn":1,"step":3}}
-{"type":"assistant/message","data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-acp-snapshot\",\"description\":\"exercise one workflow child through ACP\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788233482737,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233482737,"index":0,"dt":[],"id":"advanced-workflow","name":"workflow","args":["{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-acp-snapshot\",\"description\":\"exercise one workflow child through ACP\"}}"]},{"type":"chunk","time":1788233482737,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-acp-snapshot\",\"description\":\"exercise one workflow child through ACP\"}}"}}},{"type":"chunk","time":1788233482737,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788233482737,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-acp-snapshot\",\"description\":\"exercise one workflow child through ACP\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788500543788,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500543788,"index":0,"dt":[],"id":"advanced-workflow","name":"workflow","args":["{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-acp-snapshot\",\"description\":\"exercise one workflow child through ACP\"}}"]},{"type":"chunk","time":1788500543788,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-acp-snapshot\",\"description\":\"exercise one workflow child through ACP\"}}"}}},{"type":"chunk","time":1788500543788,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788500543788,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":3,"callId":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-acp-snapshot\",\"description\":\"exercise one workflow child through ACP\"}}"}}
{"type":"tool-workflow/run-start","data":{"runId":"{{workflow:1}}","name":"advanced-acp-snapshot"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:3}}","childCreatedAt":1788500543873,"mode":"one-shot"}}
{"type":"tool-workflow/agent-start","data":{"runId":"{{workflow:1}}","seq":1,"label":"workflow-child","phase":"Delegate","childId":"{{session:3}}"}}
{"type":"tool-workflow/agent-end","data":{"runId":"{{workflow:1}}","seq":1,"outcome":"completed"}}
{"type":"tool-workflow/run-end","data":{"runId":"{{workflow:1}}","stopReason":"completed"}}
-{"type":"tool/result","data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"advanced-workflow"},"content":[{"type":"tool-result","toolCallId":"advanced-workflow","content":[{"type":"text","text":"workflow \"advanced-acp-snapshot\" completed (1 agent).\nReturn value:\n{\n \"reply\": \"WORKFLOW_CHILD_OK\"\n}"}],"isError":false}],"role":"user","id":"{{message:8}}"}},"sourceEventSeqs":[23],"surfaceOp":"append"}
+{"type":"tool/result","data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"advanced-workflow"},"content":[{"type":"tool-result","toolCallId":"advanced-workflow","content":[{"type":"text","text":"workflow \"advanced-acp-snapshot\" completed (1 agent).\nReturn value:\n{\n \"reply\": \"WORKFLOW_CHILD_OK\"\n}"}],"isError":false}],"role":"user","id":"{{message:8}}"}},"sourceEventSeqs":[24],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":3}}
{"type":"step/start","data":{"turn":1,"step":4}}
-{"type":"assistant/message","data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\":\"snap-1\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:9}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788233482842,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233482842,"index":0,"dt":[],"id":"advanced-undefine","name":"cordis_undefine","args":["{\"pluginId\":\"snap-1\"}"]},{"type":"chunk","time":1788233482842,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\":\"snap-1\"}"}}},{"type":"chunk","time":1788233482842,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788233482842,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\":\"snap-1\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:9}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788500543931,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500543931,"index":0,"dt":[],"id":"advanced-undefine","name":"cordis_undefine","args":["{\"pluginId\":\"snap-1\"}"]},{"type":"chunk","time":1788500543931,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\":\"snap-1\"}"}}},{"type":"chunk","time":1788500543931,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788500543931,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":4,"callId":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\":\"snap-1\"}"}}
-{"type":"tool/result","data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"advanced-undefine"},"content":[{"type":"tool-result","toolCallId":"advanced-undefine","content":[{"type":"text","text":"Removed dynamic Plugin snap-1 and all of its Packages."}],"isError":false}],"role":"user","id":"{{message:10}}"}},"sourceEventSeqs":[32],"surfaceOp":"append"}
+{"type":"tool/result","data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"advanced-undefine"},"content":[{"type":"tool-result","toolCallId":"advanced-undefine","content":[{"type":"text","text":"Removed dynamic Plugin snap-1 and all of its Packages."}],"isError":false}],"role":"user","id":"{{message:10}}"}},"sourceEventSeqs":[34],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":4}}
{"type":"step/start","data":{"turn":1,"step":5}}
-{"type":"assistant/message","data":{"turn":1,"step":5,"message":{"role":"assistant","content":[{"type":"text","text":"ADVANCED_ACP_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:11}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788233482871,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788233482871,"index":0,"dt":[],"texts":["ADVANCED_ACP_OK"]},{"type":"chunk","time":1788233482871,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"ADVANCED_ACP_OK"}}},{"type":"chunk","time":1788233482871,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788233482871,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":5,"message":{"role":"assistant","content":[{"type":"text","text":"ADVANCED_ACP_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:11}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788500543947,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500543947,"index":0,"dt":[],"texts":["ADVANCED_ACP_OK"]},{"type":"chunk","time":1788500543947,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"ADVANCED_ACP_OK"}}},{"type":"chunk","time":1788500543947,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788500543947,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":5}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
diff --git a/snapshots/session/advanced-toolchain/session.v2.jsonl b/snapshots/session/advanced-toolchain/session.v2.jsonl
index 35c5b2fbfb..8deeb37cc9 100644
--- a/snapshots/session/advanced-toolchain/session.v2.jsonl
+++ b/snapshots/session/advanced-toolchain/session.v2.jsonl
@@ -11,12 +11,12 @@
{"type":"session/title","data":{"title":"Run this advanced flow exactly","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-define","name":"cordis_define","arguments":"{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788233481631,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233481631,"index":0,"dt":[],"id":"advanced-define","name":"cordis_define","args":["{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"]},{"type":"chunk","time":1788233481631,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-define","name":"cordis_define","arguments":"{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"}}},{"type":"chunk","time":1788233481631,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788233481631,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-define","name":"cordis_define","arguments":"{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788500542227,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500542227,"index":0,"dt":[],"id":"advanced-define","name":"cordis_define","args":["{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"]},{"type":"chunk","time":1788500542227,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-define","name":"cordis_define","arguments":"{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"}}},{"type":"chunk","time":1788500542227,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788500542227,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"advanced-define","name":"cordis_define","arguments":"{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"advanced-define"},"content":[{"type":"tool-result","toolCallId":"advanced-define","content":[{"type":"text","text":"Defined snap-1/pkg-1 (Snapshot Marker); it is not running yet. Use cordis_run to activate this Package."}],"isError":false}],"role":"user","id":"{{message:4}}"},"meta":{"pluginId":"snap-1","packageId":"pkg-1"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\":\"const run = await tools.cordis_run({ pluginId: 'snap-1', packageId: 'pkg-1', mode: 'run' });\\nconst inspected = await tools.cordis_inspect_self({ pluginId: 'snap-1' });\\nreturn { run, inspected };\",\"description\":\"Run and inspect the dynamic Cordis Package\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788233481651,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233481651,"index":0,"dt":[],"id":"advanced-code","name":"run_code","args":["{\"code\":\"const run = await tools.cordis_run({ pluginId: 'snap-1', packageId: 'pkg-1', mode: 'run' });\\nconst inspected = await tools.cordis_inspect_self({ pluginId: 'snap-1' });\\nreturn { run, inspected };\",\"description\":\"Run and inspect the dynamic Cordis Package\"}"]},{"type":"chunk","time":1788233481651,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\":\"const run = await tools.cordis_run({ pluginId: 'snap-1', packageId: 'pkg-1', mode: 'run' });\\nconst inspected = await tools.cordis_inspect_self({ pluginId: 'snap-1' });\\nreturn { run, inspected };\",\"description\":\"Run and inspect the dynamic Cordis Package\"}"}}},{"type":"chunk","time":1788233481651,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788233481651,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\":\"const run = await tools.cordis_run({ pluginId: 'snap-1', packageId: 'pkg-1', mode: 'run' });\\nconst inspected = await tools.cordis_inspect_self({ pluginId: 'snap-1' });\\nreturn { run, inspected };\",\"description\":\"Run and inspect the dynamic Cordis Package\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788500542247,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500542247,"index":0,"dt":[],"id":"advanced-code","name":"run_code","args":["{\"code\":\"const run = await tools.cordis_run({ pluginId: 'snap-1', packageId: 'pkg-1', mode: 'run' });\\nconst inspected = await tools.cordis_inspect_self({ pluginId: 'snap-1' });\\nreturn { run, inspected };\",\"description\":\"Run and inspect the dynamic Cordis Package\"}"]},{"type":"chunk","time":1788500542247,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\":\"const run = await tools.cordis_run({ pluginId: 'snap-1', packageId: 'pkg-1', mode: 'run' });\\nconst inspected = await tools.cordis_inspect_self({ pluginId: 'snap-1' });\\nreturn { run, inspected };\",\"description\":\"Run and inspect the dynamic Cordis Package\"}"}}},{"type":"chunk","time":1788500542247,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788500542247,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":2,"callId":"advanced-code","name":"run_code","arguments":"{\"code\":\"const run = await tools.cordis_run({ pluginId: 'snap-1', packageId: 'pkg-1', mode: 'run' });\\nconst inspected = await tools.cordis_inspect_self({ pluginId: 'snap-1' });\\nreturn { run, inspected };\",\"description\":\"Run and inspect the dynamic Cordis Package\"}"}}
{"type":"tool/code-dispatch-start","data":{"rootCallId":"advanced-code","parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_run","arguments":{"pluginId":"snap-1","packageId":"pkg-1","mode":"run"}}}
{"type":"tool/code-dispatch","data":{"rootCallId":"advanced-code","parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_run","arguments":{"pluginId":"snap-1","packageId":"pkg-1","mode":"run"},"isError":false,"content":[{"type":"text","text":"snap-1/pkg-1 is running (run-1)."}]}}
@@ -25,25 +25,27 @@
{"type":"tool/result","data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"advanced-code"},"content":[{"type":"tool-result","toolCallId":"advanced-code","content":[{"type":"text","text":"{\n \"run\": {\n \"status\": \"running\",\n \"pluginId\": \"snap-1\",\n \"packageId\": \"pkg-1\",\n \"pluginRunId\": \"run-1\",\n \"currentPackageId\": \"pkg-1\",\n \"host\": {\n \"status\": \"running\",\n \"provides\": [],\n \"waitingFor\": []\n },\n \"client\": {\n \"status\": \"absent\",\n \"waitingFor\": []\n }\n },\n \"inspected\": {\n \"mode\": \"plugin\",\n \"pluginId\": \"snap-1\",\n \"name\": \"Snapshot Marker\",\n \"packageCount\": 1,\n \"state\": \"running\",\n \"currentPackageId\": \"pkg-1\",\n \"activeRun\": {\n \"pluginRunId\": \"run-1\",\n \"packageId\": \"pkg-1\"\n },\n \"packages\": [\n {\n \"packageId\": \"pkg-1\",\n \"name\": \"Snapshot Marker\",\n \"purpose\": \"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\n \"hasHostHalf\": true,\n \"hasClientHalf\": false,\n \"isCurrent\": true,\n \"isNext\": false\n }\n ]\n }\n}"}],"isError":false}],"role":"user","id":"{{message:6}}"}},"sourceEventSeqs":[18],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"step/start","data":{"turn":1,"step":3}}
-{"type":"assistant/message","data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788233481726,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233481726,"index":0,"dt":[],"id":"advanced-direct-child","name":"subagent","args":["{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"]},{"type":"chunk","time":1788233481726,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}}},{"type":"chunk","time":1788233481726,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788233481726,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788500542326,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500542326,"index":0,"dt":[],"id":"advanced-direct-child","name":"subagent","args":["{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"]},{"type":"chunk","time":1788500542326,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}}},{"type":"chunk","time":1788500542326,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788500542326,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":3,"callId":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500542331,"mode":"one-shot","label":"Check direct child"}}
{"type":"tool/result","data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"advanced-direct-child"},"content":[{"type":"tool-result","toolCallId":"advanced-direct-child","content":[{"type":"text","text":"DIRECT_CHILD_OK"}],"isError":false}],"role":"user","id":"{{message:8}}"}},"sourceEventSeqs":[27],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":3}}
{"type":"step/start","data":{"turn":1,"step":4}}
-{"type":"assistant/message","data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-headless-snapshot\",\"description\":\"exercise one workflow child through the headless agent\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:9}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788233481803,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233481803,"index":0,"dt":[],"id":"advanced-workflow","name":"workflow","args":["{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-headless-snapshot\",\"description\":\"exercise one workflow child through the headless agent\"}}"]},{"type":"chunk","time":1788233481803,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-headless-snapshot\",\"description\":\"exercise one workflow child through the headless agent\"}}"}}},{"type":"chunk","time":1788233481803,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788233481803,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-headless-snapshot\",\"description\":\"exercise one workflow child through the headless agent\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:9}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788500542391,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500542391,"index":0,"dt":[],"id":"advanced-workflow","name":"workflow","args":["{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-headless-snapshot\",\"description\":\"exercise one workflow child through the headless agent\"}}"]},{"type":"chunk","time":1788500542391,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-headless-snapshot\",\"description\":\"exercise one workflow child through the headless agent\"}}"}}},{"type":"chunk","time":1788500542391,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788500542391,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":4,"callId":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-headless-snapshot\",\"description\":\"exercise one workflow child through the headless agent\"}}"}}
{"type":"tool-workflow/run-start","data":{"runId":"{{workflow:1}}","name":"advanced-headless-snapshot"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:3}}","childCreatedAt":1788500542517,"mode":"one-shot"}}
{"type":"tool-workflow/agent-start","data":{"runId":"{{workflow:1}}","seq":1,"label":"workflow-child","phase":"Delegate","childId":"{{session:3}}"}}
{"type":"tool-workflow/agent-end","data":{"runId":"{{workflow:1}}","seq":1,"outcome":"completed"}}
{"type":"tool-workflow/run-end","data":{"runId":"{{workflow:1}}","stopReason":"completed"}}
-{"type":"tool/result","data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"advanced-workflow"},"content":[{"type":"tool-result","toolCallId":"advanced-workflow","content":[{"type":"text","text":"workflow \"advanced-headless-snapshot\" completed (1 agent).\nReturn value:\n{\n \"reply\": \"WORKFLOW_CHILD_OK\"\n}"}],"isError":false}],"role":"user","id":"{{message:10}}"}},"sourceEventSeqs":[32],"surfaceOp":"append"}
+{"type":"tool/result","data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"advanced-workflow"},"content":[{"type":"tool-result","toolCallId":"advanced-workflow","content":[{"type":"text","text":"workflow \"advanced-headless-snapshot\" completed (1 agent).\nReturn value:\n{\n \"reply\": \"WORKFLOW_CHILD_OK\"\n}"}],"isError":false}],"role":"user","id":"{{message:10}}"}},"sourceEventSeqs":[33],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":4}}
{"type":"step/start","data":{"turn":1,"step":5}}
-{"type":"assistant/message","data":{"turn":1,"step":5,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\":\"snap-1\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:11}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788233481908,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233481908,"index":0,"dt":[],"id":"advanced-undefine","name":"cordis_undefine","args":["{\"pluginId\":\"snap-1\"}"]},{"type":"chunk","time":1788233481908,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\":\"snap-1\"}"}}},{"type":"chunk","time":1788233481908,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788233481908,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":5,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\":\"snap-1\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:11}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788500542582,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500542582,"index":0,"dt":[],"id":"advanced-undefine","name":"cordis_undefine","args":["{\"pluginId\":\"snap-1\"}"]},{"type":"chunk","time":1788500542582,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\":\"snap-1\"}"}}},{"type":"chunk","time":1788500542582,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788500542582,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":5,"callId":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\":\"snap-1\"}"}}
-{"type":"tool/result","data":{"turn":1,"step":5,"message":{"source":{"kind":"tool","callId":"advanced-undefine"},"content":[{"type":"tool-result","toolCallId":"advanced-undefine","content":[{"type":"text","text":"Removed dynamic Plugin snap-1 and all of its Packages."}],"isError":false}],"role":"user","id":"{{message:12}}"}},"sourceEventSeqs":[41],"surfaceOp":"append"}
+{"type":"tool/result","data":{"turn":1,"step":5,"message":{"source":{"kind":"tool","callId":"advanced-undefine"},"content":[{"type":"tool-result","toolCallId":"advanced-undefine","content":[{"type":"text","text":"Removed dynamic Plugin snap-1 and all of its Packages."}],"isError":false}],"role":"user","id":"{{message:12}}"}},"sourceEventSeqs":[43],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":5}}
{"type":"step/start","data":{"turn":1,"step":6}}
-{"type":"assistant/message","data":{"turn":1,"step":6,"message":{"role":"assistant","content":[{"type":"text","text":"ADVANCED_HEADLESS_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:13}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788233481936,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788233481936,"index":0,"dt":[],"texts":["ADVANCED_HEADLESS_OK"]},{"type":"chunk","time":1788233481936,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"ADVANCED_HEADLESS_OK"}}},{"type":"chunk","time":1788233481936,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788233481936,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":6,"message":{"role":"assistant","content":[{"type":"text","text":"ADVANCED_HEADLESS_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:13}}"},"usage":{"inputTokens":3,"outputTokens":3},"stream":[{"type":"chunk","time":1788500542598,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500542598,"index":0,"dt":[],"texts":["ADVANCED_HEADLESS_OK"]},{"type":"chunk","time":1788500542598,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"ADVANCED_HEADLESS_OK"}}},{"type":"chunk","time":1788500542598,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}},{"type":"chunk","time":1788500542598,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":6}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
diff --git a/snapshots/session/headless.snapshot.ts b/snapshots/session/headless.snapshot.ts
index f6f2212726..b10a87b47f 100644
--- a/snapshots/session/headless.snapshot.ts
+++ b/snapshots/session/headless.snapshot.ts
@@ -26,6 +26,7 @@ import {
normalizedHeaders,
normalizedSystemPrompts,
normalizedToolSchemas,
+ omitSubagentCatalogForHistoricalComparison,
parseSnapshotManifest,
parseToolSchemasSnapshot,
redactSessionSnapshotIds,
@@ -975,6 +976,9 @@ describe('headless recorded-session snapshots', () => {
expect(await fixtureSessions(scenario), 'historical replay input remains unchanged').toEqual(fixtures)
}
const actualSnapshots = normalizeSessionSnapshots(actualLogs.map(log => log.content), actualContext)
+ .map(snapshot => scenario.manifest.sessionFormat === undefined
+ ? snapshot
+ : omitSubagentCatalogForHistoricalComparison(snapshot))
const expectedSnapshots = normalizeSessionSnapshots(expected, contextOf(expected))
for (const [index, actual] of actualSnapshots.entries()) {
expect(records(actual), `${scenario.name}: session ${index}`).toEqual(records(expectedSnapshots[index] as string))
diff --git a/snapshots/session/ralph-loop/session.v2.jsonl b/snapshots/session/ralph-loop/session.v2.jsonl
index a7c6797092..aedf01a58c 100644
--- a/snapshots/session/ralph-loop/session.v2.jsonl
+++ b/snapshots/session/ralph-loop/session.v2.jsonl
@@ -11,11 +11,13 @@
{"type":"session/title","data":{"title":"Run a two-round fresh-agent Ralph","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_ralph","name":"ralph","arguments":"{\"objective\":\"Prove two fresh Ralph rounds through the shipped headless app.\",\"maxRounds\":2}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":20,"outputTokens":8},"stream":[{"type":"chunk","time":1788233515711,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233515711,"index":0,"dt":[],"id":"call_ralph","name":"ralph","args":["{\"objective\":\"Prove two fresh Ralph rounds through the shipped headless app.\",\"maxRounds\":2}"]},{"type":"chunk","time":1788233515711,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_ralph","name":"ralph","arguments":"{\"objective\":\"Prove two fresh Ralph rounds through the shipped headless app.\",\"maxRounds\":2}"}}},{"type":"chunk","time":1788233515711,"chunk":{"type":"usage","usage":{"inputTokens":20,"outputTokens":8}}},{"type":"chunk","time":1788233515711,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_ralph","name":"ralph","arguments":"{\"objective\":\"Prove two fresh Ralph rounds through the shipped headless app.\",\"maxRounds\":2}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":20,"outputTokens":8},"stream":[{"type":"chunk","time":1788500544849,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500544849,"index":0,"dt":[],"id":"call_ralph","name":"ralph","args":["{\"objective\":\"Prove two fresh Ralph rounds through the shipped headless app.\",\"maxRounds\":2}"]},{"type":"chunk","time":1788500544849,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_ralph","name":"ralph","arguments":"{\"objective\":\"Prove two fresh Ralph rounds through the shipped headless app.\",\"maxRounds\":2}"}}},{"type":"chunk","time":1788500544849,"chunk":{"type":"usage","usage":{"inputTokens":20,"outputTokens":8}}},{"type":"chunk","time":1788500544849,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_ralph","name":"ralph","arguments":"{\"objective\":\"Prove two fresh Ralph rounds through the shipped headless app.\",\"maxRounds\":2}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500544927,"mode":"one-shot"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:3}}","childCreatedAt":1788500544976,"mode":"one-shot"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_ralph"},"content":[{"type":"tool-result","toolCallId":"call_ralph","content":[{"type":"text","text":"Ralph worker reported completion after 2 rounds.\nFinal report:\n{\n \"status\": \"complete\",\n \"summary\": \"The Ralph snapshot objective is complete.\",\n \"evidence\": [\n \"Two fresh rounds completed through the shipped app.\"\n ],\n \"nextSteps\": [],\n \"blocker\": \"\"\n}"}],"isError":false}],"role":"user","id":"{{message:4}}"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"RALPH SNAPSHOT COMPLETE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":30,"outputTokens":4},"stream":[{"type":"chunk","time":1788233515902,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788233515902,"index":0,"dt":[],"texts":["RALPH SNAPSHOT COMPLETE"]},{"type":"chunk","time":1788233515902,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"RALPH SNAPSHOT COMPLETE"}}},{"type":"chunk","time":1788233515902,"chunk":{"type":"usage","usage":{"inputTokens":30,"outputTokens":4}}},{"type":"chunk","time":1788233515902,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"RALPH SNAPSHOT COMPLETE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":30,"outputTokens":4},"stream":[{"type":"chunk","time":1788500545054,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500545054,"index":0,"dt":[],"texts":["RALPH SNAPSHOT COMPLETE"]},{"type":"chunk","time":1788500545054,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"RALPH SNAPSHOT COMPLETE"}}},{"type":"chunk","time":1788500545054,"chunk":{"type":"usage","usage":{"inputTokens":30,"outputTokens":4}}},{"type":"chunk","time":1788500545054,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
diff --git a/snapshots/session/subagent-child-question-rejection/session.v2.jsonl b/snapshots/session/subagent-child-question-rejection/session.v2.jsonl
index 13ab513d72..7d11041678 100644
--- a/snapshots/session/subagent-child-question-rejection/session.v2.jsonl
+++ b/snapshots/session/subagent-child-question-rejection/session.v2.jsonl
@@ -11,11 +11,12 @@
{"type":"session/title","data":{"title":"Delegate one question check. Ask","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_question_child","name":"subagent","arguments":"{\"description\":\"Check deployment question\",\"prompt\":\"Call ask_user_question once to ask whether deployment should use the CUDA fallback. If the tool returns an error, include the unresolved question verbatim in your final result.\", \"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788233523819,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233523819,"index":0,"dt":[],"id":"call_question_child","name":"subagent","args":["{\"description\":\"Check deployment question\",\"prompt\":\"Call ask_user_question once to ask whether deployment should use the CUDA fallback. If the tool returns an error, include the unresolved question verbatim in your final result.\", \"run_in_background\":false}"]},{"type":"chunk","time":1788233523819,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_question_child","name":"subagent","arguments":"{\"description\":\"Check deployment question\",\"prompt\":\"Call ask_user_question once to ask whether deployment should use the CUDA fallback. If the tool returns an error, include the unresolved question verbatim in your final result.\", \"run_in_background\":false}"}}},{"type":"chunk","time":1788233523819,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788233523819,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_question_child","name":"subagent","arguments":"{\"description\":\"Check deployment question\",\"prompt\":\"Call ask_user_question once to ask whether deployment should use the CUDA fallback. If the tool returns an error, include the unresolved question verbatim in your final result.\", \"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500547269,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500547269,"index":0,"dt":[],"id":"call_question_child","name":"subagent","args":["{\"description\":\"Check deployment question\",\"prompt\":\"Call ask_user_question once to ask whether deployment should use the CUDA fallback. If the tool returns an error, include the unresolved question verbatim in your final result.\", \"run_in_background\":false}"]},{"type":"chunk","time":1788500547269,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_question_child","name":"subagent","arguments":"{\"description\":\"Check deployment question\",\"prompt\":\"Call ask_user_question once to ask whether deployment should use the CUDA fallback. If the tool returns an error, include the unresolved question verbatim in your final result.\", \"run_in_background\":false}"}}},{"type":"chunk","time":1788500547270,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500547270,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_question_child","name":"subagent","arguments":"{\"description\":\"Check deployment question\",\"prompt\":\"Call ask_user_question once to ask whether deployment should use the CUDA fallback. If the tool returns an error, include the unresolved question verbatim in your final result.\", \"run_in_background\":false}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500547276,"mode":"one-shot","label":"Check deployment question"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_question_child"},"content":[{"type":"tool-result","toolCallId":"call_question_child","content":[{"type":"text","text":"UNRESOLVED: Should deployment use the CUDA fallback?"}],"isError":false}],"role":"user","id":"{{message:4}}"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"PARENT_COMPLETED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":10,"outputTokens":2},"stream":[{"type":"chunk","time":1788233523914,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788233523915,"index":0,"dt":[],"texts":["PARENT_COMPLETED"]},{"type":"chunk","time":1788233523915,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"PARENT_COMPLETED"}}},{"type":"chunk","time":1788233523915,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}},{"type":"chunk","time":1788233523915,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"PARENT_COMPLETED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":10,"outputTokens":2},"stream":[{"type":"chunk","time":1788500547345,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500547345,"index":0,"dt":[],"texts":["PARENT_COMPLETED"]},{"type":"chunk","time":1788500547345,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"PARENT_COMPLETED"}}},{"type":"chunk","time":1788500547345,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}},{"type":"chunk","time":1788500547345,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
diff --git a/snapshots/session/subagent-depth-two-rejection/session.1.v2.jsonl b/snapshots/session/subagent-depth-two-rejection/session.1.v2.jsonl
index 459b241c5d..98334abe6f 100644
--- a/snapshots/session/subagent-depth-two-rejection/session.1.v2.jsonl
+++ b/snapshots/session/subagent-depth-two-rejection/session.1.v2.jsonl
@@ -12,11 +12,12 @@
{"type":"session/title","data":{"title":"Call subagent once. Ask that","messageSeqs":[8],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_depth_one_child","name":"subagent","arguments":"{\"description\":\"Start depth two\",\"prompt\":\"Attempt one subagent call beyond the configured cap, then report the rejection.\",\"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:8}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788233524598,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233524598,"index":0,"dt":[],"id":"call_depth_one_child","name":"subagent","args":["{\"description\":\"Start depth two\",\"prompt\":\"Attempt one subagent call beyond the configured cap, then report the rejection.\",\"run_in_background\":false}"]},{"type":"chunk","time":1788233524598,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_depth_one_child","name":"subagent","arguments":"{\"description\":\"Start depth two\",\"prompt\":\"Attempt one subagent call beyond the configured cap, then report the rejection.\",\"run_in_background\":false}"}}},{"type":"chunk","time":1788233524598,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788233524598,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_depth_one_child","name":"subagent","arguments":"{\"description\":\"Start depth two\",\"prompt\":\"Attempt one subagent call beyond the configured cap, then report the rejection.\",\"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:8}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500548365,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500548366,"index":0,"dt":[],"id":"call_depth_one_child","name":"subagent","args":["{\"description\":\"Start depth two\",\"prompt\":\"Attempt one subagent call beyond the configured cap, then report the rejection.\",\"run_in_background\":false}"]},{"type":"chunk","time":1788500548366,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_depth_one_child","name":"subagent","arguments":"{\"description\":\"Start depth two\",\"prompt\":\"Attempt one subagent call beyond the configured cap, then report the rejection.\",\"run_in_background\":false}"}}},{"type":"chunk","time":1788500548366,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500548366,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_depth_one_child","name":"subagent","arguments":"{\"description\":\"Start depth two\",\"prompt\":\"Attempt one subagent call beyond the configured cap, then report the rejection.\",\"run_in_background\":false}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:3}}","childCreatedAt":1788500548373,"mode":"one-shot","label":"Start depth two"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_depth_one_child"},"content":[{"type":"tool-result","toolCallId":"call_depth_one_child","content":[{"type":"text","text":"DEPTH_REJECTED"}],"isError":false}],"role":"user","id":"{{message:9}}"}},"sourceEventSeqs":[14],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"DEPTH_ONE_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:10}}"},"usage":{"inputTokens":10,"outputTokens":2},"stream":[{"type":"chunk","time":1788233524703,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788233524703,"index":0,"dt":[],"texts":["DEPTH_ONE_DONE"]},{"type":"chunk","time":1788233524703,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DEPTH_ONE_DONE"}}},{"type":"chunk","time":1788233524703,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}},{"type":"chunk","time":1788233524703,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"DEPTH_ONE_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:10}}"},"usage":{"inputTokens":10,"outputTokens":2},"stream":[{"type":"chunk","time":1788500548476,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500548476,"index":0,"dt":[],"texts":["DEPTH_ONE_DONE"]},{"type":"chunk","time":1788500548477,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DEPTH_ONE_DONE"}}},{"type":"chunk","time":1788500548477,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}},{"type":"chunk","time":1788500548477,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
diff --git a/snapshots/session/subagent-depth-two-rejection/session.v2.jsonl b/snapshots/session/subagent-depth-two-rejection/session.v2.jsonl
index 764ab99c92..e4b17cd756 100644
--- a/snapshots/session/subagent-depth-two-rejection/session.v2.jsonl
+++ b/snapshots/session/subagent-depth-two-rejection/session.v2.jsonl
@@ -11,11 +11,12 @@
{"type":"session/title","data":{"title":"Delegate through two child generations.","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_root_child","name":"subagent","arguments":"{\"description\":\"Start depth one\",\"prompt\":\"Call subagent once. Ask that child to attempt one further subagent call, then report the result.\",\"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788233524552,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233524552,"index":0,"dt":[],"id":"call_root_child","name":"subagent","args":["{\"description\":\"Start depth one\",\"prompt\":\"Call subagent once. Ask that child to attempt one further subagent call, then report the result.\",\"run_in_background\":false}"]},{"type":"chunk","time":1788233524552,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_root_child","name":"subagent","arguments":"{\"description\":\"Start depth one\",\"prompt\":\"Call subagent once. Ask that child to attempt one further subagent call, then report the result.\",\"run_in_background\":false}"}}},{"type":"chunk","time":1788233524553,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788233524553,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_root_child","name":"subagent","arguments":"{\"description\":\"Start depth one\",\"prompt\":\"Call subagent once. Ask that child to attempt one further subagent call, then report the result.\",\"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500548303,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500548303,"index":0,"dt":[],"id":"call_root_child","name":"subagent","args":["{\"description\":\"Start depth one\",\"prompt\":\"Call subagent once. Ask that child to attempt one further subagent call, then report the result.\",\"run_in_background\":false}"]},{"type":"chunk","time":1788500548303,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_root_child","name":"subagent","arguments":"{\"description\":\"Start depth one\",\"prompt\":\"Call subagent once. Ask that child to attempt one further subagent call, then report the result.\",\"run_in_background\":false}"}}},{"type":"chunk","time":1788500548303,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500548303,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_root_child","name":"subagent","arguments":"{\"description\":\"Start depth one\",\"prompt\":\"Call subagent once. Ask that child to attempt one further subagent call, then report the result.\",\"run_in_background\":false}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500548310,"mode":"one-shot","label":"Start depth one"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_root_child"},"content":[{"type":"tool-result","toolCallId":"call_root_child","content":[{"type":"text","text":"DEPTH_ONE_DONE"}],"isError":false}],"role":"user","id":"{{message:4}}"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"ROOT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":10,"outputTokens":2},"stream":[{"type":"chunk","time":1788233524723,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788233524723,"index":0,"dt":[],"texts":["ROOT_DONE"]},{"type":"chunk","time":1788233524723,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"ROOT_DONE"}}},{"type":"chunk","time":1788233524723,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}},{"type":"chunk","time":1788233524723,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"ROOT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":10,"outputTokens":2},"stream":[{"type":"chunk","time":1788500548498,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500548498,"index":0,"dt":[],"texts":["ROOT_DONE"]},{"type":"chunk","time":1788500548498,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"ROOT_DONE"}}},{"type":"chunk","time":1788500548498,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}},{"type":"chunk","time":1788500548498,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
diff --git a/snapshots/session/subagent-max-tokens-partial/session.v2.jsonl b/snapshots/session/subagent-max-tokens-partial/session.v2.jsonl
index fc7b96f216..82120de5f6 100644
--- a/snapshots/session/subagent-max-tokens-partial/session.v2.jsonl
+++ b/snapshots/session/subagent-max-tokens-partial/session.v2.jsonl
@@ -11,11 +11,12 @@
{"type":"session/title","data":{"title":"Use the subagent tool exactly","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_parent_1","name":"subagent","arguments":"{\"description\": \"Truncated child\", \"prompt\": \"Write the words 'partial one', call todo_write once, then keep going until you are cut off.\", \"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788233525350,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"chunk","time":1788233525350,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_parent_1","name":"subagent","arguments":"{\"description\": \"Truncated child\", \"prompt\": \"Write the words 'partial one', call todo_write once, then keep going until you are cut off.\", \"run_in_background\":false}"}}},{"type":"chunk","time":1788233525350,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788233525350,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_parent_1","name":"subagent","arguments":"{\"description\": \"Truncated child\", \"prompt\": \"Write the words 'partial one', call todo_write once, then keep going until you are cut off.\", \"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500549527,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"chunk","time":1788500549527,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_parent_1","name":"subagent","arguments":"{\"description\": \"Truncated child\", \"prompt\": \"Write the words 'partial one', call todo_write once, then keep going until you are cut off.\", \"run_in_background\":false}"}}},{"type":"chunk","time":1788500549527,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500549527,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_parent_1","name":"subagent","arguments":"{\"description\": \"Truncated child\", \"prompt\": \"Write the words 'partial one', call todo_write once, then keep going until you are cut off.\", \"run_in_background\":false}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500549533,"mode":"one-shot","label":"Truncated child"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_parent_1"},"content":[{"type":"tool-result","toolCallId":"call_parent_1","content":[{"type":"text","text":"Error: subagent run hit its token limit before finishing\nPartial output before the run ended:\npartial one"}],"isError":true}],"role":"user","id":"{{message:4}}"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"PARENT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":12,"outputTokens":2},"stream":[{"type":"chunk","time":1788233525447,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"chunk","time":1788233525447,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"PARENT_DONE"}}},{"type":"chunk","time":1788233525447,"chunk":{"type":"usage","usage":{"inputTokens":12,"outputTokens":2}}},{"type":"chunk","time":1788233525447,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"PARENT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":12,"outputTokens":2},"stream":[{"type":"chunk","time":1788500549606,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"chunk","time":1788500549606,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"PARENT_DONE"}}},{"type":"chunk","time":1788500549606,"chunk":{"type":"usage","usage":{"inputTokens":12,"outputTokens":2}}},{"type":"chunk","time":1788500549606,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
diff --git a/snapshots/session/subagent-parallel/session.v2.jsonl b/snapshots/session/subagent-parallel/session.v2.jsonl
index a01d33384e..2cbca0e0fb 100644
--- a/snapshots/session/subagent-parallel/session.v2.jsonl
+++ b/snapshots/session/subagent-parallel/session.v2.jsonl
@@ -11,13 +11,15 @@
{"type":"session/title","data":{"title":"Use the subagent tool TWICE","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_parallel_alpha_1","name":"subagent","arguments":"{\"description\": \"Say the word ALPHA\", \"prompt\": \"Reply with exactly the word ALPHA and nothing else.\", \"run_in_background\":false}"},{"type":"tool-call","id":"call_parallel_alpha_2","name":"subagent","arguments":"{\"description\": \"Say the word ALPHA\", \"prompt\": \"Reply with exactly the word ALPHA and nothing else.\", \"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"stream":[{"type":"chunk","time":1788233526821,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"chunk","time":1788233526821,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_parallel_alpha_1","name":"subagent","arguments":"{\"description\": \"Say the word ALPHA\", \"prompt\": \"Reply with exactly the word ALPHA and nothing else.\", \"run_in_background\":false}"}}},{"type":"chunk","time":1788233526821,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"chunk","time":1788233526821,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_parallel_alpha_2","name":"subagent","arguments":"{\"description\": \"Say the word ALPHA\", \"prompt\": \"Reply with exactly the word ALPHA and nothing else.\", \"run_in_background\":false}"}}},{"type":"chunk","time":1788233526821,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_parallel_alpha_1","name":"subagent","arguments":"{\"description\": \"Say the word ALPHA\", \"prompt\": \"Reply with exactly the word ALPHA and nothing else.\", \"run_in_background\":false}"},{"type":"tool-call","id":"call_parallel_alpha_2","name":"subagent","arguments":"{\"description\": \"Say the word ALPHA\", \"prompt\": \"Reply with exactly the word ALPHA and nothing else.\", \"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"stream":[{"type":"chunk","time":1788500551334,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"chunk","time":1788500551334,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_parallel_alpha_1","name":"subagent","arguments":"{\"description\": \"Say the word ALPHA\", \"prompt\": \"Reply with exactly the word ALPHA and nothing else.\", \"run_in_background\":false}"}}},{"type":"chunk","time":1788500551334,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"chunk","time":1788500551334,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_parallel_alpha_2","name":"subagent","arguments":"{\"description\": \"Say the word ALPHA\", \"prompt\": \"Reply with exactly the word ALPHA and nothing else.\", \"run_in_background\":false}"}}},{"type":"chunk","time":1788500551334,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_parallel_alpha_1","name":"subagent","arguments":"{\"description\": \"Say the word ALPHA\", \"prompt\": \"Reply with exactly the word ALPHA and nothing else.\", \"run_in_background\":false}"}}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_parallel_alpha_2","name":"subagent","arguments":"{\"description\": \"Say the word ALPHA\", \"prompt\": \"Reply with exactly the word ALPHA and nothing else.\", \"run_in_background\":false}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500551344,"mode":"one-shot","label":"Say the word ALPHA"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:3}}","childCreatedAt":1788500551344,"mode":"one-shot","label":"Say the word ALPHA"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_parallel_alpha_1"},"content":[{"type":"tool-result","toolCallId":"call_parallel_alpha_1","content":[{"type":"text","text":"ALPHA"}],"isError":false}],"role":"user","id":"{{message:4}}"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_parallel_alpha_2"},"content":[{"type":"tool-result","toolCallId":"call_parallel_alpha_2","content":[{"type":"text","text":"ALPHA"}],"isError":false}],"role":"user","id":"{{message:5}}"}},"sourceEventSeqs":[14],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"PARENT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:6}}"},"stream":[{"type":"chunk","time":1788233526904,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"chunk","time":1788233526904,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"PARENT_DONE"}}},{"type":"chunk","time":1788233526904,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"PARENT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:6}}"},"stream":[{"type":"chunk","time":1788500551413,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"chunk","time":1788500551413,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"PARENT_DONE"}}},{"type":"chunk","time":1788500551413,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
diff --git a/snapshots/session/subagent-published-run-failure/session.v2.jsonl b/snapshots/session/subagent-published-run-failure/session.v2.jsonl
index 62755d8d49..e723042e93 100644
--- a/snapshots/session/subagent-published-run-failure/session.v2.jsonl
+++ b/snapshots/session/subagent-published-run-failure/session.v2.jsonl
@@ -11,11 +11,12 @@
{"type":"session/title","data":{"title":"Delegate one foreground subagent. Its","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_published_failure","name":"subagent","arguments":"{\"description\":\"Fail published run\",\"prompt\":\"This child prompt must never run.\",\"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788233527588,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233527588,"index":0,"dt":[],"id":"call_published_failure","name":"subagent","args":["{\"description\":\"Fail published run\",\"prompt\":\"This child prompt must never run.\",\"run_in_background\":false}"]},{"type":"chunk","time":1788233527588,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_published_failure","name":"subagent","arguments":"{\"description\":\"Fail published run\",\"prompt\":\"This child prompt must never run.\",\"run_in_background\":false}"}}},{"type":"chunk","time":1788233527588,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788233527588,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_published_failure","name":"subagent","arguments":"{\"description\":\"Fail published run\",\"prompt\":\"This child prompt must never run.\",\"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":10,"outputTokens":5},"stream":[{"type":"chunk","time":1788500552312,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500552312,"index":0,"dt":[],"id":"call_published_failure","name":"subagent","args":["{\"description\":\"Fail published run\",\"prompt\":\"This child prompt must never run.\",\"run_in_background\":false}"]},{"type":"chunk","time":1788500552312,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_published_failure","name":"subagent","arguments":"{\"description\":\"Fail published run\",\"prompt\":\"This child prompt must never run.\",\"run_in_background\":false}"}}},{"type":"chunk","time":1788500552312,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}},{"type":"chunk","time":1788500552312,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_published_failure","name":"subagent","arguments":"{\"description\":\"Fail published run\",\"prompt\":\"This child prompt must never run.\",\"run_in_background\":false}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500552318,"mode":"one-shot","label":"Fail published run"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_published_failure"},"content":[{"type":"tool-result","toolCallId":"call_published_failure","content":[{"type":"text","text":"Error: subagent run failed: Error: snapshot published run failed; dispose failed: Error: snapshot published handle disposal failed"}],"isError":true}],"role":"user","id":"{{message:4}}"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"PARENT_OBSERVED_ERROR"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":10,"outputTokens":2},"stream":[{"type":"chunk","time":1788233527613,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788233527613,"index":0,"dt":[],"texts":["PARENT_OBSERVED_ERROR"]},{"type":"chunk","time":1788233527613,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"PARENT_OBSERVED_ERROR"}}},{"type":"chunk","time":1788233527613,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}},{"type":"chunk","time":1788233527613,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"PARENT_OBSERVED_ERROR"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":10,"outputTokens":2},"stream":[{"type":"chunk","time":1788500552354,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":1788500552354,"index":0,"dt":[],"texts":["PARENT_OBSERVED_ERROR"]},{"type":"chunk","time":1788500552354,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"PARENT_OBSERVED_ERROR"}}},{"type":"chunk","time":1788500552354,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}},{"type":"chunk","time":1788500552354,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
diff --git a/snapshots/session/subagent-spawn-in-process/session.v2.jsonl b/snapshots/session/subagent-spawn-in-process/session.v2.jsonl
index 81f85f4de9..a2f3f9c449 100644
--- a/snapshots/session/subagent-spawn-in-process/session.v2.jsonl
+++ b/snapshots/session/subagent-spawn-in-process/session.v2.jsonl
@@ -11,11 +11,12 @@
{"type":"session/title","data":{"title":"Use the subagent tool exactly","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to:\n1. Use the subagent tool exactly once to delegate the task: \"Reply with exactly the word CHILD_OK and nothing else.\"\n2. After the subagent returns, reply with the single word PARENT_DONE and stop.\n3. Do not use the bash tool.\n\nLet me do this."},{"type":"tool-call","id":"call_00_gVbLWC12Qu8JheZpVRRz8749","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":2907,"outputTokens":142,"cacheReadTokens":0,"reasoningTokens":67},"stream":[{"type":"chunk","time":1788233528227,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788233528227,"index":0,"dt":[0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," user"," wants"," me"," to",":\n","1","."," Use"," the"," sub","agent"," tool"," exactly"," once"," to"," delegate"," the"," task",":"," \"","Reply"," with"," exactly"," the"," word"," CH","ILD","_OK"," and"," nothing"," else",".\"\n","2","."," After"," the"," sub","agent"," returns",","," reply"," with"," the"," single"," word"," PAR","ENT","_D","ONE"," and"," stop",".\n","3","."," Do"," not"," use"," the"," bash"," tool",".\n\n","Let"," me"," do"," this","."]},{"type":"chunk","time":1788233528228,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233528228,"index":1,"dt":[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"id":"call_00_gVbLWC12Qu8JheZpVRRz8749","name":"subagent","args":["","{","\"","description","\"",": ","\"","Reply"," with"," CH","ILD","_OK","\"",", ","\"","prom","pt","\"",": ","\"","Reply"," with"," exactly"," the"," word"," CH","ILD","_OK"," and"," nothing"," else",".","\"",", \"run_in_background\":false}"]},{"type":"chunk","time":1788233528229,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to:\n1. Use the subagent tool exactly once to delegate the task: \"Reply with exactly the word CHILD_OK and nothing else.\"\n2. After the subagent returns, reply with the single word PARENT_DONE and stop.\n3. Do not use the bash tool.\n\nLet me do this."}}},{"type":"chunk","time":1788233528229,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_gVbLWC12Qu8JheZpVRRz8749","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\":false}"}}},{"type":"chunk","time":1788233528229,"chunk":{"type":"usage","usage":{"inputTokens":2907,"outputTokens":142,"cacheReadTokens":0,"reasoningTokens":67}}},{"type":"chunk","time":1788233528229,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to:\n1. Use the subagent tool exactly once to delegate the task: \"Reply with exactly the word CHILD_OK and nothing else.\"\n2. After the subagent returns, reply with the single word PARENT_DONE and stop.\n3. Do not use the bash tool.\n\nLet me do this."},{"type":"tool-call","id":"call_00_gVbLWC12Qu8JheZpVRRz8749","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":2907,"outputTokens":142,"cacheReadTokens":0,"reasoningTokens":67},"stream":[{"type":"chunk","time":1788500553301,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788500553301,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," user"," wants"," me"," to",":\n","1","."," Use"," the"," sub","agent"," tool"," exactly"," once"," to"," delegate"," the"," task",":"," \"","Reply"," with"," exactly"," the"," word"," CH","ILD","_OK"," and"," nothing"," else",".\"\n","2","."," After"," the"," sub","agent"," returns",","," reply"," with"," the"," single"," word"," PAR","ENT","_D","ONE"," and"," stop",".\n","3","."," Do"," not"," use"," the"," bash"," tool",".\n\n","Let"," me"," do"," this","."]},{"type":"chunk","time":1788500553302,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500553302,"index":1,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"id":"call_00_gVbLWC12Qu8JheZpVRRz8749","name":"subagent","args":["","{","\"","description","\"",": ","\"","Reply"," with"," CH","ILD","_OK","\"",", ","\"","prom","pt","\"",": ","\"","Reply"," with"," exactly"," the"," word"," CH","ILD","_OK"," and"," nothing"," else",".","\"",", \"run_in_background\":false}"]},{"type":"chunk","time":1788500553302,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to:\n1. Use the subagent tool exactly once to delegate the task: \"Reply with exactly the word CHILD_OK and nothing else.\"\n2. After the subagent returns, reply with the single word PARENT_DONE and stop.\n3. Do not use the bash tool.\n\nLet me do this."}}},{"type":"chunk","time":1788500553302,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_gVbLWC12Qu8JheZpVRRz8749","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\":false}"}}},{"type":"chunk","time":1788500553302,"chunk":{"type":"usage","usage":{"inputTokens":2907,"outputTokens":142,"cacheReadTokens":0,"reasoningTokens":67}}},{"type":"chunk","time":1788500553302,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_00_gVbLWC12Qu8JheZpVRRz8749","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\":false}"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500553308,"mode":"one-shot","label":"Reply with CHILD_OK"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_00_gVbLWC12Qu8JheZpVRRz8749"},"content":[{"type":"tool-result","toolCallId":"call_00_gVbLWC12Qu8JheZpVRRz8749","content":[{"type":"text","text":"CHILD_OK"}],"isError":false}],"role":"user","id":"{{message:4}}"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The subagent returned \"CHILD_OK\" as expected. Now I need to reply with the single word \"PARENT_DONE\" and stop."},{"type":"text","text":"PARENT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":120,"outputTokens":35,"cacheReadTokens":2944,"reasoningTokens":30},"stream":[{"type":"chunk","time":1788233528286,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788233528286,"index":0,"dt":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," sub","agent"," returned"," \"","CH","ILD","_OK","\""," as"," expected","."," Now"," I"," need"," to"," reply"," with"," the"," single"," word"," \"","PAR","ENT","_D","ONE","\""," and"," stop","."]},{"type":"chunk","time":1788233528287,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788233528287,"index":1,"dt":[0,0,0],"texts":["PAR","ENT","_D","ONE"]},{"type":"chunk","time":1788233528287,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The subagent returned \"CHILD_OK\" as expected. Now I need to reply with the single word \"PARENT_DONE\" and stop."}}},{"type":"chunk","time":1788233528287,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"PARENT_DONE"}}},{"type":"chunk","time":1788233528287,"chunk":{"type":"usage","usage":{"inputTokens":120,"outputTokens":35,"cacheReadTokens":2944,"reasoningTokens":30}}},{"type":"chunk","time":1788233528287,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The subagent returned \"CHILD_OK\" as expected. Now I need to reply with the single word \"PARENT_DONE\" and stop."},{"type":"text","text":"PARENT_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":120,"outputTokens":35,"cacheReadTokens":2944,"reasoningTokens":30},"stream":[{"type":"chunk","time":1788500553369,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788500553369,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," sub","agent"," returned"," \"","CH","ILD","_OK","\""," as"," expected","."," Now"," I"," need"," to"," reply"," with"," the"," single"," word"," \"","PAR","ENT","_D","ONE","\""," and"," stop","."]},{"type":"chunk","time":1788500553369,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788500553369,"index":1,"dt":[0,0,0],"texts":["PAR","ENT","_D","ONE"]},{"type":"chunk","time":1788500553369,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The subagent returned \"CHILD_OK\" as expected. Now I need to reply with the single word \"PARENT_DONE\" and stop."}}},{"type":"chunk","time":1788500553369,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"PARENT_DONE"}}},{"type":"chunk","time":1788500553369,"chunk":{"type":"usage","usage":{"inputTokens":120,"outputTokens":35,"cacheReadTokens":2944,"reasoningTokens":30}}},{"type":"chunk","time":1788500553369,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
diff --git a/snapshots/session/workflow-run/session.v2.jsonl b/snapshots/session/workflow-run/session.v2.jsonl
index f9285f97f6..46bd43686a 100644
--- a/snapshots/session/workflow-run/session.v2.jsonl
+++ b/snapshots/session/workflow-run/session.v2.jsonl
@@ -11,15 +11,16 @@
{"type":"session/title","data":{"title":"Use the workflow tool exactly","messageSeqs":[7],"source":{"kind":"fallback"}}}
{"type":"request/header","data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
-{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to use the workflow tool exactly once with specific parameters. Let me carefully follow the instructions:\n\n1. args omitted (so I don't include it)\n2. meta = { \"name\": \"snapshot-flow\", \"description\": \"one child for the snapshot\" }\n3. script = as given verbatim\n4. After it returns, reply with \"WORKFLOW_DONE\"\n\nLet me do exactly that."},{"type":"tool-call","id":"call_00_dD2BLuNeJCTh2iiYC1QR3449","name":"workflow","arguments":"{\"meta\": {\"name\": \"snapshot-flow\", \"description\": \"one child for the snapshot\"}, \"script\": \"\\nphase('Run')\\nconst reply = await agent('Reply with exactly the word WF_CHILD_OK and nothing else.')\\nreturn { reply }\\n\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":3174,"outputTokens":191,"cacheReadTokens":0,"reasoningTokens":88},"stream":[{"type":"chunk","time":1788233532122,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788233532122,"index":0,"dt":[0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," user"," wants"," me"," to"," use"," the"," workflow"," tool"," exactly"," once"," with"," specific"," parameters","."," Let"," me"," carefully"," follow"," the"," instructions",":\n\n","1","."," args"," omitted"," (","so"," I"," don","'t"," include"," it",")\n","2","."," meta"," ="," {"," \"","name","\":"," \"","sn","apshot","-flow","\","," \"","description","\":"," \"","one"," child"," for"," the"," snapshot","\""," }\n","3","."," script"," ="," as"," given"," verb","atim","\n","4","."," After"," it"," returns",","," reply"," with"," \"","WORK","FL","OW","_D","ONE","\"\n\n","Let"," me"," do"," exactly"," that","."]},{"type":"chunk","time":1788233532123,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788233532123,"index":1,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"id":"call_00_dD2BLuNeJCTh2iiYC1QR3449","name":"workflow","args":["","{","\"","meta","\"",": ","{\"","name","\":"," \"","sn","apshot","-flow","\","," \"","description","\":"," \"","one"," child"," for"," the"," snapshot","\"","}",", ","\"","script","\"",": ","\"","\\n","phase","('","Run","')\\n","const"," reply"," ="," await"," agent","('","Reply"," with"," exactly"," the"," word"," WF","_CH","ILD","_OK"," and"," nothing"," else",".')\\n","return"," {"," reply"," }\\n","\"","}"]},{"type":"chunk","time":1788233532123,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to use the workflow tool exactly once with specific parameters. Let me carefully follow the instructions:\n\n1. args omitted (so I don't include it)\n2. meta = { \"name\": \"snapshot-flow\", \"description\": \"one child for the snapshot\" }\n3. script = as given verbatim\n4. After it returns, reply with \"WORKFLOW_DONE\"\n\nLet me do exactly that."}}},{"type":"chunk","time":1788233532124,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_dD2BLuNeJCTh2iiYC1QR3449","name":"workflow","arguments":"{\"meta\": {\"name\": \"snapshot-flow\", \"description\": \"one child for the snapshot\"}, \"script\": \"\\nphase('Run')\\nconst reply = await agent('Reply with exactly the word WF_CHILD_OK and nothing else.')\\nreturn { reply }\\n\"}"}}},{"type":"chunk","time":1788233532124,"chunk":{"type":"usage","usage":{"inputTokens":3174,"outputTokens":191,"cacheReadTokens":0,"reasoningTokens":88}}},{"type":"chunk","time":1788233532124,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to use the workflow tool exactly once with specific parameters. Let me carefully follow the instructions:\n\n1. args omitted (so I don't include it)\n2. meta = { \"name\": \"snapshot-flow\", \"description\": \"one child for the snapshot\" }\n3. script = as given verbatim\n4. After it returns, reply with \"WORKFLOW_DONE\"\n\nLet me do exactly that."},{"type":"tool-call","id":"call_00_dD2BLuNeJCTh2iiYC1QR3449","name":"workflow","arguments":"{\"meta\": {\"name\": \"snapshot-flow\", \"description\": \"one child for the snapshot\"}, \"script\": \"\\nphase('Run')\\nconst reply = await agent('Reply with exactly the word WF_CHILD_OK and nothing else.')\\nreturn { reply }\\n\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:3}}"},"usage":{"inputTokens":3174,"outputTokens":191,"cacheReadTokens":0,"reasoningTokens":88},"stream":[{"type":"chunk","time":1788500554310,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788500554310,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0],"texts":["The"," user"," wants"," me"," to"," use"," the"," workflow"," tool"," exactly"," once"," with"," specific"," parameters","."," Let"," me"," carefully"," follow"," the"," instructions",":\n\n","1","."," args"," omitted"," (","so"," I"," don","'t"," include"," it",")\n","2","."," meta"," ="," {"," \"","name","\":"," \"","sn","apshot","-flow","\","," \"","description","\":"," \"","one"," child"," for"," the"," snapshot","\""," }\n","3","."," script"," ="," as"," given"," verb","atim","\n","4","."," After"," it"," returns",","," reply"," with"," \"","WORK","FL","OW","_D","ONE","\"\n\n","Let"," me"," do"," exactly"," that","."]},{"type":"chunk","time":1788500554311,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788500554311,"index":1,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"id":"call_00_dD2BLuNeJCTh2iiYC1QR3449","name":"workflow","args":["","{","\"","meta","\"",": ","{\"","name","\":"," \"","sn","apshot","-flow","\","," \"","description","\":"," \"","one"," child"," for"," the"," snapshot","\"","}",", ","\"","script","\"",": ","\"","\\n","phase","('","Run","')\\n","const"," reply"," ="," await"," agent","('","Reply"," with"," exactly"," the"," word"," WF","_CH","ILD","_OK"," and"," nothing"," else",".')\\n","return"," {"," reply"," }\\n","\"","}"]},{"type":"chunk","time":1788500554311,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to use the workflow tool exactly once with specific parameters. Let me carefully follow the instructions:\n\n1. args omitted (so I don't include it)\n2. meta = { \"name\": \"snapshot-flow\", \"description\": \"one child for the snapshot\" }\n3. script = as given verbatim\n4. After it returns, reply with \"WORKFLOW_DONE\"\n\nLet me do exactly that."}}},{"type":"chunk","time":1788500554311,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_dD2BLuNeJCTh2iiYC1QR3449","name":"workflow","arguments":"{\"meta\": {\"name\": \"snapshot-flow\", \"description\": \"one child for the snapshot\"}, \"script\": \"\\nphase('Run')\\nconst reply = await agent('Reply with exactly the word WF_CHILD_OK and nothing else.')\\nreturn { reply }\\n\"}"}}},{"type":"chunk","time":1788500554311,"chunk":{"type":"usage","usage":{"inputTokens":3174,"outputTokens":191,"cacheReadTokens":0,"reasoningTokens":88}}},{"type":"chunk","time":1788500554311,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_00_dD2BLuNeJCTh2iiYC1QR3449","name":"workflow","arguments":"{\"meta\": {\"name\": \"snapshot-flow\", \"description\": \"one child for the snapshot\"}, \"script\": \"\\nphase('Run')\\nconst reply = await agent('Reply with exactly the word WF_CHILD_OK and nothing else.')\\nreturn { reply }\\n\"}"}}
{"type":"tool-workflow/run-start","data":{"runId":"{{workflow:1}}","name":"snapshot-flow"}}
+{"type":"subagent/catalog","data":{"version":0,"childId":"{{session:2}}","childCreatedAt":1788500554400,"mode":"one-shot"}}
{"type":"tool-workflow/agent-start","data":{"runId":"{{workflow:1}}","seq":1,"label":"Reply with exactly the word WF_CHILD_OK and not…","phase":"Run","childId":"{{session:2}}"}}
{"type":"tool-workflow/agent-end","data":{"runId":"{{workflow:1}}","seq":1,"outcome":"completed"}}
{"type":"tool-workflow/run-end","data":{"runId":"{{workflow:1}}","stopReason":"completed"}}
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_00_dD2BLuNeJCTh2iiYC1QR3449"},"content":[{"type":"tool-result","toolCallId":"call_00_dD2BLuNeJCTh2iiYC1QR3449","content":[{"type":"text","text":"workflow \"snapshot-flow\" completed (1 agent).\nReturn value:\n{\n \"reply\": \"WF_CHILD_OK\"\n}"}],"isError":false}],"role":"user","id":"{{message:4}}"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"step/start","data":{"turn":1,"step":2}}
-{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The workflow returned successfully with the reply \"WF_CHILD_OK\". Now I need to reply with exactly \"WORKFLOW_DONE\" and stop."},{"type":"text","text":"WORKFLOW_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":328,"outputTokens":36,"cacheReadTokens":3072,"reasoningTokens":30},"stream":[{"type":"chunk","time":1788233532207,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788233532207,"index":0,"dt":[0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," workflow"," returned"," successfully"," with"," the"," reply"," \"","WF","_CH","ILD","_OK","\"."," Now"," I"," need"," to"," reply"," with"," exactly"," \"","WORK","FL","OW","_D","ONE","\""," and"," stop","."]},{"type":"chunk","time":1788233532208,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788233532208,"index":1,"dt":[0,0,0,0],"texts":["WORK","FL","OW","_D","ONE"]},{"type":"chunk","time":1788233532208,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The workflow returned successfully with the reply \"WF_CHILD_OK\". Now I need to reply with exactly \"WORKFLOW_DONE\" and stop."}}},{"type":"chunk","time":1788233532208,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"WORKFLOW_DONE"}}},{"type":"chunk","time":1788233532208,"chunk":{"type":"usage","usage":{"inputTokens":328,"outputTokens":36,"cacheReadTokens":3072,"reasoningTokens":30}}},{"type":"chunk","time":1788233532208,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
+{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The workflow returned successfully with the reply \"WF_CHILD_OK\". Now I need to reply with exactly \"WORKFLOW_DONE\" and stop."},{"type":"text","text":"WORKFLOW_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":328,"outputTokens":36,"cacheReadTokens":3072,"reasoningTokens":30},"stream":[{"type":"chunk","time":1788500554460,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788500554460,"index":0,"dt":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"texts":["The"," workflow"," returned"," successfully"," with"," the"," reply"," \"","WF","_CH","ILD","_OK","\"."," Now"," I"," need"," to"," reply"," with"," exactly"," \"","WORK","FL","OW","_D","ONE","\""," and"," stop","."]},{"type":"chunk","time":1788500554460,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788500554460,"index":1,"dt":[0,0,0,0],"texts":["WORK","FL","OW","_D","ONE"]},{"type":"chunk","time":1788500554460,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The workflow returned successfully with the reply \"WF_CHILD_OK\". Now I need to reply with exactly \"WORKFLOW_DONE\" and stop."}}},{"type":"chunk","time":1788500554460,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"WORKFLOW_DONE"}}},{"type":"chunk","time":1788500554460,"chunk":{"type":"usage","usage":{"inputTokens":328,"outputTokens":36,"cacheReadTokens":3072,"reasoningTokens":30}}},{"type":"chunk","time":1788500554460,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":2}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}