Skip to content

RaiSE 3.1 Migration Guide: Per-Project venv to Global Binary

Audience: Any user on a previous RaiSE install (per-project venv, pipx, pip --user, or the old install.sh) who does not yet have the global binary.

Time required: 5--15 minutes per project checkout.

Every command below is copy-pasteable.


1. Who this is for -- how to tell which install you have

Run which rai (Linux/macOS) or Get-Command rai (Windows PowerShell) and compare the output:

which rai output Install method Action
.venv/bin/rai or .venv\Scripts\rai.exe Per-project venv (install script or manual) Follow this guide
~/.local/pipx/venvs/raise-cli/bin/rai pipx Follow this guide
~/.local/bin/rai (symlink into a pip --user site) pip --user Follow this guide
~/.local/bin/rai (symlink into ~/.local/share/rai/) Global binary -- already migrated Skip to Step 3
No output / "not found" Not installed Go to Step 1

If unsure, check the target: ls -l $(which rai). A symlink pointing into ~/.local/share/rai/ is the global binary. Anything else is a previous install.


2. Step 1 -- Install the global binary

Linux / macOS

curl -fsSL https://github.com/humansys/raise/releases/latest/download/install.sh | bash

Windows (PowerShell)

irm https://github.com/humansys/raise/releases/latest/download/install.ps1 | iex

Download and inspect first

If you prefer to review before running:

curl -fsSL -o /tmp/rai-install.sh https://github.com/humansys/raise/releases/latest/download/install.sh
less /tmp/rai-install.sh
bash /tmp/rai-install.sh

Pin a specific version

curl -fsSL https://github.com/humansys/raise/releases/latest/download/install.sh | bash -s -- --version v3.1.0
./install.ps1 -Version v3.1.0

WARNING: Do NOT use docs.raiseframework.ai/install.sh to upgrade.

The URL https://docs.raiseframework.ai/install.sh is the old per-project venv installer. It creates a .venv in your project directory and installs raise-cli from the GitLab pre-release registry. Running it "to upgrade" recreates the exact residue this migration removes.

The new binary installer lives in the GitHub Releases for humansys/raise: https://github.com/humansys/raise/releases/latest/download/install.sh

What the installer does

  1. Downloads prebuilt binaries (rai + rai-mcp-pipeline) from GitHub Releases.
  2. Verifies SHA-256 checksums for both binaries before installing either (atomic).
  3. Installs to ~/.local/share/rai/ (Linux/macOS) or %LOCALAPPDATA%\rai\ (Windows), with symlinks in ~/.local/bin/.
  4. Registers %LOCALAPPDATA%\rai\ on the user PATH (Windows only).
  5. No Python required.

3. Step 2 -- Verify the binary is active

which rai        # should print ~/.local/bin/rai
rai --version    # should print the installed version

On Windows:

Get-Command rai
rai --version

If which rai still shows .venv/bin/rai or a pipx path, the old entry point is shadowing the binary. See PATH shadowing in the troubleshooting section below.

Quick fix:

hash -r                       # clear bash's command cache
export PATH="$HOME/.local/bin:$PATH"  # ensure binary dir is first

4. Step 3 -- Scan and clean

This is the core of the migration. You have two options:

  • Automatic (recommended): rai clean --force handles everything -- venvs, orphan databases, stale configs. No manual uninstall needed.
  • Manual control: if you prefer to review and remove things yourself, see Appendix A for per-method uninstall commands, then come back here and run rai clean for the rest.

Preview what will happen

cd ~/projects/my-app
rai clean --dry-run

Example output (sanitized):

Legacy install scan -- 12 residue(s) found

                          ACTIONS (will be processed)
+----------------------------+---------------------+-------------+
| path                       | kind                | action      |
+----------------------------+---------------------+-------------+
| .raise/rai/raise.db        | orphan-db           | consolidate |
| .mcp.json                  | stale-mcp-command   | fix-config  |
| .codex/config.toml         | stale-runtime-config| fix-config  |
+----------------------------+---------------------+-------------+

                        ADVISORY (manual action needed)
+----------------------------+---------------------+-------------------+
| path                       | kind                | hint              |
+----------------------------+---------------------+-------------------+
| .venv                      | venv-raise-cli      | delete or move    |
| requirements.txt           | requirements-dep    | remove raise-cli  |
| pyproject.toml             | pyproject-dep       | remove raise-cli  |
| uv.lock                    | uvlock-entry        | re-lock           |
+----------------------------+---------------------+-------------------+

Dry run -- nothing was changed.
Run rai clean to process owned residues.
Run rai clean --force to process ALL residues (including advisory).

ACTIONS are residues that rai clean owns and will process automatically (orphan databases, stale config keys). These are safe to process without manual review.

ADVISORY are residues in files you own (venvs, pyproject.toml, uv.lock) -- rai clean lists them but does not touch them unless you pass --force.

Clean everything

rai clean --force

