11 KiB
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-serviceon127.0.0.1:8082. - Portal live root remains
/Users/john/Project/Memind. /Users/john/Project/Memind/MindSpaceis 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.
Invariants
- Existing Memind local behavior remains the baseline.
localandremoteadapter modes must stay switchable through env only.- User-facing functionality must not regress when
remotepoints to the local standalone service. - Production release rules stay unchanged: merge to
main, passbash scripts/check-release-ready.sh, release from verifiedmain.
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/MindSpaceas the production service root on 103 - Memind can use
MINDSPACE_SERVER_ADAPTER=remoteagainst the standalone service npm run verify:phase-a-localpasses 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/MindSpacepaths 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/MindSpaceon 103 production
Responsibilities:
- bootstrap DB-backed local MindSpace services
- expose
POST /mindspace/v1/adapter/:binding/:method - expose
/healthand/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_ROOTMINDSPACE_STORAGE_ROOTH5_USERS_ROOT
Start Order
1. Start standalone MindSpace service
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
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
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
cd /Users/john/MindSpace
MINDSPACE_LOOPBACK_USER_ID=<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
cd /Users/john/MindSpace
MINDSPACE_LOOPBACK_USER_ID=<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
cd /Users/john/MindSpace
node scripts/loopback-smoke.mjs
User-scoped smoke
cd /Users/john/MindSpace
MINDSPACE_LOOPBACK_USER_ID=<user-id> \
MINDSPACE_REMOTE_AUTH_TOKEN=local-dev-token \
node scripts/loopback-smoke.mjs
Expected result:
asset count,page count,job countreturn 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
cd /Users/john/MindSpace
MINDSPACE_LOOPBACK_USER_ID=<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,changedall stay0for stable read surfaces
Write-path parity
cd /Users/john/MindSpace
MINDSPACE_LOOPBACK_USER_ID=<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 -> deleteproduces no semantic diff between local and remote comparisons- temporary validation data is cleaned up before the script exits
Asset upload parity
cd /Users/john/MindSpace
MINDSPACE_LOOPBACK_USER_ID=<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 -> deleteAssetproduces no semantic diff- temporary validation assets are deleted before the script exits
Conversation package parity
cd /Users/john/MindSpace
MINDSPACE_LOOPBACK_USER_ID=<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
Bufferarguments - 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_fileregression 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:
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:
- Stop local writes or switch Memind back to
local - Run
npm run migrate:data-root -- --yes - Start standalone service
- Run
npm run smoke:loopbackMINDSPACE_LOOPBACK_USER_ID=<user-id> npm run compare:local-remoteMINDSPACE_LOOPBACK_USER_ID=<user-id> npm run compare:write-local-remoteMINDSPACE_LOOPBACK_USER_ID=<user-id> npm run compare:asset-local-remoteMINDSPACE_LOOPBACK_USER_ID=<user-id> npm run compare:conversation-package-local-remoteMINDSPACE_LOOPBACK_USER_ID=<user-id> npm run verify:memind-remote-mode
- Only keep the new root if parity remains clean
Rollback:
- stop standalone service
- point Memind back to
localor stop the standalone service - if needed for rollback/compatibility, start standalone with an explicit legacy root; do not assume
/Users/john/Project/Memind/MindSpaceis the current production service root - old Memind data root becomes active again immediately
Deferred
- Phase C
105integration - Phase D production cutover