Skip to content

This page is written to be read by an AI coding agent. You do not follow it yourself; you hand it to a coding session on the machine you want archived, and the session interviews you, runs the installer, activates the hourly schedule, and checks that transcripts are actually landing in the archive.

Point your agent at this page

Open a coding session on the machine you want Recall to archive, and give it this instruction:

Set up Pibmo Recall on this machine by following https://pibmo.com/recall/onboarding/.

The session will fetch this page and work through it top to bottom, asking you the questions in section 2 one at a time. The rest of this page is addressed to that session.

If you are an agent reading this: follow it top to bottom. Ask the questions in section 2 one at a time, in order, and wait for an answer before moving on. Do not guess an answer you were not given. Do not run the installer until section 4. One step — wiring the session banner — cannot be run from inside your session at all; section 5 tells you what to hand the human instead.

A human can also follow this page by hand. It is the same sequence either way.


1. What you are setting up

Recall archives AI coding-session data — Claude Code (~/.claude), Gemini CLI and Antigravity (~/.gemini), Codex CLI (~/.codex) — into an append-only dataset root on machine-local storage, so transcripts survive the tools’ rotation windows. An hourly native scheduler unit (LaunchAgent on macOS, systemd user timer on Linux) runs the sync straight from the repo checkout: nothing is installed into ~/.claude or ~/.pibmo, nothing calls an LLM, and the archive is never overwritten or shrunk. Setting it up means deciding four things:

DecisionWhy it cannot be defaulted
What this machine is calledThe name keys this machine’s subtree and its entry in the fleet-wide registry; only you know what your fleet calls this box
Whether this is a single computer or one machine of severalNothing on this machine reveals the rest of your fleet, and consolidation only exists in the multi-machine shape
Where the consolidated root lives (multi-machine only)Every machine pushes into it, so it must be a path that means the same shared place on each of them
Whether sessions get the archive-health bannerIt is the one write outside the dataset root — a hook entry in ~/.claude/settings.json — so it is strictly opt-in

Conspicuously absent from the list: where the local dataset root lives. The installer proposes the platform default and the right answer is almost always Enter. It refuses cloud-synced and remote paths for that root outright — the archive’s write path must be plain local disk that no cloud mount, permission fence, or network can deny. A cloud folder belongs as the consolidated root, never as the local one.

Before you start

  • Python 3.9 or newer (python3 --version). The sync layer is pure stdlib — there is nothing to pip install.
  • git, to clone the repo. A cloud account or client is not a prerequisite.
  • Clone the repo to a durable location, because the scheduler unit will embed this path:
Terminal window
git clone https://github.com/attilabalogh/pibmo-recall.git ~/code/pibmo-recall

Check both at once:

Terminal window
python3 --version && git --version

Updating later is git pull — the unit points at the checkout, so the next tick runs the new code. There is no deployed copy and no self-updater.


2. The interview

Ask these in order. The answers become environment prefills for the installer.

Q1. What should this machine be called?

Short, lowercase, unique across the fleet (moraba, gavi, desktop). It becomes the machine’s subtree name ({root}/<name>/) and its entry in the shared {root}/machines.json registry, keyed by this machine’s hardware UUID. The lowercased hostname is the installer’s proposed default; confirm it rather than assume it, because the registry is what every analysis session uses to tell the fleet’s machines apart.

Q2. Is this a single computer, or one machine of several?

Only the human knows the fleet, so ask plainly.

  • A single computer. The interview is over — two answers and Enter, and consolidation never comes up. This is the whole product on one machine, not a reduced mode.
  • One machine of several. Each machine archives to its own local root, and every sync additionally pushes this machine’s subtree into a shared consolidated root. Ask Q3 and Q4.

Q3. (Multi-machine only) Where should the consolidated root live?

This is the shared root every machine’s sync pushes its own subtree into, accumulate-only — the place analysis sessions and the processing layer read the whole fleet. It may be a vendor cloud mount (for example ~/Library/CloudStorage/Dropbox/Datasets/pibmo); the installer names that choice out loud, and the vendor’s client then becomes your replication tool — keep it running and the folder fully synced (“available offline”), not online-only placeholders. Whatever path is chosen must resolve to the same shared place from every machine in the fleet.