This processes ACTIONS (owned residues) and ADVISORY (venvs, dependency references) with a confirmation prompt. Review the plan and type yes to proceed.

About venvs: rai clean --force deletes venvs that contain raise-cli. If a venv also holds your project's own dependencies, rai clean will warn you -- remove raise-cli from it manually instead (see Appendix A).

What "consolidate" means for orphan databases: if rai clean finds a project-local .raise/rai/raise.db, its data is merged into the global ~/.rai/raise.db. After a successful merge, the local file is renamed to raise.db.consolidated (never deleted). You can safely remove the .consolidated files once you have verified the migration.

Repair configs

rai clean --fix-config

This repairs configuration files that reference old paths (e.g., .mcp.json entries pointing to .venv/bin/rai-mcp-pipeline instead of the global binary).

If .mcp.json is tracked in git, --fix-config still applies the repair: it writes a .bak backup and leaves the diff in your working tree for you to review and commit.

Before moving on, resolve any pyproject-dep and uvlock-entry residues listed under Residues that need manual action -- rai upgrade in the next step assumes a clean project.


5. Step 4 -- Upgrade the project scaffold

Run rai upgrade --detect to bring your project's .raise/ scaffold up to date and re-detect installed agents:

rai upgrade --detect

Prefer upgrade over rai init --force. upgrade --detect preserves your manifest, governance docs, and custom skills, and it does not write orphan entries into ~/.rai/developer.yaml (a known issue with init --force). Reserve rai init --force --detect for a checkout that was never initialized (no .raise/ directory at all).


6. Step 5 -- Import legacy data

Legacy sessions, journal entries, signals, pipeline runs, and patterns live in flat files (JSONL/JSON/YAML) or an older SQLite schema. Import them into the current database explicitly -- nothing triggers this automatically during upgrade or init --force:

rai db import-legacy

This is idempotent: original files are renamed *.migrated, never deleted, so it is safe to run more than once. Although rai db import-legacy --help lists only sessions, journal entries, signals, and pipeline runs, it also migrates your patterns completely.

Depending on which version you are migrating from:

Coming from What to expect
2.x (JSONL) Required. patterns.jsonl does not auto-migrate -- skipping this step silently loses your patterns.
3.0.0 (SQLite v24) May print an IntegrityError traceback from the slug migration. This is cosmetic -- the migration completes and your data is intact. Safe to ignore.
3.1.0 pre-releases (SQLite v50+) Typically prints "Nothing to migrate" -- expected, your data was already in SQLite.

Verify the import:

rai db status

For background on why this storage change happened, see BC3 -- SQLite replaces JSONL/JSON storage in the 2.x migration guide.


7. Step 6 -- Rebuild the knowledge graph

The knowledge graph is derived state -- rebuild it after a schema or data migration:

rai graph build

Symbol granularity may differ slightly from old builds (scanner changes across versions); that is not data loss.


8. Step 7 -- Verify

rai doctor                    # full diagnostics
rai doctor -c legacy          # legacy-specific checks only

Then run a quick smoke test:

rai session start my-test --project .

Finally, confirm no residues remain:

rai clean --dry-run    # expect zero residues

Repeat steps 3--7 for every project checkout and worktree on your machine. Each checkout may have its own residues (venvs, local databases, config files). Steps 1--2 and 8 are per-machine, done once.


9. Step 8 -- Clean up ~/.rai/developer.yaml

This is a one-time, per-machine cleanup -- not a per-checkout step.

rai init writes to the real global ~/.rai/developer.yaml regardless of which environment triggered it (a known issue), so orphan entries can accumulate across test runs and deleted checkouts. rai doctor and rai clean now detect these automatically:

rai doctor -c developer-yaml    # reports orphan project entries and stale sessions
rai clean --dry-run              # lists them alongside other residues
rai clean                        # prunes orphan entries (writes developer.yaml.bak first)

What gets detected:

  • projects: entries pointing to paths that no longer exist on disk.
  • active_sessions: entries older than 48 hours with no matching session state directory.

Valid entries are never touched. A backup of the original file is written to developer.yaml.bak before any modification.


10. Residues that need manual action

After rai clean --force, some residues may remain because they require a judgment call. Here is what each kind means and what to do:

Kind Where What to do
requirements-dep requirements.txt or similar Remove the raise-cli / raise-core line. These are no longer installed via pip.
pyproject-dep pyproject.toml [project.dependencies] Remove raise-cli / raise-core from the dependency list.
uvlock-entry uv.lock After removing the pyproject dep, run uv lock to regenerate.
repo-cartridge-self-ingest .raise/cartridges/repo/instances/repo.json The old repo cartridge will be re-ingested on the next graph build, causing a RepoCartridgeCollapseError. Move the instances/ directory aside: mv .raise/cartridges/repo/instances /tmp/repo-instances-bak && rai graph build

If rai clean --dry-run shows zero ADVISORY items after you handle these, your checkout is fully migrated.


