Background
Tool output overflow (large outputs >50 KB) is currently stored as UUID files on disk. This was a pragmatic initial solution but has several drawbacks compared to SQLite, which is already used for conversation history and memory.
Exposed in PR #1771 (#1740): the overflow path is an absolute filesystem path, leaking the username into LLM context (SEC-JIT-03) and making the database non-portable.
Problems with current approach
- Absolute paths leak
/Users/<username>/.zeph/overflow/ into LLM context
- No cleanup — files are not deleted when a conversation ends or the DB is wiped
- Not portable — copying the
.db file alone is insufficient for backup/migration
- No atomicity — overflow file and conversation record written in separate operations
- No size limits — files can accumulate indefinitely
Proposal
Store overflow content as a BLOB in a new tool_overflow SQLite table, linked to the conversation message by message_id:
CREATE TABLE tool_overflow (
id TEXT PRIMARY KEY, -- UUID, referenced in message body
message_id TEXT NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
content BLOB NOT NULL,
created_at INTEGER NOT NULL
);
The reference injected into body becomes an opaque ID rather than a path:
[tool output pruned; full content at overflow:{uuid}]
The agent retrieves it via a dedicated tool (or the existing memory_search path).
Tasks
- Add
tool_overflow table with migration step (--migrate-config)
- Update
save_overflow() in tool_execution/mod.rs to write to SQLite instead of disk
- Update
extract_overflow_ref() and reference format (opaque ID, not path)
- Add a retrieval path — either extend an existing tool or add
read_overflow native tool
- Add TTL/eviction policy (e.g., delete on conversation end, or age-based)
- Update
debug_dump.rs rendering
References
Background
Tool output overflow (large outputs >50 KB) is currently stored as UUID files on disk. This was a pragmatic initial solution but has several drawbacks compared to SQLite, which is already used for conversation history and memory.
Exposed in PR #1771 (#1740): the overflow path is an absolute filesystem path, leaking the username into LLM context (SEC-JIT-03) and making the database non-portable.
Problems with current approach
/Users/<username>/.zeph/overflow/into LLM context.dbfile alone is insufficient for backup/migrationProposal
Store overflow content as a BLOB in a new
tool_overflowSQLite table, linked to the conversation message bymessage_id:The reference injected into body becomes an opaque ID rather than a path:
The agent retrieves it via a dedicated tool (or the existing
memory_searchpath).Tasks
tool_overflowtable with migration step (--migrate-config)save_overflow()intool_execution/mod.rsto write to SQLite instead of diskextract_overflow_ref()and reference format (opaque ID, not path)read_overflownative tooldebug_dump.rsrenderingReferences
crates/zeph-core/src/agent/tool_execution/mod.rs