diff --git a/keyserver/src/bots/commbot.js b/keyserver/src/bots/commbot.js
--- a/keyserver/src/bots/commbot.js
+++ b/keyserver/src/bots/commbot.js
@@ -3,7 +3,7 @@
 import invariant from 'invariant';
 
 import bots from 'lib/facts/bots.js';
-import { threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 
 import { createThread } from '../creators/thread-creator.js';
 import { createBotViewer } from '../session/bots.js';
diff --git a/keyserver/src/creators/account-creator.js b/keyserver/src/creators/account-creator.js
--- a/keyserver/src/creators/account-creator.js
+++ b/keyserver/src/creators/account-creator.js
@@ -24,7 +24,7 @@
 import type { CalendarQuery } from 'lib/types/entry-types.js';
 import { messageTypes } from 'lib/types/message-types-enum.js';
 import type { SIWESocialProof } from 'lib/types/siwe-types.js';
-import { threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 import { ServerError } from 'lib/utils/errors.js';
 import { values } from 'lib/utils/objects.js';
 import { reservedUsernamesSet } from 'lib/utils/reserved-users.js';
diff --git a/keyserver/src/creators/entry-creator.js b/keyserver/src/creators/entry-creator.js
--- a/keyserver/src/creators/entry-creator.js
+++ b/keyserver/src/creators/entry-creator.js
@@ -7,7 +7,7 @@
   SaveEntryResponse,
 } from 'lib/types/entry-types.js';
 import { messageTypes } from 'lib/types/message-types-enum.js';
-import { threadPermissions } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import { dateFromString } from 'lib/utils/date-utils.js';
 import { ServerError } from 'lib/utils/errors.js';
 import { values } from 'lib/utils/objects.js';
diff --git a/keyserver/src/creators/message-creator.js b/keyserver/src/creators/message-creator.js
--- a/keyserver/src/creators/message-creator.js
+++ b/keyserver/src/creators/message-creator.js
@@ -19,7 +19,7 @@
   type RawMessageInfo,
 } from 'lib/types/message-types.js';
 import { redisMessageTypes } from 'lib/types/redis-types.js';
-import { threadPermissions } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import { updateTypes } from 'lib/types/update-types.js';
 import { promiseAll } from 'lib/utils/promises.js';
 
diff --git a/keyserver/src/creators/role-creator.js b/keyserver/src/creators/role-creator.js
--- a/keyserver/src/creators/role-creator.js
+++ b/keyserver/src/creators/role-creator.js
@@ -1,7 +1,8 @@
 // @flow
 
 import { getRolePermissionBlobs } from 'lib/permissions/thread-permissions.js';
-import type { RoleInfo, ThreadType } from 'lib/types/thread-types.js';
+import type { ThreadType } from 'lib/types/thread-types-enum.js';
+import type { RoleInfo } from 'lib/types/thread-types.js';
 
 import createIDs from './id-creator.js';
 import { dbQuery, SQL } from '../database/database.js';
diff --git a/keyserver/src/creators/thread-creator.js b/keyserver/src/creators/thread-creator.js
--- a/keyserver/src/creators/thread-creator.js
+++ b/keyserver/src/creators/thread-creator.js
@@ -13,12 +13,14 @@
 import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
 import type { Shape } from 'lib/types/core.js';
 import { messageTypes } from 'lib/types/message-types-enum.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import {
-  type ServerNewThreadRequest,
-  type NewThreadResponse,
   threadTypes,
-  threadPermissions,
   threadTypeIsCommunityRoot,
+} from 'lib/types/thread-types-enum.js';
+import {
+  type ServerNewThreadRequest,
+  type NewThreadResponse,
 } from 'lib/types/thread-types.js';
 import type { UserInfos } from 'lib/types/user-types.js';
 import { pushAll } from 'lib/utils/array.js';
diff --git a/keyserver/src/cron/daily-updates.js b/keyserver/src/cron/daily-updates.js
--- a/keyserver/src/cron/daily-updates.js
+++ b/keyserver/src/cron/daily-updates.js
@@ -4,7 +4,7 @@
 
 import ashoat from 'lib/facts/ashoat.js';
 import { messageTypes } from 'lib/types/message-types-enum.js';
-import { threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 import {
   getDate,
   dateString,
diff --git a/keyserver/src/database/setup-db.js b/keyserver/src/database/setup-db.js
--- a/keyserver/src/database/setup-db.js
+++ b/keyserver/src/database/setup-db.js
@@ -6,7 +6,7 @@
 import { usernameMaxLength } from 'lib/shared/account-utils.js';
 import { sortIDs } from 'lib/shared/relationship-utils.js';
 import { undirectedStatus } from 'lib/types/relationship-types.js';
-import { threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 
 import { createThread } from '../creators/thread-creator.js';
 import { dbQuery, SQL } from '../database/database.js';
diff --git a/keyserver/src/deleters/entry-deleters.js b/keyserver/src/deleters/entry-deleters.js
--- a/keyserver/src/deleters/entry-deleters.js
+++ b/keyserver/src/deleters/entry-deleters.js
@@ -7,7 +7,7 @@
   RestoreEntryResponse,
 } from 'lib/types/entry-types.js';
 import { messageTypes } from 'lib/types/message-types-enum.js';
-import { threadPermissions } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import { dateString } from 'lib/utils/date-utils.js';
 import { ServerError } from 'lib/utils/errors.js';
 import { values } from 'lib/utils/objects.js';
diff --git a/keyserver/src/deleters/thread-deleters.js b/keyserver/src/deleters/thread-deleters.js
--- a/keyserver/src/deleters/thread-deleters.js
+++ b/keyserver/src/deleters/thread-deleters.js
@@ -2,10 +2,10 @@
 
 import { permissionLookup } from 'lib/permissions/thread-permissions.js';
 import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import {
   type ThreadDeletionRequest,
   type LeaveThreadResult,
-  threadPermissions,
 } from 'lib/types/thread-types.js';
 import { updateTypes } from 'lib/types/update-types.js';
 import { ServerError } from 'lib/utils/errors.js';
diff --git a/keyserver/src/fetchers/entry-fetchers.js b/keyserver/src/fetchers/entry-fetchers.js
--- a/keyserver/src/fetchers/entry-fetchers.js
+++ b/keyserver/src/fetchers/entry-fetchers.js
@@ -17,10 +17,8 @@
 } from 'lib/types/entry-types.js';
 import { calendarThreadFilterTypes } from 'lib/types/filter-types.js';
 import type { HistoryRevisionInfo } from 'lib/types/history-types.js';
-import {
-  threadPermissions,
-  type ThreadPermission,
-} from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
+import type { ThreadPermission } from 'lib/types/thread-permission-types.js';
 import { dateString } from 'lib/utils/date-utils.js';
 import { ServerError } from 'lib/utils/errors.js';
 
diff --git a/keyserver/src/fetchers/message-fetchers.js b/keyserver/src/fetchers/message-fetchers.js
--- a/keyserver/src/fetchers/message-fetchers.js
+++ b/keyserver/src/fetchers/message-fetchers.js
@@ -28,7 +28,7 @@
   type FetchPinnedMessagesResult,
   isMessageSidebarSourceReactionOrEdit,
 } from 'lib/types/message-types.js';
-import { threadPermissions } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import { ServerError } from 'lib/utils/errors.js';
 
 import {
diff --git a/keyserver/src/fetchers/thread-fetchers.js b/keyserver/src/fetchers/thread-fetchers.js
--- a/keyserver/src/fetchers/thread-fetchers.js
+++ b/keyserver/src/fetchers/thread-fetchers.js
@@ -11,9 +11,8 @@
 import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
 import type { AvatarDBContent, ClientAvatar } from 'lib/types/avatar-types.js';
 import type { RawMessageInfo, MessageInfo } from 'lib/types/message-types.js';
+import { threadTypes, type ThreadType } from 'lib/types/thread-types-enum.js';
 import {
-  threadTypes,
-  type ThreadType,
   type RawThreadInfo,
   type ServerThreadInfo,
 } from 'lib/types/thread-types.js';
diff --git a/keyserver/src/fetchers/thread-permission-fetchers.js b/keyserver/src/fetchers/thread-permission-fetchers.js
--- a/keyserver/src/fetchers/thread-permission-fetchers.js
+++ b/keyserver/src/fetchers/thread-permission-fetchers.js
@@ -12,11 +12,11 @@
 } from 'lib/shared/thread-utils.js';
 import { userRelationshipStatus } from 'lib/types/relationship-types.js';
 import type {
-  ThreadType,
   ThreadPermission,
   ThreadPermissionsBlob,
   ThreadRolePermissionsBlob,
-} from 'lib/types/thread-types.js';
+} from 'lib/types/thread-permission-types.js';
+import type { ThreadType } from 'lib/types/thread-types-enum.js';
 
 import { fetchThreadInfos } from './thread-fetchers.js';
 import { fetchKnownUserInfos } from './user-fetchers.js';
diff --git a/keyserver/src/fetchers/upload-fetchers.js b/keyserver/src/fetchers/upload-fetchers.js
--- a/keyserver/src/fetchers/upload-fetchers.js
+++ b/keyserver/src/fetchers/upload-fetchers.js
@@ -7,7 +7,7 @@
 import { messageTypes } from 'lib/types/message-types-enum.js';
 import type { MediaMessageServerDBContent } from 'lib/types/messages/media.js';
 import { getUploadIDsFromMediaMessageServerDBContents } from 'lib/types/messages/media.js';
-import { threadPermissions } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import type {
   ThreadFetchMediaResult,
   ThreadFetchMediaRequest,
diff --git a/keyserver/src/fetchers/user-fetchers.js b/keyserver/src/fetchers/user-fetchers.js
--- a/keyserver/src/fetchers/user-fetchers.js
+++ b/keyserver/src/fetchers/user-fetchers.js
@@ -9,10 +9,8 @@
   directedStatus,
   userRelationshipStatus,
 } from 'lib/types/relationship-types.js';
