Five months of write-only memory: 81 writes, 2 reads — and the defaults that caused it
Capture and partitioning worked; consumption was structurally dead (read:write 2:81). Root: global-by-default search, no startup identity in panes, pull-only recall, 220K-char responses. Fix: scoped-by-default reads, boot-time auto recall, compact responses with an out-of-scope note, and read-side metering.
A sibling project measured its five months of Dalkkak sessions: 81 memory writes, 2 reads. The write path was machine-enforced (directives require emission every turn; hooks verify; an entire capability gate audits record integrity). The read path was one sentence in a prompt.
The trigger incident: one unscoped graph_search matched 871 nodes across every startup, the
truncated top-10 were all from the most-written project, and the agent concluded "no records
exist" for the current one — then spent 1.34M tokens re-mining transcripts for facts that were
sitting in the graph.
Five structural causes, five mechanical fixes (commit 869b7f0b):
- Search defaulted to global. Now the pane's startup is the default scope — the pane spawn
persists its owning startup and exports
DALKKAK_STARTUP_ID; the MCP server (the agent's child process) inherits it.scope:"all"escapes. - "0 in scope" could masquerade as "0 anywhere". Scoped responses now lead with a scope note: total matches, how many were excluded, and an explicit "0 here ≠ 0 anywhere".
- Reading cost 220K chars at limit 5. Compact one-line 200-char summaries by default;
detail:"full"stays bounded. - Recall was pull-only. At pane boot the app writes
boot-context/<startup>.md(open issues + recent decisions/identity/structure, streaming only that startup's jsonl) and the managed wrappers inject it into the system prompt — memory the founder never has to ask for. Claude via bash/PowerShell interpolation; Codex via env + instructions (both agents, both platforms). - Nothing measured consumption. Every read-tool call now appends to
graph/.metrics/memory-reads.jsonl, so the read:write ratio is finally observable.
The meta-lesson matches the same-day capability-gate incident: we prove one direction and ship. Writes were tested; reads weren't even counted. Defaults are the product — a scope that is optional, a recall that must be requested, and a compact mode nobody turns on are indistinguishable from not existing.
Deferred: pre-command risk surfacing (hook), trial-and-error narrative capture, and the ratio dashboard UI.