stacklok / stacklok/mecatl

feat(subagent): opt-in parent tool to read a child's raw session transcript

Open
#568 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Go
Stars
152
Forks
16
Avg merge
14h 48m
Merged PRs (30d)
536

Description

Motivation

When a subagent misbehaves, the fastest debugging loop is reading the child's RAW transcript — its exact prompts, tool calls, and results — not the bounded observability projection. Today a human operator can do this (InspectSubagent loads a persisted child session by its agentId: trailer; children persist via WithSubagentStore), but the PARENT AGENT has no sanctioned way to do it. The workaround people reach for elsewhere (e.g. hand-reading Claude Code's raw JSONL subagent logs) is exactly the kind of janky, unguarded access we should replace with a first-class, security-conscious tool.

Proposal

A new tool (name TBD — a sibling of InspectSubagent, raw-transcript mode on it, or a dedicated ReadSubagentTranscript) that returns a child session's raw persisted transcript to the calling agent, given the child id the parent already holds from the agentId: result trailer.

Source: the child's PERSISTED session (the SessionStore snapshot and/or the event log), not the live run — this matches InspectSubagent's cross-run semantics and never perturbs a live child.

Security requirements (the point of doing this first-class)

This deliberately widens gauntlet #7: child content — which may be untrusted (web pages via WebFetch, files, MCP results) — would flow into the parent model's context, and the parent runs at higher privilege (Bash/Edit on the real tree). So:

  • Default OFF, operator-gated. A config/flag opt-in (candidate: a permissions:-adjacent or delegation config key), never on by default. Not merely a model-discoverable tool that exists in every catalog.
  • Content treated as UNTRUSTED. The transcript is fenced with the existing engine/agent/fence.go helpers (UntrustedFence/WriteUntrustedBlock) and rendered through NeutraliseFraming-safe paths — the same discipline as team findings and delegation results. No harness marker in the transcript may be forgeable into an instruction.
  • Bounded. Clamp total size (transcripts are large); consider a per-call token/byte cap and pagination by message range rather than dumping the whole session.
  • Decide the permission posture explicitly. Whether calls resolve Allow / Ask / floor-scoped is a documented decision, not an accident — a child could contain content that asks the parent to do things.
  • Document the tradeoff. The default summary-fold (only the child's final text enters the parent conversation) exists for context hygiene AND injection containment (ADR 0079, gauntlet #7). The tool's doc/Spec must state that opting in trades that containment away for the children the parent inspects.

Non-goals (v1)

  • Live tailing of an in-flight child (persisted transcripts only).
  • Team/Parallel variants (the same seam could serve them later; scope this to Subagent).

References

  • ADR 0079 (delegation observability convergence — the bounded-preview tier this deliberately exceeds)
  • Gauntlet #7 (context isolation), ADR 0004 §8
  • engine/agent/fence.go (UntrustedFence / NeutraliseFraming / WriteUntrustedBlock / StripLoneCodeFence)
  • WithSubagentStore child persistence + agentId: trailer discovery
  • The inspect path this extends for the agent audience: InspectSubagent (read-only, floor-scoped, issue #37)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the existing InspectSubagent path and engine/agent/fence.go, then read ADR 0079, Gauntlet #7, and ADR 0004 §8 for the security and context-isolation constraints. Define the opt-in configuration, persisted-session access, bounded retrieval, permission posture, and tool naming before implementation. Done means a Subagent-only feature returns fenced, bounded raw transcripts and documents the containment tradeoff.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.