◈ Memo & Caching

Stop re-reading
unchanged files

Memo tracks which files your agent has read in the current session and tells it when they have changed on disk. The search cache does the same for repeated grep queries. Together they prevent redundant token use across every major AI coding harness.

// 01 — overview

Two layers of caching

TriSeek ships two complementary caching systems. Memo handles file reads; the search cache handles grep-style queries. Both are session-scoped and automatically invalidated when files change.

Memo (File Read Cache)

Memo observes every Read and Edit tool call in a session. When the agent reads the same file again, Memo checks the disk hash. If unchanged, the agent skips the re-read and trusts conversation history.

Agent reads file
Memo records hash
Second read: skip or re-read?

Validated at 85%+ redundant-read prevention across Claude Code sessions.

Search Cache (Grep Cache)

Repeated identical search_content, find_files, and search_path_and_content queries return cached results instead of re-scanning the index. Each response includes a cache field showing whether it was a hit, miss, or bypass.

Agent greps
Result cached
Same grep: instant hit

In-process LRU, 256 entries, 60s TTL. Cleared on reindex.

// 02 — multi-harness support

Works across every harness

Memo runs in passive mode where the harness supports hooks, and active mode where it does not. One triseek install command wires everything up.

Passive Mode

Hooks fire automatically after every Read and Edit tool call. The agent does not need to call anything explicitly.

Harness Mechanism
Claude Code Native hooks via Claude settings files, user-level by default
OpenCode TS plugin at ~/.config/opencode/plugins/triseek-memo.ts
Pi TS extension at ~/.pi/agent/extensions/triseek-memo/

Active Mode (Codex)

Codex hooks currently fire only for the Bash tool (#16732). Until that is resolved, agents call memo_check before re-reading a file.

memo_check input
{
  "path": "src/auth/router.rs"
}

If recommendation is skip_reread, trust conversation history. Otherwise, read the file normally.

// 03 — memo tools

Memo MCP tools

memo_check

Single-file freshness check. Returns a recommendation for whether to re-read.

response
{
  "path": "src/auth/router.rs",
  "status": "fresh",
  "recommendation": "skip_reread",
  "tokens_at_last_read": 120,
  "last_read_ago_seconds": 9
}
Recommendation Meaning
skip_reread File unchanged. Trust conversation history.
reread_with_diff File changed slightly (<10% size delta). Re-read expecting a small diff.
reread File changed significantly or was never read. Read normally.

memo_status

Bulk freshness check for multiple files. Returns per-file status, read count, and token estimates.

response (stale file)
{
  "session_id": "session-123",
  "results": [{
    "path": "src/auth/router.rs",
    "status": "stale",
    "tokens": 120,
    "current_tokens": 132,
    "read_count": 1,
    "message": "Changed since last read..."
  }]
}

The current_tokens field is set only when the file is stale, showing how much the file has grown or shrunk since the last read.

memo_session

Session-level aggregate showing tracked files, total reads, and token savings. Useful for debugging and demos.

response
{
  "session_id": "session-123",
  "tracked_files": 14,
  "total_reads": 38,
  "redundant_reads_prevented": 12,
  "tokens_saved": 4820,
  "compaction_count": 0
}
// 04 — search cache

Search result caching

Every search tool response includes a cache field. Identical queries against an unchanged index return instantly from the in-process LRU cache.

How it works

cache key · tool_name | limit | QueryRequest
storage · In-memory LRU, 256 entries max
TTL · 60 seconds (override: TRISEEK_SEARCH_CACHE_TTL_SECS)
invalidation · Cleared on reindex + TTL expiry
bypass · ripgrep fallback and direct-scan results are never cached

Cache field in responses

Every search envelope includes a cache field:

Value Meaning
hit Returned from cache. No search executed.
miss Cache miss. Search ran and result was cached.
bypass Fallback path used. Result not eligible for caching.

Applies to find_files, search_content, and search_path_and_content.

Example — second call returns instantly

search_content response (cache hit)
{
  "strategy":    "triseek_index",
  "generation":  42,
  "cache":       "hit",
  "results": [
    { "path": "crates/search-cli/src/mcp/tools.rs", "line": 530,
      "snippet": "fn run_and_envelope(" }
  ],
  "total_results": 1,
  "truncated":   false
}

Scope & limits

scope · Per MCP process. Two concurrent agent sessions do not share a cache.
max size · 256 entries × ~40 KB each ≈ 10 MB worst case
stale risk · Up to 60 s of staleness after a file changes. Call reindex for instant invalidation.
key normalisation · Exact match only. Changing limit or any query field is treated as a new entry.
// 05 — install

One command setup

Each installer wires up both MCP search tools and Memo hooks/plugins. The search cache is built into the MCP server and requires no configuration.

Install Commands

shell
# Claude Code
triseek install claude-code

# Codex
triseek install codex

# OpenCode
triseek install opencode

# Pi
triseek install pi

Verify the install and check Memo health:

shell
triseek doctor

What gets installed

Harness Installed
Claude Code MCP config + hook entries in ~/.claude/settings.json by default
Codex MCP entry in ~/.codex/config.toml + hooks in ~/.codex/hooks.json + codex_hooks = true feature flag
OpenCode MCP config + TS plugin at ~/.config/opencode/plugins/triseek-memo.ts
Pi MCP config + TS extension at ~/.pi/agent/extensions/triseek-memo/
// 06 — related

Related docs

Related Pages

Codex Active Mode Guide

For Codex agents that need step-by-step instructions on when and how to call memo_check, see the dedicated skill doc:

docs/codex-memo-skill.md

This doc includes a decision table, full response field reference, and an example system prompt addition.