🤖 feat: share workspace memory notes across a sub-agent task tree - #4139
🤖 feat: share workspace memory notes across a sub-agent task tree#4139ThomasK33 wants to merge 28 commits into
Conversation
Sub-agent child workspaces (parentWorkspaceId set) now resolve /memories/workspace/... to the task-tree root's <sessionDir>/memory, so an owner and all of its (nested) sub-agents read and write one notebook while their transcripts and session artifacts stay separate. - MemoryService.resolveWorkspaceMemoryOwnerId walks parentWorkspaceId to the root (cycle/depth guarded, unknown ids resolve to themselves) and is used for the workspace store root, sidecar pin/usage keys, change events, the workspace-scope refinement journal (owner session, where rollback confinement holds), and the removal tombstone check (acting + owner). - Memory tab subscriptions/list/pin resolve the owner too. - Dream consolidation refuses sub-agent children and the launch sweep skips them; children still harvest into the shared inbox, the owner sweeps it. - A workspace-scope write invalidates the cached memory context of every live session in the same tree. --- _Generated with `xum` • Model: `anthropic:claude-fable-5-1` • Thinking: `high` • Cost: `$1.38`_ <!-- mux-attribution: model=anthropic:claude-fable-5-1 thinking=high costs=1.38 -->
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
Security findingsAdvisory findings (7)
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7f235f92df
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
- Removal of a sub-agent also holds the task-tree owner's memory store lock, closing the tombstone-vs-admitted-write window. - Workspace-scope rows stay in the acting session's journal (refine audit correlation); rollback admits the owner memory root via a caller-supplied sharedWorkspaceMemorySessionDir (tool ctx, debug CLI). - Memory-context invalidation bumps a generation so an in-flight build cannot repopulate the cache with a pre-write snapshot. - Cross-session invalidation resolves owners from one config snapshot. - Dream/sweep suppression compares the resolved owner, so dangling parent chains keep their private store consolidatable. --- _Generated with `xum` • Model: `anthropic:claude-fable-5-1` • Thinking: `high` • Cost: `$2.30`_ <!-- mux-attribution: model=anthropic:claude-fable-5-1 thinking=high costs=2.30 -->
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3164b699f9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
- Owner memo is cleared on config changes so a child of a removed owner re-resolves to its own store instead of the tombstoned owner. - Rollback re-checks the shared owner's removal tombstone inside the target lock before applying an inverse into the owner's memory root. - refinement_rollback announces its direct-to-disk writes through MemoryService.notifyExternalMutation (subscriptions + tree-wide cache invalidation); startup-recovery sessions are invalidated too. - Sub-agent Dream runs (manual/compaction, incl. post-harvest) redirect to the owner under the owner's in-flight lock; archive is refused; the child's status view reports the owner's workspace record. --- _Generated with `xum` • Model: `anthropic:claude-fable-5-1` • Thinking: `high` • Cost: `$3.10`_ <!-- mux-attribution: model=anthropic:claude-fable-5-1 thinking=high costs=3.10 -->
|
@codex review |
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3ab8207bc2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Owner memo is validated against a durable config.json stamp (Config.configFileStamp) so another backend's owner removal is picked up, not only local editConfig notifications. - Memory change subscriptions resolve the subscriber's owner per event. - Pin toggles emit an owner-addressed change event so other tabs on the shared store refetch. --- _Generated with `xum` • Model: `anthropic:claude-fable-5-1` • Thinking: `high` • Cost: `$3.70`_ <!-- mux-attribution: model=anthropic:claude-fable-5-1 thinking=high costs=3.70 -->
|
@codex review |
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f6e044dc0b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Owner memo invalidation emits `ownersInvalidated` for formerly-shared children; core.ts drops those live sessions' cached memory context. - Caller-supplied config snapshots are used for resolution but never populate the memo (a snapshot can predate the current file stamp). - Harvest recovery on an owner run retries every tree member's bucket, so a sub-agent's failed/stale harvest is retried through the redirected run. --- _Generated with `xum` • Model: `anthropic:claude-fable-5-1` • Thinking: `high` • Cost: `$4.20`_ <!-- mux-attribution: model=anthropic:claude-fable-5-1 thinking=high costs=4.20 -->
|
@codex review |
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a684564bcf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- AgentSession probes memory ownership (AIService.probeMemoryOwnership → stamp-validated owner lookup) before consulting its cached context, so a removed owner rebuilds the CURRENT request's index. - Rollback also refuses when the acting workspace itself is tombstoned (orphaned journal after a fail-closed removal). --- _Generated with `xum` • Model: `anthropic:claude-fable-5-1` • Thinking: `high` • Cost: `$4.60`_ <!-- mux-attribution: model=anthropic:claude-fable-5-1 thinking=high costs=4.60 -->
|
@codex review |
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6b926d3116
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Launch sweep folds every tree member's recency into the owner's row, so an active sub-agent keeps the shared notebook from being swept as idle. - Memory subscriptions forward `ownersInvalidated` for the subscribed workspace as a root-addressed change plus a consolidation-status refresh. --- _Generated with `xum` • Model: `anthropic:claude-fable-5-1` • Thinking: `high` • Cost: `$5.00`_ <!-- mux-attribution: model=anthropic:claude-fable-5-1 thinking=high costs=5.00 -->
|
@codex review |
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 00145748fa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Sub-agent removal aborts (SharedMemoryLockUnavailableError, no tombstone, stays registered) when the owner store lock cannot be acquired instead of taking the orphan path, which would let an admitted child write land in the owner's live notebook after removal. - A removal-cancelled owner run no longer starts tree-wide harvest recovery; cancelled buckets are skipped. - Open memory subscriptions probe ownership every 30s (one stat) so an external owner removal refreshes an idle tab. --- _Generated with `xum` • Model: `anthropic:claude-fable-5-1` • Thinking: `high` • Cost: `$5.50`_ <!-- mux-attribution: model=anthropic:claude-fable-5-1 thinking=high costs=5.50 -->
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c16f8f883f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Security Review
Here are some automated security review suggestions for this pull request.
Reviewed commit: c16f8f883f
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
- assertMutationCommittable compares the store's bound owner with a fresh resolution and refuses (recoverable) when they differ, so a command that resolved its store as a self-fallback while config.json was unreadable cannot commit into the private store after the file recovered. - Harvest finalization on removal is one read-check-write under the sidecar lock, and saveHarvestRecordEffect never lets a terminal record (completed, or failed with retries exhausted) be reopened by a residual pending/retryable write — only a genuine completion may replace it. - Cross-process cache coherence for the shared workspace store: every workspace-scope mutation rewrites <sessionsDir>/<owner>/memory.revision; AgentSession records the token with its cached memory context and revalidates it before reuse (probeMemoryStore), and the Memory tab's existing 30s probe emits a root refresh when the token moved without an in-process change event. Scoped to the owner store; the metadata sidecar is not used so read/usage churn does not invalidate contexts. - The persisted workspaceMemoryWritable bit now mirrors the final toolset: readwrite access AND memory experiment + service AND a policy that keeps the memory tool (isMemoryToolDisabled mirrors applyToolPolicyToNames). --- _Generated with [`mux`](https://github.com/coder/mux) • Model: `anthropic:claude-fable-5-1` • Thinking: `high`_
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bc3564c70f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Here are some automated security review suggestions for this pull request.
Reviewed commit: bc3564c70f
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
- Harvest permission follows the FINAL toolset: after the primary request is prepared (request.assemble middleware included), an absent `memory` tool downgrades the persisted workspaceMemoryWritable bit to false (turn refused if the deny cannot be persisted). Built-in tools are never deferred by tool search, so absence means denied. - Consolidation sidecar read-modify-writes (run records, harvest records, removal finalization) take a cross-process lockfile alongside the in-process mutex, so a residual harvest in another backend cannot race finalization with a stale read. - refinement_rollback (RLM) refuses memory-row rollback when the memory tool is policy/grant-denied (view-only memory policy handed to the tool in tool assembly) or stripped by request.assemble middleware. --- _Generated with [`mux`](https://github.com/coder/mux) • Model: `anthropic:claude-fable-5-1` • Thinking: `high`_
|
@codex review |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a2abede9a7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Persist the workspace memory harvest permission for the request that actually streams, not at preparation time: the primary request records it inside `start` from its final toolset (so an admission-only candidate that is rejected or disposed leaves nothing behind), and the model fallback's `prepare` downgrades it when its own request.assemble pass strips `memory`. A deny that cannot be made durable still refuses the turn (or the fallback attempt). --- _Generated with [`mux`](https://github.com/coder/mux) • Model: `anthropic:claude-fable-5-1` • Thinking: `high`_
|
@codex review |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 74b6f90107
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Persisting the memory harvest permission is now asymmetric by failure mode: a DENY lands at the top of `start` (and refuses the turn when it cannot be made durable — a stale deny only fails closed), while a GRANT is persisted through the new `onStreamStarted` hook that AIService awaits only after startStream succeeded, so append failures, late aborts, thinking-level rebuild rejections and stream start failures leave no stale grant behind. The model fallback persists `writable && nextRequest.tools.memory !== undefined` for every selected fallback, restoring the grant when only the primary's request.assemble pass had stripped `memory`. --- _Generated with [`mux`](https://github.com/coder/mux) • Model: `anthropic:claude-fable-5-1` • Thinking: `high`_
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a592857f8e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Here are some automated security review suggestions for this pull request.
Reviewed commit: a592857f8e
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
- Shared-store clock (refinement/workspaceMemoryRevision.ts): memory.revision now holds a strictly monotonic ms-domain value advanced under the store's target mutation lock by every workspace-scope mutation — memory commands AND rollbacks (including the debug CLI path) — and stamped as the row's sourceTs, giving owner and sub-agent journals one total order for rollback conflict detection and a cross-process change signal that rollbacks also publish. Quota resweep now keys on migratedFrom, not sourceTs. - refinement_rollback fails closed when a memory row's path cannot be classified against the context's scope roots. - MemoryService re-resolves the per-context owner at every command boundary (a stream-long context no longer pins a stale owner) and refuses workspace-scope reads once the acting workspace or the store's owner is tombstoned. --- _Generated with [`mux`](https://github.com/coder/mux) • Model: `anthropic:claude-fable-5-1` • Thinking: `high`_
|
@codex review |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5dd6a26759
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- AgentSession accumulates the workspace memory write policy fail-closed over the compaction epoch (one read-only turn denies the whole epoch's harvest even if a writable turn follows), restarting at the compaction boundary unless a preserved tail carries the epoch forward; WorkspaceService persists that effective value. - The store clock only advances under the store's mutation lock: mutations advance it when they journal (or, for UI saves, in-lock explicitly), notifyPinChange takes the lock for its advance, and the rollback announcement no longer re-advances (the engine did so under the lock). emitChange is a pure in-process signal again. --- _Generated with [`mux`](https://github.com/coder/mux) • Model: `anthropic:claude-fable-5-1` • Thinking: `high`_
|
@codex review |
--- _Generated with [`mux`](https://github.com/coder/mux) • Model: `anthropic:claude-fable-5-1` • Thinking: `high`_
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b5fca43aee
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Here are some automated security review suggestions for this pull request.
Reviewed commit: b5fca43aee
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
- The persisted workspaceMemoryWritable bit is now THE epoch accumulator: WorkspaceService ANDs each turn's policy into the durable value (fail-closed), so a restart mid-epoch and backends sharing one chat.jsonl (multi-instance) all contribute to one conjunction; the session only mirrors it for the compaction completion. - Both copies restart at context boundaries: compaction without a preserved tail and destructive boundaries (/clear, reset, history replace via clearPostCompactionState) delete the durable field, so a stale deny cannot refuse an all-writable new epoch. - Unjournaled deletes (unrepresentable subtree) still advance the store revision so other backends drop cached views of the removed entry. --- _Generated with [`mux`](https://github.com/coder/mux) • Model: `anthropic:claude-fable-5-1` • Thinking: `high`_
|
@codex review |
Summary
Sub-agent child workspaces now share their parent/owner's
/memories/workspace/...notes. The workspace scope resolves to the task-tree root's<sessionDir>/memory, so an owner and all of its (nested) sub-agents read and write one notebook, while transcripts and other session artifacts stay per-workspace.Background
Workspace memory was strictly per-workspace: a sub-agent spawned via
taskgot an empty/memories/workspace/and any notes it wrote died with its child workspace, invisible to the parent that delegated the work. Since the parent owns the task, the tree should share one notebook (context-notes.mdincluded). Fullkind: "workspace"tasks and forks carry noparentWorkspaceIdand keep their own notes.Implementation
MemoryService.resolveWorkspaceMemoryOwnerId(workspaceId)walksparentWorkspaceIdto the root (cycle/depth guarded; unknown ids resolve to themselves; positive results memoized since parent links are immutable). It backs the workspace store root, sidecar pin/usage keys (one ranking per shared file),changeevents (carry the owner id), and the removal-tombstone commit check (acting and owner: a removed child cannot keep writing into its parent, a lingering child cannot recreate a removed owner's session dir).<sessionDir>/memory; global/project rows stay attributed to the acting workspace.AgentSessionin the same tree (WorkspaceService.invalidateMemoryContextWhere, wired incore.ts).Validation
New tests cover owner resolution (root / parentless / unknown), the shared physical store with owner-keyed events and sidecar stats (and isolation from unrelated workspaces), journal placement (owner vs acting), the subscription filter, child Dream refusal + launch-sweep skip, and external memory-context invalidation.
Risks
Medium, scoped to the Memory experiment. Workspaces without
parentWorkspaceIdbehave exactly as before (owner == self). For sub-agents the notebook location moves from the child's session dir to the owner's; existing child-local notes from earlier sessions are not migrated (children are ephemeral). Known limitation: the launch sweep does not fold child activity into the owner's idle recency, mirroring the existing owner-agent vs. Dream concurrency.Generated with
xum• Model:anthropic:claude-fable-5-1• Thinking:high• Cost:$1.63