Extract event type string literals as constants in space_roles.rs and
replace all occurrences across service and admin code. Add a forward
index (space_to_rooms) for O(1) child room lookups instead of scanning
the reverse index. Introduce resolve_space! macro to deduplicate the
repeated enabled-check + alias-resolve + space-type-guard pattern in
all 9 admin command handlers. Flatten deeply nested if-let chains in
append.rs using let-chains syntax.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove redundant StdHashSet import alias in cache_tests.rs
- Add type alias SpaceEnforcementData for readability in build.rs
- Fix formatting of for-loop closing brace in PL check
- Move BTreeMap and RoleDefinition imports to file-level in build.rs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Critical fixes:
- handle_space_child_change now reads the actual m.space.child state event
and checks if via is empty; removes child from index on removal instead
of unconditionally adding
- Server user is exempted from PL rejection guard so sync_power_levels
can function without being blocked by its own protection
- PL rejection now also checks that space-managed users aren't omitted
from proposed power level events
Important fixes:
- room_to_space changed from 1:1 to 1:many (HashMap<RoomId, HashSet<RoomId>>)
so a room can belong to multiple parent spaces; get_parent_space renamed
to get_parent_spaces; join gating checks all parents (qualify in any)
- All custom event types renamed from m.space.* to com.continuwuity.space.*
to avoid squatting on the Matrix namespace
- Cache cleanup on child removal from space
- Added tokio Semaphore (capacity 4) to limit concurrent enforcement tasks
- Server user membership checked before enforcement in auto_join, kick,
and sync_power_levels to avoid noisy errors
Suggestions:
- Replaced expect() calls with proper error propagation via map_err/?
- Fixed indentation in timeline/mod.rs line 116
- handle_space_child_change now directly joins users to the specific new
child room instead of scanning all children via auto_join_qualifying_rooms
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Gate memory_usage() and clear_cache() with is_enabled()
- Gate populate_space() and get_parent_space() as defense-in-depth
- All admin commands now refuse when feature is disabled with
a clear message pointing to the config option
- Prefix memory labels with space_ for disambiguation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add spawn_enforcement methods (handle_state_event_change,
handle_space_child_change, handle_space_member_join) that run
enforcement as background tasks to avoid recursive Send issues
- Expand append_pdu hook to trigger enforcement on role events,
space child changes, and space member joins
- Fix deadlock risk in get_user_power_level and user_qualifies_for_room
by dropping read guards before acquiring new ones
- Batch room_to_space writes in populate_space with a single write lock
- Add space type validation to all admin commands
- Fix PL rejection check to reject any change (!=) not just lowering (<)
- Fix sync_power_levels to also lower PLs for users who lost their roles
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Checks proposed m.room.power_levels events against Space-granted power
levels. Rejects if any user's proposed PL is below their Space role PL.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add ensure_default_roles() to check if a Space has m.space.roles state
event and create default admin/mod roles if missing. Add worker() to
rebuild the space roles cache on startup by iterating all rooms and
populating cache for spaces.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updates the space roles cache when m.space.roles, m.space.role.member,
or m.space.role.room state events are appended. Adds roles service as
a dependency of the timeline service.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- sync_power_levels(): Overrides child room PLs with Space role PLs
- auto_join_qualifying_rooms(): Joins user to all rooms they qualify for
- kick_unqualified_from_rooms(): Kicks user from rooms they no longer qualify for
- Adds globals dep for server_user access
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Checks if user has required Space roles before allowing join to a
child room. Runs after antispam checks, before the actual join path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds is_enabled(), populate_space(), get_user_power_level(),
user_qualifies_for_room(), and get_parent_space() methods.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Create rooms::roles::Service with in-memory caches for role definitions,
user-role assignments, room requirements, and room-to-space mappings.
Register the service in the service stack alongside other room services.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Define serde content types for m.space.roles, m.space.role.member,
and m.space.role.room custom state events used by space permission
cascading.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Only the server user can now remove the #admins alias, matching the
existing check for setting the alias. This prevents users from
accidentally breaking the admin room functionality.
fixes#1408
- Disabled first-run mode when running Complement tests
- Updated logging config under complement to be a bit less verbose
- Changed test result and log output locations
Add dedicated \`GET /_matrix/client/v1/rtc/transports\` and \`GET /_matrix/client/unstable/org.matrix.msc4143/rtc/transports\` endpoints for MatrixRTC focus discovery (MSC4143), replacing the deprecated well-known approach.
Move RTC foci configuration from \`[global.well_known]\` into a new \`[global.matrix_rtc]\` config section with a \`foci\` field. Remove \`rtc_foci\` from the \`.well-known/matrix/client\` response. Update LiveKit setup documentation accordingly.
Closes#1431