-import {
-  communityThreadTypes,
-  threadPermissions,
-} from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
+import { communityThreadTypes } from 'lib/types/thread-types-enum.js';
 import type {
   UserInfos,
   CurrentUserInfo,
diff --git a/keyserver/src/push/rescind.js b/keyserver/src/push/rescind.js
--- a/keyserver/src/push/rescind.js
+++ b/keyserver/src/push/rescind.js
@@ -4,7 +4,7 @@
 import invariant from 'invariant';
 
 import { threadSubscriptions } from 'lib/types/subscription-types.js';
-import { threadPermissions } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import { promiseAll } from 'lib/utils/promises.js';
 
 import { getAPNsNotificationTopic } from './providers.js';
diff --git a/keyserver/src/push/utils.js b/keyserver/src/push/utils.js
--- a/keyserver/src/push/utils.js
+++ b/keyserver/src/push/utils.js
@@ -14,7 +14,7 @@
   WNSNotification,
 } from 'lib/types/notif-types.js';
 import { threadSubscriptions } from 'lib/types/subscription-types.js';
-import { threadPermissions } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 
 import {
   getAPNPushProfileForCodeVersion,
diff --git a/keyserver/src/responders/message-responders.js b/keyserver/src/responders/message-responders.js
--- a/keyserver/src/responders/message-responders.js
+++ b/keyserver/src/responders/message-responders.js
@@ -29,7 +29,7 @@
 import type { EditMessageData } from 'lib/types/messages/edit.js';
 import type { ReactionMessageData } from 'lib/types/messages/reaction.js';
 import type { TextMessageData } from 'lib/types/messages/text.js';
-import { threadPermissions } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import { userInfosValidator } from 'lib/types/user-types.js';
 import { ServerError } from 'lib/utils/errors.js';
 import { values } from 'lib/utils/objects.js';
diff --git a/keyserver/src/responders/thread-responders.js b/keyserver/src/responders/thread-responders.js
--- a/keyserver/src/responders/thread-responders.js
+++ b/keyserver/src/responders/thread-responders.js
@@ -9,6 +9,7 @@
   rawMessageInfoValidator,
   messageTruncationStatusesValidator,
 } from 'lib/types/message-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 import {
   type ThreadDeletionRequest,
   type RoleChangeRequest,
@@ -25,7 +26,6 @@
   type ThreadFetchMediaRequest,
   type ToggleMessagePinRequest,
   type ToggleMessagePinResult,
-  threadTypes,
   rawThreadInfoValidator,
 } from 'lib/types/thread-types.js';
 import { serverUpdateInfoValidator } from 'lib/types/update-types.js';
diff --git a/keyserver/src/responders/thread-responders.test.js b/keyserver/src/responders/thread-responders.test.js
--- a/keyserver/src/responders/thread-responders.test.js
+++ b/keyserver/src/responders/thread-responders.test.js
@@ -1,6 +1,6 @@
 // @flow
 
-import { threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 
 import { newThreadRequestInputValidator } from './thread-responders.js';
 
diff --git a/keyserver/src/responders/website-responders.js b/keyserver/src/responders/website-responders.js
--- a/keyserver/src/responders/website-responders.js
+++ b/keyserver/src/responders/website-responders.js
@@ -27,7 +27,8 @@
 import { defaultNumberPerThread } from 'lib/types/message-types.js';
 import { defaultEnabledReports } from 'lib/types/report-types.js';
 import { defaultConnectionInfo } from 'lib/types/socket-types.js';
-import { threadPermissions, threadTypes } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 import { currentDateInTimeZone } from 'lib/utils/date-utils.js';
 import { ServerError } from 'lib/utils/errors.js';
 import { promiseAll } from 'lib/utils/promises.js';
diff --git a/keyserver/src/scripts/add-edit-thread-detailed-permissions.js b/keyserver/src/scripts/add-edit-thread-detailed-permissions.js
--- a/keyserver/src/scripts/add-edit-thread-detailed-permissions.js
+++ b/keyserver/src/scripts/add-edit-thread-detailed-permissions.js
@@ -1,7 +1,7 @@
 // @flow
 
 import bots from 'lib/facts/bots.js';
-import { assertThreadType } from 'lib/types/thread-types.js';
+import { assertThreadType } from 'lib/types/thread-types-enum.js';
 
 import { main } from './utils.js';
 import { dbQuery, SQL } from '../database/database.js';
diff --git a/keyserver/src/scripts/add-leave-thread-permissions.js b/keyserver/src/scripts/add-leave-thread-permissions.js
--- a/keyserver/src/scripts/add-leave-thread-permissions.js
+++ b/keyserver/src/scripts/add-leave-thread-permissions.js
@@ -1,6 +1,7 @@
 // @flow
 
-import { threadPermissions, threadTypes } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 
 import { endScript } from './utils.js';
 import { dbQuery, SQL } from '../database/database.js';
diff --git a/keyserver/src/scripts/create-community.js b/keyserver/src/scripts/create-community.js
--- a/keyserver/src/scripts/create-community.js
+++ b/keyserver/src/scripts/create-community.js
@@ -1,7 +1,7 @@
 // @flow
 
 import ashoat from 'lib/facts/ashoat.js';
-import { threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 
 import { main } from './utils.js';
 import { createThread } from '../creators/thread-creator.js';
diff --git a/keyserver/src/scripts/create-sidebar-permissions.js b/keyserver/src/scripts/create-sidebar-permissions.js
--- a/keyserver/src/scripts/create-sidebar-permissions.js
+++ b/keyserver/src/scripts/create-sidebar-permissions.js
@@ -1,9 +1,9 @@
 // @flow
 
 import {
-  threadPermissions,
   threadPermissionPropagationPrefixes,
-} from 'lib/types/thread-types.js';
+  threadPermissions,
+} from 'lib/types/thread-permission-types.js';
 
 import { endScript } from './utils.js';
 import { dbQuery, SQL } from '../database/database.js';
diff --git a/keyserver/src/scripts/fix-new-thread-types.js b/keyserver/src/scripts/fix-new-thread-types.js
--- a/keyserver/src/scripts/fix-new-thread-types.js
+++ b/keyserver/src/scripts/fix-new-thread-types.js
@@ -1,7 +1,7 @@
 // @flow
 
 import bots from 'lib/facts/bots.js';
-import { threadTypes, assertThreadType } from 'lib/types/thread-types.js';
+import { threadTypes, assertThreadType } from 'lib/types/thread-types-enum.js';
 
 import { main } from './utils.js';
 import { dbQuery, SQL } from '../database/database.js';
diff --git a/keyserver/src/scripts/make-channel-private.js b/keyserver/src/scripts/make-channel-private.js
--- a/keyserver/src/scripts/make-channel-private.js
+++ b/keyserver/src/scripts/make-channel-private.js
@@ -1,7 +1,7 @@
 // @flow
 
 import ashoat from 'lib/facts/ashoat.js';
-import { threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 
 import { main } from './utils.js';
 import { createScriptViewer } from '../session/scripts.js';
diff --git a/keyserver/src/scripts/move-threads.js b/keyserver/src/scripts/move-threads.js
--- a/keyserver/src/scripts/move-threads.js
+++ b/keyserver/src/scripts/move-threads.js
@@ -1,7 +1,7 @@
 // @flow
 
 import ashoat from 'lib/facts/ashoat.js';
-import { threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 
 import { main } from './utils.js';
 import { createScriptViewer } from '../session/scripts.js';
diff --git a/keyserver/src/scripts/rescind-notifs.js b/keyserver/src/scripts/rescind-notifs.js
--- a/keyserver/src/scripts/rescind-notifs.js
+++ b/keyserver/src/scripts/rescind-notifs.js
@@ -1,6 +1,6 @@
 // @flow
 
-import { threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 
 import { main } from './utils.js';
 import { dbQuery, SQL } from '../database/database.js';
diff --git a/keyserver/src/scripts/set-last-read-messages.js b/keyserver/src/scripts/set-last-read-messages.js
--- a/keyserver/src/scripts/set-last-read-messages.js
+++ b/keyserver/src/scripts/set-last-read-messages.js
@@ -1,7 +1,7 @@
 // @flow
 
 import { messageTypes } from 'lib/types/message-types-enum.js';
-import { threadPermissions } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 
 import { endScript } from './utils.js';
 import { dbQuery, SQL } from '../database/database.js';
diff --git a/keyserver/src/scripts/sidebar-know-of-migration.js b/keyserver/src/scripts/sidebar-know-of-migration.js
--- a/keyserver/src/scripts/sidebar-know-of-migration.js
+++ b/keyserver/src/scripts/sidebar-know-of-migration.js
@@ -1,7 +1,7 @@
 // @flow
 
 import bots from 'lib/facts/bots.js';
-import { threadTypes, type ThreadType } from 'lib/types/thread-types.js';
+import { threadTypes, type ThreadType } from 'lib/types/thread-types-enum.js';
 
 import { main } from './utils.js';
 import { dbQuery, SQL } from '../database/database.js';
diff --git a/keyserver/src/scripts/soft-launch-migration.js b/keyserver/src/scripts/soft-launch-migration.js
--- a/keyserver/src/scripts/soft-launch-migration.js
+++ b/keyserver/src/scripts/soft-launch-migration.js
@@ -7,7 +7,7 @@
 import genesis from 'lib/facts/genesis.js';
 import testers from 'lib/facts/testers.js';
 import { messageTypes } from 'lib/types/message-types-enum.js';
-import { threadTypes, type ThreadType } from 'lib/types/thread-types.js';
+import { threadTypes, type ThreadType } from 'lib/types/thread-types-enum.js';
 
 import { main } from './utils.js';
 import createMessages from '../creators/message-creator.js';
diff --git a/keyserver/src/updaters/activity-updaters.js b/keyserver/src/updaters/activity-updaters.js
--- a/keyserver/src/updaters/activity-updaters.js
+++ b/keyserver/src/updaters/activity-updaters.js
@@ -12,7 +12,7 @@
   SetThreadUnreadStatusResult,
 } from 'lib/types/activity-types.js';
 import { messageTypes } from 'lib/types/message-types-enum.js';
-import { threadPermissions } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import { updateTypes } from 'lib/types/update-types.js';
 import { ServerError } from 'lib/utils/errors.js';
 
diff --git a/keyserver/src/updaters/entry-updaters.js b/keyserver/src/updaters/entry-updaters.js
--- a/keyserver/src/updaters/entry-updaters.js
+++ b/keyserver/src/updaters/entry-updaters.js
@@ -15,7 +15,7 @@
   defaultCalendarQuery,
 } from 'lib/types/entry-types.js';
 import { messageTypes } from 'lib/types/message-types-enum.js';
-import { threadPermissions } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import {
   updateTypes,
   type ServerCreateUpdatesResponse,
diff --git a/keyserver/src/updaters/relationship-updaters.js b/keyserver/src/updaters/relationship-updaters.js
--- a/keyserver/src/updaters/relationship-updaters.js
+++ b/keyserver/src/updaters/relationship-updaters.js
@@ -12,7 +12,7 @@
   undirectedStatus,
   directedStatus,
 } from 'lib/types/relationship-types.js';
-import { threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 import { updateTypes, type UpdateData } from 'lib/types/update-types.js';
 import { cartesianProduct } from 'lib/utils/array.js';
 import { ServerError } from 'lib/utils/errors.js';
diff --git a/keyserver/src/updaters/role-updaters.js b/keyserver/src/updaters/role-updaters.js
--- a/keyserver/src/updaters/role-updaters.js
+++ b/keyserver/src/updaters/role-updaters.js
@@ -4,7 +4,7 @@
 import _isEqual from 'lodash/fp/isEqual.js';
 
 import { getRolePermissionBlobs } from 'lib/permissions/thread-permissions.js';
-import type { ThreadType } from 'lib/types/thread-types.js';
+import type { ThreadType } from 'lib/types/thread-types-enum.js';
 
 import createIDs from '../creators/id-creator.js';
 import { dbQuery, SQL } from '../database/database.js';
diff --git a/keyserver/src/updaters/thread-permission-updaters.js b/keyserver/src/updaters/thread-permission-updaters.js
--- a/keyserver/src/updaters/thread-permission-updaters.js
+++ b/keyserver/src/updaters/thread-permission-updaters.js
@@ -11,12 +11,14 @@
   getRoleForPermissions,
 } from 'lib/permissions/thread-permissions.js';
 import type { CalendarQuery } from 'lib/types/entry-types.js';
+import type {
+  ThreadPermissionsBlob,
+  ThreadRolePermissionsBlob,
+} from 'lib/types/thread-permission-types.js';
 import {
-  type ThreadPermissionsBlob,
-  type ThreadRolePermissionsBlob,
   type ThreadType,
   assertThreadType,
-} from 'lib/types/thread-types.js';
+} from 'lib/types/thread-types-enum.js';
 import {
   updateTypes,
   type ServerUpdateInfo,
diff --git a/keyserver/src/updaters/thread-updaters.js b/keyserver/src/updaters/thread-updaters.js
--- a/keyserver/src/updaters/thread-updaters.js
+++ b/keyserver/src/updaters/thread-updaters.js
@@ -14,6 +14,8 @@
 import type { Shape } from 'lib/types/core.js';
 import { messageTypes } from 'lib/types/message-types-enum.js';
 import { defaultNumberPerThread } from 'lib/types/message-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 import {
   type RoleChangeRequest,
   type ChangeThreadSettingsResult,
@@ -25,8 +27,6 @@
   type ThreadJoinResult,
   type ToggleMessagePinRequest,
   type ToggleMessagePinResult,
-  threadPermissions,
-  threadTypes,
 } from 'lib/types/thread-types.js';
 import { updateTypes } from 'lib/types/update-types.js';
 import { ServerError } from 'lib/utils/errors.js';
diff --git a/lib/flow-typed/npm/tcomb_v3.x.x.js b/lib/flow-typed/npm/tcomb_v3.x.x.js
--- a/lib/flow-typed/npm/tcomb_v3.x.x.js
+++ b/lib/flow-typed/npm/tcomb_v3.x.x.js
@@ -112,11 +112,11 @@
     +Object: TIrreducible<Object>,
     maybe<T>(type: TType<T>, name?: string): TMaybe<void | T>,
     list<T>(type: TType<T>, name?: string): TList<Array<T>>,
-    dict<T>(
-      domain: TType<string>,
+    dict<S: string, T>(
+      domain: TType<S>,
       codomain: TType<T>,
       name?: string,
-    ): TDict<{ [key: string]: T }>,
+    ): TDict<{ [key: S]: T }>,
     union<+T>(types: $ReadOnlyArray<TType<T>>, name?: string): TUnion<T>,
     +enums: {
       of(enums: $ReadOnlyArray<string>, name?: string): TEnums,
diff --git a/lib/hooks/promote-sidebar.react.js b/lib/hooks/promote-sidebar.react.js
--- a/lib/hooks/promote-sidebar.react.js
+++ b/lib/hooks/promote-sidebar.react.js
@@ -13,11 +13,9 @@
   threadIsSidebar,
 } from '../shared/thread-utils.js';
 import type { LoadingStatus } from '../types/loading-types.js';
-import {
-  threadTypes,
-  type ThreadInfo,
-  threadPermissions,
-} from '../types/thread-types.js';
+import { threadPermissions } from '../types/thread-permission-types.js';
+import { threadTypes } from '../types/thread-types-enum.js';
+import { type ThreadInfo } from '../types/thread-types.js';
 import {
   useServerCall,
   useDispatchActionPromise,
diff --git a/lib/permissions/prefixes.js b/lib/permissions/prefixes.js
--- a/lib/permissions/prefixes.js
+++ b/lib/permissions/prefixes.js
@@ -1,15 +1,16 @@
 // @flow
 
+import type {
+  ThreadPermission,
+  ThreadPermissionFilterPrefix,
+  ThreadPermissionPropagationPrefix,
+} from '../types/thread-permission-types.js';
 import {
-  type ThreadPermission,
   assertThreadPermissions,
-  threadPermissionPropagationPrefixes,
-  type ThreadPermissionPropagationPrefix,
   threadPermissionFilterPrefixes,
-  type ThreadPermissionFilterPrefix,
-  threadTypes,
-  type ThreadType,
-} from '../types/thread-types.js';
+  threadPermissionPropagationPrefixes,
+} from '../types/thread-permission-types.js';
+import { threadTypes, type ThreadType } from '../types/thread-types-enum.js';
 
 type ParsedThreadPermissionString = {
   +permission: ThreadPermission,
diff --git a/lib/permissions/thread-permissions.js b/lib/permissions/thread-permissions.js
--- a/lib/permissions/thread-permissions.js
+++ b/lib/permissions/thread-permissions.js
@@ -5,17 +5,18 @@
   includeThreadPermissionForThreadType,
 } from './prefixes.js';
 import {
-  type ThreadPermissionsBlob,
-  type ThreadType,
-  type ThreadPermission,
-  type ThreadRolePermissionsBlob,
-  type ThreadPermissionInfo,
-  type ThreadPermissionsInfo,
-  threadPermissions,
-  threadPermissionPropagationPrefixes,
   threadPermissionFilterPrefixes,
-  threadTypes,
-} from '../types/thread-types.js';
+  threadPermissionPropagationPrefixes,
+  threadPermissions,
+} from '../types/thread-permission-types.js';
+import type {
+  ThreadPermission,
+  ThreadPermissionInfo,
+  ThreadPermissionsBlob,
+  ThreadPermissionsInfo,
+  ThreadRolePermissionsBlob,
+} from '../types/thread-permission-types.js';
+import { type ThreadType, threadTypes } from '../types/thread-types-enum.js';
 
 function permissionLookup(
   permissions: ?ThreadPermissionsBlob | ?ThreadPermissionsInfo,
diff --git a/lib/reducers/message-reducer.js b/lib/reducers/message-reducer.js
--- a/lib/reducers/message-reducer.js
+++ b/lib/reducers/message-reducer.js
@@ -90,10 +90,8 @@
   fullStateSyncActionType,
   incrementalStateSyncActionType,
 } from '../types/socket-types.js';
