os-sdlc: run summary carries model and token usage read from dispatch transcripts #553
Labels
No labels
P0
P1
P2
P3
bug
create
delete
enhancement
filed-by/agent
filed-by/user
frozen
lint-rule
needs-info
needs-triage
next
plugin/cc-architect
plugin/os
plugin/os-adr
plugin/os-aidd-lint
plugin/os-backlog
plugin/os-context
plugin/os-doc-hygiene
plugin/os-sdlc
plugin/os-vault
project/cc-os
ready-for-agent
ready-for-human
recurring
review
update
waiting
wayfinder:grilling
wayfinder:map
wayfinder:map
wayfinder:research
wayfinder:task
wayfinder:task
wontfix
worklist/deviations
worklist/lint-rule
worklist/new-implement-build
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
jared/cc-os#553
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Follow-on to #552 (terminal payload run summary, merged
61995ac). The user wants model and tokens per dispatch in the end-of-run table. The runner never receives these: the SubagentStop hook event carries no usage, and the database has no model or token columns. Each dispatch belongs to an agent row (dispatches.agent_id), and the agent row ownstranscript_path. The transcript JSONL holds assistant entries withmessage.modelandmessage.usage(input_tokens,output_tokens,cache_read_input_tokens,cache_creation_input_tokens).Design decided with the user on 2026-09-11 (option C plus a report command): the model belongs to the agent, the tokens belong to the dispatch, both persisted. Stamping happens in a new
implementation-reportCLI command that the orchestrator runs after the last agent has returned, so every transcript is complete. The terminal payload fromsubagent-stopandnextstays as shipped in #552. Same domain modeling as #552: objects named by what they summarize, each model responsible for its own value, no code comments.Observed
Dispatch entries in the run summary carry id, agent_type, elapsed_s, verdict, stalled, gate_steps. No model, no tokens. No report command exists; the Thor CLI has implementation-open, next, subagent-start, subagent-stop, gate, violations.
Reproduce
n/a: feature ticket
Expected
os-sdlc-runner implementation-report SESSION_IDstamps usage on every dispatch of the session's latest implementation and prints the summary JSON: each dispatch entry gainsmodel:andtokens: {in:, out:, cache_read:, cache_creation:};totalsgainstokens:with the same four keys summed. A dispatch whose transcript is missing or unreadable carriesmodel: nil, tokens: niland the command still succeeds. Running the command twice returns identical output.Tasks
db.rb:agents.model(String);dispatches.input_tokens,output_tokens,cache_read_tokens,cache_creation_tokens(Integer, nullable).lib/os_sdlc/runner/transcript_usage.rb: classTranscriptUsagewithTotals = Data.define(:model, :input, :output, :cache_read, :cache_creation);self.read(path)returns nil unless the path exists, elsenew(File.foreach(path)).totals;totalswalks lines, parses JSON, skips lines that fail to parse, takesmessagefrom entries whosetypeisassistant, takes the first non-nilmodel, and sums the four usage keys.Agent#usagereturnsTranscriptUsage.read(transcript_path);Agent#record_model!(model)updates the column when model is non-nil.Dispatch#record_usage!: returns early ifinput_tokensis set; readsagent.usage; returns if nil; callsagent.record_model!; updates the four token columns.Implementation#record_usage!callsrecord_usage!on each dispatch.implementation-report SESSION_IDincli.rb: finds the session's latest implementation the same waynextdoes, callsrecord_usage!, then emitsSummary.for(Models.for(db).implementation[id])as JSON. Follow the existing command-object pattern inlib/os_sdlc/runner/(one class per command).DispatchSummary#entry_foraddsmodel: dispatch.agent.modelandtokens: { in:, out:, cache_read:, cache_creation: }from the dispatch columns (nil when unstamped).DispatchSummary#token_totalssums the four across dispatches, nil-safe.Summary#totalsaddstokens: @dispatch_summary.token_totals.tests/runner/transcript_usage_test.rbwith a fixture JSONL undertests/fixtures/(two assistant messages with known usage, one malformed line, one non-assistant entry): sums, first model, missing file returns nil. A dispatch test:record_usage!stamps tokens and the agent model; a second call does not re-read.tests/runner/implementation/summary_test.rb: totals tokens sums two dispatches. A CLI test:implementation-reportoutput carriesmodelandtokensfor a dispatch whose agent has a fixture transcript path, and is byte-identical on a repeated call.skills/implement/SKILL.md: replace the #552 render line with this one unwrapped line:On any terminal payload, run \os-sdlc-runner implementation-report SESSION_ID` and render its `dispatches` as a table: one row per dispatch, followed by the `totals` line. If you observed workflow issues, list them below the table.`/os-adr:create: usage persisted on agent and dispatch rather than read lazily; stamped by the report command after the last agent returns rather than at subagent-stop or at terminal transition; transcript format knowledge confined to TranscriptUsage.docs/implementation-status/os-sdlc.md; refresh the plugin cache.Acceptance criteria
implementation-reportprints model and token figures per dispatch and a token total when transcripts exist.implementation-reportoutput is byte-identical.Out of scope
Reload-after-stamp for CURRENT_TIMESTAMP columns (separate ticket). A node column on dispatches.
Blocking edges
Blocked by #552 (closed 2026-09-11).
Origin
Session: 5fdd0aa3-8a9c-4c31-a5b3-d575d8e709ab
Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/5fdd0aa3-8a9c-4c31-a5b3-d575d8e709ab.jsonl
Where: plugins/os-sdlc/lib/os_sdlc/runner/cli.rb; plugins/os-sdlc/lib/os_sdlc/runner/implementation/dispatch_summary.rb; plugins/os-sdlc/lib/os_sdlc/runner/agent.rb; plugins/os-sdlc/lib/os_sdlc/runner/dispatch.rb
Filed by: user request, 2026-09-11. Body rewritten 2026-09-11 after design review.
Work started via /os-sdlc:implement on branch ticket-553 (session 5fdd0aa3). Body rewritten to the option C + implementation-report design first.
Resolution
Done: Model persisted on agents.model_id, tokens on four dispatch columns (schema 23); TranscriptUsage reads the transcript; implementation-report CLI stamps usage once after the last agent returns and prints the summary with model, tokens, and a tokens total; SKILL.md updated; ADR-0174; history row.
Evidence: Commit
9252987on branch ticket-553; full os-sdlc suite 1187 runs, 0 failures, 0 errors; rubocop clean on changed files. Pipeline: implementation 3 ended on a test-reviewer error verdict (commented on #555), implementation 4 ran four red-green increments then escalated with unexpected_pass; docs, model_id rename (Sequel collision), DispatchEntry fold, and a no-re-read test finished by hand under the escalation procedure. Live check of the report command against the shared DB wiped it (schema bump, ADR-0129); lesson recorded in memory.Follow-ups: #557 reload-after-stamp; test-reviewer error-verdict route noted on #555; none other
Merged to main at
69fc891(fast-forward via ticket-553 merge). Correction to the close comment: the ADR is ADR-0175, renumbered after a collision with #558's ADR-0174.