MLP/3 has one release-blocking Alpha journey and a smaller browser-only diagnostic journey. Both use a disposable real Synapse server and the actual built PWA/Gateway. Unit tests or mocked Matrix transports are not release acceptance.
- Docker is running.
- Node.js 22 or newer and workspace dependencies are installed.
- Chromium/Chrome is available to Playwright.
- An Android emulator or physical device is visible to
adb.
The fixture binds Synapse to a random localhost port and writes all accounts, keys, Gateway state, browser state, screenshots, and APK artifacts to isolated temporary/test directories. It never uses the deployed Gateway or the user's normal APK application ID.
Set the exact Android serial, then run:
MALINK_ANDROID_SERIAL=emulator-5554 pnpm test:e2e:alpha-livetest:e2e:alpha-live requires Android. It fails immediately if the serial is
missing, so a browser-only run cannot be mistaken for complete acceptance.
The journey proves, through real UI and Matrix traffic:
- A cache-cold browser pairs and sees the room-bound project identity.
- It creates a session, sends a prompt, receives Agent output, and creates a second session while the first Agent turn is still running.
- A second independent browser pairs and restores inventory and transcript without a manual refresh or application checkpoint.
- A retained pre-manifest
malink-matrix-v3database is upgraded in place: the durable command outbox survives while stale inbox/projection rows are discarded and rebuilt from authoritative Matrix state. - The second browser retains its Matrix account, device identity, and Gateway
trust while its local MLP/3 read model is erased. With current snapshot
requests held, it remains visibly in recovery instead of reporting
Connectedwith an empty inventory. An injected snapshot failure remains a non-blocking recovery state; after the fault is released the same page reconnects and restores its sessions without a reload, retry button, or new invitation. The same failure is injected again with a retained projection to prove that cached conversations remain visible throughout the retry. - The isolated Android APK installs and pairs while that trusted browser is offline. Android creates a session, then the browser cold-starts and restores the complete cross-device inventory before the session is deleted.
- Android sends a prompt, the Activity moves to the background, the foreground service receives the terminal Agent result, and a task notification appears.
- Android is force-stopped and restarted, then restores its durable projection and history without resending the command.
- Android deletes a session and both browsers converge.
- A deliberately malformed MLP/3 event is quarantined without blocking the next valid event.
- Browser reload/history recovery and concurrent archive converge on both browser devices.
A successful Android sub-journey ends with:
PASS — Android MLP/3 paired, restored, ran in background, notified, restarted, and deleted.
The complete run ends with:
PASS — MLP/3 over Matrix paired, created, ran concurrently, synchronized, restored, quarantined poison, and archived.
Artifacts for a failed run are retained under artifacts/e2e/matrix-mlp3-*.
When no Android target is available, the browser/Synapse/Gateway portion can be run explicitly:
MALINK_MATRIX_MLP3_LIVE_E2E=1 pnpm test:e2e:matrix-mlp3-liveThis command is useful during browser or Gateway development, but it is not the Alpha release gate.
Start the PWA and local Gateway in separate terminals:
cd apps/pwa && pnpm devpnpm dev:matrix-gatewayThe Gateway prints a QR code, invitation code, and pasteable fallback link. Use Add a Gateway in a fresh browser profile, confirm the matching invitation code, and complete the Matrix login offered by the invitation. One Matrix room is one project; new sessions appear as threads in that project.
Manual checks are useful for visual quality and provider-specific behavior, but do not replace the isolated Alpha journey. Never point the disposable test scripts at the production room or production Gateway data directory.
- One Malink tab owns one Matrix crypto store. A full-lifetime Web Lock rejects another tab before the two can share a Rust crypto database.
- Android uses the isolated
id.my.anciety.malink.e2eapplication ID andapp-e2e.apk; acceptance must not overwrite the user's installed data. - Raw Matrix events are durable before projection, and a
/synctoken is saved only after accepted events have been handled. - Thread enumeration and history are fully paginated. A bounded initial sync is not evidence that all sessions or history were restored.
- Repeated Gateway/session updates must converge through
/syncwithout issuing selected-thread relation requests. A cached reload, focus change, foreground transition, and ordinary network recovery must also issue zero recent-history requests. - A deliberately limited
/syncmust persist and close its gap in the background while cached history remains readable; it must not make the WebView wait for a history RPC. - The foreground Android service, not the WebView, owns background sync and notifications.
- Only MLP/3 application data is accepted. Pairing and signed Gateway transport rotation are separate control-plane operations.