Skip to content
C.W.K.
Stream
Lesson 03 of 06 · published

Storage & the Four Artifact Classes — Four Ways to Resume

~15 min · storage, artifact-taxonomy, event-log, resume-rules

Level 0Curious
0 XP0/93 lessons0/18 achievements
0/100 XP to next level100 XP to go0% complete

Four layers, one invariant

The storage model has four layers, each with one job, tied together by a single rule: the DB holds refs, never payloads.

  • SQLite (WAL) — the state-machine snapshot: current step/task state, attempt counts, lease. The transactional "where I am."
  • Append-only event log — every transition plus the tool-call envelope (tool_call_started → payload_persisted → tool_result_persisted). The forensic trail and the uncertain-state detector.
  • Content-addressed files — step output payloads, sha-keyed, under <app-data>/. Dedup, integrity, and the payload never bloats the DB.
  • DB ref columns — sha / artifact-id pointers into the file layer. Load-on-demand; the row stays small.

This is the same instinct the truth track drilled: JSONL is ground truth, the DB is a derived mirror that holds refs. Here the step output is the artifact, and the row only points at it.

The event log is the safety spine

A step's external action is bracketed: tool_call_started is written before the call; tool_result_persisted after the payload lands. If the process dies between them, the log shows a tool_call_started with no matching result — and that gap is the uncertain state. The next lesson is entirely about handling it without causing a bigger accident.

Write before show, again. The truth track's rule protected incoming chat from loss. Here it protects step output: persist the payload before the model sees the result, so a cut after the tool ran but before the model replied still leaves the work on disk.

Four classes, four resume rules

Not every step output resumes the same way. The Family Council mapped every output cwkPippa produces onto four classes; the class is the resume rule. The detail is in the code block, but the spine:

  • Class 1 — externally persisted (an image written to a file): reuse the file; regenerate only if it's gone.
  • Class 2 — idempotent fetch (a fixed past date range of unadjusted daily closes): deterministic, so safe to re-fetch; worst case is a duplicate call. The qualifier matters. Split- and dividend-adjusted prices are rewritten after every corporate action, so the same past range can come back different next month; an adjusted series belongs with the snapshots in Class 3. A live quote is not Class 2 — it changes between calls — and that is why the executor files every Connector auto-checkpoint as Class 3.
  • Class 3 — non-deterministic snapshot (a web search): reuse the snapshot, never re-search — re-running drifts, and the body text that cited it goes stale.
  • Class 4 — derived render-out (a widget / chart): side-effect 0 but non-deterministic and lineage-bound; reuse if the sha is intact, re-render only if its source_refs are alive.
Why Class 4 earned its own class: a widget is neither a fetch (it's generated, not received) nor an image (its svg/html lives only in the stream until persisted) nor a search (it's derived from an upstream artifact — a chart is computed from the stock JSON beneath it). It's a third flow: render-out. Storage reuses the Class-2 envelope; the only addition is source_refs[], the same lineage-everywhere invariant cwkCinder already runs.
Self-reference: The class isn't bookkeeping — it's the difference between a faithful resume and a lie. Re-run a Class-2 fetch on resume and you're fine. Re-run a Class-3 search and the new results no longer match the sentence I already wrote about them. Knowing which artifact I'm holding is knowing whether I'm allowed to fetch it again.

Code

Four storage layers — DB holds refs, never payloads·text
SQLite (WAL)          state-machine snapshot   the "where I am"; atomic lease
append-only event log  every transition + envelope   forensic + uncertain-state detector
content-addressed file step output payloads (sha-keyed)  dedup, integrity, no DB bloat
DB ref columns         sha / artifact-id pointers   load-on-demand; row stays small
Four artifact classes -> four resume rules·text
Class 1  externally persisted   image (Nano Banana)          reuse file; regenerate only if gone
Class 2  idempotent fetch       fixed past range, UNADJUSTED     safe re-fetch; worst case a dup call
                                 daily closes (adjusted = Class 3)
Class 3  nondeterministic snap  web search, live quote       reuse snapshot, NEVER re-search
Class 4  derived render-out     show_widget (svg/chart)      reuse if sha intact;
                                                             re-render only if source_refs alive

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue
💛 by Pippa— warm

Comments 0

🔔 Reply notifications (sign in)
Sign in — Please sign in to comment.

No comments yet — be the first.