-import {
-  type RawThreadInfo,
-  threadPermissions,
-} from '../types/thread-types.js';
+import { threadPermissions } from '../types/thread-permission-types.js';
+import { type RawThreadInfo } from '../types/thread-types.js';
 import {
   updateTypes,
   type ClientUpdateInfo,
diff --git a/lib/reducers/message-reducer.test.js b/lib/reducers/message-reducer.test.js
--- a/lib/reducers/message-reducer.test.js
+++ b/lib/reducers/message-reducer.test.js
@@ -6,7 +6,7 @@
 import { createPendingThread } from '../shared/thread-utils.js';
 import { messageTypes } from '../types/message-types-enum.js';
 import type { MessageStore } from '../types/message-types.js';
-import { threadTypes } from '../types/thread-types.js';
+import { threadTypes } from '../types/thread-types-enum.js';
 
 const messageStoreBeforeMediaUpdate: MessageStore = {
   messages: {
diff --git a/lib/selectors/chat-selectors.js b/lib/selectors/chat-selectors.js
--- a/lib/selectors/chat-selectors.js
+++ b/lib/selectors/chat-selectors.js
@@ -37,13 +37,13 @@
   isComposableMessageType,
 } from '../types/message-types.js';
 import type { BaseAppState } from '../types/redux-types.js';
+import { threadTypes } from '../types/thread-types-enum.js';
 import {
   type ThreadInfo,
   type RawThreadInfo,
   type SidebarInfo,
   maxReadSidebars,
   maxUnreadSidebars,
-  threadTypes,
 } from '../types/thread-types.js';
 import type {
   UserInfo,
diff --git a/lib/selectors/thread-selectors.js b/lib/selectors/thread-selectors.js
--- a/lib/selectors/thread-selectors.js
+++ b/lib/selectors/thread-selectors.js
@@ -39,14 +39,16 @@
 import type { EntryInfo } from '../types/entry-types.js';
 import type { MessageStore, RawMessageInfo } from '../types/message-types.js';
 import type { BaseAppState } from '../types/redux-types.js';
+import { threadPermissions } from '../types/thread-permission-types.js';
+import {
+  threadTypes,
+  threadTypeIsCommunityRoot,
+} from '../types/thread-types-enum.js';
 import {
   type ThreadInfo,
   type RawThreadInfo,
   type RelativeMemberInfo,
-  threadPermissions,
-  threadTypes,
   type SidebarInfo,
-  threadTypeIsCommunityRoot,
 } from '../types/thread-types.js';
 import { dateString, dateFromString } from '../utils/date-utils.js';
 import { values } from '../utils/objects.js';
diff --git a/lib/selectors/user-selectors.js b/lib/selectors/user-selectors.js
--- a/lib/selectors/user-selectors.js
+++ b/lib/selectors/user-selectors.js
@@ -15,10 +15,10 @@
 import type { ClientEmojiAvatar } from '../types/avatar-types';
 import type { BaseAppState } from '../types/redux-types.js';
 import { userRelationshipStatus } from '../types/relationship-types.js';
+import { threadTypes } from '../types/thread-types-enum.js';
 import {
   type RawThreadInfo,
   type RelativeMemberInfo,
-  threadTypes,
 } from '../types/thread-types.js';
 import type {
   UserInfos,
diff --git a/lib/shared/avatar-utils.js b/lib/shared/avatar-utils.js
--- a/lib/shared/avatar-utils.js
+++ b/lib/shared/avatar-utils.js
@@ -15,11 +15,8 @@
   ClientAvatar,
   ResolvedClientAvatar,
 } from '../types/avatar-types.js';
-import {
-  type RawThreadInfo,
-  type ThreadInfo,
-  threadTypes,
-} from '../types/thread-types.js';
+import { threadTypes } from '../types/thread-types-enum.js';
+import { type RawThreadInfo, type ThreadInfo } from '../types/thread-types.js';
 import type { UserInfos, UserInfo } from '../types/user-types.js';
 import { useSelector } from '../utils/redux-utils.js';
 
diff --git a/lib/shared/edit-messages-utils.js b/lib/shared/edit-messages-utils.js
--- a/lib/shared/edit-messages-utils.js
+++ b/lib/shared/edit-messages-utils.js
@@ -14,7 +14,8 @@
   ComposableMessageInfo,
 } from '../types/message-types';
 import { messageTypes } from '../types/message-types-enum.js';
-import { threadPermissions, type ThreadInfo } from '../types/thread-types.js';
+import { threadPermissions } from '../types/thread-permission-types.js';
+import { type ThreadInfo } from '../types/thread-types.js';
 import {
   useDispatchActionPromise,
   useServerCall,
diff --git a/lib/shared/mention-utils.js b/lib/shared/mention-utils.js
--- a/lib/shared/mention-utils.js
+++ b/lib/shared/mention-utils.js
@@ -4,8 +4,8 @@
 import SearchIndex from './search-index.js';
 import { threadOtherMembers } from './thread-utils.js';
 import { stringForUserExplicit } from './user-utils.js';
+import { threadTypes } from '../types/thread-types-enum.js';
 import {
-  threadTypes,
   type ThreadInfo,
   type RelativeMemberInfo,
 } from '../types/thread-types.js';
diff --git a/lib/shared/messages/change-settings-message-spec.js b/lib/shared/messages/change-settings-message-spec.js
--- a/lib/shared/messages/change-settings-message-spec.js
+++ b/lib/shared/messages/change-settings-message-spec.js
@@ -20,7 +20,7 @@
   rawChangeSettingsMessageInfoValidator,
 } from '../../types/messages/change-settings.js';
 import type { NotifTexts } from '../../types/notif-types.js';
-import { assertThreadType } from '../../types/thread-types.js';
+import { assertThreadType } from '../../types/thread-types-enum.js';
 import type { ThreadInfo } from '../../types/thread-types.js';
 import type { RelativeUserInfo } from '../../types/user-types.js';
 import { ET, type EntityText } from '../../utils/entity-text.js';
diff --git a/lib/shared/messages/create-sub-thread-message-spec.js b/lib/shared/messages/create-sub-thread-message-spec.js
--- a/lib/shared/messages/create-sub-thread-message-spec.js
+++ b/lib/shared/messages/create-sub-thread-message-spec.js
@@ -22,7 +22,8 @@
   rawCreateSubthreadMessageInfoValidator,
 } from '../../types/messages/create-subthread.js';
 import type { NotifTexts } from '../../types/notif-types.js';
-import { threadPermissions, threadTypes } from '../../types/thread-types.js';
+import { threadPermissions } from '../../types/thread-permission-types.js';
+import { threadTypes } from '../../types/thread-types-enum.js';
 import type { ThreadInfo } from '../../types/thread-types.js';
 import type { RelativeUserInfo } from '../../types/user-types.js';
 import { ET, type EntityText } from '../../utils/entity-text.js';
diff --git a/lib/shared/messages/text-message-spec.js b/lib/shared/messages/text-message-spec.js
--- a/lib/shared/messages/text-message-spec.js
+++ b/lib/shared/messages/text-message-spec.js
@@ -26,7 +26,7 @@
   rawTextMessageInfoValidator,
 } from '../../types/messages/text.js';
 import type { NotifTexts } from '../../types/notif-types.js';