Q4. (Multi-machine only) Does this machine need a secondary mirror?

An optional whole-root disaster-recovery copy onto a genuinely local second disk. Cloud DR belongs to a dedicated replication recipe (rclone) by design, not to a vendor-mount write path, so the answer for most machines is no.

Q5. Should sessions get the archive-health banner?

Recommended: yes. A SessionStart hook prints a quiet Archive: OK when this machine’s last sync is fresh and a loud Archive: STALE warning when it is older than 26 hours — the watcher that watches the watchers. Two things to say before the human answers:

  • It is the only step that writes outside the dataset root: one hook entry in ~/.claude/settings.json, pointing back at the repo.
  • The wiring script must run from a real terminal, not from inside an agent session — the session sandbox blocks ~/.claude/settings.json writes. If the answer is yes, you will hand the human one command to run themselves in section 5.

See Host integration.


3. Confirm the answers

Assemble the answers as environment variables. Each one pre-fills the matching installer prompt, so Enter accepts it. A single computer needs only the first two:

Terminal window
export PIBMO_ROOT="$HOME/Library/Application Support/pibmo/recall" # Linux/WSL: ~/.local/share/pibmo/recall
export PIBMO_MACHINE="moraba"

A multi-machine setup adds one or both of:

Terminal window
export PIBMO_CONSOLIDATE="$HOME/Library/CloudStorage/Dropbox/Datasets/pibmo"
export PIBMO_SECONDARY="/Volumes/Backup/pibmo-recall" # only if Q4 said yes

Leave PIBMO_CONSOLIDATE and PIBMO_SECONDARY unset on a single computer: setting either one is what tells the installer this is the multi-machine path.

Show the human the values and get confirmation before running anything.


4. Run the installer

The interview configures; this script installs. Everything from here is deterministic and re-runnable.

Terminal window
cd ~/code/pibmo-recall && bash install.sh

Enter accepts each pre-filled prompt. If your tooling cannot answer interactive prompts, feed empty lines to accept the answers already in the environment: yes '' | bash install.sh.

The installer will:

  1. Propose the local dataset root and refuse a cloud-synced or remote path for it. If it aborts here, that is the guard from section 1 doing its job: press Enter to accept the proposed default. --force overrides it, eyes open.
  2. Register this machine’s hardware UUID under its friendly name in {root}/machines.json, and create {root}/<machine>/logs/.
  3. Seed the shared config (projects.json, profiles.json) from the repo’s templates — never overwriting a file that already exists.
  4. Write the native scheduler unit (LaunchAgent on macOS, systemd user timer on Linux; Task Scheduler guidance on WSL) and print its activation commands, plus a crontab fallback line. It never edits your crontab.

It writes nothing into ~/.claude or ~/.pibmo; the root travels only on the unit line. Re-running it with the same answers is safe: registration updates in place, existing shared config is kept, and the unit is re-rendered.

Activate the scheduler unit

Run the commands the installer printed. They are, per platform:

  • macOS:
    Terminal window
    launchctl bootout gui/$UID com.pibmo.recall.sync 2>/dev/null || true
    launchctl bootstrap gui/$UID ~/Library/LaunchAgents/com.pibmo.recall.sync.plist
    RunAtLoad fires an immediate catch-up sync on bootstrap and login; hourly ticks missed while the Mac slept coalesce into one run on wake.
  • Linux:
    Terminal window
    systemctl --user daemon-reload
    systemctl --user enable --now pibmo-recall-sync.timer
    Persistent=true catches missed ticks. On a headless box, also loginctl enable-linger $USER.
  • WSL: schedule from the Windows side with Task Scheduler — the installer prints the exact command. It starts WSL on demand, so it does not depend on a window staying open.
  • Fallback (any platform): paste the printed cron line via crontab -e instead — never schedule both.