Appendix A -- Manual uninstall (when rai clean is not enough)

In most cases rai clean --force handles everything. Use manual uninstall only when the venv is shared with your project's own dependencies and cannot be deleted entirely.

Per-project venv (most common)

cd ~/projects/my-app
rm -rf .venv

WARNING: Delete the venv, never rename it.

Although 3.1.0 final now excludes common renamed patterns (.venv.old, .venv-backup), earlier versions did not. In one field report on rc3, a renamed venv produced 89,589 garbage nodes (97% of the graph) and a 62 MB tracked repo.json. Deleting is the safest approach regardless of version.

If you need to preserve packages for reference, copy the pip freeze output to a file outside the project tree, then delete the venv.

On Windows:

cd ~/projects/my-app
Remove-Item .venv -Recurse -Force

Shared venv (venv contains your project's own deps)

If the .venv also holds your project dependencies and cannot be deleted:

cd ~/projects/my-app
source .venv/bin/activate
uv pip uninstall raise-cli raise-core
deactivate

Or without uv:

cd ~/projects/my-app
.venv/bin/pip uninstall raise-cli raise-core -y

pipx

pipx uninstall raise-cli

pip --user

pip uninstall raise-cli raise-core -y

Windows shim

The old Windows installer (docs/install.ps1) may have left a rai.cmd shim. The new binary installer removes it automatically, but if you skipped the installer:

Remove-Item "$HOME\.local\bin\rai.cmd" -Force -ErrorAction SilentlyContinue

Troubleshooting

Five known issues from field reports, ordered by frequency. Each entry uses the exact error text so you can search for it.

PATH shadowing

Symptom: After installing the global binary, which rai still returns a legacy path:

$ which rai
/home/user/projects/my-app/.venv/bin/rai

or:

$ which rai
/home/user/.local/pipx/venvs/raise-cli/bin/rai

rai --version reports the old version, or the command behaves unexpectedly.

Cause: The legacy entry point (.venv/bin/rai from an activated venv, or a pipx shim) appears earlier in $PATH than ~/.local/bin/rai, where the global binary is symlinked.

Diagnose:

which -a rai     # show all rai executables on PATH
ls -l $(which rai)  # check what the first hit points to

On Windows:

Get-Command rai -All

Fix:

  1. Deactivate any active venv:
deactivate
  1. Remove the legacy entry point (follow Appendix A):

  2. Venv: rm -rf .venv

  3. pipx: pipx uninstall raise-cli
  4. pip --user: pip uninstall raise-cli -y

  5. Clear the shell's command hash:

hash -r
  1. Verify:
which rai        # should show ~/.local/bin/rai
rai --version
  1. If ~/.local/bin is not on PATH at all, add it to your shell profile:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

.mcp.json tracked in git

Symptom: rai doctor reports a warning about the tracked config:

[WARN] .mcp.json is tracked in git — a committed copy overwrites any local
       per-worktree override on checkout/pull

Cause: Some projects committed .mcp.json to version control. The file contains paths to the MCP pipeline binary that must be updated to the global binary path.

Fix:

  1. Run the config repair:
rai clean --fix-config
  1. Review and commit the change:
git diff .mcp.json
git add .mcp.json
git commit -m "fix: update .mcp.json paths to global binary"
  1. Consider untracking the file going forward:
echo ".mcp.json" >> .gitignore
git rm --cached .mcp.json
git add .gitignore
git commit -m "chore: stop tracking .mcp.json"

database is locked

Symptom:

sqlite3.OperationalError: database is locked

Commands hang or fail intermittently with the SQLite lock error.

Cause: An old venv-installed rai process is still running and holding a write lock on ~/.rai/raise.db. Two processes at different schema versions writing to the same file can produce inconsistent state.

Fix:

  1. Kill any running legacy rai processes.
  2. Remove the legacy entry point (see Appendix A).
  3. Verify only one rai binary exists: which -a rai
  4. If the database is corrupted, restore from backup:
cp ~/.rai/raise.db.backup-pre-3.1 ~/.rai/raise.db

RepoCartridgeCollapseError

Symptom:

RepoCartridgeCollapseError

rai graph build fails on the first build after migrating.

Cause: The existing .raise/cartridges/repo/instances/repo.json is re-ingested as a node source during the graph build, causing collisions with freshly scanned nodes.

Fix: Move the old instances/ directory aside and rebuild:

mv .raise/cartridges/repo/instances /tmp/repo-instances-bak
rai graph build

Renamed venv gets indexed

Symptom: After renaming .venv to .venv.old, rai graph build produces an enormous graph with tens of thousands of unexpected nodes.

Cause: In rc3, the scanner excluded directories by exact name. A renamed directory like .venv.old did not match. Fixed in 3.1.0 final (RAISE-16215).

Fix: Never rename venvs inside the project tree. Delete them:

rm -rf .venv.old
rai graph build