Reference

Mental CLI identity

Mental CLI identity is a UUID in ~/.mental/bindings.json. Origin is a hint (SSH ≡ HTTPS). The folder path is not the id. mental where reports the active bundle and does not create a UUID. First write (status, journal, install, …) does.

Two clones of the same origin share one brain until you split.

Commands

Situation Command
This clone should use an existing UUID mental remap --to <uuid> (--from is the same retarget) or mental link --to <uuid>
This clone should diverge mental split (--copy keeps OKF files)
List bindings mental remap
Opt in to ./.mental in this repo mental doctor --fix-ignore then mental local
Copy home slice into ./.mental mental local --import
Same, and mark store=local mental local --move (--delete-home removes the home slice after the copy)
Carry this HOME to another PC mental backup --out <dir> then mental restore --from <dir> on the other machine
Disaster: replace packed slices only mental restore --from <dir> --replace --confirm REPLACE

How a bundle is chosen

  1. MENTAL_DIR (or --dir) if it is a directory → mode env
  2. Walk-up ./.mental/ with the .mental-local marker → mode local
  3. Git repo → ~/.mental/projects/<uuid>/ → mode home
  4. Not a git repo → ~/.mental → mode personal

Exclusive: never concatenate personal + project trees in status / search. Until a write creates a UUID, search / list / show are empty. They must not walk ~/.mental/projects (the parent of every slice). Leftover ./.mental stays invisible until that write. mental pulse is the cross-project surface.

Origin matching treats git@github.com:org/repo and https://github.com/org/repo.git as the same hint. A fork (new origin, upstream matches an old origin) does not inherit silently — remap or split. A git worktree shares the main worktree’s UUID. A monorepo binds the git root, not packages/foo.

Leftover project .mental/

Leftover Balakit ./.mental (no .mental-local marker) is ingested into ~/.mental/projects/<uuid>/ on the first write. Files are classified onto canonical OKF paths and frontmatter is normalized. The leftover folder is not deleted. After import, where reports home unless you ran mental local.

Privacy

Same contract as the README table What leaves your machine. Core CLI, the skill, MCP (stdio), the dashboard (loopback), hooks, and time tracking send nothing. The update check sends the package name to npm unless MENTAL_SKIP_UPDATE_CHECK=1. Decision models send redacted text only after a key is set. There is no account, no telemetry, and no Mental server. Keys stay in ~/.mental/config.json (mode 0600; on Windows that mode is a no-op and Mental sets an owner-only ACL when icacls is available). mental doctor --json repeats the table as network.

  • Default store: ~/.mental/ (never commit)
  • Project .mental/ is opt-in and must be gitignored (mental doctor --fix-ignore)
  • Agents must not edit .gitignore
  • Writes redact obvious credentials before they hit disk. --no-redact is the escape hatch and is logged
  • Uninstall does not delete OKF unless you type DELETE
  • Do not live-sync ~/.mental with Syncthing, Dropbox, or iCloud. Use mental backup / mental restore

On-disk shape

~/.mental/
  bindings.json
  config.json          # decision-model keys when you opt in
  dashboard.json       # port file while `mental dashboard` is running
  projects/<uuid>/
    journal/YYYY-MM-DD.md
    decisions/
    attention/
    notes/
    status/current.md

Cache (rebuildable, never SoT):

${XDG_CACHE_HOME:-~/.cache}/mental/<uuid>.sqlite