guide · ai

Tier 2 session memory: the run log you actually use

A schema for one-line-per-step JSONL run logs, a directory layout with an index, three small tools that turn the log into something you will actually open, and a what-to-log / what-not-to-log list.

July 22, 2026 · By Alastair Fraser

Retro editorial illustration of a chrome-domed robot tending one of four drawers in a tiered cabinet, representing this guide's memory tier.

Session memory is the black box. Every agent run is one file. If something went wrong, this is the file you open. If you want to know what the agent really did when it said it did X, this is the file you open.

If you do not have a per-run log, you do not have session memory. You have vibes.

The shape is the one the OpenTelemetry logs spec describes and the 12-Factor App endorses: one event per line, structured, with stable attribute keys. Google’s SRE book recommends this exact pattern as the only way to debug distributed/agent systems at all.

Where this comes from: Marvin’s 2026-07-20 original. Sources verified 2026-07-22 against the linked OpenTelemetry, Python, Google SRE, and 12-Factor pages.

The shape

One run = one JSONL file. One JSON object per line. One file per run.

{"ts":"2026-07-20T13:11:04Z","run_id":"7c2a","step":1,"kind":"model","model":"claude-sonnet-4","prompt_tokens":482,"completion_tokens":124,"cost_usd":0.0014,"latency_ms":1340,"summary":"decide which tool to call"}
{"ts":"2026-07-20T13:11:06Z","run_id":"7c2a","step":2,"kind":"tool","tool":"ocr.vision","input":"receipt.jpg","output_chars":312,"cost_usd":0.0008,"latency_ms":2100,"summary":"OCR receipt"}
{"ts":"2026-07-20T13:11:09Z","run_id":"7c2a","step":3,"kind":"tool","tool":"calendar.create","input":{"title":"Standup","when":"2026-07-21T15:00Z"},"output":"ok","cost_usd":0,"latency_ms":410}
{"ts":"2026-07-20T13:11:11Z","run_id":"7c2a","step":4,"kind":"error","tool":"email.send","error":"401 unauthorized","retry":true}
{"ts":"2026-07-20T13:11:14Z","run_id":"7c2a","step":5,"kind":"tool","tool":"email.send","output":"ok"}
{"ts":"2026-07-20T13:11:14Z","run_id":"7c2a","step":99,"kind":"end","total_steps":5,"total_cost_usd":0.0022,"status":"ok"}

This is enough. You can add fields. You cannot remove fields without losing the ability to debug later.

The directory layout

~/.hermes/runs/
  index.jsonl              # one row per run, fast to scan
  2026-07-20/
    7c2a-standup-scheduler.jsonl
    9b41-etsy-listing-pack.jsonl
    ...

index.jsonl is the cheap fast index. Each entry is the last line of the run (the kind:"end" summary) plus the path.

{"run_id":"7c2a","ts":"2026-07-20T13:11:14Z","summary":"scheduled standup + sent reminder","status":"ok","cost_usd":0.0022,"path":"2026-07-20/7c2a-standup-scheduler.jsonl"}

Now you can answer “what did the agent do yesterday” with tail -n 50 index.jsonl | jq -r '.summary'.

The three tools that make a log useful

A log nobody reads is hoarding, not memory. Add three small tools.

1. run show <id>

Reads the file and pretty-prints the timeline. Every step, latency, cost, summary.

$ hermes run show 7c2a
13:11:04  model   claude-sonnet-4   decide which tool to call   482+124 tok  $0.0014  1.3s
13:11:06  tool    ocr.vision        OCR receipt                  312 chars   $0.0008  2.1s
13:11:09  tool    calendar.create   ok                                       $0.0000  0.4s
13:11:11  tool    email.send        FAIL  401 unauthorized                   -        -
13:11:14  tool    email.send        ok                                       -        -
13:11:14  end     ok                5 steps                       $0.0022

2. run search <term>

Greps every log for a term. “When did the agent last touch pending-posts.json?” “Which run last called the email tool?“

$ hermes run search email.send
2026-07-20  7c2a   ok
2026-07-19  ff01   error 401
2026-07-18  a3c4   ok

3. run cost --since=7d

Sums cost by day, by tool, by model. Tells you where the budget is going without opening a dashboard.

$ hermes run cost --since=7d
2026-07-14  $0.42
2026-07-15  $0.51
2026-07-16  $0.18
2026-07-17  $0.63
2026-07-18  $0.39
2026-07-19  $0.27
2026-07-20  $0.71  (so far)

What to log, what not to log

Log: ts, run_id, step, kind, model, tool, prompt_tokens, completion_tokens, latency_ms, cost_usd, summary, error.

Do not log: full prompts, full tool outputs, secrets, PII. Log a summary plus an id; keep the full payload in Tier 1 for the duration of the run, then drop it.

If a step is interesting enough to need the full payload later, promote it to Tier 3 (project memory) with a link. Otherwise let it die with the run.

Trade-offs (per tip)

TipWhat it costsWhat it saves
One file per runDisk + index maintenance.Locating the run that produced a given output, post-hoc.
index.jsonl updated on every run endOne write per run.Answers to “what did the agent do yesterday” in 1 second vs. minutes.
Three small CLI tools~50 lines of Python each.Hours of log archaeology per failed run.
Log a summary, not full payloadsSlightly more work to write the summary.Logs that fit on a 16 GB disk for 6+ months.
Prune run files older than 30 daysLoss of detailed old runs.Disk that doesn’t fill up.

Failure modes

  • Logging the world. Every byte of every tool call ends up in the log. Logs explode. Search becomes useless. Fix: log a summary, store the full payload only for failed steps.
  • Logging nothing. No run ids, no timestamps, no costs. When the agent breaks, you have nothing. Fix: at minimum, log one line per run with start, end, total_cost_usd, status.
  • Logs without an index. 10,000 files, no way to find the one you need. Fix: index.jsonl written on every run end.
  • Logs without retention. Six months of logs, 40 GB. Fix: keep index.jsonl forever, prune run files older than 30 days unless status != "ok".

What you will have at the end

  • A schema for one-line-per-step JSONL run logs, compatible with the OpenTelemetry logs spec.
  • A directory layout with index.jsonl.
  • Three small tools that turn a log into something you will open.
  • A list of what to log and what not to.

Where to get unstuck

Sources

Last verified: 2026-07-22. Adapted from Marvin’s original “B3. Tier 2 — Session Memory: The Run Log You Actually Use” (2026-07-20). Drafter and source-notes author are the same model (MiniMax-M3). Tips category — no subagent review required per the v2.4.0 skill rule (Setup/Playbook only).

Submit a take

Have a different read on this? Drop a comment below — your email isn't published, and I read every one. Nothing leaves the site until I approve it.

Your email address will not be published. Required fields are marked.