Development record
Every Autonomous Run Pass Leaves the Same Durable, Queryable Transcript an Interactive Session Does
Press Release
abcd captures the instruction-set and reasoning of every autonomous-run pass into the same native transcript corpus it already keeps for interactive sessions — so the work done while no human is watching is exactly as auditable as the work done with one. There is an asymmetry to close: an operator's interactive session is redirected into the native transcript corpus at
~/.abcd.noindex/history/<root_sha>/(a durable, queryable store). But the autonomous worker on the pluggable run seam — the thing that runs unattended for hours, plans, implements, and self-reviews — emits its instructions and reasoning only to an ephemeral per-pass log that run-dir hygiene prunes. The agent doing the most consequential, least-supervised work leaves the least durable record. This intent closes that gap: every autonomous run pass's instructions + reasoning is captured to the same corpus, with the same queryability, as an interactive session."abcd's whole promise is that you can trust what the agent did while you were away," said Kira, framework author. "But when I went to audit an autonomous run after the fact, the interactive sessions were all there in the transcript corpus and the autonomous worker — the one I most needed to check — had left only an ephemeral log that the run-dir cleanup had already eaten. The unattended work is exactly the work that most needs a durable trail."
Why This Matters
abcd is an autonomous-development framework whose differentiator is auditable, provenance-bearing automation — the operator can leave an autonomous run going and later reconstruct what it decided and why. That promise has a hole precisely where it matters most:
- Interactive sessions ARE captured: operator sessions are redirected into the native transcript corpus at
~/.abcd.noindex/history/<root_sha>/and stay durably queryable. - Autonomous-run passes are NOT: the worker on the pluggable run seam emits its instructions and reasoning only to an ephemeral per-pass log under the run directory, which run-dir hygiene prunes — neither committed nor durably stored.
The consequence: the worker's full chain of reasoning (the instructions it received, the autonomous-run rules, every tool call and decision across a pass) exists only transiently. After a run is pruned, the autonomous reasoning is gone, while every interactive session that touched the repo is permanently queryable. For a framework that markets unattended trustworthiness, the unattended path is the one missing its black box.
This is also a symmetry failure, not just a missing feature: the native transcript corpus already exists and already works for one caller class. The autonomous caller was simply never routed through it (or through an equivalent durable sink).
What's In Scope
- The capture gap itself: every autonomous-run pass's instructions + reasoning lands in the native transcript corpus under
~/.abcd.noindex/history/<root_sha>/— parity with interactive-session capture. - All autonomous entry points: every phase the run seam drives (plan / work / completion-review), and any other unattended model invocation the seam makes, are covered — not just the work phase.
- Queryability + provenance: captured transcripts are associated with the run id, spec/task id, run pass, and phase, so a later audit can answer "what did the worker reason for spc-NN.M, run pass K?".
- Honor abcd's boundaries: whatever the mechanism, it feeds the native transcript corpus through the run seam's own capture point rather than forking anything, and stays intact across the pluggable seam's implementations (Workflows / the companion harness / native loop).
What's Out of Scope
- Re-architecting the transcript corpus.
~/.abcd.noindex/history/<root_sha>/and its single-owner provisioning (spc-15, predecessor store) stay as-is; this intent FEEDS that store, it does not redesign it. - Capturing the operator's interactive sessions — already solved (native transcript-corpus redirect). This is only the autonomous-worker half.
- The live run-console view — that is orthogonal to durable capture; unchanged.
- Retroactive recovery of already-pruned runs — this is forward-looking capture, not archaeology of lost logs.
Approach (deliberately OPEN — for plan/grill to decide)
The mechanism is intentionally left undecided; the planning/grill stage chooses between (at least) these candidates, weighing the feed-don't-fork rule, survival across seam implementations, and the autonomous worker's non-interactive mode:
- (a) Capture at the seam — route each pass's model invocation through the native transcript corpus's capture point, so autonomous transcripts land in the SAME store and shape as interactive ones (maximal symmetry; verify the corpus captures a non-interactive run, and that capture holds across seam implementations).
- (b) Ingest the per-pass log — keep the current spawn but durably ingest each pass's log into the corpus at pass end (less invasive to the spawn path; but must capture the instructions too, not just stdout).
- (c) A structured stream sink — capture the worker's structured stream output into a per-pass record in the corpus.
Open questions for grill: does capturing a headless (non-interactive) run need a different hook than an interactive one? Does capture interfere with the live run-console view or the timeout/cancel controls? Should the capture be best-effort (never block a run pass) or gated? What is the retention/size policy for autonomous transcripts vs interactive?
SOTA
Surveyed on 2026-10-23; sources, evidence tiers and the local fit risks are in the autonomous-loops SOTA note. The store, the redaction door and the hook as capture path were settled in the 2026-07-30 session-recording note; this pass covers what the host's non-interactive mode does to that path.
- A headless run is stored like a session. A
claude -psession is written to the same transcript store and is resumable by id, though left out of the picker; sub-agent transcripts persist under the session'ssubagents/folder and are deleted aftercleanupPeriodDays(30 days by default);--no-session-persistencesuppresses a run's transcript (Claude Code sessions and sub-agents docs). - Both lane routes are already captured. Without
--barea-psession runs the project's hooks and plugins;--bareskips them, is the host's recommendation for scripts, and "will become the default for-pin a future release" (Claude Code headless docs). A host-route lane, the default, runs as a sub-agent in the person's session, where abcd'sSubagentStophook captures its transcript. A role routed to abcd's claude runner is launched with--print --bareon a paid key (RN2, dcn-2610020000000016) and with--no-session-persistence, so for that role no hook fires and no session is left in the host's store; the runner's dispatcher captures it from its stream instead, storing each lane's transcript as a native record throughhistory.Captureand its redaction door, keyed on the session id and the role (runner.HistoryStore, wired into build and drain). The guard reaches a runner lane as its permission-prompt answerer (dcn-2610161624025493). - Termination matters. On SIGTERM the host runs
SessionEndand no other hook, records no result for the turn, and exits 143; SIGINT ends the turn first; the Stop hook'stranscript_pathmay lag the conversation (Claude Code docs).SubagentStopcarriesagent_transcript_path, which abcd already captures;--forward-subagent-textonstream-jsonis the alternative reconstruction from the stream. - The format is declared unstable. The transcript "entry format is internal to Claude Code and changes between versions" (Claude Code sessions docs), so the raw file is stored and the index derived.
Path 2: the capture exists on both routes; the keys do not. A host-route
lane is captured by the SubagentStop hook, approach (a); a lane whose role
is routed to a runner is captured from its stream by the dispatcher, approach
(c) as shipped. Neither capture is keyed by the run id, lane, pass and phase
the first criterion asks for: the hook's record carries the person's session
and the sub-agent, the runner's the session id and the role, and the run's
record can list transcripts named at its end, which links them to the run but
not to a lane, pass or phase. The gap is setting those keys in the lane's
environment or the dispatch request and recording them on the capture,
through the same history.Capture door. For a host-route lane whose hook did
not fire (a SIGTERM window), an ingest by session id from the result's
session_id and the sub-agent paths stays the fallback; a runner lane needs
none, since it persists no session and the dispatcher already stores its
stream. Best-effort as the criteria require. No Go dependency. The independent fit-challenge runs at plan
time.
Acceptance Criteria
Given-When-Then per the itd-1 discipline.
- Given an autonomous-run pass (plan, work, or completion-review phase), when it completes (or is terminated), then its instructions + reasoning is present in the native transcript corpus under
~/.abcd.noindex/history/<root_sha>/, queryable after the run dir is pruned, and associated with run id + spec/task id + run-pass + phase. - Given the existing interactive-session capture, when the autonomous capture lands, then both reach the same transcript corpus (parity), and a single audit query can enumerate autonomous AND interactive activity for the repo.
- Given abcd's boundaries, when the mechanism is implemented, then it feeds the native transcript corpus (no fork) and remains intact across the pluggable run seam's implementations.
- Given the live controls, when capture is active, then it does not break the live run-console view, the worker timeout, or the cancel/budget controls, and a capture failure never blocks or fails a run pass (best-effort, fail-open on the capture path only).
References
- The native transcript corpus at
~/.abcd.noindex/history/<root_sha>/and its single-owner provisioning (spc-15, predecessor store) — the store this feeds .abcd/development/research/notes/ahoy-history-store-manual-scaffolding.md(the transcript-store design this feeds)- ADR-29 (native transcript corpus), ADR-27 (pluggable autonomous seam)
- Related: the abcd transparency/provenance promise in the brief (
01-product/), itd-58 (a sibling autonomous-run-provenance closure)
Frontmatter
| id | itd-59 |
|---|---|
| type | intent |
| lifecycle | drafts |
| kind | standalone |
| severity | minor |
.abcd/development/intents/drafts/itd-59-autonomous-worker-transcript-capture.md
open on GitHub ↗ · commit history ↗
References3
- adr-27The autonomous run is a pluggable seam, not a Ralph portrelated
- adr-29A native local redacted transcript corpusrelated
- itd-2609201916151817One verb takes a READY intent to delivered, and refuses while a decision is openbuilds on
Referenced by10
- iss-2610262031439210Invariant 15 puts the session-transcript store at `~/.abcd.noindex/transcripts/<root-sha>/`, but itd-59 feeds a corpus at `~/.abcd.noindex/history/<root_sha>/`.related
- iss-2610262033019185itd-59 puts the transcript corpus at ~/.abcd.noindex/history/< root_sha>/; the ahoy page says history/ is the registry only and holds no transcripts.related
- iss-2610262036113224The history chapter puts the transcript corpus under ~/.abcd.noindex/transcripts/ and keeps ~/.abcd.noindex/history/ for ahoy's registry, holding no transcripts; itd-59 places the corpus at ~/.abcd.noindex/history/< root_sha>/.related
- iss-2610262036129928itd-59 claims, as missing work, the capture of autonomous-run transcripts into the corpus; the history chapter says abcd build's delegated agent transcripts already reach the store through capture.related
- iss-2610262037262122itd-59 says the autonomous worker leaves only an ephemeral, pruned log; the build brief says a runner's transcript lands in the history storerelated
- iss-2610262039086156itd-59 puts the transcript corpus at `~/.abcd.noindex/history/<root_sha>/`, but the configuration page puts it in the sibling store `~/.abcd.noindex/transcripts/<root-sha>/`related
- iss-2610262041210479The transcript-capture draft takes as given an autonomous worker running on the pluggable run seam; the build sequence keeps the run seam a design target.related
- iss-2610262044057318itd-59 and itd-2609201916151817 both claim capturing the autonomous run's transcripts into the transcript storerelated
- iss-2610262044255432The worker-transcript draft says autonomous passes leave only an ephemeral log, but the shipped runner captures every role's transcript into abcd's storerelated
- itd-2609212137128014abcd lab mechanises the lab conventions three hand-run experiments provedrelated
mentions7
- dcn-26100200000000162026-10-02 — Ruling RN2 of the technical facilitator, FINAL (2026-10-02, asked in plain words by abcd-a2 [75597f]; same local-tier file as the H3-0 entry above; recorded by lane rd2), verbatim: "YES, SEALED, PAID KEY ONLY — runner keeps --bare with an API key; only machine-layer (personal) routes may hand a role to a runner; repo routes skipped with a warning; subscription-only owners run the role in their own session." It supersedes the provisional answer, "TREAT IT LIKE A PAID SERVICE", given with the note "are you sure it cannot run via a subscription? Investigate first.", which stood only until a research pass returned: no flag set short of the bare flag seals project instructions, plugins, skills and agents (code.claude.com/docs/en/cli-reference, read 2026-10-02), and the vendor's terms do not permit third-party developers to route requests through Free, Pro or Max plan credentials on behalf of their users (code.claude.com/docs/en/legal-and-compliance, read 2026-10-02). Not built at this entry's base; lane runnerSeal of autonomous run A builds it with OC1 and OC2.
- dcn-26101616240254932026-10-16 — A headless claude run whose role's contract grants the shell gets its permission prompts answered by abcd's guard through the harness's --permission-prompt-tool, naming the one tool of an 'abcd guard approve' MCP server that the launch passes inline with --mcp-config and --strict-mcp-config, under --permission-mode default; the shell is no longer pre-granted on that launch, so every shell command the harness would ask about reaches the guard, which approves only a clean allow (no entry, signal or diagnostic, a program the line names, no inline code handed to a non-shell interpreter) and refuses every other prompt with the guard's reason. The expected shape, a PreToolUse hook in a per-launch --settings file, cannot work: --bare skips every hook, those --settings declares included (probed on claude 2.1.301: a SessionStart and a UserPromptSubmit hook from --settings ran without --bare and not with it), and dropping --bare would let the repository's hooks, plugins and CLAUDE.md run. A role whose contract grants no shell keeps dontAsk, which already refuses every prompt; opencode has no per-launch approval callback and is unchanged; the person's host settings are never touched. This change adds no sandbox; sandboxing autonomous runs is a separate later step (dcn-2610161619296615). Grounds: claude --help 2.1.301; code.claude.com/docs/en/cli-reference, /headless, /agent-sdk/permissions, /agent-sdk/user-input; live probes of the prompt tool's request and allow/deny answers, and of --bare connecting an --mcp-config server.
- itd-1Every Intent Has Acceptance Criteria; Every Audit Verifies Them
- itd-58A Real Reviewer's SHIP Verdict Reaches The Session Gate Through A Channel The Worker Cannot Forge
- itd-89Capture the Session You Just Had, Because You Cannot Capture It Later
- itd-2609090559376002Every Sub-Agent a Session Spawns Leaves the Same Redacted Record Its Main Thread Does
- spc-15alice-reads-one-page-and-knows-exactly-where-abcd-stands-in