-import { threadTypes } from '../../types/thread-types.js';
+import { threadTypes } from '../../types/thread-types-enum.js';
 import type { ThreadInfo } from '../../types/thread-types.js';
 import type { RelativeUserInfo } from '../../types/user-types.js';
 import {
diff --git a/lib/shared/notif-utils.js b/lib/shared/notif-utils.js
--- a/lib/shared/notif-utils.js
+++ b/lib/shared/notif-utils.js
@@ -18,11 +18,8 @@
 import type { CreateSidebarMessageInfo } from '../types/messages/create-sidebar.js';
 import type { TextMessageInfo } from '../types/messages/text.js';
 import type { NotifTexts, ResolvedNotifTexts } from '../types/notif-types.js';
-import {
-  type ThreadInfo,
-  type ThreadType,
-  threadTypes,
-} from '../types/thread-types.js';
+import { type ThreadType, threadTypes } from '../types/thread-types-enum.js';
+import { type ThreadInfo } from '../types/thread-types.js';
 import type { RelativeUserInfo, UserInfo } from '../types/user-types.js';
 import { prettyDate } from '../utils/date-utils.js';
 import type { GetENSNames } from '../utils/ens-helpers.js';
diff --git a/lib/shared/reaction-utils.js b/lib/shared/reaction-utils.js
--- a/lib/shared/reaction-utils.js
+++ b/lib/shared/reaction-utils.js
@@ -12,7 +12,8 @@
   RobotextMessageInfo,
   ComposableMessageInfo,
 } from '../types/message-types.js';
-import { threadPermissions, type ThreadInfo } from '../types/thread-types.js';
+import { threadPermissions } from '../types/thread-permission-types.js';
+import { type ThreadInfo } from '../types/thread-types.js';
 import { useSelector } from '../utils/redux-utils.js';
 
 function stringForReactionList(reactions: ReactionInfo): string {
diff --git a/lib/shared/search-utils.js b/lib/shared/search-utils.js
--- a/lib/shared/search-utils.js
+++ b/lib/shared/search-utils.js
@@ -8,12 +8,9 @@
 } from './thread-utils.js';
 import genesis from '../facts/genesis.js';
 import { userRelationshipStatus } from '../types/relationship-types.js';
-import {
-  type ThreadInfo,
-  type ThreadType,
-  threadTypes,
-  threadPermissions,
-} from '../types/thread-types.js';
+import { threadPermissions } from '../types/thread-permission-types.js';
+import { type ThreadType, threadTypes } from '../types/thread-types-enum.js';
+import { type ThreadInfo } from '../types/thread-types.js';
 import type { AccountUserInfo, UserListItem } from '../types/user-types.js';
 
 const notFriendNotice = 'not friend';
diff --git a/lib/shared/thread-utils.js b/lib/shared/thread-utils.js
--- a/lib/shared/thread-utils.js
+++ b/lib/shared/thread-utils.js
@@ -51,26 +51,30 @@
   type ComposableMessageInfo,
 } from '../types/message-types.js';
 import { userRelationshipStatus } from '../types/relationship-types.js';
