Description
Two modeling nits left open by the sigil feature, recorded in signals/sigil.md “Implementation status & next steps” item 1 (the resume list).
-
Tool-result carry-forward is in the wrong turn. Today a turn’s tool results sit in the SAME
AssembledTurn.Inputas the call that produced them. Real agent transcripts carry a tool result forward into the NEXT turn’s input, because that is when the model actually sees it. The current shape is structurally wrong for anyone reading a generation trail turn by turn. -
Per-subagent
agent_nameforclaude-code/<subagent>child conversations. Thegeneral_orchestrationarchetype already fans out correctly (internal/workload/aiagent/orchestration.go mints sub-agent generations with distinct AgentName drawn from agent.Subagents, parented to the orchestrator gen). The codingclaude-codearchetype does not do the equivalent for its child conversations, so its sub-agent activity is not attributable by agent_name.
Source of truth for the vocabulary is signals/sigil.md. Do NOT invent an attribute name — every name comes from that file or from vendor docs via ctx7.
Acceptance Criteria
- #1 A turn’s tool results appear in the NEXT turn’s AssembledTurn.Input, not the same one; the first turn of a conversation carries no inherited results and the last turn’s results are not silently dropped.
- #2 claude-code child conversations carry a per-subagent agent_name, consistent with how orchestration.go already attributes general_orchestration sub-agent generations.
- #3 No new metric, label, span or attribute name is introduced that is not already in signals/sigil.md; if one is needed and cannot be sourced, work stops and a cantfind.md PENDING is added instead.
- #4 Output stays deterministic across two DRY_RUN=true go run ./cmd/synthkit -once -dump runs (decisions derived from seedUnit, never wall clock).
- #5 signals/sigil.md “Implementation status & next steps” item 1 is updated to reflect what now ships.
Definition of Done
- #1 make gate (build vet test race rw-proto-check spdx-check forbidden-words)
- #2 make blueprint-schema (only if a blueprint field or construct/workload config struct changed)
- #3 DRY_RUN=true go run ./cmd/synthkit -once -dump — inventory diffed against signals/
Implementation Plan
Wave lane (Sonnet subagent, dispatched 2026-08-19): (1) TDD the tool-result carry-forward shift so a turn’s results land in the NEXT AssembledTurn.Input; (2) mirror orchestration.go’s per-subagent AgentName minting into the claude-code archetype’s child conversations; (3) lane returns the signals/sigil.md item-1 replacement prose for the main thread to apply, since signals/ is single-owner.
Final Summary
Both modelling nits shipped in 63ababe.
AC #1 — tool-result carry-forward. internal/sigil/assemble.go: AssembleConversation now threads a carry slice turn-to-turn; assembleTurn takes carryIn and RETURNS this turn’s own tool-result for the caller to feed into the NEXT turn’s Input, instead of appending it to the same turn’s inputMsgs. Turn 0 inherits nothing. The last turn’s results, having no following turn to carry into, are appended to that same final turn’s own Input rather than dropped — the documented no-drop decision. Tests written first and watched fail for the right reason (‘turn 0 Input carries an inherited tool_result’): TestAssembleConversationToolResultCarriesToNextTurn, TestAssembleConversationLastTurnToolResultNotDropped.
AC #2 — coding subagent attribution. internal/workload/aiagent/orchestration.go: makeSubAgent generalised to take agentName + parentSpanID instead of hardcoding the peer name and art.envSpanID, and a new buildCodingSubagentFanout mirrors buildOrchestrationFanout’s shape (turn 0 to every declared peer, later turns one seeded peer at delegationProb), wired in conversation.go:122. agent_name is agent.Name + ‘/’ + peer, which is DERIVED FROM BLUEPRINT IDENTITY rather than hardcoded: the showcase blueprint declares ‘name: claude-code’ with ‘subagents: [general-purpose, explore, subagent]’, so it yields exactly the captured claude-code/
AC #3 — no invented names. Both agent_name forms are sourced from signals/sigil.md (lines 64, 250, 320 document claude-code/
AC #4 — determinism. Two DRY_RUN -once -dump runs produce a BYTE-IDENTICAL series inventory: 2668 metric-name + sorted-label-key shapes, ‘diff’ exit 0. The seeded rng draw order is unchanged by the carry-forward fix (pure routing of an already-drawn message), and the new fanout derives every decision from seedUnit/seedHash on the generation ID. Note the run-to-run variance in the ‘== sigil: generations=N … scores=N ==’ summary line is PRE-EXISTING and NOT from this change — reproduced at 183 vs 199 on a clean throwaway worktree of the base commit; filed as SKT-0004.
AC #5 — signals/sigil.md updated: the shipped work moved INTO the ‘Emitted + verified’ paragraph (coding sub-agent fan-out + turn-accurate tool-result carry-forward) rather than left sitting under the ‘PENDING — next steps’ heading, which a CodeRabbit minor finding correctly flagged; the pending list now holds only the heuristic-evaluator item.
Verification: ‘make gate’ GREEN, exit 0 — build, vet, test, race (no data races), rw-proto-check, spdx-check (593 .go files), forbidden-words (846 files) (DoD #1). ‘make blueprint-schema’ regenerated: the generalised subAgentGen.parentEnv doc comment made internal/blueprintschema/fielddocs.json stale and TestSchemaCurrent caught it; one line changed, committed (DoD #2). Inventory diff as above (DoD #3). CodeRabbit review: 1 finding, minor, on signals/sigil.md — applied, not dismissed; zero critical or major.