--- id: TASK-50 title: Implement nested spaces architecture with permission cascade status: Done assignee: - '@claude' created_date: '2026-02-25 02:27' updated_date: '2026-02-25 02:43' labels: - architecture - spaces - permissions - encryptid dependencies: [] references: - server/community-store.ts - server/spaces.ts - src/encryptid/server.ts - lib/community-sync.ts documentation: - docs/SPACE-ARCHITECTURE.md priority: high --- ## Description Spaces are now nestable — any space can embed references to other spaces via SpaceRef, with a permission cascade model (most-restrictive-wins at each nesting boundary). Every EncryptID registration auto-provisions a sovereign space at <username>.rspace.online with consent-based nesting controls. Core principle: a space is a space is a space. No type field distinguishing personal vs community. The "personal" quality emerges from ownership + permissions, not a schema distinction. ## Acceptance Criteria - [ ] #1 NestPolicy type with consent levels (open/members/approval/closed) - [ ] #2 SpaceRef CRUD endpoints on /api/spaces/:slug/nest - [ ] #3 Permission cascade via intersection (most-restrictive-wins) - [ ] #4 Approval flow for nest requests with admin review - [ ] #5 Source space admins can always revoke nestings (sovereignty guarantee) - [ ] #6 Auto-provision .rspace.online on EncryptID registration - [ ] #7 defaultPermissions ceiling caps requested permissions - [ ] #8 Allowlist/blocklist per space - [ ] #9 Reverse lookup (nested-in) endpoint - [ ] #10 Client-side types for nested space rendering - [ ] #11 TypeScript compiles clean - [ ] #12 Full architecture spec at docs/SPACE-ARCHITECTURE.md ## Implementation Notes Phase 3-5 implemented and pushed to dev: - Phase 3: folk-canvas nested space shape with live WS, auto-scaling, collapsed/expanded views - Phase 4: WS cascade enforcement — nest filter on broadcasts, addShapes/deleteShapes checks - Phase 5: AES-256-GCM at-rest encryption with transparent encrypt/decrypt and API endpoints - All phases type-check clean (npx tsc --noEmit) ## Final Summary ## Phase 1+2 Implementation Complete ### Schema changes (community-store.ts) - New types: NestPermissions, NestNotifications, NestPolicy, SpaceRef, SpaceRefFilter, PendingNestRequest - Default policies: DEFAULT_USER_NEST_POLICY (approval consent) and DEFAULT_COMMUNITY_NEST_POLICY (members consent) - Updated CommunityMeta with enabledModules, description, avatar, nestPolicy, encrypted fields - Updated CommunityDoc with nestedSpaces map - CRUD: addNestedSpace, updateNestedSpace, removeNestedSpace, getNestPolicy, updateNestPolicy, setEnabledModules - Permission logic: capPermissions (ceiling), cascadePermissions (intersection) - Reverse lookup: findNestedIn ### REST API (spaces.ts) - GET/PATCH /:slug/nest-policy - GET/POST /:slug/nest (with full consent flow) - GET/PATCH/DELETE /:slug/nest/:refId - GET /:slug/nested-in - GET/PATCH /:slug/nest-requests (approval flow) ### Auto-provisioning (encryptid/server.ts) - After registration, creates <username>.rspace.online with members_only visibility, user nest policy, default modules ### Remaining phases - Phase 3: folk-canvas shape renderer for SpaceRef entries - Phase 4: Full cascade enforcement on WebSocket writes - Phase 5: Encryption integration