@ttt-productions/ttt-core 0.79.59 → 0.79.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/dist/capabilities/capability-registry.d.ts +4 -4
  2. package/dist/capabilities/capability-registry.d.ts.map +1 -1
  3. package/dist/capabilities/capability-registry.js.map +1 -1
  4. package/dist/constants/admin-labels.d.ts +29 -1
  5. package/dist/constants/admin-labels.d.ts.map +1 -1
  6. package/dist/constants/admin-labels.js +78 -0
  7. package/dist/constants/admin-labels.js.map +1 -1
  8. package/dist/constants/analytics.d.ts +3 -0
  9. package/dist/constants/analytics.d.ts.map +1 -0
  10. package/dist/constants/analytics.js +16 -0
  11. package/dist/constants/analytics.js.map +1 -0
  12. package/dist/constants/app-mode.d.ts +2 -0
  13. package/dist/constants/app-mode.d.ts.map +1 -1
  14. package/dist/constants/app-mode.js +10 -0
  15. package/dist/constants/app-mode.js.map +1 -1
  16. package/dist/constants/business-admin.d.ts +15 -0
  17. package/dist/constants/business-admin.d.ts.map +1 -1
  18. package/dist/constants/business-admin.js +15 -0
  19. package/dist/constants/business-admin.js.map +1 -1
  20. package/dist/constants/business-content.d.ts +2 -0
  21. package/dist/constants/business-content.d.ts.map +1 -1
  22. package/dist/constants/business-content.js +2 -0
  23. package/dist/constants/business-content.js.map +1 -1
  24. package/dist/constants/business-platform.d.ts +4 -0
  25. package/dist/constants/business-platform.d.ts.map +1 -1
  26. package/dist/constants/business-platform.js +4 -0
  27. package/dist/constants/business-platform.js.map +1 -1
  28. package/dist/constants/index.d.ts +1 -0
  29. package/dist/constants/index.d.ts.map +1 -1
  30. package/dist/constants/index.js +1 -0
  31. package/dist/constants/index.js.map +1 -1
  32. package/dist/constants/pagination.d.ts +2 -0
  33. package/dist/constants/pagination.d.ts.map +1 -1
  34. package/dist/constants/pagination.js +2 -0
  35. package/dist/constants/pagination.js.map +1 -1
  36. package/dist/doc-schemas/backend-state.d.ts +0 -11
  37. package/dist/doc-schemas/backend-state.d.ts.map +1 -1
  38. package/dist/doc-schemas/backend-state.js +1 -44
  39. package/dist/doc-schemas/backend-state.js.map +1 -1
  40. package/dist/doc-schemas/commissions.d.ts.map +1 -1
  41. package/dist/doc-schemas/commissions.js +3 -2
  42. package/dist/doc-schemas/commissions.js.map +1 -1
  43. package/dist/doc-schemas/erasure-fates.d.ts +1 -0
  44. package/dist/doc-schemas/erasure-fates.d.ts.map +1 -1
  45. package/dist/doc-schemas/erasure-fates.js +1 -0
  46. package/dist/doc-schemas/erasure-fates.js.map +1 -1
  47. package/dist/doc-schemas/index.d.ts +1 -0
  48. package/dist/doc-schemas/index.d.ts.map +1 -1
  49. package/dist/doc-schemas/index.js +1 -0
  50. package/dist/doc-schemas/index.js.map +1 -1
  51. package/dist/doc-schemas/messaging.d.ts +66 -0
  52. package/dist/doc-schemas/messaging.d.ts.map +1 -1
  53. package/dist/doc-schemas/messaging.js +14 -6
  54. package/dist/doc-schemas/messaging.js.map +1 -1
  55. package/dist/doc-schemas/moderation.d.ts +10 -5
  56. package/dist/doc-schemas/moderation.d.ts.map +1 -1
  57. package/dist/doc-schemas/moderation.js +13 -1
  58. package/dist/doc-schemas/moderation.js.map +1 -1
  59. package/dist/doc-schemas/ncii/allegations.d.ts +2 -2
  60. package/dist/doc-schemas/ncii/requests.d.ts +1 -1
  61. package/dist/doc-schemas/notification-ledger.d.ts +3 -0
  62. package/dist/doc-schemas/notification-ledger.d.ts.map +1 -1
  63. package/dist/doc-schemas/notification-ledger.js +3 -1
  64. package/dist/doc-schemas/notification-ledger.js.map +1 -1
  65. package/dist/doc-schemas/operational.d.ts +2 -0
  66. package/dist/doc-schemas/operational.d.ts.map +1 -1
  67. package/dist/doc-schemas/operational.js +7 -6
  68. package/dist/doc-schemas/operational.js.map +1 -1
  69. package/dist/doc-schemas/payments.d.ts +70 -0
  70. package/dist/doc-schemas/payments.d.ts.map +1 -1
  71. package/dist/doc-schemas/payments.js +106 -20
  72. package/dist/doc-schemas/payments.js.map +1 -1
  73. package/dist/doc-schemas/registry.d.ts +70 -25
  74. package/dist/doc-schemas/registry.d.ts.map +1 -1
  75. package/dist/doc-schemas/registry.js +2 -1
  76. package/dist/doc-schemas/registry.js.map +1 -1
  77. package/dist/doc-schemas/report-docs.d.ts +3 -0
  78. package/dist/doc-schemas/report-docs.d.ts.map +1 -1
  79. package/dist/doc-schemas/report-docs.js +2 -0
  80. package/dist/doc-schemas/report-docs.js.map +1 -1
  81. package/dist/doc-schemas/safety/age.d.ts +1 -5
  82. package/dist/doc-schemas/safety/age.d.ts.map +1 -1
  83. package/dist/doc-schemas/safety/age.js +4 -5
  84. package/dist/doc-schemas/safety/age.js.map +1 -1
  85. package/dist/doc-schemas/safety/case.d.ts +59 -6
  86. package/dist/doc-schemas/safety/case.d.ts.map +1 -1
  87. package/dist/doc-schemas/safety/case.js +111 -18
  88. package/dist/doc-schemas/safety/case.js.map +1 -1
  89. package/dist/doc-schemas/safety/foundation.d.ts +10 -13
  90. package/dist/doc-schemas/safety/foundation.d.ts.map +1 -1
  91. package/dist/doc-schemas/safety/foundation.js +10 -12
  92. package/dist/doc-schemas/safety/foundation.js.map +1 -1
  93. package/dist/doc-schemas/safety/holds.d.ts +1 -1
  94. package/dist/doc-schemas/safety/provenance.d.ts +0 -4
  95. package/dist/doc-schemas/safety/provenance.d.ts.map +1 -1
  96. package/dist/doc-schemas/safety/provenance.js +2 -5
  97. package/dist/doc-schemas/safety/provenance.js.map +1 -1
  98. package/dist/doc-schemas/safety/report.d.ts +10 -10
  99. package/dist/doc-schemas/social.d.ts +2 -2
  100. package/dist/doc-schemas/social.d.ts.map +1 -1
  101. package/dist/doc-schemas/social.js +7 -3
  102. package/dist/doc-schemas/social.js.map +1 -1
  103. package/dist/doc-schemas/square-announcement-jobs.d.ts +3 -3
  104. package/dist/doc-schemas/sweep-cursor.d.ts +13 -0
  105. package/dist/doc-schemas/sweep-cursor.d.ts.map +1 -0
  106. package/dist/doc-schemas/sweep-cursor.js +50 -0
  107. package/dist/doc-schemas/sweep-cursor.js.map +1 -0
  108. package/dist/doc-schemas/user.d.ts.map +1 -1
  109. package/dist/doc-schemas/user.js +2 -2
  110. package/dist/doc-schemas/user.js.map +1 -1
  111. package/dist/doc-schemas/work-project.d.ts +0 -2
  112. package/dist/doc-schemas/work-project.d.ts.map +1 -1
  113. package/dist/doc-schemas/work-project.js +8 -6
  114. package/dist/doc-schemas/work-project.js.map +1 -1
  115. package/dist/media/atoms.d.ts +57 -0
  116. package/dist/media/atoms.d.ts.map +1 -1
  117. package/dist/media/atoms.js +88 -2
  118. package/dist/media/atoms.js.map +1 -1
  119. package/dist/media/edge-serving-contract.d.ts.map +1 -1
  120. package/dist/media/edge-serving-contract.js +2 -1
  121. package/dist/media/edge-serving-contract.js.map +1 -1
  122. package/dist/media/index.d.ts +1 -1
  123. package/dist/media/index.d.ts.map +1 -1
  124. package/dist/media/index.js +1 -1
  125. package/dist/media/index.js.map +1 -1
  126. package/dist/media/target-info.d.ts +1 -1
  127. package/dist/media/target-info.d.ts.map +1 -1
  128. package/dist/media/target-info.js +27 -29
  129. package/dist/media/target-info.js.map +1 -1
  130. package/dist/paths/collections.d.ts +1 -0
  131. package/dist/paths/collections.d.ts.map +1 -1
  132. package/dist/paths/collections.js +2 -0
  133. package/dist/paths/collections.js.map +1 -1
  134. package/dist/paths/path-builders.d.ts +2 -0
  135. package/dist/paths/path-builders.d.ts.map +1 -1
  136. package/dist/paths/path-builders.js +3 -0
  137. package/dist/paths/path-builders.js.map +1 -1
  138. package/dist/paths/related-ids.d.ts +2 -0
  139. package/dist/paths/related-ids.d.ts.map +1 -1
  140. package/dist/paths/related-ids.js +5 -4
  141. package/dist/paths/related-ids.js.map +1 -1
  142. package/dist/report/report-config-values.d.ts.map +1 -1
  143. package/dist/report/report-config-values.js +7 -0
  144. package/dist/report/report-config-values.js.map +1 -1
  145. package/dist/schemas/admin-dispatch-actions.d.ts +0 -11
  146. package/dist/schemas/admin-dispatch-actions.d.ts.map +1 -1
  147. package/dist/schemas/admin-dispatch-actions.js +0 -14
  148. package/dist/schemas/admin-dispatch-actions.js.map +1 -1
  149. package/dist/schemas/admin.d.ts +6 -6
  150. package/dist/schemas/admin.d.ts.map +1 -1
  151. package/dist/schemas/admin.js +32 -32
  152. package/dist/schemas/admin.js.map +1 -1
  153. package/dist/schemas/atoms.d.ts +26 -0
  154. package/dist/schemas/atoms.d.ts.map +1 -1
  155. package/dist/schemas/atoms.js +77 -33
  156. package/dist/schemas/atoms.js.map +1 -1
  157. package/dist/schemas/chat.d.ts.map +1 -1
  158. package/dist/schemas/chat.js +6 -6
  159. package/dist/schemas/chat.js.map +1 -1
  160. package/dist/schemas/conversation-files.d.ts.map +1 -1
  161. package/dist/schemas/conversation-files.js +2 -1
  162. package/dist/schemas/conversation-files.js.map +1 -1
  163. package/dist/schemas/hall-library.d.ts.map +1 -1
  164. package/dist/schemas/hall-library.js +4 -4
  165. package/dist/schemas/hall-library.js.map +1 -1
  166. package/dist/schemas/index.d.ts +1 -0
  167. package/dist/schemas/index.d.ts.map +1 -1
  168. package/dist/schemas/index.js +1 -0
  169. package/dist/schemas/index.js.map +1 -1
  170. package/dist/schemas/ncii.d.ts +56 -6
  171. package/dist/schemas/ncii.d.ts.map +1 -1
  172. package/dist/schemas/ncii.js +94 -23
  173. package/dist/schemas/ncii.js.map +1 -1
  174. package/dist/schemas/notification.d.ts +33 -3
  175. package/dist/schemas/notification.d.ts.map +1 -1
  176. package/dist/schemas/notification.js +42 -12
  177. package/dist/schemas/notification.js.map +1 -1
  178. package/dist/schemas/payments.d.ts +15 -0
  179. package/dist/schemas/payments.d.ts.map +1 -1
  180. package/dist/schemas/payments.js +24 -7
  181. package/dist/schemas/payments.js.map +1 -1
  182. package/dist/schemas/safety.d.ts +63 -73
  183. package/dist/schemas/safety.d.ts.map +1 -1
  184. package/dist/schemas/safety.js +44 -71
  185. package/dist/schemas/safety.js.map +1 -1
  186. package/dist/schemas/social.d.ts +1 -1
  187. package/dist/schemas/social.d.ts.map +1 -1
  188. package/dist/schemas/social.js +10 -12
  189. package/dist/schemas/social.js.map +1 -1
  190. package/dist/schemas/stake-share-operation.d.ts.map +1 -1
  191. package/dist/schemas/stake-share-operation.js +7 -7
  192. package/dist/schemas/stake-share-operation.js.map +1 -1
  193. package/dist/schemas/uploads.d.ts.map +1 -1
  194. package/dist/schemas/uploads.js +3 -2
  195. package/dist/schemas/uploads.js.map +1 -1
  196. package/dist/schemas/utility.d.ts +3 -10
  197. package/dist/schemas/utility.d.ts.map +1 -1
  198. package/dist/schemas/utility.js +9 -12
  199. package/dist/schemas/utility.js.map +1 -1
  200. package/dist/schemas/voting.js +1 -1
  201. package/dist/schemas/voting.js.map +1 -1
  202. package/dist/schemas/work-project-management.d.ts +1 -0
  203. package/dist/schemas/work-project-management.d.ts.map +1 -1
  204. package/dist/schemas/work-project-management.js +21 -17
  205. package/dist/schemas/work-project-management.js.map +1 -1
  206. package/dist/types/admin-ops.d.ts +2 -1
  207. package/dist/types/admin-ops.d.ts.map +1 -1
  208. package/dist/types/admin-ops.js.map +1 -1
  209. package/dist/types/audit.d.ts +1 -1
  210. package/dist/types/audit.d.ts.map +1 -1
  211. package/dist/types/audit.js.map +1 -1
  212. package/dist/upload-variables/create-audition-entry-variables.d.ts.map +1 -1
  213. package/dist/upload-variables/create-audition-entry-variables.js +2 -1
  214. package/dist/upload-variables/create-audition-entry-variables.js.map +1 -1
  215. package/dist/upload-variables/create-commission-variables.d.ts.map +1 -1
  216. package/dist/upload-variables/create-commission-variables.js +2 -1
  217. package/dist/upload-variables/create-commission-variables.js.map +1 -1
  218. package/dist/upload-variables/create-work-project-audition-variables.d.ts.map +1 -1
  219. package/dist/upload-variables/create-work-project-audition-variables.js +2 -1
  220. package/dist/upload-variables/create-work-project-audition-variables.js.map +1 -1
  221. package/dist/upload-variables/square-streetz-post-variables.d.ts +1 -1
  222. package/dist/upload-variables/square-streetz-post-variables.d.ts.map +1 -1
  223. package/dist/upload-variables/square-streetz-post-variables.js +4 -7
  224. package/dist/upload-variables/square-streetz-post-variables.js.map +1 -1
  225. package/dist/upload-variables/update-chapter-media-variables.d.ts.map +1 -1
  226. package/dist/upload-variables/update-chapter-media-variables.js +4 -3
  227. package/dist/upload-variables/update-chapter-media-variables.js.map +1 -1
  228. package/dist/upload-variables/update-episode-media-variables.d.ts.map +1 -1
  229. package/dist/upload-variables/update-episode-media-variables.js +4 -3
  230. package/dist/upload-variables/update-episode-media-variables.js.map +1 -1
  231. package/dist/upload-variables/update-tale-cover-photo-variables.d.ts.map +1 -1
  232. package/dist/upload-variables/update-tale-cover-photo-variables.js +3 -2
  233. package/dist/upload-variables/update-tale-cover-photo-variables.js.map +1 -1
  234. package/dist/upload-variables/update-television-cover-photo-variables.d.ts.map +1 -1
  235. package/dist/upload-variables/update-television-cover-photo-variables.js +3 -2
  236. package/dist/upload-variables/update-television-cover-photo-variables.js.map +1 -1
  237. package/dist/upload-variables/update-track-media-variables.d.ts.map +1 -1
  238. package/dist/upload-variables/update-track-media-variables.js +4 -3
  239. package/dist/upload-variables/update-track-media-variables.js.map +1 -1
  240. package/dist/upload-variables/update-tune-cover-photo-variables.d.ts.map +1 -1
  241. package/dist/upload-variables/update-tune-cover-photo-variables.js +3 -2
  242. package/dist/upload-variables/update-tune-cover-photo-variables.js.map +1 -1
  243. package/dist/upload-variables/upload-work-file-variables.d.ts.map +1 -1
  244. package/dist/upload-variables/upload-work-file-variables.js +3 -2
  245. package/dist/upload-variables/upload-work-file-variables.js.map +1 -1
  246. package/dist/utils/admin-standing.d.ts +15 -0
  247. package/dist/utils/admin-standing.d.ts.map +1 -0
  248. package/dist/utils/admin-standing.js +29 -0
  249. package/dist/utils/admin-standing.js.map +1 -0
  250. package/dist/utils/index.d.ts +4 -0
  251. package/dist/utils/index.d.ts.map +1 -1
  252. package/dist/utils/index.js +4 -0
  253. package/dist/utils/index.js.map +1 -1
  254. package/dist/utils/pledge-refund-eligibility.d.ts +30 -0
  255. package/dist/utils/pledge-refund-eligibility.d.ts.map +1 -0
  256. package/dist/utils/pledge-refund-eligibility.js +49 -0
  257. package/dist/utils/pledge-refund-eligibility.js.map +1 -0
  258. package/dist/utils/work-file-folder.d.ts +12 -0
  259. package/dist/utils/work-file-folder.d.ts.map +1 -0
  260. package/dist/utils/work-file-folder.js +26 -0
  261. package/dist/utils/work-file-folder.js.map +1 -0
  262. package/dist/utils/work-realm-eligibility.d.ts +26 -0
  263. package/dist/utils/work-realm-eligibility.d.ts.map +1 -0
  264. package/dist/utils/work-realm-eligibility.js +19 -0
  265. package/dist/utils/work-realm-eligibility.js.map +1 -0
  266. package/package.json +3 -3