+import {
+  threadPermissionPropagationPrefixes,
+  threadPermissions,
+  type ThreadPermission,
+  type ThreadPermissionsInfo,
+} from '../types/thread-permission-types.js';
+import {
+  type ThreadType,
+  threadTypes,
+  threadTypeIsCommunityRoot,
+  assertThreadType,
+} from '../types/thread-types-enum.js';
 import {
   type RawThreadInfo,
   type ThreadInfo,
-  type ThreadPermission,
   type MemberInfo,
   type ServerThreadInfo,
   type RelativeMemberInfo,
   type ThreadCurrentUserInfo,
   type RoleInfo,
   type ServerMemberInfo,
-  type ThreadPermissionsInfo,
-  type ThreadType,
   type ClientNewThreadRequest,
   type NewThreadResult,
   type ChangeThreadSettingsPayload,
-  threadTypes,
-  threadPermissions,
-  threadTypeIsCommunityRoot,
-  assertThreadType,
-  threadPermissionPropagationPrefixes,
 } from '../types/thread-types.js';
 import { type ClientUpdateInfo, updateTypes } from '../types/update-types.js';
 import type {
diff --git a/lib/shared/thread-utils.test.js b/lib/shared/thread-utils.test.js
--- a/lib/shared/thread-utils.test.js
+++ b/lib/shared/thread-utils.test.js
@@ -1,7 +1,7 @@
 // @flow
 
 import { parsePendingThreadID } from './thread-utils.js';
-import { threadTypes } from '../types/thread-types.js';
+import { threadTypes } from '../types/thread-types-enum.js';
 
 describe('parsePendingThreadID(pendingThreadID: string)', () => {
   it('should return correct data for real pending sidebar ID', () => {
diff --git a/lib/types/messages/create-thread.js b/lib/types/messages/create-thread.js
--- a/lib/types/messages/create-thread.js
+++ b/lib/types/messages/create-thread.js
@@ -10,11 +10,8 @@
   tNumEnum,
 } from '../../utils/validation-utils.js';
 import { messageTypes } from '../message-types-enum.js';
-import {
-  threadTypes,
-  type ThreadInfo,
-  type ThreadType,
-} from '../thread-types.js';
+import { threadTypes, type ThreadType } from '../thread-types-enum.js';
+import { type ThreadInfo } from '../thread-types.js';
 import type { RelativeUserInfo } from '../user-types.js';
 
 export type CreateThreadMessageData = {
diff --git a/lib/types/thread-permission-types.js b/lib/types/thread-permission-types.js
new file mode 100644
--- /dev/null
+++ b/lib/types/thread-permission-types.js
@@ -0,0 +1,102 @@
+// @flow
+
+import invariant from 'invariant';
+import t, { type TDict } from 'tcomb';
+
+import { values } from '../utils/objects.js';
+import { tBool, tShape } from '../utils/validation-utils.js';
+
+export const threadPermissions = Object.freeze({
+  KNOW_OF: 'know_of',
+  MEMBERSHIP_DEPRECATED: 'membership',
+  VISIBLE: 'visible',
+  VOICED: 'voiced',
+  EDIT_ENTRIES: 'edit_entries',
+  EDIT_THREAD_NAME: 'edit_thread',
+  EDIT_THREAD_DESCRIPTION: 'edit_thread_description',
+  EDIT_THREAD_COLOR: 'edit_thread_color',
+  DELETE_THREAD: 'delete_thread',
+  CREATE_SUBCHANNELS: 'create_subthreads',
+  CREATE_SIDEBARS: 'create_sidebars',
+  JOIN_THREAD: 'join_thread',
+  EDIT_PERMISSIONS: 'edit_permissions',
+  ADD_MEMBERS: 'add_members',
+  REMOVE_MEMBERS: 'remove_members',
+  CHANGE_ROLE: 'change_role',
+  LEAVE_THREAD: 'leave_thread',
+  REACT_TO_MESSAGE: 'react_to_message',
+  EDIT_MESSAGE: 'edit_message',
+  EDIT_THREAD_AVATAR: 'edit_thread_avatar',
+  MANAGE_PINS: 'manage_pins',
+});
+export type ThreadPermission = $Values<typeof threadPermissions>;
+
+export function assertThreadPermissions(
+  ourThreadPermissions: string,
+): ThreadPermission {
+  invariant(
+    ourThreadPermissions === 'know_of' ||
+      ourThreadPermissions === 'membership' ||
+      ourThreadPermissions === 'visible' ||
+      ourThreadPermissions === 'voiced' ||
+      ourThreadPermissions === 'edit_entries' ||
+      ourThreadPermissions === 'edit_thread' ||
+      ourThreadPermissions === 'edit_thread_description' ||
+      ourThreadPermissions === 'edit_thread_color' ||
+      ourThreadPermissions === 'delete_thread' ||
+      ourThreadPermissions === 'create_subthreads' ||
+      ourThreadPermissions === 'create_sidebars' ||
+      ourThreadPermissions === 'join_thread' ||
+      ourThreadPermissions === 'edit_permissions' ||
+      ourThreadPermissions === 'add_members' ||
+      ourThreadPermissions === 'remove_members' ||
+      ourThreadPermissions === 'change_role' ||
+      ourThreadPermissions === 'leave_thread' ||
+      ourThreadPermissions === 'react_to_message' ||
+      ourThreadPermissions === 'edit_message' ||
+      ourThreadPermissions === 'edit_thread_avatar' ||
+      ourThreadPermissions === 'manage_pins',
+    'string is not threadPermissions enum',
+  );
+  return ourThreadPermissions;
+}
+
+const threadPermissionValidator = t.enums.of(values(threadPermissions));
+export const threadPermissionPropagationPrefixes = Object.freeze({
+  DESCENDANT: 'descendant_',
+  CHILD: 'child_',
+});
+export type ThreadPermissionPropagationPrefix = $Values<
+  typeof threadPermissionPropagationPrefixes,
+>;
+export const threadPermissionFilterPrefixes = Object.freeze({
+  // includes only SIDEBAR, COMMUNITY_OPEN_SUBTHREAD,
+  // COMMUNITY_OPEN_ANNOUNCEMENT_SUBTHREAD
+  OPEN: 'open_',
+  // excludes only SIDEBAR
+  TOP_LEVEL: 'toplevel_',
+  // includes only COMMUNITY_OPEN_SUBTHREAD,
+  // COMMUNITY_OPEN_ANNOUNCEMENT_SUBTHREAD
+  OPEN_TOP_LEVEL: 'opentoplevel_',
+});
+export type ThreadPermissionFilterPrefix = $Values<
+  typeof threadPermissionFilterPrefixes,
+>;
+export type ThreadPermissionInfo =
+  | { +value: true, +source: string }
+  | { +value: false, +source: null };
+const threadPermissionInfoValidator = t.union([
+  tShape({ value: tBool(true), source: t.String }),
+  tShape({ value: tBool(false), source: t.Nil }),
+]);
+export type ThreadPermissionsBlob = {
+  +[permission: string]: ThreadPermissionInfo,
+};
+export type ThreadRolePermissionsBlob = { +[permission: string]: boolean };
+export const threadRolePermissionsBlobValidator: TDict<ThreadRolePermissionsBlob> =
+  t.dict(t.String, t.Boolean);
+export type ThreadPermissionsInfo = {
+  +[permission: ThreadPermission]: ThreadPermissionInfo,
+};
+export const threadPermissionsInfoValidator: TDict<ThreadPermissionsInfo> =
+  t.dict(threadPermissionValidator, threadPermissionInfoValidator);
diff --git a/lib/types/thread-types-enum.js b/lib/types/thread-types-enum.js
new file mode 100644
--- /dev/null
+++ b/lib/types/thread-types-enum.js
@@ -0,0 +1,77 @@
+// @flow
+
+import invariant from 'invariant';
+import type { TRefinement } from 'tcomb';
+
+import { values } from '../utils/objects.js';
+import { tNumEnum } from '../utils/validation-utils.js';
+
+export const threadTypes = Object.freeze({
+  //OPEN: 0,   (DEPRECATED)
+  //CLOSED: 1, (DEPRECATED)
+  //SECRET: 2, (DEPRECATED)
+  // has parent, not top-level (appears under parent in inbox), and visible to
+  // all members of parent
+  SIDEBAR: 5,
+  // canonical thread for each pair of users. represents the friendship
+  PERSONAL: 6,
+  // canonical thread for each single user
+  PRIVATE: 7,
+  // local "thick" thread (outside of community). no parent, can only have
+  // sidebar children. currently a proxy for COMMUNITY_SECRET_SUBTHREAD until we
+  // launch actual E2E
+  LOCAL: 4,
+  // aka "org". no parent, top-level, has admin
+  COMMUNITY_ROOT: 8,
+  // like COMMUNITY_ROOT, but members aren't voiced
+  COMMUNITY_ANNOUNCEMENT_ROOT: 9,
+  // an open subthread. has parent, top-level (not sidebar), and visible to all
+  // members of parent. root ancestor is a COMMUNITY_ROOT
+  COMMUNITY_OPEN_SUBTHREAD: 3,
+  // like COMMUNITY_SECRET_SUBTHREAD, but members aren't voiced
+  COMMUNITY_OPEN_ANNOUNCEMENT_SUBTHREAD: 10,
+  // a secret subthread. optional parent, top-level (not sidebar), visible only
+  // to its members. root ancestor is a COMMUNITY_ROOT
+  COMMUNITY_SECRET_SUBTHREAD: 4,
+  // like COMMUNITY_SECRET_SUBTHREAD, but members aren't voiced
+  COMMUNITY_SECRET_ANNOUNCEMENT_SUBTHREAD: 11,
+  // like COMMUNITY_SECRET_ANNOUNCEMENT_SUBTHREAD, but you can't leave
+  GENESIS: 12,
+});
+export type ThreadType = $Values<typeof threadTypes>;
+export function assertThreadType(threadType: number): ThreadType {
+  invariant(
+    threadType === 3 ||
+      threadType === 4 ||
+      threadType === 5 ||
+      threadType === 6 ||
+      threadType === 7 ||
+      threadType === 8 ||
+      threadType === 9 ||
+      threadType === 10 ||
+      threadType === 11 ||
+      threadType === 12,
+    'number is not ThreadType enum',
+  );
+  return threadType;
+}
+export const threadTypeValidator: TRefinement<number> = tNumEnum(
+  values(threadTypes),
+);
+
+export const communityThreadTypes: $ReadOnlyArray<number> = Object.freeze([
+  threadTypes.COMMUNITY_ROOT,
+  threadTypes.COMMUNITY_ANNOUNCEMENT_ROOT,
+  threadTypes.GENESIS,
+]);
+
+export const communitySubthreads: $ReadOnlyArray<number> = Object.freeze([
+  threadTypes.COMMUNITY_OPEN_SUBTHREAD,
+  threadTypes.COMMUNITY_OPEN_ANNOUNCEMENT_SUBTHREAD,
+  threadTypes.COMMUNITY_SECRET_SUBTHREAD,
+  threadTypes.COMMUNITY_SECRET_ANNOUNCEMENT_SUBTHREAD,
+]);
+
+export function threadTypeIsCommunityRoot(threadType: ThreadType): boolean {
+  return communityThreadTypes.includes(threadType);
+}
diff --git a/lib/types/thread-types.js b/lib/types/thread-types.js
--- a/lib/types/thread-types.js
+++ b/lib/types/thread-types.js
@@ -1,198 +1,35 @@
 // @flow
 
-import invariant from 'invariant';
 import t, { type TInterface } from 'tcomb';
 
 import {
   type AvatarDBContent,
   type ClientAvatar,
-  type UpdateUserAvatarRequest,
   clientAvatarValidator,
+  type UpdateUserAvatarRequest,
 } from './avatar-types.js';
 import type { Shape } from './core.js';
 import type { CalendarQuery, RawEntryInfo } from './entry-types.js';
 import type { Media } from './media-types.js';
 import type {
-  RawMessageInfo,
   MessageTruncationStatuses,
+  RawMessageInfo,
 } from './message-types.js';
 import {
   type ThreadSubscription,
   threadSubscriptionValidator,
 } from './subscription-types.js';
-import type { ServerUpdateInfo, ClientUpdateInfo } from './update-types.js';
+import {
+  type ThreadPermissionsInfo,
+  type ThreadRolePermissionsBlob,
+  threadPermissionsInfoValidator,
+  threadRolePermissionsBlobValidator,
+} from './thread-permission-types.js';
+import { type ThreadType, threadTypeValidator } from './thread-types-enum.js';
+import type { ClientUpdateInfo, ServerUpdateInfo } from './update-types.js';
 import type { UserInfo, UserInfos } from './user-types.js';
-import type { ThreadEntity } from '../utils/entity-text.js';
-import { values } from '../utils/objects.js';
-import { tNumEnum, tBool, tID, tShape } from '../utils/validation-utils.js';
-
-export const threadTypes = Object.freeze({
-  //OPEN: 0,   (DEPRECATED)
-  //CLOSED: 1, (DEPRECATED)
-  //SECRET: 2, (DEPRECATED)
-  // has parent, not top-level (appears under parent in inbox), and visible to
-  // all members of parent
-  SIDEBAR: 5,
-  // canonical thread for each pair of users. represents the friendship
-  PERSONAL: 6,
-  // canonical thread for each single user
-  PRIVATE: 7,
-  // local "thick" thread (outside of community). no parent, can only have
-  // sidebar children. currently a proxy for COMMUNITY_SECRET_SUBTHREAD until we
-  // launch actual E2E
-  LOCAL: 4,
-  // aka "org". no parent, top-level, has admin
-  COMMUNITY_ROOT: 8,
-  // like COMMUNITY_ROOT, but members aren't voiced
-  COMMUNITY_ANNOUNCEMENT_ROOT: 9,
-  // an open subthread. has parent, top-level (not sidebar), and visible to all
-  // members of parent. root ancestor is a COMMUNITY_ROOT
-  COMMUNITY_OPEN_SUBTHREAD: 3,
-  // like COMMUNITY_SECRET_SUBTHREAD, but members aren't voiced
-  COMMUNITY_OPEN_ANNOUNCEMENT_SUBTHREAD: 10,
-  // a secret subthread. optional parent, top-level (not sidebar), visible only
-  // to its members. root ancestor is a COMMUNITY_ROOT
-  COMMUNITY_SECRET_SUBTHREAD: 4,
-  // like COMMUNITY_SECRET_SUBTHREAD, but members aren't voiced
-  COMMUNITY_SECRET_ANNOUNCEMENT_SUBTHREAD: 11,
-  // like COMMUNITY_SECRET_ANNOUNCEMENT_SUBTHREAD, but you can't leave
-  GENESIS: 12,
-});
-export type ThreadType = $Values<typeof threadTypes>;
-export function assertThreadType(threadType: number): ThreadType {
-  invariant(
-    threadType === 3 ||
-      threadType === 4 ||
-      threadType === 5 ||
-      threadType === 6 ||
-      threadType === 7 ||
-      threadType === 8 ||
-      threadType === 9 ||
-      threadType === 10 ||
-      threadType === 11 ||
-      threadType === 12,
-    'number is not ThreadType enum',
-  );
-  return threadType;
-}
-const threadTypeValidator = tNumEnum(values(threadTypes));
-
-export const communityThreadTypes: $ReadOnlyArray<number> = Object.freeze([
-  threadTypes.COMMUNITY_ROOT,
-  threadTypes.COMMUNITY_ANNOUNCEMENT_ROOT,
-  threadTypes.GENESIS,
-]);
-
-export const communitySubthreads: $ReadOnlyArray<number> = Object.freeze([
-  threadTypes.COMMUNITY_OPEN_SUBTHREAD,
-  threadTypes.COMMUNITY_OPEN_ANNOUNCEMENT_SUBTHREAD,
-  threadTypes.COMMUNITY_SECRET_SUBTHREAD,
-  threadTypes.COMMUNITY_SECRET_ANNOUNCEMENT_SUBTHREAD,
-]);
-
-export function threadTypeIsCommunityRoot(threadType: ThreadType): boolean {
-  return communityThreadTypes.includes(threadType);
-}
-
-export const threadPermissions = Object.freeze({
-  KNOW_OF: 'know_of',
-  MEMBERSHIP_DEPRECATED: 'membership',
-  VISIBLE: 'visible',
-  VOICED: 'voiced',
-  EDIT_ENTRIES: 'edit_entries',
-  EDIT_THREAD_NAME: 'edit_thread',
-  EDIT_THREAD_DESCRIPTION: 'edit_thread_description',
-  EDIT_THREAD_COLOR: 'edit_thread_color',
-  DELETE_THREAD: 'delete_thread',
-  CREATE_SUBCHANNELS: 'create_subthreads',
-  CREATE_SIDEBARS: 'create_sidebars',
-  JOIN_THREAD: 'join_thread',
-  EDIT_PERMISSIONS: 'edit_permissions',
-  ADD_MEMBERS: 'add_members',
-  REMOVE_MEMBERS: 'remove_members',
-  CHANGE_ROLE: 'change_role',
-  LEAVE_THREAD: 'leave_thread',
-  REACT_TO_MESSAGE: 'react_to_message',
-  EDIT_MESSAGE: 'edit_message',
-  EDIT_THREAD_AVATAR: 'edit_thread_avatar',
-  MANAGE_PINS: 'manage_pins',
-});
-export type ThreadPermission = $Values<typeof threadPermissions>;
-export function assertThreadPermissions(
-  ourThreadPermissions: string,
-): ThreadPermission {
-  invariant(
-    ourThreadPermissions === 'know_of' ||
-      ourThreadPermissions === 'membership' ||
-      ourThreadPermissions === 'visible' ||
-      ourThreadPermissions === 'voiced' ||
-      ourThreadPermissions === 'edit_entries' ||
-      ourThreadPermissions === 'edit_thread' ||
-      ourThreadPermissions === 'edit_thread_description' ||
-      ourThreadPermissions === 'edit_thread_color' ||
-      ourThreadPermissions === 'delete_thread' ||
-      ourThreadPermissions === 'create_subthreads' ||
-      ourThreadPermissions === 'create_sidebars' ||
-      ourThreadPermissions === 'join_thread' ||
-      ourThreadPermissions === 'edit_permissions' ||
-      ourThreadPermissions === 'add_members' ||
-      ourThreadPermissions === 'remove_members' ||
-      ourThreadPermissions === 'change_role' ||
-      ourThreadPermissions === 'leave_thread' ||
-      ourThreadPermissions === 'react_to_message' ||
-      ourThreadPermissions === 'edit_message' ||
-      ourThreadPermissions === 'edit_thread_avatar' ||
-      ourThreadPermissions === 'manage_pins',
-    'string is not threadPermissions enum',
-  );
-  return ourThreadPermissions;
-}
-const threadPermissionValidator = t.enums.of(values(threadPermissions));
-
-export const threadPermissionPropagationPrefixes = Object.freeze({
-  DESCENDANT: 'descendant_',
-  CHILD: 'child_',
-});
-export type ThreadPermissionPropagationPrefix = $Values<
-  typeof threadPermissionPropagationPrefixes,
->;
-
-export const threadPermissionFilterPrefixes = Object.freeze({
-  // includes only SIDEBAR, COMMUNITY_OPEN_SUBTHREAD,
-  // COMMUNITY_OPEN_ANNOUNCEMENT_SUBTHREAD
-  OPEN: 'open_',
-  // excludes only SIDEBAR
-  TOP_LEVEL: 'toplevel_',
-  // includes only COMMUNITY_OPEN_SUBTHREAD,
-  // COMMUNITY_OPEN_ANNOUNCEMENT_SUBTHREAD
-  OPEN_TOP_LEVEL: 'opentoplevel_',
-});
-export type ThreadPermissionFilterPrefix = $Values<
-  typeof threadPermissionFilterPrefixes,
->;
-
-export type ThreadPermissionInfo =
-  | { +value: true, +source: string }
-  | { +value: false, +source: null };
-
-const threadPermissionInfoValidator = t.union([
-  tShape({ value: tBool(true), source: t.String }),
-  tShape({ value: tBool(false), source: t.Nil }),
-]);
-
-export type ThreadPermissionsBlob = {
-  +[permission: string]: ThreadPermissionInfo,
-};
-export type ThreadRolePermissionsBlob = { +[permission: string]: boolean };
-const threadRolePermissionsBlobValidator = t.dict(t.String, t.Boolean);
-
-export type ThreadPermissionsInfo = {
-  +[permission: ThreadPermission]: ThreadPermissionInfo,
-};
-const threadPermissionsInfoValidator = t.dict(
-  threadPermissionValidator,
-  threadPermissionInfoValidator,
-);
+import { type ThreadEntity } from '../utils/entity-text.js';
+import { tID, tShape } from '../utils/validation-utils.js';
 
 export type MemberInfo = {
   +id: string,
diff --git a/lib/types/validation.test.js b/lib/types/validation.test.js
--- a/lib/types/validation.test.js
+++ b/lib/types/validation.test.js
@@ -21,7 +21,8 @@
   serverStateSyncServerSocketMessageValidator,
   serverUpdatesServerSocketMessageValidator,
 } from './socket-types.js';
-import { threadTypes, rawThreadInfoValidator } from './thread-types.js';
+import { threadTypes } from './thread-types-enum.js';
+import { rawThreadInfoValidator } from './thread-types.js';
 import {
   updateTypes,
   accountDeletionUpdateInfoValidator,
diff --git a/lib/utils/call-server-endpoint.js b/lib/utils/call-server-endpoint.js
--- a/lib/utils/call-server-endpoint.js
+++ b/lib/utils/call-server-endpoint.js
@@ -19,7 +19,7 @@
   ServerSessionChange,
   ClientSessionChange,
 } from '../types/session-types.js';
-import type { ConnectionStatus } from '../types/socket-types.js';
+import type { ConnectionStatus } from '../types/socket-types';
 import type { CurrentUserInfo } from '../types/user-types.js';
 
 export type CallServerEndpointOptions = Shape<{
diff --git a/lib/utils/drawer-utils.react.js b/lib/utils/drawer-utils.react.js
--- a/lib/utils/drawer-utils.react.js
+++ b/lib/utils/drawer-utils.react.js
@@ -1,10 +1,10 @@
 // @flow
 
 import { threadIsChannel } from '../shared/thread-utils.js';
+import { communitySubthreads } from '../types/thread-types-enum.js';
 import {
   type ThreadInfo,
   type ResolvedThreadInfo,
-  communitySubthreads,
 } from '../types/thread-types.js';
 
 export type CommunityDrawerItemData<T> = {
diff --git a/lib/utils/entity-text.js b/lib/utils/entity-text.js
--- a/lib/utils/entity-text.js
+++ b/lib/utils/entity-text.js
@@ -7,12 +7,8 @@
 import { useENSNames } from '../hooks/ens-cache.js';
 import { threadNoun } from '../shared/thread-utils.js';
 import { stringForUser } from '../shared/user-utils.js';
-import {
-  threadTypes,
-  type ThreadType,
-  type RawThreadInfo,
-  type ThreadInfo,
-} from '../types/thread-types.js';
+import { type ThreadType, threadTypes } from '../types/thread-types-enum.js';
+import { type RawThreadInfo, type ThreadInfo } from '../types/thread-types.js';
 import { basePluralize } from '../utils/text-utils.js';
 
 type UserEntity = {
diff --git a/lib/utils/thread-ops-utils.js b/lib/utils/thread-ops-utils.js
--- a/lib/utils/thread-ops-utils.js
+++ b/lib/utils/thread-ops-utils.js
@@ -1,11 +1,11 @@
 // @flow
 
+import { assertThreadType } from '../types/thread-types-enum.js';
 import {
   type ClientDBThreadInfo,
   type ThreadStoreOperation,
   type ClientDBThreadStoreOperation,
   type RawThreadInfo,
-  assertThreadType,
 } from '../types/thread-types.js';
 
 function convertRawThreadInfoToClientDBThreadInfo(
diff --git a/lib/utils/validation-utils.test.js b/lib/utils/validation-utils.test.js
--- a/lib/utils/validation-utils.test.js
+++ b/lib/utils/validation-utils.test.js
@@ -5,7 +5,7 @@
   tMediaMessageVideo,
   tNumEnum,
 } from './validation-utils.js';
-import { threadTypes } from '../types/thread-types.js';
+import { threadTypes } from '../types/thread-types-enum.js';
 import { values } from '../utils/objects.js';
 
 describe('Validation utils', () => {
diff --git a/native/avatars/thread-avatar.react.js b/native/avatars/thread-avatar.react.js
--- a/native/avatars/thread-avatar.react.js
+++ b/native/avatars/thread-avatar.react.js
@@ -7,11 +7,8 @@
   useENSResolvedAvatar,
 } from 'lib/shared/avatar-utils.js';
 import { getSingleOtherUser } from 'lib/shared/thread-utils.js';
-import {
-  threadTypes,
-  type RawThreadInfo,
-  type ThreadInfo,
-} from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
+import { type RawThreadInfo, type ThreadInfo } from 'lib/types/thread-types.js';
 
 import Avatar from './avatar.react.js';
 import { useSelector } from '../redux/redux-utils.js';
diff --git a/native/calendar/entry.react.js b/native/calendar/entry.react.js
--- a/native/calendar/entry.react.js
+++ b/native/calendar/entry.react.js
@@ -45,10 +45,10 @@
 } from 'lib/types/entry-types.js';
 import type { LoadingStatus } from 'lib/types/loading-types.js';
 import type { Dispatch } from 'lib/types/redux-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import {
   type ThreadInfo,
   type ResolvedThreadInfo,
-  threadPermissions,
 } from 'lib/types/thread-types.js';
 import {
   useServerCall,
diff --git a/native/chat/chat-input-bar.react.js b/native/chat/chat-input-bar.react.js
--- a/native/chat/chat-input-bar.react.js
+++ b/native/chat/chat-input-bar.react.js
@@ -64,9 +64,9 @@
   MessageInfo,
 } from 'lib/types/message-types.js';
 import type { Dispatch } from 'lib/types/redux-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import {
   type ThreadInfo,
-  threadPermissions,
   type ClientThreadJoinRequest,
   type ThreadJoinPayload,
   type RelativeMemberInfo,
diff --git a/native/chat/chat-thread-list.react.js b/native/chat/chat-thread-list.react.js
--- a/native/chat/chat-thread-list.react.js
+++ b/native/chat/chat-thread-list.react.js
@@ -30,8 +30,8 @@
   getThreadListSearchResults,
 } from 'lib/shared/thread-utils.js';
 import type { UserSearchResult } from 'lib/types/search-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 import type { ThreadInfo } from 'lib/types/thread-types.js';
-import { threadTypes } from 'lib/types/thread-types.js';
 import type {
   GlobalAccountUserInfo,
   UserInfo,
diff --git a/native/chat/compose-subchannel.react.js b/native/chat/compose-subchannel.react.js
--- a/native/chat/compose-subchannel.react.js
+++ b/native/chat/compose-subchannel.react.js
@@ -16,11 +16,8 @@
 } from 'lib/selectors/user-selectors.js';
 import { getPotentialMemberItems } from 'lib/shared/search-utils.js';
 import { threadInFilterList, userIsMember } from 'lib/shared/thread-utils.js';
-import {
-  type ThreadInfo,
-  type ThreadType,
-  threadTypes,
-} from 'lib/types/thread-types.js';
+import { type ThreadType, threadTypes } from 'lib/types/thread-types-enum.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
 import { type AccountUserInfo } from 'lib/types/user-types.js';
 import {
   useServerCall,
diff --git a/native/chat/compose-thread-button.react.js b/native/chat/compose-thread-button.react.js
--- a/native/chat/compose-thread-button.react.js
+++ b/native/chat/compose-thread-button.react.js
@@ -5,7 +5,7 @@
 
 import { useLoggedInUserInfo } from 'lib/hooks/account-hooks.js';
 import { createPendingThread } from 'lib/shared/thread-utils.js';
-import { threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 
 import type { ChatNavigationProp } from './chat.react.js';
 import Button from '../components/button.react.js';
diff --git a/native/chat/message-list.react.js b/native/chat/message-list.react.js
--- a/native/chat/message-list.react.js
+++ b/native/chat/message-list.react.js
@@ -17,7 +17,8 @@
 import { messageKey } from 'lib/shared/message-utils.js';
 import { useWatchThread } from 'lib/shared/thread-utils.js';
 import type { FetchMessageInfosPayload } from 'lib/types/message-types.js';
-import { type ThreadInfo, threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
 import {
   type DispatchActionPromise,
   useServerCall,
diff --git a/native/chat/multimedia-message.react.js b/native/chat/multimedia-message.react.js
--- a/native/chat/multimedia-message.react.js
+++ b/native/chat/multimedia-message.react.js
@@ -15,7 +15,7 @@
   useCanCreateSidebarFromMessage,
 } from 'lib/shared/thread-utils.js';
 import type { MediaInfo } from 'lib/types/media-types.js';
-import { threadPermissions } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 
 import ComposedMessage from './composed-message.react.js';
 import { InnerMultimediaMessage } from './inner-multimedia-message.react.js';
diff --git a/native/chat/parent-thread-header.react.js b/native/chat/parent-thread-header.react.js
--- a/native/chat/parent-thread-header.react.js
+++ b/native/chat/parent-thread-header.react.js
@@ -4,7 +4,8 @@
 import { View, Text } from 'react-native';
 import { ScrollView } from 'react-native-gesture-handler';
 
-import type { ThreadInfo, ThreadType } from 'lib/types/thread-types.js';
+import type { ThreadType } from 'lib/types/thread-types-enum.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
 
 import { useNavigateToThread } from './message-list-types.js';
 import Button from '../components/button.react.js';
diff --git a/native/chat/settings/compose-subchannel-modal.react.js b/native/chat/settings/compose-subchannel-modal.react.js
--- a/native/chat/settings/compose-subchannel-modal.react.js
+++ b/native/chat/settings/compose-subchannel-modal.react.js
@@ -5,7 +5,8 @@
 import { Text } from 'react-native';
 
 import { threadTypeDescriptions } from 'lib/shared/thread-utils.js';
-import { type ThreadInfo, threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
 
 import Button from '../../components/button.react.js';
 import Modal from '../../components/modal.react.js';
diff --git a/native/chat/settings/thread-settings-description.react.js b/native/chat/settings/thread-settings-description.react.js
--- a/native/chat/settings/thread-settings-description.react.js
+++ b/native/chat/settings/thread-settings-description.react.js
@@ -17,9 +17,9 @@
 import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
 import { threadHasPermission } from 'lib/shared/thread-utils.js';
 import type { LoadingStatus } from 'lib/types/loading-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import {
   type ThreadInfo,
-  threadPermissions,
   type ChangeThreadSettingsPayload,
   type UpdateThreadRequest,
 } from 'lib/types/thread-types.js';
diff --git a/native/chat/settings/thread-settings.react.js b/native/chat/settings/thread-settings.react.js
--- a/native/chat/settings/thread-settings.react.js
+++ b/native/chat/settings/thread-settings.react.js
@@ -29,12 +29,12 @@
 } from 'lib/shared/thread-utils.js';
 import threadWatcher from 'lib/shared/thread-watcher.js';
 import type { RelationshipButton } from 'lib/types/relationship-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 import {
   type ThreadInfo,
   type ResolvedThreadInfo,
   type RelativeMemberInfo,
-  threadPermissions,
-  threadTypes,
 } from 'lib/types/thread-types.js';
 import type { UserInfos } from 'lib/types/user-types.js';
 import {
diff --git a/native/chat/text-message.react.js b/native/chat/text-message.react.js
--- a/native/chat/text-message.react.js
+++ b/native/chat/text-message.react.js
@@ -10,7 +10,7 @@
   threadHasPermission,
   useCanCreateSidebarFromMessage,
 } from 'lib/shared/thread-utils.js';
-import { threadPermissions } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 
 import type { ChatNavigationProp } from './chat.react.js';
 import ComposedMessage from './composed-message.react.js';
diff --git a/native/components/thread-icon.react.js b/native/components/thread-icon.react.js
--- a/native/components/thread-icon.react.js
+++ b/native/components/thread-icon.react.js
@@ -4,7 +4,7 @@
 import * as React from 'react';
 import { StyleSheet } from 'react-native';
 
-import { threadTypes, type ThreadType } from 'lib/types/thread-types.js';
+import { threadTypes, type ThreadType } from 'lib/types/thread-types-enum.js';
 
 import SWMansionIcon from './swmansion-icon.react.js';
 
diff --git a/native/components/thread-visibility.react.js b/native/components/thread-visibility.react.js
--- a/native/components/thread-visibility.react.js
+++ b/native/components/thread-visibility.react.js
@@ -5,7 +5,7 @@
 import tinycolor from 'tinycolor2';
 
 import { threadLabel } from 'lib/shared/thread-utils.js';
-import type { ThreadType } from 'lib/types/thread-types.js';
+import type { ThreadType } from 'lib/types/thread-types-enum.js';
 
 import Pill from './pill.react.js';
 import ThreadIcon from './thread-icon.react.js';
diff --git a/native/input/input-state-container.react.js b/native/input/input-state-container.react.js
--- a/native/input/input-state-container.react.js
+++ b/native/input/input-state-container.react.js
@@ -79,11 +79,11 @@
   type MediaMissionReportCreationRequest,
   reportTypes,
 } from 'lib/types/report-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 import {
   type ClientNewThreadRequest,
   type NewThreadResult,
   type ThreadInfo,
-  threadTypes,
 } from 'lib/types/thread-types.js';
 import {
   type DispatchActionPromise,
diff --git a/native/redux/edit-thread-permission-migration.js b/native/redux/edit-thread-permission-migration.js
--- a/native/redux/edit-thread-permission-migration.js
+++ b/native/redux/edit-thread-permission-migration.js
@@ -1,12 +1,12 @@
 // @flow
 
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 import type {
   MemberInfo,
   ThreadCurrentUserInfo,
   RawThreadInfo,
   RoleInfo,
 } from 'lib/types/thread-types.js';
-import { threadTypes } from 'lib/types/thread-types.js';
 
 function addDetailedThreadEditPermissionsToUser<
   T: MemberInfo | ThreadCurrentUserInfo,
diff --git a/native/redux/update-roles-and-permissions.js b/native/redux/update-roles-and-permissions.js
--- a/native/redux/update-roles-and-permissions.js
+++ b/native/redux/update-roles-and-permissions.js
@@ -6,9 +6,9 @@
   makePermissionsBlob,
   makePermissionsForChildrenBlob,
 } from 'lib/permissions/thread-permissions.js';
+import type { ThreadPermissionsBlob } from 'lib/types/thread-permission-types.js';
 import type {
   RawThreadInfo,
-  ThreadPermissionsBlob,
   ThreadStoreThreadInfos,
   MemberInfo,
 } from 'lib/types/thread-types.js';
diff --git a/web/calendar/entry.react.js b/web/calendar/entry.react.js
--- a/web/calendar/entry.react.js
+++ b/web/calendar/entry.react.js
@@ -36,7 +36,7 @@
 } from 'lib/types/entry-types.js';
 import type { LoadingStatus } from 'lib/types/loading-types.js';
 import type { Dispatch } from 'lib/types/redux-types.js';
-import { threadPermissions } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import type { ResolvedThreadInfo } from 'lib/types/thread-types.js';
 import {
   type DispatchActionPromise,
diff --git a/web/chat/chat-input-bar.react.js b/web/chat/chat-input-bar.react.js
--- a/web/chat/chat-input-bar.react.js
+++ b/web/chat/chat-input-bar.react.js
@@ -30,9 +30,9 @@
 import type { CalendarQuery } from 'lib/types/entry-types.js';
 import type { LoadingStatus } from 'lib/types/loading-types.js';
 import { messageTypes } from 'lib/types/message-types-enum.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import {
   type ThreadInfo,
-  threadPermissions,
   type ClientThreadJoinRequest,
   type ThreadJoinPayload,
   type RelativeMemberInfo,
diff --git a/web/chat/chat-message-list.react.js b/web/chat/chat-message-list.react.js
--- a/web/chat/chat-message-list.react.js
+++ b/web/chat/chat-message-list.react.js
@@ -20,7 +20,8 @@
 import { messageKey } from 'lib/shared/message-utils.js';
 import { threadIsPending } from 'lib/shared/thread-utils.js';
 import type { FetchMessageInfosPayload } from 'lib/types/message-types.js';
-import { type ThreadInfo, threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
 import {
   type DispatchActionPromise,
   useServerCall,
diff --git a/web/chat/thread-list-provider.js b/web/chat/thread-list-provider.js
--- a/web/chat/thread-list-provider.js
+++ b/web/chat/thread-list-provider.js
@@ -17,7 +17,7 @@
   useThreadListSearch,
   threadIsPending,
 } from 'lib/shared/thread-utils.js';
-import { threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 
 import { useSelector } from '../redux/redux-utils.js';
 import {
diff --git a/web/chat/thread-menu.react.js b/web/chat/thread-menu.react.js
--- a/web/chat/thread-menu.react.js
+++ b/web/chat/thread-menu.react.js
@@ -15,11 +15,9 @@
   viewerIsMember,
   threadIsChannel,
 } from 'lib/shared/thread-utils.js';
-import {
-  type ThreadInfo,
-  threadTypes,
-  threadPermissions,
-} from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
 import {
   useServerCall,
   useDispatchActionPromise,
diff --git a/web/components/thread-avatar.react.js b/web/components/thread-avatar.react.js
--- a/web/components/thread-avatar.react.js
+++ b/web/components/thread-avatar.react.js
@@ -7,11 +7,8 @@
   useENSResolvedAvatar,
 } from 'lib/shared/avatar-utils.js';
 import { getSingleOtherUser } from 'lib/shared/thread-utils.js';
-import {
-  threadTypes,
-  type RawThreadInfo,
-  type ThreadInfo,
-} from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
+import { type RawThreadInfo, type ThreadInfo } from 'lib/types/thread-types.js';
 
 import Avatar from './avatar.react.js';
 import { useSelector } from '../redux/redux-utils.js';
diff --git a/web/input/input-state-container.react.js b/web/input/input-state-container.react.js
--- a/web/input/input-state-container.react.js
+++ b/web/input/input-state-container.react.js
@@ -75,12 +75,12 @@
 import type { RawTextMessageInfo } from 'lib/types/messages/text.js';
 import type { Dispatch } from 'lib/types/redux-types.js';
 import { reportTypes } from 'lib/types/report-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 import {
   type ClientNewThreadRequest,
   type NewThreadResult,
   type ThreadInfo,
   type RawThreadInfo,
-  threadTypes,
 } from 'lib/types/thread-types.js';
 import {
   type DispatchActionPromise,
diff --git a/web/modals/threads/create/compose-subchannel-modal.react.js b/web/modals/threads/create/compose-subchannel-modal.react.js
--- a/web/modals/threads/create/compose-subchannel-modal.react.js
+++ b/web/modals/threads/create/compose-subchannel-modal.react.js
@@ -4,8 +4,8 @@
 
 import { newThread, newThreadActionTypes } from 'lib/actions/thread-actions.js';
 import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 import type { ThreadInfo } from 'lib/types/thread-types.js';
-import { threadTypes } from 'lib/types/thread-types.js';
 import {
   useDispatchActionPromise,
   useServerCall,
diff --git a/web/modals/threads/create/steps/subchannel-settings.react.js b/web/modals/threads/create/steps/subchannel-settings.react.js
--- a/web/modals/threads/create/steps/subchannel-settings.react.js
+++ b/web/modals/threads/create/steps/subchannel-settings.react.js
@@ -4,7 +4,7 @@
 
 import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
 import { threadTypeDescriptions } from 'lib/shared/thread-utils.js';
-import { threadTypes } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
 
 import css from './subchannel-settings.css';
 import CommIcon from '../../../../CommIcon.react.js';
diff --git a/web/modals/threads/members/members-modal.react.js b/web/modals/threads/members/members-modal.react.js
--- a/web/modals/threads/members/members-modal.react.js
+++ b/web/modals/threads/members/members-modal.react.js
@@ -10,10 +10,8 @@
   memberIsAdmin,
   threadHasPermission,
 } from 'lib/shared/thread-utils.js';
-import {
-  type RelativeMemberInfo,
-  threadPermissions,
-} from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
+import { type RelativeMemberInfo } from 'lib/types/thread-types.js';
 
 import AddMembersModal from './add-members-modal.react.js';
 import ThreadMembersList from './members-list.react.js';
diff --git a/web/modals/threads/settings/thread-settings-general-tab.react.js b/web/modals/threads/settings/thread-settings-general-tab.react.js
--- a/web/modals/threads/settings/thread-settings-general-tab.react.js
+++ b/web/modals/threads/settings/thread-settings-general-tab.react.js
@@ -12,11 +12,8 @@
   chatNameMaxLength,
 } from 'lib/shared/thread-utils.js';
 import { type SetState } from 'lib/types/hook-types.js';
-import {
-  type ThreadInfo,
-  type ThreadChanges,
-  threadPermissions,
-} from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
+import { type ThreadInfo, type ThreadChanges } from 'lib/types/thread-types.js';
 import {
   useDispatchActionPromise,
   useServerCall,
diff --git a/web/modals/threads/settings/thread-settings-modal.react.js b/web/modals/threads/settings/thread-settings-modal.react.js
--- a/web/modals/threads/settings/thread-settings-modal.react.js
+++ b/web/modals/threads/settings/thread-settings-modal.react.js
@@ -16,12 +16,9 @@
   getSingleOtherUser,
   threadUIName,
 } from 'lib/shared/thread-utils.js';
-import {
-  type ThreadInfo,
-  threadTypes,
-  threadPermissions,
-  type ThreadChanges,
-} from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
+import { type ThreadInfo, type ThreadChanges } from 'lib/types/thread-types.js';
 import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
 
 import ThreadSettingsDeleteTab from './thread-settings-delete-tab.react.js';
diff --git a/web/modals/threads/settings/thread-settings-privacy-tab.react.js b/web/modals/threads/settings/thread-settings-privacy-tab.react.js
--- a/web/modals/threads/settings/thread-settings-privacy-tab.react.js
+++ b/web/modals/threads/settings/thread-settings-privacy-tab.react.js
@@ -10,11 +10,8 @@
 import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
 import { threadTypeDescriptions } from 'lib/shared/thread-utils.js';
 import { type SetState } from 'lib/types/hook-types.js';
-import {
-  type ThreadInfo,
-  type ThreadChanges,
-  threadTypes,
-} from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
+import { type ThreadInfo, type ThreadChanges } from 'lib/types/thread-types.js';
 import {
   useDispatchActionPromise,
   useServerCall,
diff --git a/web/utils/thread-utils.js b/web/utils/thread-utils.js
--- a/web/utils/thread-utils.js
+++ b/web/utils/thread-utils.js
@@ -10,7 +10,8 @@
   createPendingThread,
   useExistingThreadInfoFinder,
 } from 'lib/shared/thread-utils.js';
-import { threadTypes, type ThreadInfo } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types-enum.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
 import type { AccountUserInfo } from 'lib/types/user-types.js';
 
 import { useSelector } from '../redux/redux-utils.js';
diff --git a/web/utils/tooltip-action-utils.js b/web/utils/tooltip-action-utils.js
--- a/web/utils/tooltip-action-utils.js
+++ b/web/utils/tooltip-action-utils.js
@@ -14,8 +14,8 @@
 } from 'lib/shared/thread-utils.js';
 import { messageTypes } from 'lib/types/message-types-enum.js';
 import { isComposableMessageType } from 'lib/types/message-types.js';
+import { threadPermissions } from 'lib/types/thread-permission-types.js';
 import type { ThreadInfo } from 'lib/types/thread-types.js';
-import { threadPermissions } from 'lib/types/thread-types.js';
 import { longAbsoluteDate } from 'lib/utils/date-utils.js';
 
 import {