#3735·nanoclaw

conversations/ archives grow without bound — no retention, no cap

Author: TO-maschenbornCreated Sep 7, 2026Updated Sep 8, 2026

Version: 2.1.53

Summary

archiveTranscriptFile() writes a markdown archive into groups/<folder>/conversations/ on every compaction, and nothing ever removes them. There is no retention, no rotation, no cap — the directory grows for the lifetime of the agent group.

On our fleet this reached 690 MB across ten agents, with a single agent at 521 MB in 718 files and a steady rate of ~30–40 files / ~35 MB per day.

Why this is not just disk usage

conversations/ lives in the agent's own workspace (/workspace/agent), so the agent sees the directory listing. One of ours accumulated 718 entries there. More importantly, it is the same failure shape as #3732 — an artifact the runtime writes on the agent's behalf, with no counter-force — so operators who add a "keep your files tidy" instruction to an agent's prompt are addressing something the agent cannot influence at all.

Reproduction

  1. Run any agent that compacts regularly (a scheduled task at */15 is enough).
  2. du -sh <data>/groups/<folder>/conversations after a few weeks.

There is no configuration that bounds this and no code path that deletes from it:

$ grep -rn "conversationsDir" container/agent-runner/src/providers/claude.ts
231:    const conversationsDir = process.env.NANOCLAW_CONVERSATIONS_DIR || '/workspace/agent/conversations';
232:    fs.mkdirSync(conversationsDir, { recursive: true });
236:    fs.writeFileSync(path.join(conversationsDir, filename), formatTranscriptMarkdown(...));

mkdirSync and writeFileSync, nothing else.

What we measured

agent files size
A (15-min scheduled task) 718 521 MB
B 218 66 MB
C 289 26 MB
D 280 19 MB
six more 6–15 MB each

Archiving everything older than 7 days from agent A produced a 37 MB tarball from 259 MB of files — the content compresses at roughly 7:1, which suggests keeping it around uncompressed is not buying much either.

Suggested fix

A retention policy next to the write, configurable and defaulted conservatively — for example NANOCLAW_CONVERSATIONS_RETENTION_DAYS (default 30) or a file-count cap, applied right after the archive is written. Deleting the oldest entries at write time keeps the logic in one place and needs no new lifecycle.

If preserving history matters, compressing archives older than N days would already remove most of the volume.

Related: the same shape in appendRunLog

modules/scheduling/run-log.ts appends one line per run to groups/<folder>/tasks/<series>.md, also without any cap. Ours reached 465 KB. That one has a second-order effect: agent-runner/src/destinations.ts tells the agent to read that file back in later runs ("Read that file when you need context from earlier runs"), so a long-running series carries an ever-growing log into its own context — and anything mistakenly recorded there is re-read on every subsequent run.

Both are the same class as #3732: something the runtime writes, with no bound and nothing the agent or its instructions can do about it.