# Safe production branch deployments Lumi can deploy the stable `main` branch or an exact published `experimental-*` branch from **Admin > Updates > Running code branch**. This is a managed deployment; Lumi does not change the live installation's Git worktree. It fetches the selected branch into `data/update-cache/repo`, verifies the core and bundled-plugin entry files, snapshots the running core and plugin code plus the database, replaces managed application files, records the deployed branch and commit, and then restarts. Local data remains in place during a normal branch switch, including settings, databases, plugin data, uploads, logs, secrets, AI models/runtimes, community knowledge, corrections, and `node_modules`. Bundled plugin code follows the selected branch; local-only plugins absent from that branch stay installed. The update-aware wrapper repairs changed runtime dependencies before it starts the new branch. ## Prerequisites 1. Start production through `npm start`, `npm run run`, or a service that runs `node run.js`. The wrapper recognizes Lumi's restart exit code and starts the deployed code after dependency verification. 2. Ensure the configured repository credential can fetch branches without an interactive password prompt. 3. Push the experimental branch before opening the deployment control. Only `main` and remote branches named `experimental-*` are accepted. 4. Keep snapshot retention high enough to retain at least the latest core backup. The default keeps five per target for 30 days. ## Test an experimental branch To enter from stable `0.2.24`, open **Admin > Settings**, select **Experimental** as the update branch, save, and use **Update from repository**. The older updater installs experimental core `0.2.25`; on its first startup the new guarded bootstrap confirms that an actual core update completed, snapshots the installation, synchronizes bundled plugin code, and restarts a second time. Merely checking metadata cannot trigger this bootstrap. Stable `0.2.24` predates the exact-branch picker, so it selects the newest published `experimental-*` branch. The same guarded entry path is available again after a return to stable. While experimental code is running, use the exact branch controls below to move between `main` and any published experimental branch. 1. Open **Admin > Updates** and find **Running code branch**. 2. Confirm the page reports the expected running branch and commit. 3. Choose the exact experimental branch and select **Deploy selected branch**. 4. Review the confirmation. Keep the page open while Lumi creates the backup, deploys, restarts gracefully, and reconnects. 5. Verify the branch and commit after reconnection, then test the affected production workflows. The same branch can be selected again for a verified repair deployment. ## Return to stable main Use **Return safely to main**. Lumi first snapshots the running experimental code, then deploys the current remote `main` while preserving live data. This is the preferred normal return path because it does not intentionally rewind the database or discard data written during the experiment. Experimental database migrations must remain backward-compatible with `main` when this path is expected to work. Mark experimental update metadata with `rollback_safe: false` and document the migration when a change cannot safely be read by the stable code. ## Emergency restore Use **Emergency restore previous backup** only when the deployed branch cannot run correctly enough to return through the normal branch control. It restores both the previous core code and the database captured before deployment, so database changes written after that snapshot may be lost. If the normal WebUI is unavailable, start recovery mode with `LUMI_SAFE_MODE=1 npm run run`, `node run.js --safe-mode`, or the `data/recovery/safe-mode.flag` marker. Recovery markers and deployment state are also visible through the production diagnostics `update_state` check. ## Failure behavior Fetching and target verification happen before live files are touched. Once replacement starts, failures trigger an automatic restore from the new snapshot. If automatic restore also fails, Lumi retains the recovery marker and snapshot for safe mode instead of silently continuing with a partial install.