--- phase: 01-matrix-qa-polish plan: 01 subsystem: matrix tags: [matrix, matrix-nio, spaces, sqlite] requires: - phase: 00-foundation provides: Matrix adapter baseline with room metadata helpers provides: - Matrix pending-confirm store helpers keyed by room id - Space-first invite flow with user space metadata and dynamic chat ids - Space-aware room routing fallback for unregistered rooms affects: [matrix invite flow, matrix chat creation, matrix confirmation flow] tech-stack: added: [] patterns: [space-first Matrix onboarding, room metadata without implicit auto-registration] key-files: created: [] modified: - adapter/matrix/store.py - adapter/matrix/handlers/auth.py - adapter/matrix/room_router.py key-decisions: - "Invite idempotency now keys off user_meta.space_id instead of invite-room metadata." - "Unknown Matrix rooms return an explicit unregistered chat id instead of silently creating room metadata." patterns-established: - "Matrix Space bootstrap creates a private Space, first chat room, and m.space.child link before welcoming the user." - "Per-room pending confirmation state is stored under a dedicated store prefix." requirements-completed: [] duration: 1 min completed: 2026-04-02 --- # Phase 01 Plan 01: Space+rooms infrastructure Summary **Matrix Space-first onboarding now creates a private Space, seeds the first chat room, and stores pending confirmations by room id.** ## Performance - **Duration:** 1 min - **Started:** 2026-04-02T19:49:25Z - **Completed:** 2026-04-02T19:50:50Z - **Tasks:** 3 - **Files modified:** 3 ## Accomplishments - Added `pending_confirm` storage helpers without changing existing Matrix store behavior. - Replaced the DM-first invite flow with Space creation, first-room linking, user invites, and dynamic `C*` chat ids. - Stopped `resolve_chat_id` from auto-registering unknown rooms and made the fallback explicit in logs and returned ids. ## Task Commits Each task was committed atomically: 1. **Task 1: Add pending_confirm helpers to store.py** - `9123401` (feat) 2. **Task 2: Rewrite handle_invite for Space+rooms** - `c2e29cc` (feat) 3. **Task 3: Update room_router.py for space-aware resolve** - `c8770da` (fix) ## Files Created/Modified - `adapter/matrix/store.py` - Adds `PENDING_CONFIRM_PREFIX` plus get/set/clear helpers for confirmation state. - `adapter/matrix/handlers/auth.py` - Rewrites invite handling to create a Space and first chat room, invite the user, and persist `space_id`. - `adapter/matrix/room_router.py` - Resolves known chat ids from stored metadata only and warns on unregistered rooms. ## Decisions Made - Used `user_meta.space_id` as the idempotency gate so repeated invites do not depend on whichever DM room triggered the event. - Preserved the initial DM `join` before Space creation so the bot still accepts the invite room and keeps nio tracking consistent. - Returned `unregistered:{room_id}` for unknown rooms instead of mutating store state from the router. ## Deviations from Plan ### Auto-fixed Issues **1. [Rule 3 - Blocking] Updated planning state artifacts manually** - **Found during:** Post-task metadata updates - **Issue:** `gsd-tools state advance-plan` could not parse the repository's existing `STATE.md` schema, which blocked the required state update flow. - **Fix:** Updated `STATE.md` and `ROADMAP.md` manually to reflect plan completion while preserving existing content. - **Files modified:** `.planning/STATE.md`, `.planning/ROADMAP.md` - **Verification:** Re-read both files after editing to confirm plan progress and decisions were recorded correctly. - **Committed in:** metadata commit --- **Total deviations:** 1 auto-fixed (1 blocking) **Impact on plan:** No product scope change. The deviation only affected GSD metadata bookkeeping. ## Issues Encountered - `gsd-tools state advance-plan` failed because the current `STATE.md` format does not include the fields the tool expects. Metadata was updated manually so execution could complete cleanly. ## User Setup Required None - no external service configuration required. ## Next Phase Readiness - Ready for `01-02-PLAN.md`, which can now rely on `space_id` in `user_meta` and non-mutating room resolution. - No blockers introduced by this plan. ## Self-Check: PASSED - Found `.planning/phases/01-matrix-qa-polish/01-01-SUMMARY.md` on disk. - Verified task commits `9123401`, `c2e29cc`, and `c8770da` in `git log`.