Repeat on the other machines

A multi-machine fleet runs this same page on every machine: same consolidated root, a distinct PIBMO_MACHINE name on each. Each machine writes only its own subtree, so the order does not matter. Replicating the consolidated root to cloud storage stays delegated to a tool built for it — the vendor’s own sync client or an rclone recipe — and the doctor measures whether it is keeping up. See Topologies and the durability model.


5. Verify it works

Do not report success until these pass.

Terminal window
# 1. Preview -- writes nothing.
python3 ~/code/pibmo-recall/scripts/sync/sync-transcripts.py --root "$PIBMO_ROOT" --dry-run | tail
# 2. First real sync (safe any time; concurrent runs exit immediately via a lock).
python3 ~/code/pibmo-recall/scripts/sync/sync-transcripts.py --root "$PIBMO_ROOT" -v
# 3. The archive now holds this machine's projects.
ls "$PIBMO_ROOT/$PIBMO_MACHINE/claude/projects/" | head
# 4. The doctor signs off. Run the exact command the installer's Done block
# printed -- its flags pin the interpreter and repo path the unit embeds.
python3 ~/code/pibmo-recall/scripts/sync/doctor.py --root "$PIBMO_ROOT" --machine "$PIBMO_MACHINE" \
--python "$(command -v python3)" --repo ~/code/pibmo-recall

A healthy machine straight after install reports roughly this:

Pibmo Recall doctor -- machine 'moraba', root /Users/you/Library/Application Support/pibmo/recall
OK root .../machines.json readable (1 machine(s) registered)
OK identity 5A2B3C4D...
OK registered 'moraba'
OK writable canary ok under moraba/logs/
OK unit 1 unit file(s) current
OK unit-cmd embedded interpreter and script exist
OK heartbeat last completed sync 2026-07-22T09:14:02+00:00 (0.1h ago)
WARN log no .../moraba/logs/cron.log yet
fix: expected after the first scheduled run; manual -v runs print to the terminal instead
Summary: 7 ok, 1 warn, 0 fail

That log warning is expected right now: manual runs print to the terminal, and the log file appears with the first scheduled run. Every FAIL row carries an indented fix: line with the exact remediation — apply it and re-run the doctor rather than improvising.

Then two follow-ups after you hand back to the human:

  • After the next full hour: tail "$PIBMO_ROOT/$PIBMO_MACHINE/logs/cron.log" shows a fresh timestamped run, and the doctor’s log warning clears.

  • If Q5 said yes to the banner: give the human this command to run from a real terminal, not inside an agent session — the session sandbox blocks ~/.claude/settings.json writes:

    Terminal window
    bash ~/code/pibmo-recall/scripts/maintenance/deprecate-sync-hooks.sh

    It is safe on a fresh machine and idempotent. The next session they start should open with Archive: OK in the banner. If it does not, see Host integration and Troubleshooting.


6. Tell the human what it does not do

Say this out loud before you finish, because these are the properties people most often assume backwards:

Recall provides faithful, append-only capture on this machine’s local disk. It does not provide backup by itself: until a consolidated root or a replication tool is in place, the archive exists in exactly one location, and a dead disk takes it along. Replication is deliberately delegated — Recall never speaks a cloud API — so the byte-mover you choose (vendor sync client, rclone, rsync) is part of your durability story, and the doctor measures its outcome, not its mechanism.

Faithful capture is also not redaction. Named credential files (oauth_creds.json, auth.json, and kin) never enter the archive, but everything inside a transcript does: a secret pasted into a session is preserved verbatim, and the archive has no delete pathway. The denylist profiles apply when the processing layer projects Markdown, not when the archive captures.

Two boundaries worth stating in the same breath: the sync archives this OS user’s ~/.claude (plus ~/.gemini and ~/.codex) only — a machine-wide multi-user sweep is a separate, explicit opt-in, never switched on silently — and if a transcript must be erasable, an append-only archive is the wrong tool and no configuration of Recall will delete it for you. The full model is in Architecture and Topologies and the durability model.


Where to go next