---
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

<!-- SECTION:DESCRIPTION:BEGIN -->
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 &lt;username&gt;.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.
<!-- SECTION:DESCRIPTION:END -->

## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #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 <username>.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
<!-- AC:END -->

## Implementation Notes

<!-- SECTION:NOTES:BEGIN -->
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)
<!-- SECTION:NOTES:END -->

## Final Summary

<!-- SECTION:FINAL_SUMMARY:BEGIN -->
## 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 &lt;username&gt;.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
<!-- SECTION:FINAL_SUMMARY:END -->
