Unit 07.04: Keeping a run record worth reading
The test of a run record is whether someone who was not there can answer the seven questions from the start of this module.
One object, every question answered
Inputs, per-task detail, tool calls, human review, totals and outcome - in one structure rather than scattered across log lines.
The code prints a complete record for a blocked run.
import json
record = {
"run_id": "run-8841",
"crew": "support-triage",
"flow_version": "support-flow-1.2.0",
"inputs": {"ticket_id": "T-8841"},
"tasks": [
{"task": "decide", "agent": "Billing analyst", "tokens": 2_050,
"guardrail": "passed", "output_summary": "not_eligible, 9 days"},
{"task": "draft", "agent": "Support writer", "tokens": 3_980,
"guardrail": "FAILED: states 30 days", "output_summary": "rejected"},
],
"tools_called": [{"tool": "read_account", "args": {"account_id": "ACC-1187"},
"attempt": 1, "result": "ok"}],
"human_review": {"reviewer": None, "reason": "run stopped before the gate"},
"totals": {"tokens": 6_030, "seconds": 14.6, "usd": 0.018},
"outcome": "blocked by guardrail",
}
print(json.dumps(record, indent=2))
print("\nA reader who was not there can answer every question from the first")
print("unit of this module using only this record.")
human_review is populated even though no human reviewed anything, with the reason: the run stopped before the gate. A field left absent would read as an oversight; a field explaining its own emptiness answers the question.
output_summary rather than full output is a deliberate choice. Full outputs make the record too large to read and often contain customer data - a summary keeps it reviewable and reduces what the log store holds.
The mistake this prevents
Treat the run record store as sensitive in its own right. It contains resolved inputs, tool arguments and output summaries - which is to say business content and often client data - held in a system built for debugging and usually reviewed less carefully than the primary one. Give it the same access control and retention limits as the data it mirrors, and redact the fields you know are sensitive on the way in.
The mistake is emitting these fields as separate log lines and reconstructing the run by grepping a timestamp range. It works while you remember the format and fails for anyone else, including you in three months. One structured record per run.
Takeaway
Emit one structured record per run covering inputs, tasks, tools, review, totals and outcome. Summarise outputs rather than storing them whole, and explain empty fields rather than omitting them.
