Two trees on your disk
Recall reads the left one. Recall owns the right one. Nothing lives anywhere else.
~/.claude/
└── projects/
├── <encoded-cwd-1>/
│ ├── <session-uuid>.jsonl
│ └── <session-uuid>.jsonl
└── <encoded-cwd-2>/
└── <session-uuid>.jsonlClaude Code writes here. Recall never modifies these files.
~/.recall/
├── db.sqlite # FTS5 index
├── aliases.json # plain-text mirror
├── tags.json # plain-text mirror
├── collections.json # plain-text mirror
├── notes/
│ └── <uuid>.md # one file per note
├── daemon.token # 0600, per-start
├── daemon.pid
├── daemon.log
└── models/
└── bge-base-en-v1.5/Tar this directory to back up everything. Untar on a new machine to restore.
Never delete user data
Every rename archives the prior value. Cleared values stay recoverable from history.
Backup in one command
tar czf recall.tgz ~/.recall/Reset without data loss
Drop db.sqlite, then run recall start and recall index. Aliases and notes survive via mirrors.
Where your data lives
Three trees, and only the last one is Recall's:
| Path | Whose | What Recall does with it |
|---|---|---|
~/.claude/projects/**/*.jsonl | Claude Code's | Reads session transcripts. Never writes, never moves, never deletes |
~/.codex/sessions/**/rollout-*.jsonl and ~/.codex/session_index.jsonl | Codex's | Reads session transcripts and thread titles. Never writes anything under ~/.codex |
~/.recall/ | Recall's | Everything Recall creates: db.sqlite, aliases.json, notes/, tags.json, collections.json, semantic/, config.json |
~/.recall/ is the only one of the three you would ever back up. The transcripts are rebuilt from the agents' own
files by recall index; the metadata you created by hand is what cannot be recreated.
#The Codex read scope, exactly
Two patterns, and that is the whole of it: ~/.codex/sessions/**/rollout-*.jsonl for transcripts and
~/.codex/session_index.jsonl for thread titles. $CODEX_HOME is honored if you have set it. Each file is opened
without following symlinks, and a symlink is refused rather than read.
Never opened: auth.json, config.toml, hooks.json, history.jsonl, the ipc/ directory, and every
Codex SQLite database. Reading Codex sessions adds zero new network egress: no endpoint was added for it, and none
is called by it. That is about reading, not an exemption. Once a Codex session is indexed it is an ordinary row, so the
features that can carry session-derived content off your machine reach it exactly as they reach a Claude Code
session, because none of them filters by agent: sharing a recap card, opt-in AI tagging, and ✨ Generate title /
synopsis, which spawns your own claude -p with the text of the session you clicked. Several other features reach
claude -p too, including thread-scan rescoring, semantic summarisation and bulk thread titling, all routing
through a single audited spawn helper rather than spawning separately. The
README network-activity table is the maintained list with each trigger, and it is enforced by a test rather than
kept by hand. Sharing uploads the moment you click Share, with no separate switch and no first-use prompt; tagging
and title generation ship off and ask first, and tagging can also run unattended if you enable its autopilot.
#Turning Codex off
If you would rather Recall did not read Codex at all, recall codex off stops it and writes the setting for you.
While it is off, no rollout and no session_index.jsonl is opened: the watcher stops (or never starts, if the source
was already off), the 60-second sweep skips the source, thread titling does not run, and recall threads scan skips a
rollout without opening it.
Two things still touch the Codex home while the source is off, and neither one opens a file. recall doctor counts
the rollout files and reads their timestamps, so it can tell you the source is off while sessions are piling up. On
macOS and Linux the tab correlator still asks lsof which rollouts a running codex process holds open, and it can
only match those against rows already in your index.
Sessions already indexed stay in the database; nothing is deleted, and they stay searchable. recall codex on
reverses it, recall codex status prints which one is in force, and the underlying key is
sources.codex.enabled in ~/.recall/config.json.
#Reset without data loss
recall stop
rm ~/.recall/db.sqlite*
recall start
recall index # re-ingests both agents from their own filesAliases, tags, notes, and collections survive because the plain-text mirrors are authoritative.
#Never-delete guarantee
Every rename archives the prior value. Cleared values stay recoverable from history. The single carve-out is recall paste --purge
(clipboard archive, where leaked-secret risk justifies a true delete).
#Plain-text reality
Notes are markdown files. Aliases and tags live in JSON mirrors. SQLite has no row-level encryption. Anything you can read in the UI is readable by any process running as your user. Same posture as Obsidian or git dotfiles. Recall is not a password manager.