Skip to content

feat(subagents): add run-scoped working context and structured file-change handoff #1621

Description

@Aaronontheweb

feat(subagents): add run-scoped working context and structured file-change handoff

Summary

Coding subagents currently inherit filesystem grounding from the parent session (ParentProjectDirectory, ParentCwd, and ParentSessionDirectory), but they do not inherit or maintain model-visible WorkingContext state.

In particular, a subagent does not receive the parent's RecentFiles, does not track files it reads or changes during its own tool loop, and does not return structured file-change context to the parent when it completes. This makes coding subagents prone to losing track of the files involved in delegated work and leaves the parent without a reliable machine-readable account of what the child observed or changed.

This issue proposes run-scoped working-context management for subagents. It is a companion to #1520, which adds derived Git/worktree grounding. The two capabilities should share context snapshot and rendering infrastructure where appropriate, but retain explicit parent/child ownership boundaries.

Current behavior

The main session actor:

  • owns durable SessionState.WorkingContext;
  • tracks ProjectDirectory and RecentFiles from tool results;
  • injects [working-context] in the turn-start volatile context nudge;
  • preserves that state across compaction and recovery.

The subagent actor:

  • receives the parent's project directory and resolved cwd at spawn time;
  • uses those values for tool execution and policy grounding;
  • receives project instructions in its system prompt;
  • does not run SessionMessageAssembler or the registered IContextLayerProvider chain;
  • does not receive the parent's recent-file snapshot;
  • does not maintain its own WorkingContext;
  • does not return structured read/changed-file metadata to the parent.

Therefore, adding a normal context-layer provider alone will not inject Git or working context into subagents.

Proposed behavior

1. Parent-to-child snapshot

At spawn time, copy a read-only snapshot into the subagent:

The snapshot is grounding only. The child must not mutate the parent's WorkingContext directly.

2. Child-owned run-scoped context

Each subagent maintains an independent, ephemeral working context for the duration of its run:

  • inherited project directory;
  • inherited recent files;
  • files read by the child;
  • files changed, created, or deleted by the child when this can be established;
  • current derived Git/worktree state.

First-party file-tool results should update this state using the same canonical path extraction behavior as the main session. Avoid a parallel file-path tracking implementation.

3. Shell and indirect change detection

Tool-call metadata alone cannot reliably identify changes made through shell_execute (git apply, formatters, generators, scripts, and similar commands).

For Git worktrees, capture a bounded status snapshot at subagent start and completion and compute observed changes. Treat this as worktree state observed during the run, not proof that the child authored every change: the parent or another child may operate in the same worktree concurrently.

Do not silently claim file ownership under shared-worktree concurrency. Exact attribution may require isolated worktrees or first-party file-tool provenance and is out of scope for the initial implementation.

4. Model-visible injection

Inject the child's initial working-context snapshot into the runtime-context portion of its initial user message, immediately before the delegated task. Keep the reusable subagent system prompt byte-stable.

Example:

Context:
[working-context]
project_dir: /worktrees/netclaw-1520
recent_files:
  - src/Netclaw.Actors/Sessions/SessionMessageAssembler.cs
git:
  worktree: /worktrees/netclaw-1520
  branch: feature/git-context
  head: a1b2c3d4
  staged: 1
  modified: 2
  untracked: 0
[/working-context]

Task:
Review the context-layer implementation.

The initial version may snapshot context once at spawn. If context is refreshed during a child tool loop, append a new tail nudge; never rewrite earlier prompt/history bytes.

5. Structured child-to-parent handoff

Extend the subagent completion result with machine-readable working-context metadata, including at minimum:

  • project/worktree directory;
  • files read by the child;
  • files changed or observed changed during the run;
  • final Git branch and HEAD when available.

The parent should merge confirmed child-touched files into its durable WorkingContext.RecentFiles through an explicit result-handling path. Observed shared-worktree changes must be labeled as observed rather than attributed to the child.

Do not require the parent model to parse prose to recover this metadata.

Ownership model

Parent durable WorkingContext
        |
        | read-only spawn snapshot
        v
Child ephemeral WorkingContext
        |
        | structured completion result
        v
Parent explicitly merges confirmed files

Security and audience handling

  • Preserve the parent turn's effective audience and filesystem authority; do not introduce a default-audience fallback.
  • Suppress internal path and Git context for audiences that are not permitted to receive working context, consistent with audience-context-filtering.
  • Sanitize Git remote identity; never expose credentials embedded in remote URLs.
  • Working context is grounding, not an authority grant. It must not expand readable/writable roots beyond the existing tool policy and inherited execution context.

Scope

In scope:

  • subagent run-scoped working context;
  • parent recent-file snapshot at spawn;
  • reuse of canonical file tracking from first-party tool results;
  • bounded Git before/after snapshots for observed changes;
  • model-visible child working-context injection;
  • structured completion metadata and explicit parent merge;
  • integration with the Git/worktree context work in feat(sessions): add git context layer to system prompt #1520.

Out of scope:

  • automatic creation of an isolated Git worktree per subagent;
  • exact authorship attribution in a shared worktree;
  • durable recovery of an in-flight ephemeral subagent;
  • silently merging arbitrary child state into the parent;
  • GitHub PR or issue context.

Acceptance criteria

  • A spawned subagent receives the parent's project directory and recent-file snapshot as model-visible grounding when allowed by audience policy.
  • A subagent using a first-party file tool records the canonical file path in its own run-scoped context.
  • Child file tracking does not mutate parent state during the run.
  • A Git-backed run reports bounded start/final status and distinguishes observed changes from confirmed child-tool changes.
  • SubAgentResult carries structured working-context metadata without requiring prose parsing.
  • Parent result handling explicitly merges confirmed child-touched files into its durable working context.
  • Multiple children sharing a worktree do not falsely claim exclusive authorship of status changes.
  • Public or otherwise restricted audiences receive no internal path/Git context.
  • The subagent system-prompt prefix remains byte-stable; dynamic context is placed in the initial runtime/task message or appended as a later tail nudge.
  • Main-agent and subagent paths reuse shared snapshot/rendering and canonical path-tracking constructs rather than introducing parallel sources of truth.

Testing

  • Unit tests for parent-to-child snapshot creation and audience suppression.
  • Unit tests for canonical file tracking from read/write/create/delete tool results.
  • Subagent integration test proving inherited recent files appear in the initial model input.
  • Subagent integration test proving child file activity is returned structurally and merged only after completion.
  • Git integration tests for clean, dirty, detached-HEAD, linked-worktree, and non-Git directories.
  • Concurrency test proving shared-worktree changes are reported as observed rather than attributed to a specific child.
  • Prompt-layout test proving dynamic child context does not modify the reusable system-prompt prefix.

Planning note

This changes the subagent protocol, prompt assembly, tool-result tracking, and parent completion handling. Before implementation, create an OpenSpec change covering both this issue and #1520, or explicitly coordinate their delta specs so the shared context contract is designed once.

Metadata

Metadata

Assignees

No one assigned

    Labels

    context-pipelineLLM context assembly: prompt layers, dynamic injection, memory recall, temporal groundingenhancementNew feature or requestsessionsLLM session actor, turn lifecycle, pipelinessubagentsspawn_agent, SubAgentActor, definition loader, discovery context layer, and related features

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions