Skip to content
Your data

Two trees on your disk

Recall reads the left one. Recall owns the right one. Nothing lives anywhere else.

Source · read-only
~/.claude/
└── projects/
    ├── <encoded-cwd-1>/
    │   ├── <session-uuid>.jsonl
    │   └── <session-uuid>.jsonl
    └── <encoded-cwd-2>/
        └── <session-uuid>.jsonl

Claude Code writes here. Recall never modifies these files.

Recall owns
~/.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:

PathWhoseWhat Recall does with it
~/.claude/projects/**/*.jsonlClaude Code'sReads session transcripts. Never writes, never moves, never deletes
~/.codex/sessions/**/rollout-*.jsonl and ~/.codex/session_index.jsonlCodex'sReads session transcripts and thread titles. Never writes anything under ~/.codex
~/.recall/Recall'sEverything 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

bash
recall stop
rm ~/.recall/db.sqlite*
recall start
recall index          # re-ingests both agents from their own files

Aliases, 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.

Last updated