# TS3 Permission ID Mapping to Chanora **TODO-069** — Map TS3 permissions to Chanora's permission system. --- ## 1. TS3 Permission System Overview ### 1.1 Permission Tiers (from YaTQA §1.2) Permissions are evaluated top-to-bottom, lowest tier wins: | Tier | Level | Description | |------|-------|-------------| | 0 | Server Groups | Highest value wins (unless Negate flag) | | 1 | Client (Server level) | Client-specific server permissions | | 2 | Channel | Skipped if Skip flag set | | 3 | Channel Group | Skipped if Skip flag set | | 4 | Client (Channel level) | Client-specific channel permissions | ### 1.2 Permission Types (from Enums.toml) | Type | ID1 | ID2 | |------|-----|-----| | ServerGroup | ServerGroupId | 0 | | GlobalClient | ClientDbId | 0 | | Channel | ChannelId | 0 | | ChannelGroup | ChannelId | ChannelGroupId | | ChannelClient | ChannelId | ClientDbId | ### 1.3 Special Flags - **Skip flag**: Skips channel and channel group permissions - **Negate flag**: If ANY server group has Negate, only Negate groups count - **Grant permission**: `i_needed_permission_modify_power_*` — controls who can modify a permission --- ## 2. Chanora's Current Permission Handling ### 2.1 What Exists | Component | Permission Handling | Location | |-----------|-------------------|----------| | `chanora_bridge::permission_jni` | Android `RECORD_AUDIO` runtime permission only | `crates/chanora_bridge/src/permission_jni.rs` | | `chanora_bridge::api::PermissionStateKind` | Android permission state enum (Granted/Denied/PermanentlyDenied) | `crates/chanora_bridge/src/api.rs` | | `chanora_core` | No TS3 permission model | — | | `chanora_protocol` | Error code `0x0a08` (permissions_client_insufficient) recognized but no permission ID mapping | `crates/chanora_protocol/src/lib.rs:109` | | `chanora_protocol::adapter` | Permission-gated fields (e.g., `client_address` empty when no permission) | `crates/chanora_protocol/src/dto.rs:181` | | `VoiceJoinErrorCode::JoinDenied` | Generic "denied by server policy/permission" | `core/chanora_core/src/events.rs:267` | ### 2.2 What Does NOT Exist - No TS3 permission ID constants - No permission evaluation engine (Skip/Negate/Grant logic) - No per-permission checks before protocol commands - No permission-aware UI gating - No server group / channel group permission tracking --- ## 3. Permission ID Mapping The following table maps all TS3 permission IDs from `Permissions.csv` / ReSpeak reference §3 to Chanora's current handling. ### 3.1 Server Instance Permissions | Permission Name | Category | Chanora Status | Notes | |----------------|----------|----------------|-------| | `b_serverinstance_help_view` | Query | Not needed | ServerQuery only | | `b_serverinstance_version_view` | Query | Not needed | ServerQuery only | | `b_serverinstance_info_view` | Query | Not needed | ServerQuery only | | `b_serverinstance_virtualserver_list` | Query | Not needed | ServerQuery only | | `b_serverinstance_binding_list` | Query | Not needed | ServerQuery only | | `b_serverinstance_permission_list` | Query | Not needed | ServerQuery only | | `b_serverinstance_permission_find` | Query | Not needed | ServerQuery only | | `b_virtualserver_create` | Admin | Not needed | Admin operation | | `b_virtualserver_delete` | Admin | Not needed | Admin operation | | `b_virtualserver_start_any` | Admin | Not needed | Admin operation | | `b_virtualserver_stop_any` | Admin | Not needed | Admin operation | | `b_virtualserver_change_machine_id` | Admin | Not needed | Admin operation | | `b_virtualserver_change_template` | Admin | Not needed | Admin operation | | `b_serverquery_login` | Query | Not needed | ServerQuery only | | `b_serverinstance_textmessage_send` | Query | Not needed | ServerQuery only | | `b_serverinstance_log_view` | Query | Not needed | ServerQuery only | | `b_serverinstance_log_add` | Query | Not needed | ServerQuery only | | `b_serverinstance_stop` | Admin | Not needed | Admin operation | | `b_serverinstance_modify_settings` | Admin | Not needed | Admin operation | | `b_serverinstance_modify_querygroup` | Admin | Not needed | Admin operation | | `b_serverinstance_modify_templates` | Admin | Not needed | Admin operation | ### 3.2 Virtual Server Permissions | Permission Name | Category | Chanora Status | Priority | Notes | |----------------|----------|----------------|----------|-------| | `b_virtualserver_select` | Query | Not needed | — | ServerQuery only | | `b_virtualserver_info_view` | Read | **Implicit** | P3 | Used by `serverinfo` command | | `b_virtualserver_connectioninfo_view` | Read | **Implicit** | P3 | Used by `serverrequestconnectioninfo` | | `b_virtualserver_channel_list` | Read | **Implicit** | P3 | Used by `channellist` command | | `b_virtualserver_channel_search` | Read | Not needed | — | ServerQuery only | | `b_virtualserver_client_list` | Read | **Implicit** | P3 | Used by `clientlist` command | | `b_virtualserver_client_search` | Read | Not needed | — | ServerQuery only | | `b_virtualserver_client_dblist` | Read | Not needed | — | ServerQuery only | | `b_virtualserver_client_dbsearch` | Read | Not needed | — | ServerQuery only | | `b_virtualserver_client_dbinfo` | Read | **Implicit** | P3 | Used by `clientdbinfo` | | `b_virtualserver_permission_find` | Read | Not needed | — | ServerQuery only | | `b_virtualserver_custom_search` | Read | Not needed | — | ServerQuery only | | `b_virtualserver_start` | Admin | Not needed | — | Admin operation | | `b_virtualserver_stop` | Admin | Not needed | — | Admin operation | | `b_virtualserver_token_list` | Admin | Not needed | — | Admin operation | | `b_virtualserver_token_add` | Admin | Not needed | — | Admin operation | | `b_virtualserver_token_use` | Connect | **Implicit** | P2 | Used in `clientinit` default_token | | `b_virtualserver_token_delete` | Admin | Not needed | — | Admin operation | | `b_virtualserver_log_view` | Query | Not needed | — | ServerQuery only | | `b_virtualserver_log_add` | Query | Not needed | — | ServerQuery only | | `b_virtualserver_join_ignore_password` | Connect | Not needed | — | Rare | | `b_virtualserver_notify_register` | Read | **Implicit** | P3 | Used by `servernotifyregister` | | `b_virtualserver_notify_unregister` | Read | **Implicit** | P3 | Used by `servernotifyunregister` | | `b_virtualserver_snapshot_create` | Admin | Not needed | — | Admin operation | | `b_virtualserver_snapshot_deploy` | Admin | Not needed | — | Admin operation | | `b_virtualserver_permission_reset` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_name` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_welcomemessage` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_maxclients` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_reserved_slots` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_password` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_default_servergroup` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_default_channelgroup` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_default_channeladmingroup` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_channel_forced_silence` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_complain` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_antiflood` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_ft_settings` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_ft_quotas` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_hostmessage` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_hostbanner` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_hostbutton` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_port` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_autostart` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_needed_identity_security_level` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_priority_speaker_dimm_modificator` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_log_settings` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_min_client_version` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_icon_id` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_weblist` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_codec_encryption_mode` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_temporary_passwords` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_temporary_passwords_own` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_channel_temp_delete_delay_default` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_nickname` | Admin | Not needed | — | Admin operation | | `b_virtualserver_modify_integrations` | Admin | Not needed | — | Admin operation | ### 3.3 Channel Permissions | Permission Name | Category | Chanora Status | Priority | Notes | |----------------|----------|----------------|----------|-------| | `i_channel_min_depth` | Channel | Not needed | — | Server-side only | | `i_channel_max_depth` | Channel | Not needed | — | Server-side only | | `b_channel_group_inheritance_end` | Channel | Not needed | — | Server-side only | | `i_channel_permission_modify_power` | Admin | Not needed | — | Admin operation | | `i_channel_needed_permission_modify_power` | Admin | Not needed | — | Admin operation | | `b_channel_info_view` | Read | **Implicit** | P3 | Used by `channelinfo` | | `b_channel_create_child` | Channel | Not needed | — | Server-side only | | `b_channel_create_permanent` | Channel | Not needed | — | Server-side only | | `b_channel_create_semi_permanent` | Channel | Not needed | — | Server-side only | | `b_channel_create_temporary` | Channel | Not needed | — | Server-side only | | `b_channel_create_private` | Channel | Not needed | — | Server-side only | | `b_channel_create_with_topic` | Channel | Not needed | — | Server-side only | | `b_channel_create_with_description` | Channel | Not needed | — | Server-side only | | `b_channel_create_with_password` | Channel | Not needed | — | Server-side only | | `b_channel_create_modify_with_codec_speex8` | Channel | Not needed | — | Server-side only | | `b_channel_create_modify_with_codec_speex16` | Channel | Not needed | — | Server-side only | | `b_channel_create_modify_with_codec_speex32` | Channel | Not needed | — | Server-side only | | `b_channel_create_modify_with_codec_celtmono48` | Channel | Not needed | — | Server-side only | | `b_channel_create_modify_with_codec_opusvoice` | Channel | Not needed | — | Server-side only | | `b_channel_create_modify_with_codec_opusmusic` | Channel | Not needed | — | Server-side only | | `i_channel_create_modify_with_codec_maxquality` | Channel | Not needed | — | Server-side only | | `i_channel_create_modify_with_codec_latency_factor_min` | Channel | Not needed | — | Server-side only | | `b_channel_create_with_maxclients` | Channel | Not needed | — | Server-side only | | `b_channel_create_with_maxfamilyclients` | Channel | Not needed | — | Server-side only | | `b_channel_create_with_sortorder` | Channel | Not needed | — | Server-side only | | `b_channel_create_with_default` | Channel | Not needed | — | Server-side only | | `b_channel_create_with_needed_talk_power` | Channel | Not needed | — | Server-side only | | `b_channel_create_modify_with_force_password` | Channel | Not needed | — | Server-side only | | `i_channel_create_modify_with_temp_delete_delay` | Channel | Not needed | — | Server-side only | | `b_channel_modify_parent` | Channel | Not needed | — | Server-side only | | `b_channel_modify_make_default` | Channel | Not needed | — | Server-side only | | `b_channel_modify_make_permanent` | Channel | Not needed | — | Server-side only | | `b_channel_modify_make_semi_permanent` | Channel | Not needed | — | Server-side only | | `b_channel_modify_make_temporary` | Channel | Not needed | — | Server-side only | | `b_channel_modify_name` | Channel | Not needed | — | Server-side only | | `b_channel_modify_topic` | Channel | Not needed | — | Server-side only | | `b_channel_modify_description` | Channel | Not needed | — | Server-side only | | `b_channel_modify_password` | Channel | Not needed | — | Server-side only | | `b_channel_modify_codec` | Channel | Not needed | — | Server-side only | | `b_channel_modify_codec_quality` | Channel | Not needed | — | Server-side only | | `b_channel_modify_codec_latency_factor` | Channel | Not needed | — | Server-side only | | `b_channel_modify_maxclients` | Channel | Not needed | — | Server-side only | | `b_channel_modify_maxfamilyclients` | Channel | Not needed | — | Server-side only | | `b_channel_modify_sortorder` | Channel | Not needed | — | Server-side only | | `b_channel_modify_needed_talk_power` | Channel | Not needed | — | Server-side only | | `i_channel_modify_power` | Channel | Not needed | — | Server-side only | | `i_channel_needed_modify_power` | Channel | Not needed | — | Server-side only | | `b_channel_modify_make_codec_encrypted` | Channel | Not needed | — | Server-side only | | `b_channel_modify_temp_delete_delay` | Channel | Not needed | — | Server-side only | | `b_channel_delete_permanent` | Channel | Not needed | — | Server-side only | | `b_channel_delete_semi_permanent` | Channel | Not needed | — | Server-side only | | `b_channel_delete_temporary` | Channel | Not needed | — | Server-side only | | `b_channel_delete_flag_force` | Channel | Not needed | — | Server-side only | | `i_channel_delete_power` | Channel | Not needed | — | Server-side only | | `i_channel_needed_delete_power` | Channel | Not needed | — | Server-side only | | `b_channel_join_permanent` | **Join** | **Implicit** | **P1** | Used by `clientmove` | | `b_channel_join_semi_permanent` | **Join** | **Implicit** | **P1** | Used by `clientmove` | | `b_channel_join_temporary` | **Join** | **Implicit** | **P1** | Used by `clientmove` | | `b_channel_join_ignore_password` | **Join** | Not needed | P3 | Rare | | `b_channel_join_ignore_maxclients` | **Join** | Not needed | P3 | Rare | | `i_channel_join_power` | **Join** | **Implicit** | **P1** | Server evaluates on join | | `i_channel_needed_join_power` | **Join** | **Implicit** | **P1** | Server evaluates on join | | `i_channel_subscribe_power` | Subscribe | **Implicit** | P2 | Used by `channelsubscribe` | | `i_channel_needed_subscribe_power` | Subscribe | **Implicit** | P2 | Used by `channelsubscribe` | | `i_channel_description_view_power` | Read | Not needed | P3 | Low priority | | `i_channel_needed_description_view_power` | Read | Not needed | P3 | Low priority | ### 3.4 Group Permissions | Permission Name | Category | Chanora Status | Priority | Notes | |----------------|----------|----------------|----------|-------| | `i_icon_id` | Group | Not needed | — | Server-side only | | `i_max_icon_filesize` | Group | Not needed | — | Server-side only | | `b_icon_manage` | Group | Not needed | — | Server-side only | | `b_group_is_permanent` | Group | Not needed | — | Server-side only | | `i_group_auto_update_type` | Group | Not needed | — | Server-side only | | `i_group_auto_update_max_value` | Group | Not needed | — | Server-side only | | `i_group_sort_id` | Group | Not needed | — | Server-side only | | `i_group_show_name_in_tree` | Group | Not needed | — | Server-side only | | `b_virtualserver_servergroup_list` | Group | Not needed | — | ServerQuery only | | `b_virtualserver_servergroup_permission_list` | Group | Not needed | — | ServerQuery only | | `b_virtualserver_servergroup_client_list` | Group | Not needed | — | ServerQuery only | | `b_virtualserver_channelgroup_list` | Group | Not needed | — | ServerQuery only | | `b_virtualserver_channelgroup_permission_list` | Group | Not needed | — | ServerQuery only | | `b_virtualserver_channelgroup_client_list` | Group | Not needed | — | ServerQuery only | | `b_virtualserver_client_permission_list` | Group | Not needed | — | ServerQuery only | | `b_virtualserver_channel_permission_list` | Group | Not needed | — | ServerQuery only | | `b_virtualserver_channelclient_permission_list` | Group | Not needed | — | ServerQuery only | | `b_virtualserver_servergroup_create` | Admin | Not needed | — | Admin operation | | `b_virtualserver_channelgroup_create` | Admin | Not needed | — | Admin operation | | `i_group_modify_power` | Admin | Not needed | — | Admin operation | | `i_group_needed_modify_power` | Admin | Not needed | — | Admin operation | | `i_group_member_add_power` | Admin | Not needed | — | Admin operation | | `i_group_needed_member_add_power` | Admin | Not needed | — | Admin operation | | `i_group_member_remove_power` | Admin | Not needed | — | Admin operation | | `i_group_needed_member_remove_power` | Admin | Not needed | — | Admin operation | | `i_permission_modify_power` | Admin | Not needed | — | Admin operation | | `b_permission_modify_power_ignore` | Admin | Not needed | — | Admin operation | | `b_virtualserver_servergroup_delete` | Admin | Not needed | — | Admin operation | | `b_virtualserver_channelgroup_delete` | Admin | Not needed | — | Admin operation | ### 3.5 Client Permissions | Permission Name | Category | Chanora Status | Priority | Notes | |----------------|----------|----------------|----------|-------| | `i_client_permission_modify_power` | Admin | Not needed | — | Admin operation | | `i_client_needed_permission_modify_power` | Admin | Not needed | — | Admin operation | | `i_client_max_clones_uid` | Connect | Not needed | — | Server-side only | | `i_client_max_idletime` | Client | Not needed | P3 | Could display idle timeout | | `i_client_max_avatar_filesize` | Client | Not needed | P3 | Could limit avatar upload | | `i_client_max_channel_subscriptions` | Client | Not needed | P3 | Could limit subscriptions | | `b_client_is_priority_speaker` | **Voice** | **Implicit** | **P1** | Tracked in `Client.is_priority_speaker` | | `b_client_skip_channelgroup_permissions` | Client | Not needed | — | Server-side only | | `b_client_force_push_to_talk` | **Voice** | Not needed | P2 | Could force PTT mode | | `b_client_ignore_bans` | Client | Not needed | — | Server-side only | | `b_client_ignore_antiflood` | Client | Not needed | — | Server-side only | | `b_client_issue_client_query_command` | Query | Not needed | — | ServerQuery only | | `b_client_use_reserved_slot` | Connect | Not needed | P3 | Could show slot availability | | `b_client_use_channel_commander` | **Voice** | Not needed | P2 | Channel commander feature | | `b_client_request_talker` | **Voice** | **Implicit** | **P1** | `client_talk_request` in events | | `b_client_avatar_delete_other` | Client | Not needed | — | Server-side only | | `b_client_is_sticky` | Client | Not needed | P3 | Could show sticky indicator | | `b_client_ignore_sticky` | Client | Not needed | P3 | Could show sticky indicator | | `b_client_info_view` | **Read** | **Implicit** | **P1** | Used by `clientinfo` | | `b_client_permissionoverview_view` | Read | Not needed | — | ServerQuery only | | `b_client_permissionoverview_own` | Read | Not needed | — | ServerQuery only | | `b_client_remoteaddress_view` | **Read** | **Implicit** | **P2** | Gated in `BridgeClientProfile.client_address` | | `i_client_serverquery_view_power` | Read | Not needed | P3 | Could gate query client visibility | | `i_client_needed_serverquery_view_power` | Read | Not needed | P3 | Could gate query client visibility | | `b_client_custom_info_view` | Read | Not needed | P3 | Custom fields | | `i_client_kick_from_server_power` | **Moderation** | Not needed | **P1** | Future: kick UI | | `i_client_needed_kick_from_server_power` | **Moderation** | Not needed | **P1** | Future: kick UI | | `i_client_kick_from_channel_power` | **Moderation** | Not needed | **P1** | Future: kick UI | | `i_client_needed_kick_from_channel_power` | **Moderation** | Not needed | **P1** | Future: kick UI | | `i_client_ban_power` | **Moderation** | Not needed | **P1** | Future: ban UI | | `i_client_needed_ban_power` | **Moderation** | Not needed | **P1** | Future: ban UI | | `i_client_move_power` | **Moderation** | Not needed | **P1** | Future: move UI | | `i_client_needed_move_power` | **Moderation** | Not needed | **P1** | Future: move UI | | `i_client_complain_power` | Moderation | Not needed | P2 | Future: complain UI | | `i_client_needed_complain_power` | Moderation | Not needed | P2 | Future: complain UI | | `b_client_complain_list` | Moderation | Not needed | P2 | Future: complain UI | | `b_client_complain_delete_own` | Moderation | Not needed | P2 | Future: complain UI | | `b_client_complain_delete` | Moderation | Not needed | P2 | Future: complain UI | | `b_client_ban_list` | Moderation | Not needed | P2 | Future: ban UI | | `b_client_ban_create` | Moderation | Not needed | P2 | Future: ban UI | | `b_client_ban_delete_own` | Moderation | Not needed | P2 | Future: ban UI | | `b_client_ban_delete` | Moderation | Not needed | P2 | Future: ban UI | | `i_client_ban_max_bantime` | Moderation | Not needed | P2 | Future: ban UI | | `i_client_private_textmessage_power` | **Chat** | Not needed | **P1** | Could gate DM UI | | `i_client_needed_private_textmessage_power` | **Chat** | Not needed | **P1** | Could gate DM UI | | `b_client_server_textmessage_send` | **Chat** | Not needed | **P1** | Could gate server chat | | `b_client_channel_textmessage_send` | **Chat** | Not needed | **P1** | Could gate channel chat | | `b_client_offline_textmessage_send` | Chat | Not needed | P2 | Offline messages | | `i_client_talk_power` | **Voice** | **Implicit** | **P1** | Tracked in `Client.talk_power` | | `i_client_needed_talk_power` | **Voice** | **Implicit** | **P1** | Compared against channel `needed_talk_power` | | `i_client_poke_power` | Chat | Not needed | P2 | Could gate poke UI | | `i_client_needed_poke_power` | Chat | Not needed | P2 | Could gate poke UI | | `b_client_set_flag_talker` | **Voice** | Not needed | **P1** | Future: grant talk power | | `i_client_whisper_power` | **Voice** | Not needed | P2 | Whisper feature | | `i_client_needed_whisper_power` | **Voice** | Not needed | P2 | Whisper feature | | `b_client_modify_description` | Client | Not needed | P2 | Future: edit description | | `b_client_modify_own_description` | Client | Not needed | P2 | Future: edit own description | | `b_client_modify_dbproperties` | Client | Not needed | — | Server-side only | | `b_client_delete_dbproperties` | Client | Not needed | — | Server-side only | | `b_client_create_modify_serverquery_login` | Query | Not needed | — | ServerQuery only | ### 3.6 File Transfer Permissions | Permission Name | Category | Chanora Status | Priority | Notes | |----------------|----------|----------------|----------|-------| | `b_ft_ignore_password` | File | Not needed | P3 | File browser | | `b_ft_transfer_list` | File | Not needed | P3 | File browser | | `i_ft_file_upload_power` | File | Not needed | P3 | File browser | | `i_ft_needed_file_upload_power` | File | Not needed | P3 | File browser | | `i_ft_file_download_power` | File | Not needed | P3 | File browser | | `i_ft_needed_file_download_power` | File | Not needed | P3 | File browser | | `i_ft_file_delete_power` | File | Not needed | P3 | File browser | | `i_ft_needed_file_delete_power` | File | Not needed | P3 | File browser | | `i_ft_file_rename_power` | File | Not needed | P3 | File browser | | `i_ft_needed_file_rename_power` | File | Not needed | P3 | File browser | | `i_ft_file_browse_power` | File | Not needed | P3 | File browser | | `i_ft_needed_file_browse_power` | File | Not needed | P3 | File browser | | `i_ft_directory_create_power` | File | Not needed | P3 | File browser | | `i_ft_needed_directory_create_power` | File | Not needed | P3 | File browser | | `i_ft_quota_mb_download_per_client` | File | Not needed | P3 | File browser | | `i_ft_quota_mb_upload_per_client` | File | Not needed | P3 | File browser | --- ## 4. Summary: Permissions Chanora Should Track ### 4.1 Already Handled (Implicit via Protocol) These permissions are evaluated server-side; Chanora sends commands and handles rejection: | Permission | How Handled | |-----------|-------------| | `b_channel_join_*` | `voice_join` → server rejects with error code | | `i_channel_join_power` / `i_channel_needed_join_power` | Server evaluates; Chanora gets `JoinDenied` | | `b_client_info_view` | `clientinfo` command; server returns error if denied | | `b_client_remoteaddress_view` | `client_address` field gated in `BridgeClientProfile` | | `i_client_talk_power` / `i_client_needed_talk_power` | Tracked in `Client.talk_power`; server enforces | | `b_client_is_priority_speaker` | Tracked in client state | | `b_client_request_talker` | Tracked via `client_talk_request` events | ### 4.2 Missing — Should Add (P1) | Permission | Reason | Implementation | |-----------|--------|----------------| | `i_client_kick_from_server_power` / `i_client_kick_from_channel_power` | Future kick UI needs to know if user can kick | Add to `BridgeClientProfile` or `PermissionHints` | | `i_client_ban_power` | Future ban UI | Add to permission hints | | `i_client_move_power` | Future move UI | Add to permission hints | | `i_client_private_textmessage_power` | Gate DM input in UI | Add to permission hints | | `b_client_server_textmessage_send` | Gate server chat input | Add to permission hints | | `b_client_channel_textmessage_send` | Gate channel chat input | Add to permission hints | | `b_client_set_flag_talker` | Future "grant talk power" button | Add to permission hints | ### 4.3 Missing — Nice to Have (P2-P3) | Permission | Reason | |-----------|--------| | `b_client_force_push_to_talk` | Could force PTT mode in UI | | `b_client_use_channel_commander` | Channel commander feature | | `i_client_whisper_power` | Whisper feature | | `b_client_complain_*` | Complain UI | | `b_client_ban_*` | Ban management UI | | `i_ft_*` | File transfer browser permissions | --- ## 5. Recommended Implementation ### 5.1 Permission Constants Module Generate from `Permissions.csv`: ```rust // crates/chanora_protocol/src/permissions.rs // Auto-generated from ReSpeak/tsdeclarations Permissions.csv pub const B_CHANNEL_JOIN_PERMANENT: &str = "b_channel_join_permanent"; pub const B_CHANNEL_JOIN_SEMI_PERMANENT: &str = "b_channel_join_semi_permanent"; pub const B_CHANNEL_JOIN_TEMPORARY: &str = "b_channel_join_temporary"; pub const I_CHANNEL_JOIN_POWER: &str = "i_channel_join_power"; pub const I_CHANNEL_NEEDED_JOIN_POWER: &str = "i_channel_needed_join_power"; // ... all 253 permissions ``` ### 5.2 Permission Hints Integration Extend the existing `PermissionHints` bitflags (already in `Enums.toml` / ReSpeak §6) to cover the P1 permissions. The server already sends `PermissionHints` in `clientinfo` responses — Chanora just needs to parse and expose them. ### 5.3 UI Gating Add permission-aware UI state to `BridgeEvent` or `BridgeClientProfile`: ```rust pub struct BridgePermissionHints { pub can_kick_server: bool, pub can_kick_channel: bool, pub can_ban: bool, pub can_move: bool, pub can_send_private_message: bool, pub can_send_server_message: bool, pub can_send_channel_message: bool, pub can_grant_talk_power: bool, } ``` --- *Created: 2026-06-11 for TODO-069*