{ "version": "1.0", "timestamp": "2026-04-07T23:54:30.473Z", "phase": "02-prototype", "phase_name": "matrix-direct-agent-prototype", "phase_dir": ".planning/phases/02-prototype", "plan": 1, "task": 4, "total_tasks": 4, "status": "paused", "completed_tasks": [ { "id": 1, "name": "Add Direct Agent Session Transport (sdk/agent_session.py)", "status": "done", "commit": "de20ff6" }, { "id": 2, "name": "Add Local Prototype State (sdk/prototype_state.py)", "status": "done", "commit": "2fad1aa" }, { "id": 3, "name": "Implement RealPlatformClient (sdk/real.py)", "status": "done", "commit": "9784ca6" }, { "id": 4, "name": "Wire Matrix Runtime to Real Backend (adapter/matrix/bot.py)", "status": "done", "commit": "94bdb44" } ], "remaining_tasks": [], "blockers": [ { "description": "Backend/provider errors can still escape as PlatformError and crash the Matrix surface instead of degrading into a user-facing reply.", "type": "technical", "workaround": "Catch PlatformError in the message path or dispatcher boundary and emit a normal OutgoingMessage while logging the root cause." }, { "description": "The required thread_id patch lives only in the local external/platform-agent clone and is not yet upstreamed.", "type": "external", "workaround": "Push or reapply external/platform-agent commit 1dca2c1 in the platform-agent repo before broader handoff." } ], "human_actions_pending": [ { "action": "Push or upstream the local external/platform-agent patch that adds WebSocket thread_id support.", "context": "The Matrix prototype depends on external/platform-agent commit 1dca2c1, but that change is only in the local clone under external/ and is not part of surfaces.git.", "blocking": false }, { "action": "Rotate exposed credentials used during manual testing.", "context": "Matrix password, provider key, and Telegram token were pasted into the session during bring-up and should be considered compromised.", "blocking": false } ], "decisions": [ { "decision": "Keep the prototype in this repo on its own branch rather than creating a separate Matrix spike repo.", "rationale": "This reuses the existing Matrix adapter and tests and keeps the migration path to future surfaces inside the same SDK boundary.", "phase": "02-prototype" }, { "decision": "Use a split backend boundary: AgentSessionClient plus PrototypeStateStore behind RealPlatformClient.", "rationale": "This keeps Matrix logic stable while allowing later replacement of local state with a real control plane.", "phase": "02-prototype" }, { "decision": "Patch only platform-agent for per-chat memory and keep agent_api unchanged.", "rationale": "Reading thread_id from the WebSocket query string minimizes rebase surface and avoids rewriting the message payload contract.", "phase": "02-prototype" }, { "decision": "Use collision-safe serialized thread keys rather than the raw spec example matrix:user:chat format.", "rationale": "Matrix IDs contain colons, so the raw concatenation could collide across distinct user/chat tuples.", "phase": "02-prototype" }, { "decision": "Treat repeat Matrix invites as join-only if the user was already provisioned.", "rationale": "Provisioning is one-time per locally known user; repeat invites should not recreate Space/chat trees but must still join the room.", "phase": "02-prototype" } ], "uncommitted_files": [ ".planning/HANDOFF.json", ".planning/phases/01.1-matrix-restart-reconciliation-and-dev-reset-workflow/.continue-here.md", ".planning/phases/02-prototype/.continue-here.md", "docs/superpowers/plans/2026-04-08-matrix-direct-agent-prototype.md" ], "next_action": "Resume by implementing graceful degradation for backend/provider failures so Matrix surface errors do not crash the process, then decide whether to upstream external/platform-agent commit 1dca2c1 and create a PR from feat/matrix-direct-agent-prototype.", "context_notes": "The direct-agent Matrix prototype is working end-to-end on branch feat/matrix-direct-agent-prototype and was manually validated against a live Matrix homeserver plus a locally running patched external/platform-agent. surfaces.git branch contains transport, local state, RealPlatformClient, runtime wiring, invite fix, and Russian runbook docs. Manual bring-up uncovered three real-world issues that were resolved: homeserver TLS trust on macOS/Python, repeat invites returning before join(), and provider/model auth mismatches. There is still one quality gap: backend errors currently bubble up and can kill the bot process. A local OpenRouter-backed external/platform-agent process was last seen listening on port 8000 (PID 13499) during pause." }