# MindSpace Seamless Migration Runbook ## Scope This runbook defines the no-loss migration path for extracting MindSpace from the Memind monolith. Current production status: - 103 already runs standalone MindSpace Service from `/Users/john/MindSpace`. - The service is `cn.tkmind.mindspace-service` on `127.0.0.1:8082`. - Portal live root remains `/Users/john/Project/Memind`. - `/Users/john/Project/Memind/MindSpace` is legacy compatibility/storage context only, not the current MindSpace Service root. Historical/local Phase A notes remain below for implementation context. For current 103 production truth, use [103 runtime topology](./103-runtime-topology.md). ## Invariants - Existing Memind local behavior remains the baseline. - `local` and `remote` adapter modes must stay switchable through env only. - User-facing functionality must not regress when `remote` points to the local standalone service. - Production release rules stay unchanged: merge to `main`, pass `bash scripts/check-release-ready.sh`, release from verified `main`. ## Phase A Goal Run MindSpace as a standalone local service while Memind uses `MINDSPACE_SERVER_ADAPTER=remote`, with no intentional feature loss versus the current local adapter path. Phase A is complete when: - standalone MindSpace service uses `/Users/john/MindSpace` as the production service root on 103 - Memind can use `MINDSPACE_SERVER_ADAPTER=remote` against the standalone service - `npm run verify:phase-a-local` passes for a real user with existing data - Memind remote-mode HTTP page list, page create, and page delete pass through the standalone service - temporary verification data and login sessions are cleaned up - remaining Memind-local responsibilities are documented instead of hidden ## Current data-root policy - Production standalone service root on 103: `/Users/john/MindSpace` - Old `/Users/john/Project/Memind/MindSpace` paths are migration source, rollback source, or legacy compatibility only - Old Memind directories are treated as migration source and rollback source - Data-root migration is executed by script, not by ad hoc manual copying ## Phase A Components ### Memind - Shared adapter contract - Local and remote adapter selection - Remote transport with auth token, timeout, and configurable operation path - Remote mode skips Memind-side generated-page workspace sync; background jobs stay on the standalone MindSpace runtime ### Standalone MindSpace service Path: - `/Users/john/MindSpace` on 103 production Responsibilities: - bootstrap DB-backed local MindSpace services - expose `POST /mindspace/v1/adapter/:binding/:method` - expose `/health` and `/mindspace/v1/contract` - manage publication cleanup - manage optional workspace maintenance - manage optional agent worker - read existing session snapshots for conversation-package public-html hydration ### Standalone data-root overrides Use these when you intentionally want a runtime root other than the production default `/Users/john/MindSpace`: - `MINDSPACE_SERVICE_H5_ROOT` - `MINDSPACE_STORAGE_ROOT` - `H5_USERS_ROOT` ## Start Order ### 1. Start standalone MindSpace service ```bash cd /Users/john/MindSpace npm run migrate:data-root -- --yes MINDSPACE_MEMIND_ROOT=../Memind \ MINDSPACE_REMOTE_AUTH_TOKEN=local-dev-token \ MINDSPACE_SERVICE_PORT=19081 \ MINDSPACE_SERVICE_AGENT_WORKER_ENABLED=true \ node server.mjs ``` ### 1b. Start standalone service against a new data root ```bash cd /Users/john/MindSpace MINDSPACE_MEMIND_ROOT=/Users/john/Project/Memind \ MINDSPACE_SERVICE_H5_ROOT=/Users/john/MindSpace \ MINDSPACE_STORAGE_ROOT=/Users/john/MindSpace/data/mindspace \ H5_USERS_ROOT=/Users/john/MindSpace/users \ MINDSPACE_REMOTE_AUTH_TOKEN=local-dev-token \ MINDSPACE_SERVICE_PORT=19081 \ MINDSPACE_SERVICE_AGENT_WORKER_ENABLED=true \ node server.mjs ``` ### 2. Point Memind at the standalone service ```bash export MINDSPACE_SERVER_ADAPTER=remote export MINDSPACE_REMOTE_BASE_URL=http://127.0.0.1:19081 export MINDSPACE_REMOTE_AUTH_TOKEN=local-dev-token ``` ### 3. Start Memind normally Use the standard local startup flow already used in this repo. ## Validation ### Phase A local gate ```bash cd /Users/john/MindSpace MINDSPACE_LOOPBACK_USER_ID= \ MINDSPACE_REMOTE_BASE_URL=http://127.0.0.1:19081 \ MINDSPACE_REMOTE_AUTH_TOKEN=local-dev-token \ npm run verify:phase-a-local ``` Expected result: - standalone service is healthy, either reused if already running or started by the verifier - RPC unit tests pass - infra smoke, read parity, page write parity, asset upload parity, and conversation package parity all pass - Memind remote-mode HTTP page list, page create, and page delete pass - final read parity still reports no drift after write-path validation - any service started by the verifier is stopped before exit Current verified local user: - `1c99b83b-0454-474f-a5d2-129d34506a32` Latest verified totals from the Phase A gate: - pages: `302 / 302` - assets: `100 / 100` - jobs: `0 / 0` - drift counters: `onlyLocal = 0`, `onlyRemote = 0`, `changed = 0` ### Memind remote-mode HTTP gate ```bash cd /Users/john/MindSpace MINDSPACE_LOOPBACK_USER_ID= \ MINDSPACE_REMOTE_BASE_URL=http://127.0.0.1:19081 \ MEMIND_REMOTE_MODE_BASE_URL=http://127.0.0.1:18082 \ MINDSPACE_REMOTE_AUTH_TOKEN=local-dev-token \ npm run verify:memind-remote-mode ``` Expected result: - standalone MindSpace service is healthy - Memind starts with `MINDSPACE_SERVER_ADAPTER=remote` - a short-lived local login session can access Memind `/auth/status` - Memind HTTP page list, page create, and page delete succeed through the remote adapter - temporary login session is revoked and temporary page is deleted before exit ### Infra smoke ```bash cd /Users/john/MindSpace node scripts/loopback-smoke.mjs ``` ### User-scoped smoke ```bash cd /Users/john/MindSpace MINDSPACE_LOOPBACK_USER_ID= \ MINDSPACE_REMOTE_AUTH_TOKEN=local-dev-token \ node scripts/loopback-smoke.mjs ``` Expected result: - `asset count`, `page count`, `job count` return real values for a user with existing MindSpace data - empty collections are acceptable only when the chosen user truly has no stored data ### Local vs remote comparison ```bash cd /Users/john/MindSpace MINDSPACE_LOOPBACK_USER_ID= \ MINDSPACE_REMOTE_BASE_URL=http://127.0.0.1:19081 \ node scripts/compare-local-remote.mjs ``` Expected result: - page totals match - asset totals match - job totals match - `onlyLocal`, `onlyRemote`, `changed` all stay `0` for stable read surfaces ### Write-path parity ```bash cd /Users/john/MindSpace MINDSPACE_LOOPBACK_USER_ID= \ MINDSPACE_REMOTE_BASE_URL=http://127.0.0.1:19081 \ node scripts/compare-write-local-remote.mjs ``` Expected result: - temporary local and remote pages are both created successfully - `create -> publish -> offline -> delete` produces no semantic diff between local and remote comparisons - temporary validation data is cleaned up before the script exits ### Asset upload parity ```bash cd /Users/john/MindSpace MINDSPACE_LOOPBACK_USER_ID= \ MINDSPACE_REMOTE_BASE_URL=http://127.0.0.1:19081 \ node scripts/compare-asset-local-remote.mjs ``` Expected result: - temporary local and remote text uploads both complete successfully - `createUpload -> writeUploadContent -> completeUpload -> readAsset -> deleteAsset` produces no semantic diff - temporary validation assets are deleted before the script exits ### Conversation package parity ```bash cd /Users/john/MindSpace MINDSPACE_LOOPBACK_USER_ID= \ MINDSPACE_REMOTE_BASE_URL=http://127.0.0.1:19081 \ node scripts/compare-conversation-package-local-remote.mjs ``` Expected result: - temporary local and remote packages are both created successfully - object write, artifact registration, manifest write, manifest file contents, and prepare-read outputs produce no semantic diff - temporary validation package rows and storage objects are removed before the script exits ### Manual UX validation - asset list and upload - page list and page render - page publish and public page access - agent job create, run, and completion - conversation package read for sessions that already have snapshots ## Phase A Boundary Audit The following MindSpace surfaces are now covered by the standalone service adapter and Phase A gate: - page list/read/create/publish/offline/delete - asset list/upload/write/complete/read/delete - conversation package object write, artifact registration, manifest write, and prepare-read - remote RPC transport including JSON-serialized `Buffer` arguments - Memind HTTP page list/create/delete while `MINDSPACE_SERVER_ADAPTER=remote` The following responsibilities intentionally remain Memind-local in Phase A: - user auth, wallet/quota/category APIs, audit writes, and subscription integration still run in Memind - public route HTTP serving is still mounted by Memind, although publication resolution and page rendering use MindSpace service APIs - chat Finish public HTML materialization still writes to the Memind workspace path to preserve the verified `edit_file` regression guard - chat-save preview/thumbnail flows still read workspace HTML from the Memind workspace path - Goose/session workspace capability is still issued from Memind user auth and exposes the local workspace path plus `workspaceRef` Remote-mode guardrails added during Phase A: - Memind remote mode no longer runs local generated-page workspace sync before page listing - remote adapter background jobs stay on the standalone MindSpace runtime - Phase A verification uses short-lived login sessions and revokes them before exit Known Phase A residual risks: - real browser UI coverage is still manual; the automated HTTP gate covers Memind API behavior, not a full browser session - full agent job execution and Goose workspace writes are not yet a standalone-service-only contract - complete production separation still needs process supervision, TLS/domain routing, monitoring, and deployment rollback work in later phases ## Rollback If any remote-path issue appears locally: ```bash unset MINDSPACE_SERVER_ADAPTER unset MINDSPACE_REMOTE_BASE_URL unset MINDSPACE_REMOTE_AUTH_TOKEN ``` Memind will fall back to the local adapter path. ## Remaining Phase A hardening - add browser-level remote-mode smoke once UI automation credentials are available - add a full agent job execution smoke that verifies workspace writes against the intended service runtime - decide when chat Finish public HTML materialization moves from Memind to the standalone service ## Data migration outline When you decide to move local data into the standalone root, use this order: 1. Stop local writes or switch Memind back to `local` 2. Run `npm run migrate:data-root -- --yes` 3. Start standalone service 4. Run - `npm run smoke:loopback` - `MINDSPACE_LOOPBACK_USER_ID= npm run compare:local-remote` - `MINDSPACE_LOOPBACK_USER_ID= npm run compare:write-local-remote` - `MINDSPACE_LOOPBACK_USER_ID= npm run compare:asset-local-remote` - `MINDSPACE_LOOPBACK_USER_ID= npm run compare:conversation-package-local-remote` - `MINDSPACE_LOOPBACK_USER_ID= npm run verify:memind-remote-mode` 5. Only keep the new root if parity remains clean Rollback: - stop standalone service - point Memind back to `local` or stop the standalone service - if needed for rollback/compatibility, start standalone with an explicit legacy root; do not assume `/Users/john/Project/Memind/MindSpace` is the current production service root - old Memind data root becomes active again immediately ## Deferred - Phase C `105` integration - Phase D production cutover