@@ -9,8 +9,8 @@ export interface CapabilityDefinition {
9
9
  id: CapabilityId;
10
10
  /** Human-facing summary (admin/debug only; not user copy). */
11
11
  description: string;
12
- /** The age gate. `adult18Plus` capabilities are server-enforced; the claim is
13
- * NOT the sole authority (accountCapabilityVersion + privateData re-check). */
12
+ /** The age gate. `adult18Plus` capabilities are server-enforced against the age flag
13
+ * the backend reads from `privateData`; no age claim exists on the token. */
14
14
  ageRequirement: CapabilityAgeRequirement;
15
15
  /** When true, BOTH ends must satisfy the requirement (no-minor-messaging). */
16
16
  bilateral: boolean;
@@ -26,8 +26,8 @@ export declare const ADULT_ONLY_UPLOAD_ORIGINS: readonly ["squareStreetz", "comm
26
26
  export declare const CAPABILITY_REGISTRY: Record<CapabilityId, CapabilityDefinition>;
27
27
  /** All capability ids (for exhaustiveness tests + iteration). */
28
28
  export declare const ALL_CAPABILITY_IDS: CapabilityId[];
29
- /** The actor's age-relevant view, derived server-side from privateData (the
30
- * claim is corroborating, never sole authority). */
29
+ /** The actor's age-relevant view, read server-side from privateData — the only age
30
+ * authority; the token carries no age claim. */
31
31
  export interface AgeCapabilityContext {
32
32
  is18Plus: boolean;
33
33
  accountCapabilityVersion: number;
@@ -1 +1 @@
1
- {"version":3,"file":"capability-registry.d.ts","sourceRoot":"","sources":["../../src/capabilities/capability-registry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D;;6CAE6C;AAC7C,MAAM,MAAM,YAAY,GACpB,uBAAuB,GACvB,aAAa,GACb,yBAAyB,GACzB,eAAe,GACf,uBAAuB,GACvB,gBAAgB,GAChB,qBAAqB,GACrB,kCAAkC,GAClC,6BAA6B,GAC7B,kBAAkB,GAClB,eAAe,CAAC;AAEpB,gDAAgD;AAChD,MAAM,MAAM,wBAAwB,GAChC,aAAa,GACb,MAAM,CAAC;AAEX,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,YAAY,CAAC;IACjB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB;mFAC+E;IAC/E,cAAc,EAAE,wBAAwB,CAAC;IACzC,8EAA8E;IAC9E,SAAS,EAAE,OAAO,CAAC;IACnB;4DACwD;IACxD,aAAa,EAAE,SAAS,UAAU,EAAE,CAAC;CACtC;AAED;;;+DAG+D;AAC/D,eAAO,MAAM,yBAAyB,wWAiBI,CAAC;AAE3C,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,YAAY,EAAE,oBAAoB,CA8E1E,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,kBAAkB,EAAuC,YAAY,EAAE,CAAC;AAErF;oDACoD;AACpD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAED,gEAAgE;AAChE,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,YAAY,EACxB,GAAG,EAAE,oBAAoB,GACxB,OAAO,CAIT;AAED,4CAA4C;AAC5C,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAElE"}
1
+ {"version":3,"file":"capability-registry.d.ts","sourceRoot":"","sources":["../../src/capabilities/capability-registry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D;;6CAE6C;AAC7C,MAAM,MAAM,YAAY,GACpB,uBAAuB,GACvB,aAAa,GACb,yBAAyB,GACzB,eAAe,GACf,uBAAuB,GACvB,gBAAgB,GAChB,qBAAqB,GACrB,kCAAkC,GAClC,6BAA6B,GAC7B,kBAAkB,GAClB,eAAe,CAAC;AAEpB,gDAAgD;AAChD,MAAM,MAAM,wBAAwB,GAChC,aAAa,GACb,MAAM,CAAC;AAEX,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,YAAY,CAAC;IACjB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB;iFAC6E;IAC7E,cAAc,EAAE,wBAAwB,CAAC;IACzC,8EAA8E;IAC9E,SAAS,EAAE,OAAO,CAAC;IACnB;4DACwD;IACxD,aAAa,EAAE,SAAS,UAAU,EAAE,CAAC;CACtC;AAED;;;+DAG+D;AAC/D,eAAO,MAAM,yBAAyB,wWAiBI,CAAC;AAE3C,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,YAAY,EAAE,oBAAoB,CA8E1E,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,kBAAkB,EAAuC,YAAY,EAAE,CAAC;AAErF;gDACgD;AAChD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAED,gEAAgE;AAChE,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,YAAY,EACxB,GAAG,EAAE,oBAAoB,GACxB,OAAO,CAIT;AAED,4CAA4C;AAC5C,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAElE"}
@@ -1 +1 @@
1
- {"version":3,"file":"capability-registry.js","sourceRoot":"","sources":["../../src/capabilities/capability-registry.ts"],"names":[],"mappings":"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","sourcesContent":["// ============================================================================\n// CAPABILITY REGISTRY — the ONE declaration of the age/eligibility capability\n// model (Phase 6). Consolidated here 2026-07-13 from the former byte-for-byte\n// mirrors in ttt-prod `src/lib/capabilities/capability-registry.ts` and\n// `functions/src/shared/capability-registry.ts` (both trees now import this;\n// the two-tree sync tests are deleted). Upload origins are compile-linked to\n// the canonical `FileOrigin` union — an origin rename fails the build here.\n// ============================================================================\n\nimport type { FileOrigin } from '../media/file-origin.js';\n\n/** Every age/eligibility-gated capability id. Past-tense/imperative-neutral,\n * dotted-namespace. Adding a value here REQUIRES adding it to CAPABILITY_REGISTRY\n * (the exhaustive test enforces the 1:1). */\nexport type CapabilityId =\n | 'account.becomeArtisan'\n | 'square.post'\n | 'square.acceptAgreements'\n | 'pledge.create'\n | 'messaging.guildInvite'\n | 'messaging.send'\n | 'messaging.fileShare'\n | 'collaboration.commissionProposal'\n | 'collaboration.auditionEntry'\n | 'stakeShares.hold'\n | 'upload.origin';\n\n/** The age requirement a capability imposes. */\nexport type CapabilityAgeRequirement =\n | 'adult18Plus' // both actor (and, for messaging, recipient) must be 18+\n | 'none'; // available to any eligible (13+) account\n\nexport interface CapabilityDefinition {\n id: CapabilityId;\n /** Human-facing summary (admin/debug only; not user copy). */\n description: string;\n /** The age gate. `adult18Plus` capabilities are server-enforced; the claim is\n * NOT the sole authority (accountCapabilityVersion + privateData re-check). */\n ageRequirement: CapabilityAgeRequirement;\n /** When true, BOTH ends must satisfy the requirement (no-minor-messaging). */\n bilateral: boolean;\n /** Upload origins this capability governs (for the startUpload gate). Empty\n * unless the capability is `upload.origin`-adjacent. */\n uploadOrigins: readonly FileOrigin[];\n}\n\n/** Upload origins that require an 18+ account to initiate (origin-level gate, not\n * just the create callable — Phase 6 item 3). Origins tied to artisan-only\n * surfaces (collaboration, hall publication, work assets) are 18+ because only\n * 18+ accounts can be artisan creators / hold stake shares. */\nexport const ADULT_ONLY_UPLOAD_ORIGINS = [\n 'squareStreetz',\n 'commission-posting',\n 'commission-proposal',\n 'audition-prompt',\n 'audition-entry',\n 'hallLibrary-cover-square',\n 'hallLibrary-cover-poster',\n 'hallLibrary-cover-cinematic',\n 'realm-cover',\n 'chapter-photo',\n 'tune-track-photo',\n 'tune-track-audio',\n 'television-episode-photo',\n 'television-episode-video',\n 'conversation-file',\n 'work-asset',\n] as const satisfies readonly FileOrigin[];\n\nexport const CAPABILITY_REGISTRY: Record<CapabilityId, CapabilityDefinition> = {\n 'account.becomeArtisan': {\n id: 'account.becomeArtisan',\n description: 'Become an artisan creator (privilege + stake-share eligibility).',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: [],\n },\n 'square.post': {\n id: 'square.post',\n description: 'Create a Square Streetz post.',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: ['squareStreetz'],\n },\n 'square.acceptAgreements': {\n id: 'square.acceptAgreements',\n description: 'Accept the Square Streetz posting agreements.',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: [],\n },\n 'pledge.create': {\n id: 'pledge.create',\n description: 'Create a pledge / payment (18+ only, pledge-only payments).',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: [],\n },\n 'messaging.guildInvite': {\n id: 'messaging.guildInvite',\n description: 'Send a guild invite (opens an invite-conversation thread).',\n ageRequirement: 'adult18Plus',\n bilateral: true,\n uploadOrigins: [],\n },\n 'messaging.send': {\n id: 'messaging.send',\n description: 'Send a chat / invite-thread message.',\n ageRequirement: 'adult18Plus',\n bilateral: true,\n uploadOrigins: [],\n },\n 'messaging.fileShare': {\n id: 'messaging.fileShare',\n description: 'Share a Conversation File in an invite / admin-support conversation.',\n ageRequirement: 'adult18Plus',\n bilateral: true,\n uploadOrigins: ['conversation-file'],\n },\n 'collaboration.commissionProposal': {\n id: 'collaboration.commissionProposal',\n description: 'Submit a commission proposal (artisan collaboration surface).',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: ['commission-proposal'],\n },\n 'collaboration.auditionEntry': {\n id: 'collaboration.auditionEntry',\n description: 'Submit an audition entry (artisan collaboration surface).',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: ['audition-entry'],\n },\n 'stakeShares.hold': {\n id: 'stakeShares.hold',\n description: 'Hold stake shares (guild membership / revenue).',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: [],\n },\n 'upload.origin': {\n id: 'upload.origin',\n description: 'Initiate an upload for an adult-only origin (startUpload gate).',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: ADULT_ONLY_UPLOAD_ORIGINS,\n },\n};\n\n/** All capability ids (for exhaustiveness tests + iteration). */\nexport const ALL_CAPABILITY_IDS = Object.keys(CAPABILITY_REGISTRY) as CapabilityId[];\n\n/** The actor's age-relevant view, derived server-side from privateData (the\n * claim is corroborating, never sole authority). */\nexport interface AgeCapabilityContext {\n is18Plus: boolean;\n accountCapabilityVersion: number;\n}\n\n/** Does this context satisfy a capability's age requirement? */\nexport function contextSatisfies(\n capability: CapabilityId,\n ctx: AgeCapabilityContext,\n): boolean {\n const def = CAPABILITY_REGISTRY[capability];\n if (def.ageRequirement === 'none') return true;\n return ctx.is18Plus === true;\n}\n\n/** Is the given upload origin 18+-gated? */\nexport function uploadOriginRequires18Plus(origin: string): boolean {\n return (ADULT_ONLY_UPLOAD_ORIGINS as readonly string[]).includes(origin);\n}\n"]}
1
+ {"version":3,"file":"capability-registry.js","sourceRoot":"","sources":["../../src/capabilities/capability-registry.ts"],"names":[],"mappings":"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","sourcesContent":["// ============================================================================\n// CAPABILITY REGISTRY — the ONE declaration of the age/eligibility capability\n// model (Phase 6). Consolidated here 2026-07-13 from the former byte-for-byte\n// mirrors in ttt-prod `src/lib/capabilities/capability-registry.ts` and\n// `functions/src/shared/capability-registry.ts` (both trees now import this;\n// the two-tree sync tests are deleted). Upload origins are compile-linked to\n// the canonical `FileOrigin` union — an origin rename fails the build here.\n// ============================================================================\n\nimport type { FileOrigin } from '../media/file-origin.js';\n\n/** Every age/eligibility-gated capability id. Past-tense/imperative-neutral,\n * dotted-namespace. Adding a value here REQUIRES adding it to CAPABILITY_REGISTRY\n * (the exhaustive test enforces the 1:1). */\nexport type CapabilityId =\n | 'account.becomeArtisan'\n | 'square.post'\n | 'square.acceptAgreements'\n | 'pledge.create'\n | 'messaging.guildInvite'\n | 'messaging.send'\n | 'messaging.fileShare'\n | 'collaboration.commissionProposal'\n | 'collaboration.auditionEntry'\n | 'stakeShares.hold'\n | 'upload.origin';\n\n/** The age requirement a capability imposes. */\nexport type CapabilityAgeRequirement =\n | 'adult18Plus' // both actor (and, for messaging, recipient) must be 18+\n | 'none'; // available to any eligible (13+) account\n\nexport interface CapabilityDefinition {\n id: CapabilityId;\n /** Human-facing summary (admin/debug only; not user copy). */\n description: string;\n /** The age gate. `adult18Plus` capabilities are server-enforced against the age flag\n * the backend reads from `privateData`; no age claim exists on the token. */\n ageRequirement: CapabilityAgeRequirement;\n /** When true, BOTH ends must satisfy the requirement (no-minor-messaging). */\n bilateral: boolean;\n /** Upload origins this capability governs (for the startUpload gate). Empty\n * unless the capability is `upload.origin`-adjacent. */\n uploadOrigins: readonly FileOrigin[];\n}\n\n/** Upload origins that require an 18+ account to initiate (origin-level gate, not\n * just the create callable — Phase 6 item 3). Origins tied to artisan-only\n * surfaces (collaboration, hall publication, work assets) are 18+ because only\n * 18+ accounts can be artisan creators / hold stake shares. */\nexport const ADULT_ONLY_UPLOAD_ORIGINS = [\n 'squareStreetz',\n 'commission-posting',\n 'commission-proposal',\n 'audition-prompt',\n 'audition-entry',\n 'hallLibrary-cover-square',\n 'hallLibrary-cover-poster',\n 'hallLibrary-cover-cinematic',\n 'realm-cover',\n 'chapter-photo',\n 'tune-track-photo',\n 'tune-track-audio',\n 'television-episode-photo',\n 'television-episode-video',\n 'conversation-file',\n 'work-asset',\n] as const satisfies readonly FileOrigin[];\n\nexport const CAPABILITY_REGISTRY: Record<CapabilityId, CapabilityDefinition> = {\n 'account.becomeArtisan': {\n id: 'account.becomeArtisan',\n description: 'Become an artisan creator (privilege + stake-share eligibility).',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: [],\n },\n 'square.post': {\n id: 'square.post',\n description: 'Create a Square Streetz post.',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: ['squareStreetz'],\n },\n 'square.acceptAgreements': {\n id: 'square.acceptAgreements',\n description: 'Accept the Square Streetz posting agreements.',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: [],\n },\n 'pledge.create': {\n id: 'pledge.create',\n description: 'Create a pledge / payment (18+ only, pledge-only payments).',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: [],\n },\n 'messaging.guildInvite': {\n id: 'messaging.guildInvite',\n description: 'Send a guild invite (opens an invite-conversation thread).',\n ageRequirement: 'adult18Plus',\n bilateral: true,\n uploadOrigins: [],\n },\n 'messaging.send': {\n id: 'messaging.send',\n description: 'Send a chat / invite-thread message.',\n ageRequirement: 'adult18Plus',\n bilateral: true,\n uploadOrigins: [],\n },\n 'messaging.fileShare': {\n id: 'messaging.fileShare',\n description: 'Share a Conversation File in an invite / admin-support conversation.',\n ageRequirement: 'adult18Plus',\n bilateral: true,\n uploadOrigins: ['conversation-file'],\n },\n 'collaboration.commissionProposal': {\n id: 'collaboration.commissionProposal',\n description: 'Submit a commission proposal (artisan collaboration surface).',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: ['commission-proposal'],\n },\n 'collaboration.auditionEntry': {\n id: 'collaboration.auditionEntry',\n description: 'Submit an audition entry (artisan collaboration surface).',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: ['audition-entry'],\n },\n 'stakeShares.hold': {\n id: 'stakeShares.hold',\n description: 'Hold stake shares (guild membership / revenue).',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: [],\n },\n 'upload.origin': {\n id: 'upload.origin',\n description: 'Initiate an upload for an adult-only origin (startUpload gate).',\n ageRequirement: 'adult18Plus',\n bilateral: false,\n uploadOrigins: ADULT_ONLY_UPLOAD_ORIGINS,\n },\n};\n\n/** All capability ids (for exhaustiveness tests + iteration). */\nexport const ALL_CAPABILITY_IDS = Object.keys(CAPABILITY_REGISTRY) as CapabilityId[];\n\n/** The actor's age-relevant view, read server-side from privateData — the only age\n * authority; the token carries no age claim. */\nexport interface AgeCapabilityContext {\n is18Plus: boolean;\n accountCapabilityVersion: number;\n}\n\n/** Does this context satisfy a capability's age requirement? */\nexport function contextSatisfies(\n capability: CapabilityId,\n ctx: AgeCapabilityContext,\n): boolean {\n const def = CAPABILITY_REGISTRY[capability];\n if (def.ageRequirement === 'none') return true;\n return ctx.is18Plus === true;\n}\n\n/** Is the given upload origin 18+-gated? */\nexport function uploadOriginRequires18Plus(origin: string): boolean {\n return (ADULT_ONLY_UPLOAD_ORIGINS as readonly string[]).includes(origin);\n}\n"]}
@@ -3,9 +3,17 @@ import type { FeedbackType } from './business-admin.js';
3
3
  import type { ClearableTextFieldName } from './business-content.js';
4
4
  import { HALL_CONTENT_TEXT_FIELDS } from './business-content.js';
5
5
  import type { HallContentTextSurface } from '../doc-schemas/content.js';
6
- import type { ReportDisposition } from '../doc-schemas/safety/foundation.js';
6
+ import type { ReportDisposition, NciiInternalStatus } from '../doc-schemas/safety/foundation.js';
7
+ import type { ChildSafetyWorkStatus } from '../doc-schemas/safety/case.js';
7
8
  import type { BroadcastAudienceSelector } from '../schemas/notification.js';
8
9
  import type { DeadLetterCollection } from '../schemas/admin.js';
10
+ import type { GuildInviteConversationStatus, ShortLinkTargetType } from '../schemas/atoms.js';
11
+ import type { AdminDispatch } from '../doc-schemas/messaging.js';
12
+ import type { CommissionProposalStatus } from '../schemas/commissions.js';
13
+ import type { InviteSourceType } from '../schemas/work-project-management.js';
14
+ import type { Audition } from '../doc-schemas/commissions.js';
15
+ import type { WorkProjectType } from '../types/content.js';
16
+ import type { HallSubItemStatus } from '../utils/hall-content.js';
9
17
  /** Moderation status labels (user-management view, status badges). */
10
18
  export declare const USER_ACCOUNT_STATUS_LABELS: Record<UserAccountStatus, string>;
11
19
  /** Broadcast audience selector labels (announcement composer). */
@@ -91,4 +99,24 @@ export declare const USER_FACING_REASON_OPTIONS: readonly UserFacingReasonOption
91
99
  export declare function userFacingReasonLabel(code: string | undefined): string | undefined;
92
100
  export declare const WORK_PROJECT_TYPE_RULE_GROUP_TITLE = "Work Type Rules";
93
101
  export declare const HALL_WING_TYPE_RULE_GROUP_TITLE = "Hall Wing Rules";
102
+ /** Guild invite statuses (a Work's invited-users list and an invite conversation's status line). */
103
+ export declare const GUILD_INVITE_STATUS_LABELS: Record<GuildInviteConversationStatus, string>;
104
+ /** Commission proposal statuses (a Work's proposals table). */
105
+ export declare const COMMISSION_PROPOSAL_STATUS_LABELS: Record<CommissionProposalStatus, string>;
106
+ /** Chapter, track, and episode review statuses (the Tale, Tune, and Television section tables). */
107
+ export declare const HALL_SUB_ITEM_STATUS_LABELS: Record<HallSubItemStatus, string>;
108
+ /** Audition statuses (the audition page). */
109
+ export declare const AUDITION_STATUS_LABELS: Record<Audition['status'], string>;
110
+ /** Work types (Work lists, the Work overview, the Works popover). */
111
+ export declare const WORK_PROJECT_TYPE_LABELS: Record<WorkProjectType, string>;
112
+ /** Invite source types, as the invite dialog names the context an invite was sent from. */
113
+ export declare const INVITE_SOURCE_TYPE_LABELS: Record<InviteSourceType, string>;
114
+ /** Short-link target types (the admin Short Links list), in the target-type enum's order. */
115
+ export declare const SHORT_LINK_TARGET_TYPE_LABELS: Record<ShortLinkTargetType, string>;
116
+ /** Support-thread statuses (a member's Messages, a Work's Correspondence, the admin browse list). */
117
+ export declare const ADMIN_DISPATCH_STATUS_LABELS: Record<AdminDispatch['status'], string>;
118
+ /** Child-safety case work statuses (the safety case console's case rows and closed-case lookup). */
119
+ export declare const CHILD_SAFETY_CASE_WORK_STATUS_LABELS: Record<ChildSafetyWorkStatus, string>;
120
+ /** NCII case statuses (the safety case console's case rows and closed-case lookup). */
121
+ export declare const NCII_CASE_STATUS_LABELS: Record<NciiInternalStatus, string>;
94
122
  //# sourceMappingURL=admin-labels.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin-labels.d.ts","sourceRoot":"","sources":["../../src/constants/admin-labels.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAGpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,sEAAsE;AACtE,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAIxE,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,8BAA8B,EAAE,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,EAAE,MAAM,CAM5F,CAAC;AAEF;;;;uEAIuE;AACvE,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAM7D,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC,sBAAsB,EAAE,MAAM,CAM9E,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,gCAAgC,GAAG;KAC5C,CAAC,IAAI,sBAAsB,CAAC,CAAC,EAAE;SAC7B,CAAC,IAAI,CAAC,OAAO,wBAAwB,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM;KAC7D;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,oCAAoC;;;;CAEI,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAS/E;AAED,uFAAuF;AACvF,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAAC,oBAAoB,EAAE,MAAM,CAc9E,CAAC;AAEF;4EAC4E;AAC5E,eAAO,MAAM,0BAA0B,EAAE,SAAS;IAChD,KAAK,EAAE,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB,EAiBA,CAAC;AAEF,gGAAgG;AAChG,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;0BAI0B;AAC1B,eAAO,MAAM,0BAA0B,EAAE,SAAS,sBAAsB,EAW9D,CAAC;AAEX,2FAA2F;AAC3F,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAElF;AASD,eAAO,MAAM,kCAAkC,oBAAoB,CAAC;AACpE,eAAO,MAAM,+BAA+B,oBAAoB,CAAC"}
1
+ {"version":3,"file":"admin-labels.d.ts","sourceRoot":"","sources":["../../src/constants/admin-labels.ts"],"names":[],"mappings":"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"}
@@ -146,4 +146,82 @@ export function userFacingReasonLabel(code) {
146
146
  // Hall / Wing (ARCH-107).
147
147
  export const WORK_PROJECT_TYPE_RULE_GROUP_TITLE = 'Work Type Rules';
148
148
  export const HALL_WING_TYPE_RULE_GROUP_TITLE = 'Hall Wing Rules';
149
+ // --- Stored-enum display labels ---
150
+ // What a screen shows for a stored enum value, keyed by the canonical union so a new member fails
151
+ // the build until it has its text. A screen renders the label, never the raw value.
152
+ /** Guild invite statuses (a Work's invited-users list and an invite conversation's status line). */
153
+ export const GUILD_INVITE_STATUS_LABELS = {
154
+ pending: 'Pending',
155
+ accepted: 'Accepted',
156
+ declined: 'Declined',
157
+ cancelled: 'Cancelled',
158
+ finalized: 'Finalized',
159
+ };
160
+ /** Commission proposal statuses (a Work's proposals table). */
161
+ export const COMMISSION_PROPOSAL_STATUS_LABELS = {
162
+ open: 'Open',
163
+ invited: 'Invited',
164
+ accepted: 'Accepted',
165
+ rejected: 'Rejected',
166
+ };
167
+ /** Chapter, track, and episode review statuses (the Tale, Tune, and Television section tables). */
168
+ export const HALL_SUB_ITEM_STATUS_LABELS = {
169
+ unpublished: 'unpublished',
170
+ pending_approval: 'Pending approval',
171
+ published: 'published',
172
+ };
173
+ /** Audition statuses (the audition page). */
174
+ export const AUDITION_STATUS_LABELS = {
175
+ open: 'Open',
176
+ closed: 'Closed',
177
+ pendingReview: 'PendingReview',
178
+ };
179
+ /** Work types (Work lists, the Work overview, the Works popover). */
180
+ export const WORK_PROJECT_TYPE_LABELS = {
181
+ Tales: 'Tales',
182
+ Tunes: 'Tunes',
183
+ Television: 'Television',
184
+ };
185
+ /** Invite source types, as the invite dialog names the context an invite was sent from. */
186
+ export const INVITE_SOURCE_TYPE_LABELS = {
187
+ standalone: 'standalone',
188
+ craftSkill: 'craftSkill',
189
+ commission: 'commission',
190
+ audition: 'audition',
191
+ };
192
+ /** Short-link target types (the admin Short Links list), in the target-type enum's order. */
193
+ export const SHORT_LINK_TARGET_TYPE_LABELS = {
194
+ audition: 'Audition',
195
+ 'audition-entry': 'Audition entry',
196
+ commission: 'Commission',
197
+ 'hall-library-item': 'Hall entry',
198
+ };
199
+ /** Support-thread statuses (a member's Messages, a Work's Correspondence, the admin browse list). */
200
+ export const ADMIN_DISPATCH_STATUS_LABELS = {
201
+ open: 'Open',
202
+ user_reply: 'User replied',
203
+ admin_reply: 'Admin replied',
204
+ closed_resolved: 'Resolved',
205
+ closed_unresolved: 'Closed',
206
+ };
207
+ /** Child-safety case work statuses (the safety case console's case rows and closed-case lookup). */
208
+ export const CHILD_SAFETY_CASE_WORK_STATUS_LABELS = {
209
+ new: 'new',
210
+ triaged: 'triaged',
211
+ reporting: 'reporting',
212
+ actioning: 'actioning',
213
+ processing: 'processing',
214
+ failed: 'failed',
215
+ operationallyResolved: 'operationallyResolved',
216
+ };
217
+ /** NCII case statuses (the safety case console's case rows and closed-case lookup). */
218
+ export const NCII_CASE_STATUS_LABELS = {
219
+ open: 'open',
220
+ removalInProgress: 'removalInProgress',
221
+ processing: 'processing',
222
+ failed: 'failed',
223
+ removed: 'removed',
224
+ rejected: 'rejected',
225
+ closed: 'closed',
226
+ };
149
227
  //# sourceMappingURL=admin-labels.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin-labels.js","sourceRoot":"","sources":["../../src/constants/admin-labels.ts"],"names":[],"mappings":"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","sourcesContent":["// ============================================================================\n// ADMIN-SURFACE DISPLAY LABELS — the ONE home for business display copy keyed\n// by canonical ttt-core enums (ARCH-102, extended 2026-07-13). Consolidated from\n// the former component-local maps in ttt-prod (admin-user-management-view,\n// admin-announcements-view, guided-resolution-flow). Any client (web, phone,\n// TV, admin app) renders the same labels by importing these.\n//\n// A few entries here are copy for ADMIN-MANAGED content that a PUBLIC surface also\n// renders (the rules-page group titles at the bottom of this file). The organizing\n// principle is one declaration, not one consumer.\n// ============================================================================\n\nimport type { UserAccountStatus } from '../doc-schemas/user.js';\nimport type { FeedbackType } from './business-admin.js';\nimport type { ClearableTextFieldName } from './business-content.js';\n// Value import: the per-surface override type below indexes this map to restrict each surface's\n// override keys to the fields that surface actually exposes.\nimport { HALL_CONTENT_TEXT_FIELDS } from './business-content.js';\nimport type { HallContentTextSurface } from '../doc-schemas/content.js';\nimport type { ReportDisposition } from '../doc-schemas/safety/foundation.js';\nimport type { BroadcastAudienceSelector } from '../schemas/notification.js';\nimport type { DeadLetterCollection } from '../schemas/admin.js';\n\n/** Moderation status labels (user-management view, status badges). */\nexport const USER_ACCOUNT_STATUS_LABELS: Record<UserAccountStatus, string> = {\n active: 'Active',\n suspended: 'Suspended',\n banned: 'Banned',\n};\n\n/** Broadcast audience selector labels (announcement composer). */\nexport const BROADCAST_AUDIENCE_KIND_LABELS: Record<BroadcastAudienceSelector['kind'], string> = {\n allActiveUsers: 'All active users',\n allArtisans: 'All artisan creators',\n explicitUids: 'Specific users (paste uids)',\n workMembers: \"A Work's guild members\",\n realmMembers: \"A Realm's members\",\n};\n\n/** Human labels for the canonical feedback types — the admin feedback-suggestions views and\n * the user-facing feedback-submission surface render these instead of restating copy. Keyed\n * by FeedbackType, so a new FEEDBACK_TYPES member fails the build until its label exists.\n * UI copy uses the SHORT settled terms (Trade → \"Trades\", Craft → \"Craft Tags\", Genre →\n * \"<Kind> Genres\"), never the compound code identifiers (ARCH-107). */\nexport const FEEDBACK_TYPE_LABELS: Record<FeedbackType, string> = {\n tradeProfessionSuggestions: 'Trades',\n craftSkillTagSuggestions: 'Craft Tags',\n talesWorkGenreSuggestions: 'Tales Genres',\n tunesWorkGenreSuggestions: 'Tunes Genres',\n televisionWorkGenreSuggestions: 'Television Genres',\n};\n\n/**\n * Human labels for the raw clearable/changeable TEXT-FIELD names the moderation text-clear\n * remedy and the published \"Update details\" change-request flow work in. The backend stores and\n * validates the raw doc field names (`workingTitle`, `description`, `content`); these are the\n * only display strings for them — rendered by the member-facing \"text removed by moderation\"\n * banners, every admin clear-text field picker, the change-request dialog, and the admin\n * change-request work view. Keyed by the derived ClearableTextFieldName union, so a new\n * clearable field fails the build here until it has a label (ARCH-102).\n *\n * The `working*` pair belongs to the Work shell and the Realm doc; the labels stay the plain\n * short terms (ARCH-107 — the code identifier carries `working`, the UI never shows it).\n */\nexport const CLEARABLE_TEXT_FIELD_LABELS: Record<ClearableTextFieldName, string> = {\n workingTitle: 'Title',\n workingDescription: 'Description',\n title: 'Title',\n description: 'Description',\n content: 'Content',\n};\n\n/**\n * Per-surface label overrides for the field labels above: `[surface][field] → label`. Only a\n * surface that genuinely names a field differently appears here; everything else resolves to the\n * base map. Each surface's override keys are restricted to the fields THAT surface exposes\n * (indexed off `HALL_CONTENT_TEXT_FIELDS`), so an override for a field the surface does not have\n * is a compile error — as is an override for a surface outside `HallContentTextSurface`.\n */\nexport type ClearableTextFieldLabelOverrides = {\n [S in HallContentTextSurface]?: {\n [F in (typeof HALL_CONTENT_TEXT_FIELDS)[S][number]]?: string;\n };\n};\n\n/**\n * A Realm's identity field is called **Name** on every Realm surface (DJ ruling 2026-07-29,\n * settling a four-surface Name/Title conflict: the creation flow said \"Realm Name\", the inline\n * edit form \"Working Title\", the moderation-cleared banner \"Title\", and the request-update\n * dialog \"Name\"). The `workingTitle` doc field is shared with the Work shell, where it IS a\n * Title — so the difference is per-surface, not per-field, and lives here rather than flattening\n * one of the two settled terms.\n */\nexport const CLEARABLE_TEXT_FIELD_LABEL_OVERRIDES = {\n workRealm: { workingTitle: 'Name' },\n} as const satisfies ClearableTextFieldLabelOverrides;\n\n/**\n * The display label for one raw clearable text-field name: the surface's override when it has\n * one, otherwise the base label, otherwise the raw name. This is the ONE accessor every surface\n * calls — pass the surface whenever the caller knows it (a Realm surface must, or it renders\n * \"Title\" for a Name); omit it only for a genuinely surface-agnostic caller.\n *\n * Both parameters tolerate a plain `string` because callers read field names off stored documents\n * (`moderationClearedFields`) and callable payloads, and the surface may be the `workProject`\n * shell — which is a clearable surface but not a `HallContentTextSurface`, so it simply has no\n * overrides and falls through to the base map.\n */\nexport function clearableTextFieldLabel(field: string, surface?: string): string {\n const overrides = surface\n ? (CLEARABLE_TEXT_FIELD_LABEL_OVERRIDES as Record<string, Record<string, string> | undefined>)[\n surface\n ]\n : undefined;\n return (\n overrides?.[field] ?? (CLEARABLE_TEXT_FIELD_LABELS as Record<string, string>)[field] ?? field\n );\n}\n\n/** Human labels for the dead-letter replay ledgers (Ops Repairs dead-letter table). */\nexport const DEAD_LETTER_COLLECTION_LABELS: Record<DeadLetterCollection, string> = {\n chatSyncEvents: 'Chat sync event',\n chatAdminActionCommands: 'Chat moderation command',\n notificationDeliveries: 'Notification delivery',\n chatMessageOutbox: 'Chat message publish',\n squareAnnouncementJobs: 'Square announcement',\n chatSyncFanoutJobs: 'Chat access fanout',\n mediaAssets: 'Media authority sync',\n quarantineSagaJobs: 'Quarantine saga',\n nciiRemovalJobs: 'NCII removal',\n safetyEvidenceJobs: 'Safety evidence job',\n accountActionCommands: 'Account safety action',\n activeReportGroups: 'Report edge sync',\n hallSubItemEdgeSync: 'Hall sub-item edge sync',\n};\n\n/** Operator-settable report dispositions with their console copy. 'undetermined' is the\n * initial state, never a settable target, so it carries no option entry. */\nexport const REPORT_DISPOSITION_OPTIONS: readonly {\n value: Exclude<ReportDisposition, 'undetermined'>;\n label: string;\n description: string;\n}[] = [\n {\n value: 'reportRequired',\n label: 'Report required (NCMEC)',\n description:\n 'Apparent CSAM — a report is legally required. Establishes actual knowledge + arms the clock.',\n },\n {\n value: 'notRequired',\n label: 'No report required',\n description: 'No reporting obligation ever arose. Disallowed once there is a validated match.',\n },\n {\n value: 'correctedNoApparentViolation',\n label: 'False positive — correct it',\n description: 'There was a triggering signal but on review it is a false positive.',\n },\n];\n\n/** One user-facing reason option (shown to the affected user for any user-affecting action). */\nexport interface UserFacingReasonOption {\n code: string;\n label: string;\n description: string;\n}\n\n/** User-facing reason picklist for the guided case-resolution flow — the affected user sees the\n * label for any user-affecting action. Canonical home (ARCH-102): the codes ARE this list's own\n * enumeration, so every client (web, phone, TV, admin app) renders the same options + labels by\n * importing from here. Final user-/legal-facing wording is subject to lawyer review; these are\n * functional defaults. */\nexport const USER_FACING_REASON_OPTIONS: readonly UserFacingReasonOption[] = [\n { code: 'harassment', label: 'Harassment or bullying', description: 'Targeted abuse, threats, or sustained harassment of a person.' },\n { code: 'hate', label: 'Hate speech', description: 'Attacks on people based on a protected characteristic.' },\n { code: 'adult-content', label: 'Explicit / adult content', description: 'Sexual or graphic content not allowed on the platform.' },\n { code: 'violence', label: 'Violence or threats', description: 'Threats of violence, or content glorifying or inciting it.' },\n { code: 'spam', label: 'Spam or scam', description: 'Unsolicited bulk content, deceptive links, or fraud.' },\n { code: 'impersonation', label: 'Impersonation', description: 'Pretending to be another person, brand, or entity.' },\n { code: 'ip', label: 'Intellectual property', description: 'Use of someone else’s work without the right to do so.' },\n { code: 'nonconsensual', label: 'Nonconsensual intimate imagery', description: 'Intimate or sexual imagery shared without the subject’s consent.' },\n { code: 'safety', label: 'Safety violation', description: 'A serious safety violation handled under our safety policies.' },\n { code: 'other', label: 'Other (explain)', description: 'A policy violation not covered above — describe it in the detail box.' },\n] as const;\n\n/** The user-facing label for a reason code (undefined when the code is unknown/absent). */\nexport function userFacingReasonLabel(code: string | undefined): string | undefined {\n return USER_FACING_REASON_OPTIONS.find((o) => o.code === code)?.label;\n}\n\n// --- Rules-surface group titles ---\n// The two rule-GROUP headings for the platform rules content (`Rule.group`\n// 'workProjectType' / 'hallWingType' — see schemas/admin.ts). BOTH the admin rules editor\n// and the public rules page render these, so they are declared once here instead of being\n// restated as literals on each surface (ENG-002). Copy uses the short settled terms Work /\n// Hall / Wing (ARCH-107).\n\nexport const WORK_PROJECT_TYPE_RULE_GROUP_TITLE = 'Work Type Rules';\nexport const HALL_WING_TYPE_RULE_GROUP_TITLE = 'Hall Wing Rules';\n"]}
1
+ {"version":3,"file":"admin-labels.js","sourceRoot":"","sources":["../../src/constants/admin-labels.ts"],"names":[],"mappings":"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","sourcesContent":["// ============================================================================\n// ADMIN-SURFACE DISPLAY LABELS — the ONE home for business display copy keyed\n// by canonical ttt-core enums (ARCH-102, extended 2026-07-13). Consolidated from\n// the former component-local maps in ttt-prod (admin-user-management-view,\n// admin-announcements-view, guided-resolution-flow). Any client (web, phone,\n// TV, admin app) renders the same labels by importing these.\n//\n// A few entries here are copy for ADMIN-MANAGED content that a PUBLIC surface also\n// renders (the rules-page group titles at the bottom of this file). The organizing\n// principle is one declaration, not one consumer.\n// ============================================================================\n\nimport type { UserAccountStatus } from '../doc-schemas/user.js';\nimport type { FeedbackType } from './business-admin.js';\nimport type { ClearableTextFieldName } from './business-content.js';\n// Value import: the per-surface override type below indexes this map to restrict each surface's\n// override keys to the fields that surface actually exposes.\nimport { HALL_CONTENT_TEXT_FIELDS } from './business-content.js';\nimport type { HallContentTextSurface } from '../doc-schemas/content.js';\nimport type { ReportDisposition, NciiInternalStatus } from '../doc-schemas/safety/foundation.js';\nimport type { ChildSafetyWorkStatus } from '../doc-schemas/safety/case.js';\nimport type { BroadcastAudienceSelector } from '../schemas/notification.js';\nimport type { DeadLetterCollection } from '../schemas/admin.js';\nimport type { GuildInviteConversationStatus, ShortLinkTargetType } from '../schemas/atoms.js';\nimport type { AdminDispatch } from '../doc-schemas/messaging.js';\nimport type { CommissionProposalStatus } from '../schemas/commissions.js';\nimport type { InviteSourceType } from '../schemas/work-project-management.js';\nimport type { Audition } from '../doc-schemas/commissions.js';\nimport type { WorkProjectType } from '../types/content.js';\nimport type { HallSubItemStatus } from '../utils/hall-content.js';\n\n/** Moderation status labels (user-management view, status badges). */\nexport const USER_ACCOUNT_STATUS_LABELS: Record<UserAccountStatus, string> = {\n active: 'Active',\n suspended: 'Suspended',\n banned: 'Banned',\n};\n\n/** Broadcast audience selector labels (announcement composer). */\nexport const BROADCAST_AUDIENCE_KIND_LABELS: Record<BroadcastAudienceSelector['kind'], string> = {\n allActiveUsers: 'All active users',\n allArtisans: 'All artisan creators',\n explicitUids: 'Specific users (paste uids)',\n workMembers: \"A Work's guild members\",\n realmMembers: \"A Realm's members\",\n};\n\n/** Human labels for the canonical feedback types — the admin feedback-suggestions views and\n * the user-facing feedback-submission surface render these instead of restating copy. Keyed\n * by FeedbackType, so a new FEEDBACK_TYPES member fails the build until its label exists.\n * UI copy uses the SHORT settled terms (Trade → \"Trades\", Craft → \"Craft Tags\", Genre →\n * \"<Kind> Genres\"), never the compound code identifiers (ARCH-107). */\nexport const FEEDBACK_TYPE_LABELS: Record<FeedbackType, string> = {\n tradeProfessionSuggestions: 'Trades',\n craftSkillTagSuggestions: 'Craft Tags',\n talesWorkGenreSuggestions: 'Tales Genres',\n tunesWorkGenreSuggestions: 'Tunes Genres',\n televisionWorkGenreSuggestions: 'Television Genres',\n};\n\n/**\n * Human labels for the raw clearable/changeable TEXT-FIELD names the moderation text-clear\n * remedy and the published \"Update details\" change-request flow work in. The backend stores and\n * validates the raw doc field names (`workingTitle`, `description`, `content`); these are the\n * only display strings for them — rendered by the member-facing \"text removed by moderation\"\n * banners, every admin clear-text field picker, the change-request dialog, and the admin\n * change-request work view. Keyed by the derived ClearableTextFieldName union, so a new\n * clearable field fails the build here until it has a label (ARCH-102).\n *\n * The `working*` pair belongs to the Work shell and the Realm doc; the labels stay the plain\n * short terms (ARCH-107 — the code identifier carries `working`, the UI never shows it).\n */\nexport const CLEARABLE_TEXT_FIELD_LABELS: Record<ClearableTextFieldName, string> = {\n workingTitle: 'Title',\n workingDescription: 'Description',\n title: 'Title',\n description: 'Description',\n content: 'Content',\n};\n\n/**\n * Per-surface label overrides for the field labels above: `[surface][field] → label`. Only a\n * surface that genuinely names a field differently appears here; everything else resolves to the\n * base map. Each surface's override keys are restricted to the fields THAT surface exposes\n * (indexed off `HALL_CONTENT_TEXT_FIELDS`), so an override for a field the surface does not have\n * is a compile error — as is an override for a surface outside `HallContentTextSurface`.\n */\nexport type ClearableTextFieldLabelOverrides = {\n [S in HallContentTextSurface]?: {\n [F in (typeof HALL_CONTENT_TEXT_FIELDS)[S][number]]?: string;\n };\n};\n\n/**\n * A Realm's identity field is called **Name** on every Realm surface (DJ ruling 2026-07-29,\n * settling a four-surface Name/Title conflict: the creation flow said \"Realm Name\", the inline\n * edit form \"Working Title\", the moderation-cleared banner \"Title\", and the request-update\n * dialog \"Name\"). The `workingTitle` doc field is shared with the Work shell, where it IS a\n * Title — so the difference is per-surface, not per-field, and lives here rather than flattening\n * one of the two settled terms.\n */\nexport const CLEARABLE_TEXT_FIELD_LABEL_OVERRIDES = {\n workRealm: { workingTitle: 'Name' },\n} as const satisfies ClearableTextFieldLabelOverrides;\n\n/**\n * The display label for one raw clearable text-field name: the surface's override when it has\n * one, otherwise the base label, otherwise the raw name. This is the ONE accessor every surface\n * calls — pass the surface whenever the caller knows it (a Realm surface must, or it renders\n * \"Title\" for a Name); omit it only for a genuinely surface-agnostic caller.\n *\n * Both parameters tolerate a plain `string` because callers read field names off stored documents\n * (`moderationClearedFields`) and callable payloads, and the surface may be the `workProject`\n * shell — which is a clearable surface but not a `HallContentTextSurface`, so it simply has no\n * overrides and falls through to the base map.\n */\nexport function clearableTextFieldLabel(field: string, surface?: string): string {\n const overrides = surface\n ? (CLEARABLE_TEXT_FIELD_LABEL_OVERRIDES as Record<string, Record<string, string> | undefined>)[\n surface\n ]\n : undefined;\n return (\n overrides?.[field] ?? (CLEARABLE_TEXT_FIELD_LABELS as Record<string, string>)[field] ?? field\n );\n}\n\n/** Human labels for the dead-letter replay ledgers (Ops Repairs dead-letter table). */\nexport const DEAD_LETTER_COLLECTION_LABELS: Record<DeadLetterCollection, string> = {\n chatSyncEvents: 'Chat sync event',\n chatAdminActionCommands: 'Chat moderation command',\n notificationDeliveries: 'Notification delivery',\n chatMessageOutbox: 'Chat message publish',\n squareAnnouncementJobs: 'Square announcement',\n chatSyncFanoutJobs: 'Chat access fanout',\n mediaAssets: 'Media authority sync',\n quarantineSagaJobs: 'Quarantine saga',\n nciiRemovalJobs: 'NCII removal',\n safetyEvidenceJobs: 'Safety evidence job',\n accountActionCommands: 'Account safety action',\n activeReportGroups: 'Report edge sync',\n hallSubItemEdgeSync: 'Hall sub-item edge sync',\n};\n\n/** Operator-settable report dispositions with their console copy. 'undetermined' is the\n * initial state, never a settable target, so it carries no option entry. */\nexport const REPORT_DISPOSITION_OPTIONS: readonly {\n value: Exclude<ReportDisposition, 'undetermined'>;\n label: string;\n description: string;\n}[] = [\n {\n value: 'reportRequired',\n label: 'Report required (NCMEC)',\n description:\n 'Apparent CSAM — a report is legally required. Establishes actual knowledge + arms the clock.',\n },\n {\n value: 'notRequired',\n label: 'No report required',\n description: 'No reporting obligation ever arose. Disallowed once there is a validated match.',\n },\n {\n value: 'correctedNoApparentViolation',\n label: 'False positive — correct it',\n description: 'There was a triggering signal but on review it is a false positive.',\n },\n];\n\n/** One user-facing reason option (shown to the affected user for any user-affecting action). */\nexport interface UserFacingReasonOption {\n code: string;\n label: string;\n description: string;\n}\n\n/** User-facing reason picklist for the guided case-resolution flow — the affected user sees the\n * label for any user-affecting action. Canonical home (ARCH-102): the codes ARE this list's own\n * enumeration, so every client (web, phone, TV, admin app) renders the same options + labels by\n * importing from here. Final user-/legal-facing wording is subject to lawyer review; these are\n * functional defaults. */\nexport const USER_FACING_REASON_OPTIONS: readonly UserFacingReasonOption[] = [\n { code: 'harassment', label: 'Harassment or bullying', description: 'Targeted abuse, threats, or sustained harassment of a person.' },\n { code: 'hate', label: 'Hate speech', description: 'Attacks on people based on a protected characteristic.' },\n { code: 'adult-content', label: 'Explicit / adult content', description: 'Sexual or graphic content not allowed on the platform.' },\n { code: 'violence', label: 'Violence or threats', description: 'Threats of violence, or content glorifying or inciting it.' },\n { code: 'spam', label: 'Spam or scam', description: 'Unsolicited bulk content, deceptive links, or fraud.' },\n { code: 'impersonation', label: 'Impersonation', description: 'Pretending to be another person, brand, or entity.' },\n { code: 'ip', label: 'Intellectual property', description: 'Use of someone else’s work without the right to do so.' },\n { code: 'nonconsensual', label: 'Nonconsensual intimate imagery', description: 'Intimate or sexual imagery shared without the subject’s consent.' },\n { code: 'safety', label: 'Safety violation', description: 'A serious safety violation handled under our safety policies.' },\n { code: 'other', label: 'Other (explain)', description: 'A policy violation not covered above — describe it in the detail box.' },\n] as const;\n\n/** The user-facing label for a reason code (undefined when the code is unknown/absent). */\nexport function userFacingReasonLabel(code: string | undefined): string | undefined {\n return USER_FACING_REASON_OPTIONS.find((o) => o.code === code)?.label;\n}\n\n// --- Rules-surface group titles ---\n// The two rule-GROUP headings for the platform rules content (`Rule.group`\n// 'workProjectType' / 'hallWingType' — see schemas/admin.ts). BOTH the admin rules editor\n// and the public rules page render these, so they are declared once here instead of being\n// restated as literals on each surface (ENG-002). Copy uses the short settled terms Work /\n// Hall / Wing (ARCH-107).\n\nexport const WORK_PROJECT_TYPE_RULE_GROUP_TITLE = 'Work Type Rules';\nexport const HALL_WING_TYPE_RULE_GROUP_TITLE = 'Hall Wing Rules';\n\n// --- Stored-enum display labels ---\n// What a screen shows for a stored enum value, keyed by the canonical union so a new member fails\n// the build until it has its text. A screen renders the label, never the raw value.\n\n/** Guild invite statuses (a Work's invited-users list and an invite conversation's status line). */\nexport const GUILD_INVITE_STATUS_LABELS: Record<GuildInviteConversationStatus, string> = {\n pending: 'Pending',\n accepted: 'Accepted',\n declined: 'Declined',\n cancelled: 'Cancelled',\n finalized: 'Finalized',\n};\n\n/** Commission proposal statuses (a Work's proposals table). */\nexport const COMMISSION_PROPOSAL_STATUS_LABELS: Record<CommissionProposalStatus, string> = {\n open: 'Open',\n invited: 'Invited',\n accepted: 'Accepted',\n rejected: 'Rejected',\n};\n\n/** Chapter, track, and episode review statuses (the Tale, Tune, and Television section tables). */\nexport const HALL_SUB_ITEM_STATUS_LABELS: Record<HallSubItemStatus, string> = {\n unpublished: 'unpublished',\n pending_approval: 'Pending approval',\n published: 'published',\n};\n\n/** Audition statuses (the audition page). */\nexport const AUDITION_STATUS_LABELS: Record<Audition['status'], string> = {\n open: 'Open',\n closed: 'Closed',\n pendingReview: 'PendingReview',\n};\n\n/** Work types (Work lists, the Work overview, the Works popover). */\nexport const WORK_PROJECT_TYPE_LABELS: Record<WorkProjectType, string> = {\n Tales: 'Tales',\n Tunes: 'Tunes',\n Television: 'Television',\n};\n\n/** Invite source types, as the invite dialog names the context an invite was sent from. */\nexport const INVITE_SOURCE_TYPE_LABELS: Record<InviteSourceType, string> = {\n standalone: 'standalone',\n craftSkill: 'craftSkill',\n commission: 'commission',\n audition: 'audition',\n};\n\n/** Short-link target types (the admin Short Links list), in the target-type enum's order. */\nexport const SHORT_LINK_TARGET_TYPE_LABELS: Record<ShortLinkTargetType, string> = {\n audition: 'Audition',\n 'audition-entry': 'Audition entry',\n commission: 'Commission',\n 'hall-library-item': 'Hall entry',\n};\n\n/** Support-thread statuses (a member's Messages, a Work's Correspondence, the admin browse list). */\nexport const ADMIN_DISPATCH_STATUS_LABELS: Record<AdminDispatch['status'], string> = {\n open: 'Open',\n user_reply: 'User replied',\n admin_reply: 'Admin replied',\n closed_resolved: 'Resolved',\n closed_unresolved: 'Closed',\n};\n\n/** Child-safety case work statuses (the safety case console's case rows and closed-case lookup). */\nexport const CHILD_SAFETY_CASE_WORK_STATUS_LABELS: Record<ChildSafetyWorkStatus, string> = {\n new: 'new',\n triaged: 'triaged',\n reporting: 'reporting',\n actioning: 'actioning',\n processing: 'processing',\n failed: 'failed',\n operationallyResolved: 'operationallyResolved',\n};\n\n/** NCII case statuses (the safety case console's case rows and closed-case lookup). */\nexport const NCII_CASE_STATUS_LABELS: Record<NciiInternalStatus, string> = {\n open: 'open',\n removalInProgress: 'removalInProgress',\n processing: 'processing',\n failed: 'failed',\n removed: 'removed',\n rejected: 'rejected',\n closed: 'closed',\n};\n"]}
@@ -0,0 +1,3 @@
1
+ export declare const ANALYTICS_EVENT_NAMES: readonly ["page_view", "sign_up", "become_artisan_creator", "project_created", "project_startup", "content_uploaded", "commission_proposal_submitted", "audition_voted", "payment_page_view", "pledge_payment_initiated", "pledge_payment_completed"];
2
+ export type AnalyticsEventName = (typeof ANALYTICS_EVENT_NAMES)[number];
3
+ //# sourceMappingURL=analytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/constants/analytics.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,qBAAqB,uPAYxB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ // The one declaration of the analytics events the app logs. The app's analytics hook takes only
2
+ // these names, so an event cannot be logged without being declared here.
3
+ export const ANALYTICS_EVENT_NAMES = [
4
+ 'page_view',
5
+ 'sign_up',
6
+ 'become_artisan_creator',
7
+ 'project_created',
8
+ 'project_startup',
9
+ 'content_uploaded',
10
+ 'commission_proposal_submitted',
11
+ 'audition_voted',
12
+ 'payment_page_view',
13
+ 'pledge_payment_initiated',
14
+ 'pledge_payment_completed',
15
+ ];
16
+ //# sourceMappingURL=analytics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/constants/analytics.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,yEAAyE;AACzE,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,WAAW;IACX,SAAS;IACT,wBAAwB;IACxB,iBAAiB;IACjB,iBAAiB;IACjB,kBAAkB;IAClB,+BAA+B;IAC/B,gBAAgB;IAChB,mBAAmB;IACnB,0BAA0B;IAC1B,0BAA0B;CAClB,CAAC","sourcesContent":["// The one declaration of the analytics events the app logs. The app's analytics hook takes only\n// these names, so an event cannot be logged without being declared here.\nexport const ANALYTICS_EVENT_NAMES = [\n 'page_view',\n 'sign_up',\n 'become_artisan_creator',\n 'project_created',\n 'project_startup',\n 'content_uploaded',\n 'commission_proposal_submitted',\n 'audition_voted',\n 'payment_page_view',\n 'pledge_payment_initiated',\n 'pledge_payment_completed',\n] as const;\n\nexport type AnalyticsEventName = (typeof ANALYTICS_EVENT_NAMES)[number];\n"]}
@@ -79,6 +79,8 @@ export interface TttLimits {
79
79
  CHANNEL_CREATE: RateLimitValue;
80
80
  CHECKOUT_CREATE: RateLimitValue;
81
81
  AGE_ATTEST: RateLimitValue;
82
+ HALL_PREFERENCE: RateLimitValue;
83
+ REFUND_DECISION: RateLimitValue;
82
84
  };
83
85
  }
84
86
  export declare const CHARTER_LIMITS: TttLimits;
@@ -1 +1 @@
1
- {"version":3,"file":"app-mode.d.ts","sourceRoot":"","sources":["../../src/constants/app-mode.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app-mode.d.ts","sourceRoot":"","sources":["../../src/constants/app-mode.ts"],"names":[],"mappings":"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"}
@@ -133,6 +133,13 @@ export const CHARTER_LIMITS = {
133
133
  // registrants per hour as DISPLAY_NAME_CHECK's 120/h at its 3–8 debounced checks each, while a
134
134
  // script minting age-attestation records gets far less headroom.
135
135
  AGE_ATTEST: { maxRequests: 30, window: '1 h' },
136
+ // A member's own Hall settings, ink marks, hidden Works, reading position, and recently viewed
137
+ // list. Reading position and recently viewed are written as the member reads, so the bucket is
138
+ // sized like NOTIFICATION_MARK_SEEN, the other passive per-member write.
139
+ HALL_PREFERENCE: { maxRequests: 120, window: '1 h' },
140
+ // An admin's approve or deny of a refund request. Admin-only, so mode-invariant like
141
+ // APPEAL_REVIEW, the other admin decision on a member's request.
142
+ REFUND_DECISION: { maxRequests: 30, window: '1 h' },
136
143
  },
137
144
  };
138
145
  export const FULL_LIMITS = {
@@ -223,6 +230,9 @@ export const FULL_LIMITS = {
223
230
  CHECKOUT_CREATE: { maxRequests: 20, window: '1 h' },
224
231
  // Scaled with DISPLAY_NAME_CHECK's full-mode 300/h — see the CHARTER_LIMITS note.
225
232
  AGE_ATTEST: { maxRequests: 75, window: '1 h' },
233
+ // Both stay at their charter values — see the CHARTER_LIMITS notes.
234
+ HALL_PREFERENCE: { maxRequests: 120, window: '1 h' },
235
+ REFUND_DECISION: { maxRequests: 30, window: '1 h' },
226
236
  },
227
237
  };
228
238
  /** The resolved limit set for the deployed mode. Import THIS (or the alias
@@ -1 +1 @@
1
- {"version":3,"file":"app-mode.js","sourceRoot":"","sources":["../../src/constants/app-mode.ts"],"names":[],"mappings":"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","sourcesContent":["// App mode + the charter/full limit sets — the single published constant that\n// drives the whole app's cost posture. The flip to full-live is: change\n// APP_MODE → publish ttt-core → install in ttt-prod (root + functions) →\n// deploy. There is NO runtime mode flag and NO console toggle.\n// See ttt-prod docs/design/charter-season-and-app-mode.md.\n//\n// Only real cost/abuse drivers vary by mode: media specs (ttt-media-specs.ts),\n// rate-limit values, count caps, batch sizes. Text-length limits and payment\n// min/max are deliberately mode-invariant — with ONE ruled exception (DJ\n// 2026-07-13): chapter body content (maxChapterContentLength), because it\n// bounds threshold-review reading effort per item during charter season.\n\nimport type { WorkProjectType } from '../types/content.js';\n\nexport type AppMode = 'charter' | 'full';\n\n/** The deployed mode. Changing this constant (and publishing) IS the flip. */\nexport const APP_MODE: AppMode = 'charter';\n\n/** Pick the active value for a mode-varied limit. */\nexport const byMode = <T>(charter: T, full: T): T =>\n (APP_MODE as AppMode) === 'charter' ? charter : full;\n\n/** Upstash-style sliding-window duration, e.g. '1 h'. */\nexport type RateLimitWindow = `${number} ${'ms' | 's' | 'm' | 'h' | 'd'}`;\n\nexport interface RateLimitValue {\n maxRequests: number;\n window: RateLimitWindow;\n}\n\nexport interface TttLimits {\n mode: AppMode;\n user: {\n maxCraftSkills: number;\n maxOwnedWorkProjects: number;\n maxAssociatedWorkProjects: number;\n };\n workProject: {\n maxGuildSize: number;\n maxFileFolders: number;\n maxWorkFiles: number;\n maxWorkFileStorageBytes: number;\n maxWorkProjectAuditions: number;\n maxCommissionListings: number;\n maxChapters: number;\n /** Chapter BODY length (chars) — the one mode-varied text limit (DJ 2026-07-13). */\n maxChapterContentLength: number;\n maxTuneTracks: number;\n maxTelevisionEpisodes: number;\n };\n /** Conversation Files container caps — PER CONVERSATION (one guild-invite\n * conversation or one admin-support dispatch thread). Both scopes share one cap\n * set; guild chat channels have no Conversation Files. DJ ruling 2026-07-25. */\n conversation: {\n /** Published active Conversation Files allowed in one conversation. */\n maxConversationFiles: number;\n /** Published STORED-OUTPUT bytes allowed in one conversation. */\n maxConversationFileStorageBytes: number;\n };\n hall: {\n maxSubmitBatch: number;\n };\n batches: {\n trendingFeedProcessLimit: number;\n maxFeedbackSubmitters: number;\n };\n /** Values for the backend rate limiters. Prefixes/factory stay in functions. */\n rateLimits: {\n UPLOAD: RateLimitValue;\n ADMIN_UPLOAD: RateLimitValue;\n CONTENT_WRITE: RateLimitValue;\n VOTE: RateLimitValue;\n MODERATION: RateLimitValue;\n SENSITIVE_ACTION: RateLimitValue;\n DISPLAY_NAME_CHECK: RateLimitValue;\n CHAT_MESSAGE: RateLimitValue;\n ADMIN_TASK: RateLimitValue;\n APPEAL_REVIEW: RateLimitValue;\n BAN_ACTION: RateLimitValue;\n SHARE_TRANSFER: RateLimitValue;\n CONTENT_REPORT: RateLimitValue;\n SHORT_LINK_CLICK: RateLimitValue;\n FOLLOW: RateLimitValue;\n MENTION_HISTORY: RateLimitValue;\n MEDIA_GRANT: RateLimitValue;\n CHAT_GRANT: RateLimitValue;\n OPERATOR_STEP_UP: RateLimitValue;\n ADMIN_MESSAGE_READ: RateLimitValue;\n USER_LOOKUP: RateLimitValue;\n NOTIFICATION_BROADCAST: RateLimitValue;\n NOTIFICATION_ARCHIVE: RateLimitValue;\n NOTIFICATION_MARK_SEEN: RateLimitValue;\n FEEDBACK: RateLimitValue;\n SHORT_LINK_CREATE: RateLimitValue;\n INVITE_ACTION: RateLimitValue;\n LIBRARY_SUBMISSION: RateLimitValue;\n CHANNEL_CREATE: RateLimitValue;\n CHECKOUT_CREATE: RateLimitValue;\n AGE_ATTEST: RateLimitValue;\n };\n}\n\nexport const CHARTER_LIMITS: TttLimits = {\n mode: 'charter',\n user: {\n maxCraftSkills: 8,\n maxOwnedWorkProjects: 3,\n maxAssociatedWorkProjects: 10,\n },\n workProject: {\n maxGuildSize: 25,\n maxFileFolders: 10,\n maxWorkFiles: 100,\n maxWorkFileStorageBytes: 2_684_354_560, // 2.5 GiB\n maxWorkProjectAuditions: 3,\n maxCommissionListings: 3,\n maxChapters: 5,\n // ~5,000 words — a full real chapter, while keeping the human threshold-review\n // reading effort per item bounded during charter season.\n maxChapterContentLength: 30_000,\n maxTuneTracks: 5,\n maxTelevisionEpisodes: 3,\n },\n // Conversation Files are QUOTA'D PER CONVERSATION (DJ ruling 2026-07-25). Counted on\n // STORED OUTPUT bytes (what actually sits in R2 after transcode), never on raw upload\n // bytes. Rationale: a per-file `maxBytes` cap alone bounds one upload but nothing stops\n // unbounded accumulation across a long-running conversation — this is the abuse brake\n // on that, and it is what `startUpload`'s reservation and the publication transfer both\n // check. Charter: 10 files / 500 MiB per conversation.\n conversation: {\n maxConversationFiles: 10,\n maxConversationFileStorageBytes: 524_288_000, // 500 MiB\n },\n hall: { maxSubmitBatch: 10 },\n batches: { trendingFeedProcessLimit: 250, maxFeedbackSubmitters: 25 },\n rateLimits: {\n // Uploads are charged ONCE per upload (in startUpload); the processor-side\n // check is a non-charging guard.\n UPLOAD: { maxRequests: 15, window: '1 h' },\n // A separate HIGHER bucket for uploads performed through the sanctioned admin\n // authority path — never an exemption. Bulk admin setup work (creating 3\n // auditions is ~5 uploads) exhausts the 15/h user bucket; 60/h covers a real\n // bulk admin session while keeping a brake on a compromised admin token and on\n // third-party quota/cost (Vision / Video Intelligence / R2). DJ ruling 2026-07-25.\n ADMIN_UPLOAD: { maxRequests: 60, window: '1 h' },\n // General content-write throttle for the non-upload write callables (text posts,\n // craft-skill edits, support-thread starts) that used to charge UPLOAD. Sharing\n // the 15/h charter upload window meant heavy text posting blocked real uploads\n // and vice versa; a separate 30/h bucket keeps each cost driver on its own\n // ceiling. DJ ruling 2026-07-25.\n CONTENT_WRITE: { maxRequests: 30, window: '1 h' },\n VOTE: { maxRequests: 100, window: '1 h' },\n MODERATION: { maxRequests: 50, window: '1 h' },\n // 30/h: one bucket is shared by ~35 callables (register, become-artisan,\n // create-work, invites, trades, appeals, …) — a real first-hour artisan does\n // 10-15 legitimate sensitive actions; 5/h blocked the intended golden path\n // (proven live by the hosted-dev E2E, 2026-07-07). DJ ruling 2026-07-08.\n SENSITIVE_ACTION: { maxRequests: 30, window: '1 h' },\n // 120/h (charter): checkDisplayNameAvailable is enforceAppCheck:true, so\n // reCAPTCHA-Enterprise attestation is the real abuse gate — this bucket is a\n // cost/DoS ceiling, not the security boundary. It is IP-keyed (pre-registration,\n // no uid yet) and the register form fires it debounced-LIVE as you type, so one\n // legit registrant spends ~3-8 checks and shared NAT/CGNAT multiplies that across\n // everyone on the IP. The old 20/h false-rejected legitimate shared-IP users and\n // could not fit a full hosted-dev E2E suite run on one IP. DJ ruling 2026-07-21.\n DISPLAY_NAME_CHECK: { maxRequests: 120, window: '1 h' },\n CHAT_MESSAGE: { maxRequests: 125, window: '1 h' },\n ADMIN_TASK: { maxRequests: 60, window: '1 h' },\n APPEAL_REVIEW: { maxRequests: 30, window: '1 h' },\n BAN_ACTION: { maxRequests: 20, window: '1 h' },\n SHARE_TRANSFER: { maxRequests: 10, window: '1 h' },\n CONTENT_REPORT: { maxRequests: 5, window: '1 h' },\n SHORT_LINK_CLICK: { maxRequests: 60, window: '1 h' },\n FOLLOW: { maxRequests: 20, window: '1 m' },\n MENTION_HISTORY: { maxRequests: 120, window: '1 h' },\n // Scoped-media grant minting (createMediaGrant). Its OWN bucket — it used to charge\n // MENTION_HISTORY, an unrelated surface, so neither limit meant what its name said and the\n // two shared a budget sized for neither (BACKEND-013). Refresh-driven, not user-initiated:\n // a grant is short-TTL (60 min work media, 15 min chat/folder scopes) and the client re-mints\n // under expiry, so a browsing session naturally spends several per hour PER SCOPE (each work,\n // each private file folder, each conversation). Cheap to serve (a Firestore permission read\n // plus an HMAC sign — no third-party cost), and a false 429 breaks media rendering outright,\n // so the ceiling is generous: it exists to stop a scripted grant-farming sweep, not to pace a\n // real reader. 120/h charter.\n MEDIA_GRANT: { maxRequests: 120, window: '1 h' },\n // Realtime chat grant minting (mintChatGrant) — previously NO limiter at all (BACKEND-013),\n // despite minting signed grants at concurrency: 20. Same refresh-driven shape as MEDIA_GRANT:\n // a 15-minute grant TTL means ~4 mints/hour for the inbox plus ~4 per open channel, doubled\n // again by socket reconnects on a flaky mobile network. It stays behind the per-channel\n // authorizeChannelScope gate, so this bucket is a cost/DoS ceiling rather than the\n // authorization boundary — sized to match MEDIA_GRANT so the two grant surfaces are paced\n // alike and neither can be starved by the other (separate Redis prefixes).\n CHAT_GRANT: { maxRequests: 120, window: '1 h' },\n // Operator step-up TOTP verification (confirmOperatorStepUp / verifyOperatorStepUp) —\n // previously unthrottled, so an attacker holding a stolen full-admin session could\n // brute-force the 6-digit second factor guarding the safety console (BACKEND-013).\n // DELIBERATELY THE TIGHTEST BUCKET IN THE SET: a real operator enrolls once and verifies\n // roughly twice an hour (the grant window is 30 minutes), so 10/h absorbs every legitimate\n // mistype while capping guessing at 10 attempts per hour against a code that rotates every\n // 30 seconds. Mode-INVARIANT — this is an admin security control, not a cost driver, so it\n // never loosens at the full-mode flip (same posture as MODERATION / BAN_ACTION / USER_LOOKUP).\n // The lockout-after-N-failures behaviour is a separate app-side concern; this is the throttle.\n OPERATOR_STEP_UP: { maxRequests: 10, window: '1 h' },\n ADMIN_MESSAGE_READ: { maxRequests: 60, window: '1 h' },\n // Admin exact-account lookup (searchPublicUsers / lookupUserByEmailOrUid) — a read, so a\n // generous per-minute bucket that still backstops a scripted enumeration sweep. Admin-only\n // and not a cost driver, so the value is the same in both modes (like MODERATION/ADMIN_TASK).\n USER_LOOKUP: { maxRequests: 30, window: '1 m' },\n NOTIFICATION_BROADCAST: { maxRequests: 10, window: '1 h' },\n NOTIFICATION_ARCHIVE: { maxRequests: 120, window: '1 h' },\n NOTIFICATION_MARK_SEEN: { maxRequests: 120, window: '1 h' },\n FEEDBACK: { maxRequests: 10, window: '1 h' },\n SHORT_LINK_CREATE: { maxRequests: 30, window: '1 h' },\n INVITE_ACTION: { maxRequests: 30, window: '1 h' },\n LIBRARY_SUBMISSION: { maxRequests: 10, window: '1 h' },\n CHANNEL_CREATE: { maxRequests: 5, window: '1 h' },\n CHECKOUT_CREATE: { maxRequests: 5, window: '1 h' },\n // The registration age step, keyed per hashed client IP (pre-account, no uid). One call per\n // attempt — a corrected date or a retry at most doubles it — so 30/h gives one IP the same\n // registrants per hour as DISPLAY_NAME_CHECK's 120/h at its 3–8 debounced checks each, while a\n // script minting age-attestation records gets far less headroom.\n AGE_ATTEST: { maxRequests: 30, window: '1 h' },\n },\n};\n\nexport const FULL_LIMITS: TttLimits = {\n mode: 'full',\n user: {\n maxCraftSkills: 24,\n maxOwnedWorkProjects: 25,\n maxAssociatedWorkProjects: 100,\n },\n workProject: {\n maxGuildSize: 250,\n maxFileFolders: 25,\n maxWorkFiles: 1000,\n maxWorkFileStorageBytes: 26_843_545_600, // 25 GiB\n maxWorkProjectAuditions: 10,\n maxCommissionListings: 10,\n maxChapters: 50,\n // The intentional design ceiling (~17,000 words; trivially inside Firestore's\n // 1 MiB doc limit) — the audit trail deliberately stores field LENGTHS, not\n // content, because chapters can be this large (runUpdateChapterDetails).\n maxChapterContentLength: 100_000,\n maxTuneTracks: 50,\n maxTelevisionEpisodes: 25,\n },\n // 20 files / 1 GiB (full): the same per-conversation Conversation Files quota as\n // charter, scaled for a public-launch conversation. Still a hard ceiling on\n // unbounded R2 accumulation. See the CHARTER_LIMITS note above. DJ ruling 2026-07-25.\n conversation: {\n maxConversationFiles: 20,\n maxConversationFileStorageBytes: 1_073_741_824, // 1 GiB\n },\n hall: { maxSubmitBatch: 50 },\n batches: { trendingFeedProcessLimit: 1000, maxFeedbackSubmitters: 100 },\n rateLimits: {\n UPLOAD: { maxRequests: 30, window: '1 h' },\n // 120/h (full): the same sanctioned-admin-path upload bucket as charter, scaled\n // with UPLOAD — always HIGHER than the user bucket, never an exemption, so a\n // compromised admin token and third-party media cost stay bounded. See the\n // CHARTER_LIMITS note above. DJ ruling 2026-07-25.\n ADMIN_UPLOAD: { maxRequests: 120, window: '1 h' },\n // 60/h (full): the same non-upload content-write bucket as charter, scaled with\n // UPLOAD so text writes and media uploads never consume each other's ceiling.\n // See the CHARTER_LIMITS note above. DJ ruling 2026-07-25.\n CONTENT_WRITE: { maxRequests: 60, window: '1 h' },\n VOTE: { maxRequests: 200, window: '1 h' },\n MODERATION: { maxRequests: 50, window: '1 h' },\n // 60/h: full-mode power users managing several works do dozens of legitimate\n // management actions per hour; still a hard backstop against scripts.\n // DJ ruling 2026-07-08 (charter 30 / full 60, single bucket; a bucket split\n // is filed post-launch in ttt-prod docs/post-launch/).\n SENSITIVE_ACTION: { maxRequests: 60, window: '1 h' },\n // 300/h (full): same reasoning as the charter value above (App-Check-gated\n // cost ceiling, IP-keyed, debounced-live). Public-launch CGNAT exposure is far\n // larger — hundreds of concurrent legit registrants can sit behind one carrier\n // IP — so err generous; the only cost of \"too high\" is trivial Firestore reads,\n // while \"too low\" false-rejects real users. Raise on evidence (watch prod logs\n // for legit 429s) rather than pre-emptively tightening. DJ ruling 2026-07-21.\n DISPLAY_NAME_CHECK: { maxRequests: 300, window: '1 h' },\n CHAT_MESSAGE: { maxRequests: 150, window: '1 h' },\n ADMIN_TASK: { maxRequests: 60, window: '1 h' },\n APPEAL_REVIEW: { maxRequests: 30, window: '1 h' },\n BAN_ACTION: { maxRequests: 20, window: '1 h' },\n SHARE_TRANSFER: { maxRequests: 10, window: '1 h' },\n CONTENT_REPORT: { maxRequests: 20, window: '1 h' },\n SHORT_LINK_CLICK: { maxRequests: 60, window: '1 h' },\n FOLLOW: { maxRequests: 60, window: '1 m' },\n MENTION_HISTORY: { maxRequests: 120, window: '1 h' },\n // 240/h (full): the same grant-minting buckets as charter, doubled with the surrounding\n // content limits. Full mode raises the ceilings a grant is minted PER (250-guildmate guilds,\n // 25 file folders, 1000 work files, 10 auditions), so one session legitimately touches more\n // scopes and re-mints more often. See the CHARTER_LIMITS notes above.\n MEDIA_GRANT: { maxRequests: 240, window: '1 h' },\n CHAT_GRANT: { maxRequests: 240, window: '1 h' },\n // Operator step-up stays at 10/h in BOTH modes — an admin second-factor throttle is a\n // security control, not a cost lever, so it never loosens at the flip. See CHARTER_LIMITS.\n OPERATOR_STEP_UP: { maxRequests: 10, window: '1 h' },\n ADMIN_MESSAGE_READ: { maxRequests: 60, window: '1 h' },\n // Admin exact-account lookup — same read bucket in both modes (see CHARTER_LIMITS note).\n USER_LOOKUP: { maxRequests: 30, window: '1 m' },\n NOTIFICATION_BROADCAST: { maxRequests: 10, window: '1 h' },\n NOTIFICATION_ARCHIVE: { maxRequests: 120, window: '1 h' },\n NOTIFICATION_MARK_SEEN: { maxRequests: 120, window: '1 h' },\n FEEDBACK: { maxRequests: 10, window: '1 h' },\n SHORT_LINK_CREATE: { maxRequests: 30, window: '1 h' },\n INVITE_ACTION: { maxRequests: 60, window: '1 h' },\n LIBRARY_SUBMISSION: { maxRequests: 20, window: '1 h' },\n CHANNEL_CREATE: { maxRequests: 20, window: '1 h' },\n CHECKOUT_CREATE: { maxRequests: 20, window: '1 h' },\n // Scaled with DISPLAY_NAME_CHECK's full-mode 300/h — see the CHARTER_LIMITS note.\n AGE_ATTEST: { maxRequests: 75, window: '1 h' },\n },\n};\n\n/** The resolved limit set for the deployed mode. Import THIS (or the alias\n * constants that re-export from it), never CHARTER_/FULL_ directly. A read bound\n * that must hold whichever mode the data was written under uses\n * HALL_SUB_ITEM_READ_BOUND_BY_WORK_TYPE below instead. */\nexport const ACTIVE_LIMITS: TttLimits = byMode(CHARTER_LIMITS, FULL_LIMITS);\n\nconst largestInAnyMode = (pick: (limits: TttLimits) => number): number =>\n Math.max(pick(CHARTER_LIMITS), pick(FULL_LIMITS));\n\n/**\n * The most sub-items one Hall item can hold of each kind (Tale chapters, Tune tracks, Television\n * episodes) in ANY app mode — each kind's count cap at its largest across CHARTER_LIMITS and\n * FULL_LIMITS. A READ bound, never an enforced limit: a Hall item keeps the sub-items it was\n * published with when the mode changes, so a reader that must see all of them sizes its query\n * from this and treats a read that returns more as uncertain. Enforcement reads the active caps\n * (MAX_CHAPTERS, MAX_TUNE_TRACKS, MAX_TELEVISION_EPISODES).\n */\nexport const HALL_SUB_ITEM_READ_BOUND_BY_WORK_TYPE: Readonly<Record<WorkProjectType, number>> = {\n Tales: largestInAnyMode((limits) => limits.workProject.maxChapters),\n Tunes: largestInAnyMode((limits) => limits.workProject.maxTuneTracks),\n Television: largestInAnyMode((limits) => limits.workProject.maxTelevisionEpisodes),\n};\n\n/**\n * User-facing copy for a reached count cap — the ONE owner of the cap-message\n * shape, beside the limits it describes. Every callable refusing on a\n * mode-varied count cap formats through this. In charter mode the message\n * names Charter Season so the cap reads as the season's limit rather than the\n * platform's permanent shape; full mode stays neutral. `hint` is an optional\n * trailing sentence (e.g. \"Delete a file to add another.\").\n */\nexport const countCapReachedMessage = (\n subject: string,\n limit: number,\n noun: string,\n hint?: string,\n): string => {\n const base = byMode(\n `${subject} already has the Charter Season maximum of ${limit} ${noun} — caps expand when Charter Season ends.`,\n `${subject} already has the maximum of ${limit} ${noun}.`,\n );\n return hint ? `${base} ${hint}` : base;\n};\n"]}
1
+ {"version":3,"file":"app-mode.js","sourceRoot":"","sources":["../../src/constants/app-mode.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,wEAAwE;AACxE,yEAAyE;AACzE,+DAA+D;AAC/D,2DAA2D;AAC3D,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,yEAAyE;AACzE,0EAA0E;AAC1E,yEAAyE;AAMzE,8EAA8E;AAC9E,MAAM,CAAC,MAAM,QAAQ,GAAY,SAAS,CAAC;AAE3C,qDAAqD;AACrD,MAAM,CAAC,MAAM,MAAM,GAAG,CAAI,OAAU,EAAE,IAAO,EAAK,EAAE,CACjD,QAAoB,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAoFvD,MAAM,CAAC,MAAM,cAAc,GAAc;IACvC,IAAI,EAAE,SAAS;IACf,IAAI,EAAE;QACJ,cAAc,EAAE,CAAC;QACjB,oBAAoB,EAAE,CAAC;QACvB,yBAAyB,EAAE,EAAE;KAC9B;IACD,WAAW,EAAE;QACX,YAAY,EAAE,EAAE;QAChB,cAAc,EAAE,EAAE;QAClB,YAAY,EAAE,GAAG;QACjB,uBAAuB,EAAE,aAAa,EAAE,UAAU;QAClD,uBAAuB,EAAE,CAAC;QAC1B,qBAAqB,EAAE,CAAC;QACxB,WAAW,EAAE,CAAC;QACd,+EAA+E;QAC/E,yDAAyD;QACzD,uBAAuB,EAAE,MAAM;QAC/B,aAAa,EAAE,CAAC;QAChB,qBAAqB,EAAE,CAAC;KACzB;IACD,qFAAqF;IACrF,sFAAsF;IACtF,wFAAwF;IACxF,sFAAsF;IACtF,wFAAwF;IACxF,uDAAuD;IACvD,YAAY,EAAE;QACZ,oBAAoB,EAAE,EAAE;QACxB,+BAA+B,EAAE,WAAW,EAAE,UAAU;KACzD;IACD,IAAI,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE;IAC5B,OAAO,EAAE,EAAE,wBAAwB,EAAE,GAAG,EAAE,qBAAqB,EAAE,EAAE,EAAE;IACrE,UAAU,EAAE;QACV,2EAA2E;QAC3E,iCAAiC;QACjC,MAAM,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC1C,8EAA8E;QAC9E,yEAAyE;QACzE,6EAA6E;QAC7E,+EAA+E;QAC/E,mFAAmF;QACnF,YAAY,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAChD,iFAAiF;QACjF,gFAAgF;QAChF,+EAA+E;QAC/E,2EAA2E;QAC3E,iCAAiC;QACjC,aAAa,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACjD,IAAI,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QACzC,UAAU,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC9C,yEAAyE;QACzE,6EAA6E;QAC7E,2EAA2E;QAC3E,yEAAyE;QACzE,gBAAgB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACpD,yEAAyE;QACzE,6EAA6E;QAC7E,iFAAiF;QACjF,gFAAgF;QAChF,kFAAkF;QAClF,iFAAiF;QACjF,iFAAiF;QACjF,kBAAkB,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QACvD,YAAY,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QACjD,UAAU,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC9C,aAAa,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACjD,UAAU,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC9C,cAAc,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAClD,cAAc,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE;QACjD,gBAAgB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACpD,MAAM,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC1C,eAAe,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QACpD,oFAAoF;QACpF,2FAA2F;QAC3F,2FAA2F;QAC3F,8FAA8F;QAC9F,8FAA8F;QAC9F,4FAA4F;QAC5F,6FAA6F;QAC7F,8FAA8F;QAC9F,8BAA8B;QAC9B,WAAW,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QAChD,4FAA4F;QAC5F,8FAA8F;QAC9F,4FAA4F;QAC5F,wFAAwF;QACxF,mFAAmF;QACnF,0FAA0F;QAC1F,2EAA2E;QAC3E,UAAU,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QAC/C,sFAAsF;QACtF,mFAAmF;QACnF,mFAAmF;QACnF,yFAAyF;QACzF,2FAA2F;QAC3F,2FAA2F;QAC3F,2FAA2F;QAC3F,+FAA+F;QAC/F,+FAA+F;QAC/F,gBAAgB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACpD,kBAAkB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACtD,yFAAyF;QACzF,2FAA2F;QAC3F,8FAA8F;QAC9F,WAAW,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC/C,sBAAsB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC1D,oBAAoB,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QACzD,sBAAsB,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QAC3D,QAAQ,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC5C,iBAAiB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACrD,aAAa,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACjD,kBAAkB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACtD,cAAc,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE;QACjD,eAAe,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE;QAClD,4FAA4F;QAC5F,2FAA2F;QAC3F,+FAA+F;QAC/F,iEAAiE;QACjE,UAAU,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC9C,+FAA+F;QAC/F,+FAA+F;QAC/F,yEAAyE;QACzE,eAAe,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QACpD,qFAAqF;QACrF,iEAAiE;QACjE,eAAe,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;KACpD;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAc;IACpC,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE;QACJ,cAAc,EAAE,EAAE;QAClB,oBAAoB,EAAE,EAAE;QACxB,yBAAyB,EAAE,GAAG;KAC/B;IACD,WAAW,EAAE;QACX,YAAY,EAAE,GAAG;QACjB,cAAc,EAAE,EAAE;QAClB,YAAY,EAAE,IAAI;QAClB,uBAAuB,EAAE,cAAc,EAAE,SAAS;QAClD,uBAAuB,EAAE,EAAE;QAC3B,qBAAqB,EAAE,EAAE;QACzB,WAAW,EAAE,EAAE;QACf,8EAA8E;QAC9E,4EAA4E;QAC5E,yEAAyE;QACzE,uBAAuB,EAAE,OAAO;QAChC,aAAa,EAAE,EAAE;QACjB,qBAAqB,EAAE,EAAE;KAC1B;IACD,iFAAiF;IACjF,4EAA4E;IAC5E,sFAAsF;IACtF,YAAY,EAAE;QACZ,oBAAoB,EAAE,EAAE;QACxB,+BAA+B,EAAE,aAAa,EAAE,QAAQ;KACzD;IACD,IAAI,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE;IAC5B,OAAO,EAAE,EAAE,wBAAwB,EAAE,IAAI,EAAE,qBAAqB,EAAE,GAAG,EAAE;IACvE,UAAU,EAAE;QACV,MAAM,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC1C,gFAAgF;QAChF,6EAA6E;QAC7E,2EAA2E;QAC3E,mDAAmD;QACnD,YAAY,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QACjD,gFAAgF;QAChF,8EAA8E;QAC9E,2DAA2D;QAC3D,aAAa,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACjD,IAAI,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QACzC,UAAU,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC9C,6EAA6E;QAC7E,sEAAsE;QACtE,4EAA4E;QAC5E,uDAAuD;QACvD,gBAAgB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACpD,2EAA2E;QAC3E,+EAA+E;QAC/E,+EAA+E;QAC/E,gFAAgF;QAChF,+EAA+E;QAC/E,8EAA8E;QAC9E,kBAAkB,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QACvD,YAAY,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QACjD,UAAU,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC9C,aAAa,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACjD,UAAU,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC9C,cAAc,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAClD,cAAc,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAClD,gBAAgB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACpD,MAAM,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC1C,eAAe,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QACpD,wFAAwF;QACxF,6FAA6F;QAC7F,4FAA4F;QAC5F,sEAAsE;QACtE,WAAW,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QAChD,UAAU,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QAC/C,sFAAsF;QACtF,2FAA2F;QAC3F,gBAAgB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACpD,kBAAkB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACtD,yFAAyF;QACzF,WAAW,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC/C,sBAAsB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC1D,oBAAoB,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QACzD,sBAAsB,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QAC3D,QAAQ,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC5C,iBAAiB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACrD,aAAa,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACjD,kBAAkB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACtD,cAAc,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAClD,eAAe,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACnD,kFAAkF;QAClF,UAAU,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAC9C,oEAAoE;QACpE,eAAe,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE;QACpD,eAAe,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;KACpD;CACF,CAAC;AAEF;;;0DAG0D;AAC1D,MAAM,CAAC,MAAM,aAAa,GAAc,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;AAE5E,MAAM,gBAAgB,GAAG,CAAC,IAAmC,EAAU,EAAE,CACvE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qCAAqC,GAA8C;IAC9F,KAAK,EAAE,gBAAgB,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC;IACnE,KAAK,EAAE,gBAAgB,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,aAAa,CAAC;IACrE,UAAU,EAAE,gBAAgB,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,qBAAqB,CAAC;CACnF,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,OAAe,EACf,KAAa,EACb,IAAY,EACZ,IAAa,EACL,EAAE;IACV,MAAM,IAAI,GAAG,MAAM,CACjB,GAAG,OAAO,8CAA8C,KAAK,IAAI,IAAI,0CAA0C,EAC/G,GAAG,OAAO,+BAA+B,KAAK,IAAI,IAAI,GAAG,CAC1D,CAAC;IACF,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACzC,CAAC,CAAC","sourcesContent":["// App mode + the charter/full limit sets — the single published constant that\n// drives the whole app's cost posture. The flip to full-live is: change\n// APP_MODE → publish ttt-core → install in ttt-prod (root + functions) →\n// deploy. There is NO runtime mode flag and NO console toggle.\n// See ttt-prod docs/design/charter-season-and-app-mode.md.\n//\n// Only real cost/abuse drivers vary by mode: media specs (ttt-media-specs.ts),\n// rate-limit values, count caps, batch sizes. Text-length limits and payment\n// min/max are deliberately mode-invariant — with ONE ruled exception (DJ\n// 2026-07-13): chapter body content (maxChapterContentLength), because it\n// bounds threshold-review reading effort per item during charter season.\n\nimport type { WorkProjectType } from '../types/content.js';\n\nexport type AppMode = 'charter' | 'full';\n\n/** The deployed mode. Changing this constant (and publishing) IS the flip. */\nexport const APP_MODE: AppMode = 'charter';\n\n/** Pick the active value for a mode-varied limit. */\nexport const byMode = <T>(charter: T, full: T): T =>\n (APP_MODE as AppMode) === 'charter' ? charter : full;\n\n/** Upstash-style sliding-window duration, e.g. '1 h'. */\nexport type RateLimitWindow = `${number} ${'ms' | 's' | 'm' | 'h' | 'd'}`;\n\nexport interface RateLimitValue {\n maxRequests: number;\n window: RateLimitWindow;\n}\n\nexport interface TttLimits {\n mode: AppMode;\n user: {\n maxCraftSkills: number;\n maxOwnedWorkProjects: number;\n maxAssociatedWorkProjects: number;\n };\n workProject: {\n maxGuildSize: number;\n maxFileFolders: number;\n maxWorkFiles: number;\n maxWorkFileStorageBytes: number;\n maxWorkProjectAuditions: number;\n maxCommissionListings: number;\n maxChapters: number;\n /** Chapter BODY length (chars) — the one mode-varied text limit (DJ 2026-07-13). */\n maxChapterContentLength: number;\n maxTuneTracks: number;\n maxTelevisionEpisodes: number;\n };\n /** Conversation Files container caps — PER CONVERSATION (one guild-invite\n * conversation or one admin-support dispatch thread). Both scopes share one cap\n * set; guild chat channels have no Conversation Files. DJ ruling 2026-07-25. */\n conversation: {\n /** Published active Conversation Files allowed in one conversation. */\n maxConversationFiles: number;\n /** Published STORED-OUTPUT bytes allowed in one conversation. */\n maxConversationFileStorageBytes: number;\n };\n hall: {\n maxSubmitBatch: number;\n };\n batches: {\n trendingFeedProcessLimit: number;\n maxFeedbackSubmitters: number;\n };\n /** Values for the backend rate limiters. Prefixes/factory stay in functions. */\n rateLimits: {\n UPLOAD: RateLimitValue;\n ADMIN_UPLOAD: RateLimitValue;\n CONTENT_WRITE: RateLimitValue;\n VOTE: RateLimitValue;\n MODERATION: RateLimitValue;\n SENSITIVE_ACTION: RateLimitValue;\n DISPLAY_NAME_CHECK: RateLimitValue;\n CHAT_MESSAGE: RateLimitValue;\n ADMIN_TASK: RateLimitValue;\n APPEAL_REVIEW: RateLimitValue;\n BAN_ACTION: RateLimitValue;\n SHARE_TRANSFER: RateLimitValue;\n CONTENT_REPORT: RateLimitValue;\n SHORT_LINK_CLICK: RateLimitValue;\n FOLLOW: RateLimitValue;\n MENTION_HISTORY: RateLimitValue;\n MEDIA_GRANT: RateLimitValue;\n CHAT_GRANT: RateLimitValue;\n OPERATOR_STEP_UP: RateLimitValue;\n ADMIN_MESSAGE_READ: RateLimitValue;\n USER_LOOKUP: RateLimitValue;\n NOTIFICATION_BROADCAST: RateLimitValue;\n NOTIFICATION_ARCHIVE: RateLimitValue;\n NOTIFICATION_MARK_SEEN: RateLimitValue;\n FEEDBACK: RateLimitValue;\n SHORT_LINK_CREATE: RateLimitValue;\n INVITE_ACTION: RateLimitValue;\n LIBRARY_SUBMISSION: RateLimitValue;\n CHANNEL_CREATE: RateLimitValue;\n CHECKOUT_CREATE: RateLimitValue;\n AGE_ATTEST: RateLimitValue;\n HALL_PREFERENCE: RateLimitValue;\n REFUND_DECISION: RateLimitValue;\n };\n}\n\nexport const CHARTER_LIMITS: TttLimits = {\n mode: 'charter',\n user: {\n maxCraftSkills: 8,\n maxOwnedWorkProjects: 3,\n maxAssociatedWorkProjects: 10,\n },\n workProject: {\n maxGuildSize: 25,\n maxFileFolders: 10,\n maxWorkFiles: 100,\n maxWorkFileStorageBytes: 2_684_354_560, // 2.5 GiB\n maxWorkProjectAuditions: 3,\n maxCommissionListings: 3,\n maxChapters: 5,\n // ~5,000 words — a full real chapter, while keeping the human threshold-review\n // reading effort per item bounded during charter season.\n maxChapterContentLength: 30_000,\n maxTuneTracks: 5,\n maxTelevisionEpisodes: 3,\n },\n // Conversation Files are QUOTA'D PER CONVERSATION (DJ ruling 2026-07-25). Counted on\n // STORED OUTPUT bytes (what actually sits in R2 after transcode), never on raw upload\n // bytes. Rationale: a per-file `maxBytes` cap alone bounds one upload but nothing stops\n // unbounded accumulation across a long-running conversation — this is the abuse brake\n // on that, and it is what `startUpload`'s reservation and the publication transfer both\n // check. Charter: 10 files / 500 MiB per conversation.\n conversation: {\n maxConversationFiles: 10,\n maxConversationFileStorageBytes: 524_288_000, // 500 MiB\n },\n hall: { maxSubmitBatch: 10 },\n batches: { trendingFeedProcessLimit: 250, maxFeedbackSubmitters: 25 },\n rateLimits: {\n // Uploads are charged ONCE per upload (in startUpload); the processor-side\n // check is a non-charging guard.\n UPLOAD: { maxRequests: 15, window: '1 h' },\n // A separate HIGHER bucket for uploads performed through the sanctioned admin\n // authority path — never an exemption. Bulk admin setup work (creating 3\n // auditions is ~5 uploads) exhausts the 15/h user bucket; 60/h covers a real\n // bulk admin session while keeping a brake on a compromised admin token and on\n // third-party quota/cost (Vision / Video Intelligence / R2). DJ ruling 2026-07-25.\n ADMIN_UPLOAD: { maxRequests: 60, window: '1 h' },\n // General content-write throttle for the non-upload write callables (text posts,\n // craft-skill edits, support-thread starts) that used to charge UPLOAD. Sharing\n // the 15/h charter upload window meant heavy text posting blocked real uploads\n // and vice versa; a separate 30/h bucket keeps each cost driver on its own\n // ceiling. DJ ruling 2026-07-25.\n CONTENT_WRITE: { maxRequests: 30, window: '1 h' },\n VOTE: { maxRequests: 100, window: '1 h' },\n MODERATION: { maxRequests: 50, window: '1 h' },\n // 30/h: one bucket is shared by ~35 callables (register, become-artisan,\n // create-work, invites, trades, appeals, …) — a real first-hour artisan does\n // 10-15 legitimate sensitive actions; 5/h blocked the intended golden path\n // (proven live by the hosted-dev E2E, 2026-07-07). DJ ruling 2026-07-08.\n SENSITIVE_ACTION: { maxRequests: 30, window: '1 h' },\n // 120/h (charter): checkDisplayNameAvailable is enforceAppCheck:true, so\n // reCAPTCHA-Enterprise attestation is the real abuse gate — this bucket is a\n // cost/DoS ceiling, not the security boundary. It is IP-keyed (pre-registration,\n // no uid yet) and the register form fires it debounced-LIVE as you type, so one\n // legit registrant spends ~3-8 checks and shared NAT/CGNAT multiplies that across\n // everyone on the IP. The old 20/h false-rejected legitimate shared-IP users and\n // could not fit a full hosted-dev E2E suite run on one IP. DJ ruling 2026-07-21.\n DISPLAY_NAME_CHECK: { maxRequests: 120, window: '1 h' },\n CHAT_MESSAGE: { maxRequests: 125, window: '1 h' },\n ADMIN_TASK: { maxRequests: 60, window: '1 h' },\n APPEAL_REVIEW: { maxRequests: 30, window: '1 h' },\n BAN_ACTION: { maxRequests: 20, window: '1 h' },\n SHARE_TRANSFER: { maxRequests: 10, window: '1 h' },\n CONTENT_REPORT: { maxRequests: 5, window: '1 h' },\n SHORT_LINK_CLICK: { maxRequests: 60, window: '1 h' },\n FOLLOW: { maxRequests: 20, window: '1 m' },\n MENTION_HISTORY: { maxRequests: 120, window: '1 h' },\n // Scoped-media grant minting (createMediaGrant). Its OWN bucket — it used to charge\n // MENTION_HISTORY, an unrelated surface, so neither limit meant what its name said and the\n // two shared a budget sized for neither (BACKEND-013). Refresh-driven, not user-initiated:\n // a grant is short-TTL (60 min work media, 15 min chat/folder scopes) and the client re-mints\n // under expiry, so a browsing session naturally spends several per hour PER SCOPE (each work,\n // each private file folder, each conversation). Cheap to serve (a Firestore permission read\n // plus an HMAC sign — no third-party cost), and a false 429 breaks media rendering outright,\n // so the ceiling is generous: it exists to stop a scripted grant-farming sweep, not to pace a\n // real reader. 120/h charter.\n MEDIA_GRANT: { maxRequests: 120, window: '1 h' },\n // Realtime chat grant minting (mintChatGrant) — previously NO limiter at all (BACKEND-013),\n // despite minting signed grants at concurrency: 20. Same refresh-driven shape as MEDIA_GRANT:\n // a 15-minute grant TTL means ~4 mints/hour for the inbox plus ~4 per open channel, doubled\n // again by socket reconnects on a flaky mobile network. It stays behind the per-channel\n // authorizeChannelScope gate, so this bucket is a cost/DoS ceiling rather than the\n // authorization boundary — sized to match MEDIA_GRANT so the two grant surfaces are paced\n // alike and neither can be starved by the other (separate Redis prefixes).\n CHAT_GRANT: { maxRequests: 120, window: '1 h' },\n // Operator step-up TOTP verification (confirmOperatorStepUp / verifyOperatorStepUp) —\n // previously unthrottled, so an attacker holding a stolen full-admin session could\n // brute-force the 6-digit second factor guarding the safety console (BACKEND-013).\n // DELIBERATELY THE TIGHTEST BUCKET IN THE SET: a real operator enrolls once and verifies\n // roughly twice an hour (the grant window is 30 minutes), so 10/h absorbs every legitimate\n // mistype while capping guessing at 10 attempts per hour against a code that rotates every\n // 30 seconds. Mode-INVARIANT — this is an admin security control, not a cost driver, so it\n // never loosens at the full-mode flip (same posture as MODERATION / BAN_ACTION / USER_LOOKUP).\n // The lockout-after-N-failures behaviour is a separate app-side concern; this is the throttle.\n OPERATOR_STEP_UP: { maxRequests: 10, window: '1 h' },\n ADMIN_MESSAGE_READ: { maxRequests: 60, window: '1 h' },\n // Admin exact-account lookup (searchPublicUsers / lookupUserByEmailOrUid) — a read, so a\n // generous per-minute bucket that still backstops a scripted enumeration sweep. Admin-only\n // and not a cost driver, so the value is the same in both modes (like MODERATION/ADMIN_TASK).\n USER_LOOKUP: { maxRequests: 30, window: '1 m' },\n NOTIFICATION_BROADCAST: { maxRequests: 10, window: '1 h' },\n NOTIFICATION_ARCHIVE: { maxRequests: 120, window: '1 h' },\n NOTIFICATION_MARK_SEEN: { maxRequests: 120, window: '1 h' },\n FEEDBACK: { maxRequests: 10, window: '1 h' },\n SHORT_LINK_CREATE: { maxRequests: 30, window: '1 h' },\n INVITE_ACTION: { maxRequests: 30, window: '1 h' },\n LIBRARY_SUBMISSION: { maxRequests: 10, window: '1 h' },\n CHANNEL_CREATE: { maxRequests: 5, window: '1 h' },\n CHECKOUT_CREATE: { maxRequests: 5, window: '1 h' },\n // The registration age step, keyed per hashed client IP (pre-account, no uid). One call per\n // attempt — a corrected date or a retry at most doubles it — so 30/h gives one IP the same\n // registrants per hour as DISPLAY_NAME_CHECK's 120/h at its 3–8 debounced checks each, while a\n // script minting age-attestation records gets far less headroom.\n AGE_ATTEST: { maxRequests: 30, window: '1 h' },\n // A member's own Hall settings, ink marks, hidden Works, reading position, and recently viewed\n // list. Reading position and recently viewed are written as the member reads, so the bucket is\n // sized like NOTIFICATION_MARK_SEEN, the other passive per-member write.\n HALL_PREFERENCE: { maxRequests: 120, window: '1 h' },\n // An admin's approve or deny of a refund request. Admin-only, so mode-invariant like\n // APPEAL_REVIEW, the other admin decision on a member's request.\n REFUND_DECISION: { maxRequests: 30, window: '1 h' },\n },\n};\n\nexport const FULL_LIMITS: TttLimits = {\n mode: 'full',\n user: {\n maxCraftSkills: 24,\n maxOwnedWorkProjects: 25,\n maxAssociatedWorkProjects: 100,\n },\n workProject: {\n maxGuildSize: 250,\n maxFileFolders: 25,\n maxWorkFiles: 1000,\n maxWorkFileStorageBytes: 26_843_545_600, // 25 GiB\n maxWorkProjectAuditions: 10,\n maxCommissionListings: 10,\n maxChapters: 50,\n // The intentional design ceiling (~17,000 words; trivially inside Firestore's\n // 1 MiB doc limit) — the audit trail deliberately stores field LENGTHS, not\n // content, because chapters can be this large (runUpdateChapterDetails).\n maxChapterContentLength: 100_000,\n maxTuneTracks: 50,\n maxTelevisionEpisodes: 25,\n },\n // 20 files / 1 GiB (full): the same per-conversation Conversation Files quota as\n // charter, scaled for a public-launch conversation. Still a hard ceiling on\n // unbounded R2 accumulation. See the CHARTER_LIMITS note above. DJ ruling 2026-07-25.\n conversation: {\n maxConversationFiles: 20,\n maxConversationFileStorageBytes: 1_073_741_824, // 1 GiB\n },\n hall: { maxSubmitBatch: 50 },\n batches: { trendingFeedProcessLimit: 1000, maxFeedbackSubmitters: 100 },\n rateLimits: {\n UPLOAD: { maxRequests: 30, window: '1 h' },\n // 120/h (full): the same sanctioned-admin-path upload bucket as charter, scaled\n // with UPLOAD — always HIGHER than the user bucket, never an exemption, so a\n // compromised admin token and third-party media cost stay bounded. See the\n // CHARTER_LIMITS note above. DJ ruling 2026-07-25.\n ADMIN_UPLOAD: { maxRequests: 120, window: '1 h' },\n // 60/h (full): the same non-upload content-write bucket as charter, scaled with\n // UPLOAD so text writes and media uploads never consume each other's ceiling.\n // See the CHARTER_LIMITS note above. DJ ruling 2026-07-25.\n CONTENT_WRITE: { maxRequests: 60, window: '1 h' },\n VOTE: { maxRequests: 200, window: '1 h' },\n MODERATION: { maxRequests: 50, window: '1 h' },\n // 60/h: full-mode power users managing several works do dozens of legitimate\n // management actions per hour; still a hard backstop against scripts.\n // DJ ruling 2026-07-08 (charter 30 / full 60, single bucket; a bucket split\n // is filed post-launch in ttt-prod docs/post-launch/).\n SENSITIVE_ACTION: { maxRequests: 60, window: '1 h' },\n // 300/h (full): same reasoning as the charter value above (App-Check-gated\n // cost ceiling, IP-keyed, debounced-live). Public-launch CGNAT exposure is far\n // larger — hundreds of concurrent legit registrants can sit behind one carrier\n // IP — so err generous; the only cost of \"too high\" is trivial Firestore reads,\n // while \"too low\" false-rejects real users. Raise on evidence (watch prod logs\n // for legit 429s) rather than pre-emptively tightening. DJ ruling 2026-07-21.\n DISPLAY_NAME_CHECK: { maxRequests: 300, window: '1 h' },\n CHAT_MESSAGE: { maxRequests: 150, window: '1 h' },\n ADMIN_TASK: { maxRequests: 60, window: '1 h' },\n APPEAL_REVIEW: { maxRequests: 30, window: '1 h' },\n BAN_ACTION: { maxRequests: 20, window: '1 h' },\n SHARE_TRANSFER: { maxRequests: 10, window: '1 h' },\n CONTENT_REPORT: { maxRequests: 20, window: '1 h' },\n SHORT_LINK_CLICK: { maxRequests: 60, window: '1 h' },\n FOLLOW: { maxRequests: 60, window: '1 m' },\n MENTION_HISTORY: { maxRequests: 120, window: '1 h' },\n // 240/h (full): the same grant-minting buckets as charter, doubled with the surrounding\n // content limits. Full mode raises the ceilings a grant is minted PER (250-guildmate guilds,\n // 25 file folders, 1000 work files, 10 auditions), so one session legitimately touches more\n // scopes and re-mints more often. See the CHARTER_LIMITS notes above.\n MEDIA_GRANT: { maxRequests: 240, window: '1 h' },\n CHAT_GRANT: { maxRequests: 240, window: '1 h' },\n // Operator step-up stays at 10/h in BOTH modes — an admin second-factor throttle is a\n // security control, not a cost lever, so it never loosens at the flip. See CHARTER_LIMITS.\n OPERATOR_STEP_UP: { maxRequests: 10, window: '1 h' },\n ADMIN_MESSAGE_READ: { maxRequests: 60, window: '1 h' },\n // Admin exact-account lookup — same read bucket in both modes (see CHARTER_LIMITS note).\n USER_LOOKUP: { maxRequests: 30, window: '1 m' },\n NOTIFICATION_BROADCAST: { maxRequests: 10, window: '1 h' },\n NOTIFICATION_ARCHIVE: { maxRequests: 120, window: '1 h' },\n NOTIFICATION_MARK_SEEN: { maxRequests: 120, window: '1 h' },\n FEEDBACK: { maxRequests: 10, window: '1 h' },\n SHORT_LINK_CREATE: { maxRequests: 30, window: '1 h' },\n INVITE_ACTION: { maxRequests: 60, window: '1 h' },\n LIBRARY_SUBMISSION: { maxRequests: 20, window: '1 h' },\n CHANNEL_CREATE: { maxRequests: 20, window: '1 h' },\n CHECKOUT_CREATE: { maxRequests: 20, window: '1 h' },\n // Scaled with DISPLAY_NAME_CHECK's full-mode 300/h — see the CHARTER_LIMITS note.\n AGE_ATTEST: { maxRequests: 75, window: '1 h' },\n // Both stay at their charter values — see the CHARTER_LIMITS notes.\n HALL_PREFERENCE: { maxRequests: 120, window: '1 h' },\n REFUND_DECISION: { maxRequests: 30, window: '1 h' },\n },\n};\n\n/** The resolved limit set for the deployed mode. Import THIS (or the alias\n * constants that re-export from it), never CHARTER_/FULL_ directly. A read bound\n * that must hold whichever mode the data was written under uses\n * HALL_SUB_ITEM_READ_BOUND_BY_WORK_TYPE below instead. */\nexport const ACTIVE_LIMITS: TttLimits = byMode(CHARTER_LIMITS, FULL_LIMITS);\n\nconst largestInAnyMode = (pick: (limits: TttLimits) => number): number =>\n Math.max(pick(CHARTER_LIMITS), pick(FULL_LIMITS));\n\n/**\n * The most sub-items one Hall item can hold of each kind (Tale chapters, Tune tracks, Television\n * episodes) in ANY app mode — each kind's count cap at its largest across CHARTER_LIMITS and\n * FULL_LIMITS. A READ bound, never an enforced limit: a Hall item keeps the sub-items it was\n * published with when the mode changes, so a reader that must see all of them sizes its query\n * from this and treats a read that returns more as uncertain. Enforcement reads the active caps\n * (MAX_CHAPTERS, MAX_TUNE_TRACKS, MAX_TELEVISION_EPISODES).\n */\nexport const HALL_SUB_ITEM_READ_BOUND_BY_WORK_TYPE: Readonly<Record<WorkProjectType, number>> = {\n Tales: largestInAnyMode((limits) => limits.workProject.maxChapters),\n Tunes: largestInAnyMode((limits) => limits.workProject.maxTuneTracks),\n Television: largestInAnyMode((limits) => limits.workProject.maxTelevisionEpisodes),\n};\n\n/**\n * User-facing copy for a reached count cap — the ONE owner of the cap-message\n * shape, beside the limits it describes. Every callable refusing on a\n * mode-varied count cap formats through this. In charter mode the message\n * names Charter Season so the cap reads as the season's limit rather than the\n * platform's permanent shape; full mode stays neutral. `hint` is an optional\n * trailing sentence (e.g. \"Delete a file to add another.\").\n */\nexport const countCapReachedMessage = (\n subject: string,\n limit: number,\n noun: string,\n hint?: string,\n): string => {\n const base = byMode(\n `${subject} already has the Charter Season maximum of ${limit} ${noun} — caps expand when Charter Season ends.`,\n `${subject} already has the maximum of ${limit} ${noun}.`,\n );\n return hint ? `${base} ${hint}` : base;\n};\n"]}
@@ -63,6 +63,9 @@ export declare const MAX_SAFETY_RESOLUTION_SUMMARY_LENGTH = 2000;
63
63
  export declare const MAX_SAFETY_ADMIN_NOTE_LENGTH = 4000;
64
64
  /** Reporter free-text narrative/comment (segregated private doc; never on the root). */
65
65
  export declare const MAX_REPORT_NARRATIVE_LENGTH = 4000;
66
+ /** The ids a client names as the target of a report — the item, its parent reference, and the
67
+ * owner hint. They are hints the server re-derives, so the cap only bounds what is read. */
68
+ export declare const MAX_REPORT_TARGET_ID_LENGTH = 256;
66
69
  /** The report DIALOG's comment field cap (the client-side compose bound — tighter than
67
70
  * the server narrative cap above, which also absorbs upgrade concatenations). */
68
71
  export declare const MAX_REPORT_COMMENT_LENGTH = 1000;
@@ -133,6 +136,17 @@ export declare const MAX_NCII_REPRESENTED_PERSON_NAME_LENGTH = 256;
133
136
  export declare const MAX_NCII_AUTHORITY_BASIS_LENGTH = 2000;
134
137
  /** Optional pointer/reference to authority evidence supplied by a representative. */
135
138
  export declare const MAX_NCII_AUTHORITY_EVIDENCE_REF_LENGTH = 512;
139
+ /** The external URL a no-login statutory request names as the content to remove. */
140
+ export declare const MAX_NCII_LOCATOR_URL_LENGTH = 2048;
141
+ /** The client-generated idempotency key of a statutory request: a retried submit carries the same
142
+ * key, and the server derives the request id from it. */
143
+ export declare const NCII_IDEMPOTENCY_KEY_MIN_LENGTH = 8;
144
+ export declare const NCII_IDEMPOTENCY_KEY_MAX_LENGTH = 256;
145
+ /** A statutory requester's contact email (the address-length ceiling of an email). */
146
+ export declare const MAX_NCII_CONTACT_EMAIL_LENGTH = 320;
147
+ /** A statutory requester's contact phone number. */
148
+ export declare const NCII_CONTACT_PHONE_MIN_LENGTH = 3;
149
+ export declare const NCII_CONTACT_PHONE_MAX_LENGTH = 64;
136
150
  /** Maximum length for a feedback suggestion. */
137
151
  export declare const MAX_FEEDBACK_SUGGESTION_LENGTH = 100;
138
152
  /** Maximum number of distinct submitters tracked per feedback suggestion. Mode-varied. */
@@ -175,6 +189,7 @@ export declare const ADMIN_TASK_RESOLUTION_OWNER_BY_TYPE: {
175
189
  readonly pledgePaymentRepairNeeded: "checkin";
176
190
  readonly pledgeDisputeOpened: "checkin";
177
191
  readonly pledgeRefundRequested: "refundDecision";
192
+ readonly pledgeRefundFailed: "refundDecision";
178
193
  readonly hallContentChangeRequest: "changeRequestReview";
179
194
  };
180
195
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"business-admin.d.ts","sourceRoot":"","sources":["../../src/constants/business-admin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"business-admin.d.ts","sourceRoot":"","sources":["../../src/constants/business-admin.ts"],"names":[],"mappings":"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"}