@ttt-productions/ttt-core 0.78.26 → 0.79.0

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 (148) hide show
  1. package/dist/capabilities/capability-registry.d.ts +2 -2
  2. package/dist/capabilities/capability-registry.d.ts.map +1 -1
  3. package/dist/capabilities/capability-registry.js +5 -5
  4. package/dist/capabilities/capability-registry.js.map +1 -1
  5. package/dist/capabilities/messaging-surfaces.d.ts.map +1 -1
  6. package/dist/capabilities/messaging-surfaces.js +7 -3
  7. package/dist/capabilities/messaging-surfaces.js.map +1 -1
  8. package/dist/constants/app-mode.d.ts +9 -0
  9. package/dist/constants/app-mode.d.ts.map +1 -1
  10. package/dist/constants/app-mode.js +17 -0
  11. package/dist/constants/app-mode.js.map +1 -1
  12. package/dist/constants/business-content.d.ts +0 -2
  13. package/dist/constants/business-content.d.ts.map +1 -1
  14. package/dist/constants/business-content.js +0 -2
  15. package/dist/constants/business-content.js.map +1 -1
  16. package/dist/constants/conversation-files.d.ts +7 -0
  17. package/dist/constants/conversation-files.d.ts.map +1 -0
  18. package/dist/constants/conversation-files.js +14 -0
  19. package/dist/constants/conversation-files.js.map +1 -0
  20. package/dist/constants/index.d.ts +1 -0
  21. package/dist/constants/index.d.ts.map +1 -1
  22. package/dist/constants/index.js +1 -0
  23. package/dist/constants/index.js.map +1 -1
  24. package/dist/doc-schemas/chat-sync.d.ts +0 -4
  25. package/dist/doc-schemas/chat-sync.d.ts.map +1 -1
  26. package/dist/doc-schemas/chat-sync.js +2 -9
  27. package/dist/doc-schemas/chat-sync.js.map +1 -1
  28. package/dist/doc-schemas/commissions.d.ts +2 -2
  29. package/dist/doc-schemas/media-activation-jobs.d.ts +3 -8
  30. package/dist/doc-schemas/media-activation-jobs.d.ts.map +1 -1
  31. package/dist/doc-schemas/media-assets.d.ts +22 -34
  32. package/dist/doc-schemas/media-assets.d.ts.map +1 -1
  33. package/dist/doc-schemas/media-assets.js +24 -21
  34. package/dist/doc-schemas/media-assets.js.map +1 -1
  35. package/dist/doc-schemas/messaging.d.ts +41 -19
  36. package/dist/doc-schemas/messaging.d.ts.map +1 -1
  37. package/dist/doc-schemas/messaging.js +64 -4
  38. package/dist/doc-schemas/messaging.js.map +1 -1
  39. package/dist/doc-schemas/moderation.d.ts +1 -1
  40. package/dist/doc-schemas/ncii/allegations.d.ts +21 -9
  41. package/dist/doc-schemas/ncii/allegations.d.ts.map +1 -1
  42. package/dist/doc-schemas/ncii/cases.d.ts +10 -4
  43. package/dist/doc-schemas/ncii/cases.d.ts.map +1 -1
  44. package/dist/doc-schemas/ncii/holds.d.ts +10 -4
  45. package/dist/doc-schemas/ncii/holds.d.ts.map +1 -1
  46. package/dist/doc-schemas/ncii/removal.d.ts +13 -7
  47. package/dist/doc-schemas/ncii/removal.d.ts.map +1 -1
  48. package/dist/doc-schemas/ncii/requests.d.ts +11 -5
  49. package/dist/doc-schemas/ncii/requests.d.ts.map +1 -1
  50. package/dist/doc-schemas/registry.d.ts +148 -119
  51. package/dist/doc-schemas/registry.d.ts.map +1 -1
  52. package/dist/doc-schemas/registry.js +5 -1
  53. package/dist/doc-schemas/registry.js.map +1 -1
  54. package/dist/doc-schemas/safety/case.d.ts +10 -4
  55. package/dist/doc-schemas/safety/case.d.ts.map +1 -1
  56. package/dist/doc-schemas/safety/case.js +4 -3
  57. package/dist/doc-schemas/safety/case.js.map +1 -1
  58. package/dist/doc-schemas/safety/evidence.d.ts +2 -3
  59. package/dist/doc-schemas/safety/evidence.d.ts.map +1 -1
  60. package/dist/doc-schemas/safety/foundation.d.ts +15 -8
  61. package/dist/doc-schemas/safety/foundation.d.ts.map +1 -1
  62. package/dist/doc-schemas/safety/foundation.js +32 -6
  63. package/dist/doc-schemas/safety/foundation.js.map +1 -1
  64. package/dist/doc-schemas/safety/holds.d.ts +1 -1
  65. package/dist/doc-schemas/safety/report.d.ts +25 -10
  66. package/dist/doc-schemas/safety/report.d.ts.map +1 -1
  67. package/dist/doc-schemas/safety/report.js +2 -1
  68. package/dist/doc-schemas/safety/report.js.map +1 -1
  69. package/dist/ids/chat-ids.d.ts +1 -2
  70. package/dist/ids/chat-ids.d.ts.map +1 -1
  71. package/dist/ids/chat-ids.js +1 -4
  72. package/dist/ids/chat-ids.js.map +1 -1
  73. package/dist/media/conversation-file-ref.d.ts +13 -0
  74. package/dist/media/conversation-file-ref.d.ts.map +1 -0
  75. package/dist/media/conversation-file-ref.js +37 -0
  76. package/dist/media/conversation-file-ref.js.map +1 -0
  77. package/dist/media/domain-events-admin.d.ts +1 -1
  78. package/dist/media/domain-events-social.d.ts +0 -7
  79. package/dist/media/domain-events-social.d.ts.map +1 -1
  80. package/dist/media/domain-events-social.js +2 -13
  81. package/dist/media/domain-events-social.js.map +1 -1
  82. package/dist/media/domain-events.d.ts +1 -7
  83. package/dist/media/domain-events.d.ts.map +1 -1
  84. package/dist/media/domain-events.js +1 -2
  85. package/dist/media/domain-events.js.map +1 -1
  86. package/dist/media/edge-serving-contract.d.ts +6 -11
  87. package/dist/media/edge-serving-contract.d.ts.map +1 -1
  88. package/dist/media/edge-serving-contract.js.map +1 -1
  89. package/dist/media/file-origin.d.ts +1 -1
  90. package/dist/media/file-origin.d.ts.map +1 -1
  91. package/dist/media/file-origin.js +6 -1
  92. package/dist/media/file-origin.js.map +1 -1
  93. package/dist/media/index.d.ts +1 -0
  94. package/dist/media/index.d.ts.map +1 -1
  95. package/dist/media/index.js +1 -0
  96. package/dist/media/index.js.map +1 -1
  97. package/dist/media/pending-media.d.ts +25 -79
  98. package/dist/media/pending-media.d.ts.map +1 -1
  99. package/dist/media/photodna-coverage.js +1 -1
  100. package/dist/media/photodna-coverage.js.map +1 -1
  101. package/dist/media/start-upload.d.ts +1 -1
  102. package/dist/media/target-info.d.ts +6 -26
  103. package/dist/media/target-info.d.ts.map +1 -1
  104. package/dist/media/target-info.js +9 -35
  105. package/dist/media/target-info.js.map +1 -1
  106. package/dist/media/ttt-media-specs.d.ts.map +1 -1
  107. package/dist/media/ttt-media-specs.js +8 -5
  108. package/dist/media/ttt-media-specs.js.map +1 -1
  109. package/dist/media/upload-tray-display.js +1 -1
  110. package/dist/media/upload-tray-display.js.map +1 -1
  111. package/dist/paths/collection-refs.d.ts +2 -0
  112. package/dist/paths/collection-refs.d.ts.map +1 -1
  113. package/dist/paths/collection-refs.js +4 -0
  114. package/dist/paths/collection-refs.js.map +1 -1
  115. package/dist/paths/collections.d.ts +1 -0
  116. package/dist/paths/collections.d.ts.map +1 -1
  117. package/dist/paths/collections.js +7 -0
  118. package/dist/paths/collections.js.map +1 -1
  119. package/dist/paths/path-builders.d.ts +2 -0
  120. package/dist/paths/path-builders.d.ts.map +1 -1
  121. package/dist/paths/path-builders.js +5 -0
  122. package/dist/paths/path-builders.js.map +1 -1
  123. package/dist/report/report-config-values.d.ts +3 -1
  124. package/dist/report/report-config-values.d.ts.map +1 -1
  125. package/dist/report/report-config-values.js +5 -1
  126. package/dist/report/report-config-values.js.map +1 -1
  127. package/dist/safety/ncii-intake-derivations.d.ts.map +1 -1
  128. package/dist/safety/ncii-intake-derivations.js +17 -5
  129. package/dist/safety/ncii-intake-derivations.js.map +1 -1
  130. package/dist/schemas/admin.d.ts +3 -0
  131. package/dist/schemas/admin.d.ts.map +1 -1
  132. package/dist/schemas/admin.js +5 -0
  133. package/dist/schemas/admin.js.map +1 -1
  134. package/dist/schemas/chat.js +3 -3
  135. package/dist/schemas/chat.js.map +1 -1
  136. package/dist/schemas/commissions.d.ts +1 -1
  137. package/dist/schemas/media.d.ts +0 -4
  138. package/dist/schemas/media.d.ts.map +1 -1
  139. package/dist/schemas/media.js +5 -10
  140. package/dist/schemas/media.js.map +1 -1
  141. package/dist/schemas/ncii.d.ts +3 -0
  142. package/dist/schemas/ncii.d.ts.map +1 -1
  143. package/dist/schemas/notification.d.ts +1 -0
  144. package/dist/schemas/notification.d.ts.map +1 -1
  145. package/dist/types/audit.d.ts +1 -1
  146. package/dist/types/audit.d.ts.map +1 -1
  147. package/dist/types/audit.js.map +1 -1
  148. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"chat-sync.js","sourceRoot":"","sources":["../../src/doc-schemas/chat-sync.ts"],"names":[],"mappings":"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","sourcesContent":["// Chat realtime SYNC / projection / command Firestore schemas (chat-edge-rebuild P1).\n// The chat sync / projection / command (Firestore-side) field lists are FROZEN\n// here — this file is their single source; the durable design owner is ttt-prod\n// docs/design/chat-realtime-system.md. All of these collections are Admin-SDK-only\n// (`allow read, write: if false`). Per the TTT timestamp convention every time\n// field is epoch-ms `number`; the SINGLE exception is the native-TTL `expireAt`,\n// which is a real Firestore `Timestamp` (modeled as `unknown` so the drift-check\n// does not false-flag a Timestamp object against `z.number()`).\n\nimport { z } from 'zod';\n\n/** Native-TTL field — a real Firestore Timestamp (NOT epoch-ms). Absent until the terminal that sets TTL. */\nconst expireAtField = z.unknown().optional();\n\n// ── chatChannelAuthProjections/{authPairKey} ────────────────────────────────\n// Per-(user, channel) authorization FACT. Absent ⇒ removed/deny (fail-closed).\nexport const ChatChannelAuthProjectionSchema = z.object({\n channelRefScope: z.enum(['channel', 'invite']),\n workProjectId: z.string().nullable(),\n guildChatChannelId: z.string().nullable(),\n guildInviteId: z.string().nullable(),\n uid: z.string(),\n channelKey: z.string(),\n channelAuthState: z.enum(['authorized', 'removed']),\n channelAuthVersion: z.number(),\n inputFingerprint: z.string(),\n updatedAt: z.number(),\n});\nexport type ChatChannelAuthProjection = z.infer<typeof ChatChannelAuthProjectionSchema>;\n\n// ── chatScopeDegraded/{scopeKey} (+ causes/{causeId}) ───────────────────────\n// Exists IFF unresolvedCauseCount > 0. Grant mints fail closed while it exists.\nexport const ChatScopeDegradedSchema = z.object({\n scopeKey: z.string(),\n scopeKind: z.enum(['channel', 'memberInWork']),\n // channel scope carries the channelRef tuple; memberInWork carries {uid, workProjectId}.\n workProjectId: z.string().nullable(),\n guildChatChannelId: z.string().nullable(),\n guildInviteId: z.string().nullable(),\n uid: z.string().nullable(),\n unresolvedCauseCount: z.number(),\n updatedAt: z.number(),\n});\nexport type ChatScopeDegraded = z.infer<typeof ChatScopeDegradedSchema>;\n\nexport const ChatScopeDegradedCauseSchema = z.object({\n causeId: z.string(),\n kind: z.enum(['syncEvent', 'fanoutJob']),\n ref: z.string(),\n deadLetteredAt: z.number(),\n});\nexport type ChatScopeDegradedCause = z.infer<typeof ChatScopeDegradedCauseSchema>;\n\n// ── chatSyncEvents/{eventId} ────────────────────────────────────────────────\nexport const ChatSyncEventSchema = z.object({\n eventId: z.string(),\n targetDo: z.string(),\n kind: z.enum(['channelAuth', 'accountAccess', 'config', 'attachmentFlip', 'serverMessage']),\n version: z.number(),\n payload: z.record(z.string(), z.unknown()).nullable(),\n tombstone: z.boolean().optional(),\n payloadHash: z.string(),\n status: z.enum(['pending', 'delivered', 'deadLetter']),\n attemptCount: z.number(),\n nextAttemptAt: z.number(),\n lastError: z.string().nullable(),\n createdAt: z.number(),\n deliveredResult: z.record(z.string(), z.unknown()).nullable(),\n deliveredAt: z.number().nullable(),\n deadLetteredAt: z.number().nullable(),\n expireAt: expireAtField,\n});\nexport type ChatSyncEvent = z.infer<typeof ChatSyncEventSchema>;\n\n// ── chatSyncFanoutJobs/{jobId} ──────────────────────────────────────────────\nexport const ChatSyncFanoutJobSchema = z.object({\n jobId: z.string(),\n selectorKind: z.enum(['channelMembers', 'workChannelsForUser', 'policyEditAffectedUsers']),\n selectorArgs: z.object({\n workProjectId: z.string().optional(),\n channelKey: z.string().optional(),\n uid: z.string().optional(),\n }),\n causeVersion: z.number(),\n cursor: z.object({ pageIndex: z.number(), lastDocId: z.string().nullable() }),\n revision: z.number(),\n status: z.enum(['pending', 'complete', 'deadLetter']),\n attemptCount: z.number(),\n nextAttemptAt: z.number(),\n lastError: z.string().nullable(),\n createdAt: z.number(),\n completedAt: z.number().nullable(),\n deadLetteredAt: z.number().nullable(),\n expireAt: expireAtField,\n});\nexport type ChatSyncFanoutJob = z.infer<typeof ChatSyncFanoutJobSchema>;\n\n// ── chatMessageOutbox/{commandId} ───────────────────────────────────────────\nexport const ChatMessageOutboxSchema = z.object({\n commandId: z.string(),\n kind: z.enum(['userMsg', 'systemMsg', 'attachmentPlaceholder']),\n threadRef: z.string(),\n payload: z.record(z.string(), z.unknown()),\n payloadVersion: z.number(),\n status: z.enum(['pending', 'applied', 'deadLetter']),\n attemptCount: z.number(),\n nextAttemptAt: z.number(),\n lastError: z.string().nullable(),\n createdAt: z.number(),\n appliedAt: z.number().nullable(),\n deadLetteredAt: z.number().nullable(),\n expireAt: expireAtField,\n});\nexport type ChatMessageOutbox = z.infer<typeof ChatMessageOutboxSchema>;\n\n// ── chatAdminActionCommands/{requestId} ─────────────────────────────────────\n// `requestId` IS the doc id + DO dedup key. `delivering` is NOT a lease (it sets\n// nextAttemptAt = now + DELIVERY_TIMEOUT). terminalFailureGeneration default 0.\nexport const ChatAdminActionCommandSchema = z.object({\n requestId: z.string(),\n actorUid: z.string(),\n actorMode: z.enum(['adminReview', 'adminOverride']),\n systemRole: z.enum(['admin', 'jrAdmin']),\n channelRef: z.record(z.string(), z.unknown()),\n messageSeq: z.number(),\n action: z.enum(['hide', 'delete']),\n caseId: z.string(),\n reason: z.string(),\n expectedMessageRevision: z.number(),\n // Ready-attachment media asset id(s) on the moderated message (block FIRST, then\n // DO tombstone — the attachment-redaction saga, round-10 blocker 9). Empty for a\n // text-only message. DERIVED SERVER-SIDE inside the moderation saga from the DO/message\n // context — NEVER client-supplied (the case-bound context read does not expose them).\n attachmentAssetIds: z.array(z.string()).default([]),\n payloadHash: z.string(),\n state: z.enum(['queued', 'delivering', 'applied', 'failed', 'deadLetter']),\n attemptCount: z.number(),\n nextAttemptAt: z.number(),\n lastError: z.string().nullable(),\n result: z.record(z.string(), z.unknown()).nullable(),\n doRevisionId: z.string().nullable(),\n // True once the redaction saga has blocked the attachment asset(s) for this command.\n attachmentBlocked: z.boolean().default(false),\n terminalFailureGeneration: z.number(),\n createdAt: z.number(),\n appliedAt: z.number().nullable(),\n failedAt: z.number().nullable(),\n deadLetteredAt: z.number().nullable(),\n reconciled: z.boolean(),\n reconciledAt: z.number().nullable(),\n expireAt: expireAtField,\n});\nexport type ChatAdminActionCommand = z.infer<typeof ChatAdminActionCommandSchema>;\n\n// ── chatHistoryAnonymizationJobs/{jobId} ────────────────────────────────────\n// Account-deletion history anonymization (Contract F; P8). Resumable + crash-safe:\n// the recorded source-manifest identity (key/hash/generation) + the three cursors\n// (scan/rewrite/delete) make every boundary restartable. jobId =\n// hash('chat-anonymize', channelDoId, epoch, anonymizedUid). `expireAt` (native TTL)\n// is set ONLY when the job reaches `done`.\n//\n// C-B1: the replacement generation is DO-OWNED — the Channel DO (single-threaded per\n// channel) allocates a DISTINCT monotonic generation per erasure off the epoch row and\n// rewrites against the CURRENT live manifest, so two erasures on one epoch chain instead\n// of colliding on a shared `anon-1` keyspace. These four fields are therefore RECORDED AT\n// SCAN (null until the DO reports/allocates them), not pinned at enqueue; if a concurrent\n// anonymization supersedes the source between scan and swap, the job resets to `scanning`\n// to re-derive against the new current manifest (keeping its own allocated generation).\nexport const ChatHistoryAnonymizationJobSchema = z.object({\n jobId: z.string(),\n channelDoId: z.string(),\n epoch: z.number(),\n anonymizedUid: z.string(),\n sourceManifestKey: z.string().nullable(),\n sourceManifestHash: z.string().nullable(),\n sourceGeneration: z.number().nullable(),\n replacementGeneration: z.number().nullable(),\n newManifestKey: z.string().nullable(),\n scanCursor: z.number(),\n rewriteCursor: z.number(),\n deleteCursor: z.number(),\n swappedAt: z.number().nullable(),\n state: z.enum(['scanning', 'rewriting', 'swapping', 'deleting', 'done', 'failed']),\n legalHoldPaused: z.boolean(),\n attemptCount: z.number(),\n nextAttemptAt: z.number(),\n lastError: z.string().nullable(),\n createdAt: z.number(),\n updatedAt: z.number(),\n expireAt: expireAtField,\n});\nexport type ChatHistoryAnonymizationJob = z.infer<typeof ChatHistoryAnonymizationJobSchema>;\n\n// ── chatHistoryAnonymizationJobs/{jobId}/affectedChunks/{chunkOrdinal} ───────\n// The non-contiguous affected-chunk set (round-16 finding 7) — a crash after the\n// manifest swap resumes deletion from these rows + `deleteCursor` without re-listing R2.\nexport const ChatHistoryAnonymizationAffectedChunkSchema = z.object({\n chunkOrdinal: z.number(),\n sourceChunkKey: z.string(),\n sourceSha256: z.string(),\n replacementChunkKey: z.string().nullable(),\n replacementSha256: z.string().nullable(),\n rewriteState: z.enum(['pending', 'done']),\n deleteState: z.enum(['pending', 'done']),\n});\nexport type ChatHistoryAnonymizationAffectedChunk = z.infer<typeof ChatHistoryAnonymizationAffectedChunkSchema>;\n"]}
1
+ {"version":3,"file":"chat-sync.js","sourceRoot":"","sources":["../../src/doc-schemas/chat-sync.ts"],"names":[],"mappings":"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","sourcesContent":["// Chat realtime SYNC / projection / command Firestore schemas (chat-edge-rebuild P1).\n// The chat sync / projection / command (Firestore-side) field lists are FROZEN\n// here — this file is their single source; the durable design owner is ttt-prod\n// docs/design/chat-realtime-system.md. All of these collections are Admin-SDK-only\n// (`allow read, write: if false`). Per the TTT timestamp convention every time\n// field is epoch-ms `number`; the SINGLE exception is the native-TTL `expireAt`,\n// which is a real Firestore `Timestamp` (modeled as `unknown` so the drift-check\n// does not false-flag a Timestamp object against `z.number()`).\n\nimport { z } from 'zod';\n\n/** Native-TTL field — a real Firestore Timestamp (NOT epoch-ms). Absent until the terminal that sets TTL. */\nconst expireAtField = z.unknown().optional();\n\n// ── chatChannelAuthProjections/{authPairKey} ────────────────────────────────\n// Per-(user, channel) authorization FACT. Absent ⇒ removed/deny (fail-closed).\nexport const ChatChannelAuthProjectionSchema = z.object({\n channelRefScope: z.enum(['channel', 'invite']),\n workProjectId: z.string().nullable(),\n guildChatChannelId: z.string().nullable(),\n guildInviteId: z.string().nullable(),\n uid: z.string(),\n channelKey: z.string(),\n channelAuthState: z.enum(['authorized', 'removed']),\n channelAuthVersion: z.number(),\n inputFingerprint: z.string(),\n updatedAt: z.number(),\n});\nexport type ChatChannelAuthProjection = z.infer<typeof ChatChannelAuthProjectionSchema>;\n\n// ── chatScopeDegraded/{scopeKey} (+ causes/{causeId}) ───────────────────────\n// Exists IFF unresolvedCauseCount > 0. Grant mints fail closed while it exists.\nexport const ChatScopeDegradedSchema = z.object({\n scopeKey: z.string(),\n scopeKind: z.enum(['channel', 'memberInWork']),\n // channel scope carries the channelRef tuple; memberInWork carries {uid, workProjectId}.\n workProjectId: z.string().nullable(),\n guildChatChannelId: z.string().nullable(),\n guildInviteId: z.string().nullable(),\n uid: z.string().nullable(),\n unresolvedCauseCount: z.number(),\n updatedAt: z.number(),\n});\nexport type ChatScopeDegraded = z.infer<typeof ChatScopeDegradedSchema>;\n\nexport const ChatScopeDegradedCauseSchema = z.object({\n causeId: z.string(),\n kind: z.enum(['syncEvent', 'fanoutJob']),\n ref: z.string(),\n deadLetteredAt: z.number(),\n});\nexport type ChatScopeDegradedCause = z.infer<typeof ChatScopeDegradedCauseSchema>;\n\n// ── chatSyncEvents/{eventId} ────────────────────────────────────────────────\nexport const ChatSyncEventSchema = z.object({\n eventId: z.string(),\n targetDo: z.string(),\n kind: z.enum(['channelAuth', 'accountAccess', 'config', 'serverMessage']),\n version: z.number(),\n payload: z.record(z.string(), z.unknown()).nullable(),\n tombstone: z.boolean().optional(),\n payloadHash: z.string(),\n status: z.enum(['pending', 'delivered', 'deadLetter']),\n attemptCount: z.number(),\n nextAttemptAt: z.number(),\n lastError: z.string().nullable(),\n createdAt: z.number(),\n deliveredResult: z.record(z.string(), z.unknown()).nullable(),\n deliveredAt: z.number().nullable(),\n deadLetteredAt: z.number().nullable(),\n expireAt: expireAtField,\n});\nexport type ChatSyncEvent = z.infer<typeof ChatSyncEventSchema>;\n\n// ── chatSyncFanoutJobs/{jobId} ──────────────────────────────────────────────\nexport const ChatSyncFanoutJobSchema = z.object({\n jobId: z.string(),\n selectorKind: z.enum(['channelMembers', 'workChannelsForUser', 'policyEditAffectedUsers']),\n selectorArgs: z.object({\n workProjectId: z.string().optional(),\n channelKey: z.string().optional(),\n uid: z.string().optional(),\n }),\n causeVersion: z.number(),\n cursor: z.object({ pageIndex: z.number(), lastDocId: z.string().nullable() }),\n revision: z.number(),\n status: z.enum(['pending', 'complete', 'deadLetter']),\n attemptCount: z.number(),\n nextAttemptAt: z.number(),\n lastError: z.string().nullable(),\n createdAt: z.number(),\n completedAt: z.number().nullable(),\n deadLetteredAt: z.number().nullable(),\n expireAt: expireAtField,\n});\nexport type ChatSyncFanoutJob = z.infer<typeof ChatSyncFanoutJobSchema>;\n\n// ── chatMessageOutbox/{commandId} ───────────────────────────────────────────\nexport const ChatMessageOutboxSchema = z.object({\n commandId: z.string(),\n kind: z.enum(['userMsg', 'systemMsg']),\n threadRef: z.string(),\n payload: z.record(z.string(), z.unknown()),\n payloadVersion: z.number(),\n status: z.enum(['pending', 'applied', 'deadLetter']),\n attemptCount: z.number(),\n nextAttemptAt: z.number(),\n lastError: z.string().nullable(),\n createdAt: z.number(),\n appliedAt: z.number().nullable(),\n deadLetteredAt: z.number().nullable(),\n expireAt: expireAtField,\n});\nexport type ChatMessageOutbox = z.infer<typeof ChatMessageOutboxSchema>;\n\n// ── chatAdminActionCommands/{requestId} ─────────────────────────────────────\n// `requestId` IS the doc id + DO dedup key. `delivering` is NOT a lease (it sets\n// nextAttemptAt = now + DELIVERY_TIMEOUT). terminalFailureGeneration default 0.\nexport const ChatAdminActionCommandSchema = z.object({\n requestId: z.string(),\n actorUid: z.string(),\n actorMode: z.enum(['adminReview', 'adminOverride']),\n systemRole: z.enum(['admin', 'jrAdmin']),\n channelRef: z.record(z.string(), z.unknown()),\n messageSeq: z.number(),\n action: z.enum(['hide', 'delete']),\n caseId: z.string(),\n reason: z.string(),\n expectedMessageRevision: z.number(),\n payloadHash: z.string(),\n state: z.enum(['queued', 'delivering', 'applied', 'failed', 'deadLetter']),\n attemptCount: z.number(),\n nextAttemptAt: z.number(),\n lastError: z.string().nullable(),\n result: z.record(z.string(), z.unknown()).nullable(),\n doRevisionId: z.string().nullable(),\n terminalFailureGeneration: z.number(),\n createdAt: z.number(),\n appliedAt: z.number().nullable(),\n failedAt: z.number().nullable(),\n deadLetteredAt: z.number().nullable(),\n reconciled: z.boolean(),\n reconciledAt: z.number().nullable(),\n expireAt: expireAtField,\n});\nexport type ChatAdminActionCommand = z.infer<typeof ChatAdminActionCommandSchema>;\n\n// ── chatHistoryAnonymizationJobs/{jobId} ────────────────────────────────────\n// Account-deletion history anonymization (Contract F; P8). Resumable + crash-safe:\n// the recorded source-manifest identity (key/hash/generation) + the three cursors\n// (scan/rewrite/delete) make every boundary restartable. jobId =\n// hash('chat-anonymize', channelDoId, epoch, anonymizedUid). `expireAt` (native TTL)\n// is set ONLY when the job reaches `done`.\n//\n// C-B1: the replacement generation is DO-OWNED — the Channel DO (single-threaded per\n// channel) allocates a DISTINCT monotonic generation per erasure off the epoch row and\n// rewrites against the CURRENT live manifest, so two erasures on one epoch chain instead\n// of colliding on a shared `anon-1` keyspace. These four fields are therefore RECORDED AT\n// SCAN (null until the DO reports/allocates them), not pinned at enqueue; if a concurrent\n// anonymization supersedes the source between scan and swap, the job resets to `scanning`\n// to re-derive against the new current manifest (keeping its own allocated generation).\nexport const ChatHistoryAnonymizationJobSchema = z.object({\n jobId: z.string(),\n channelDoId: z.string(),\n epoch: z.number(),\n anonymizedUid: z.string(),\n sourceManifestKey: z.string().nullable(),\n sourceManifestHash: z.string().nullable(),\n sourceGeneration: z.number().nullable(),\n replacementGeneration: z.number().nullable(),\n newManifestKey: z.string().nullable(),\n scanCursor: z.number(),\n rewriteCursor: z.number(),\n deleteCursor: z.number(),\n swappedAt: z.number().nullable(),\n state: z.enum(['scanning', 'rewriting', 'swapping', 'deleting', 'done', 'failed']),\n legalHoldPaused: z.boolean(),\n attemptCount: z.number(),\n nextAttemptAt: z.number(),\n lastError: z.string().nullable(),\n createdAt: z.number(),\n updatedAt: z.number(),\n expireAt: expireAtField,\n});\nexport type ChatHistoryAnonymizationJob = z.infer<typeof ChatHistoryAnonymizationJobSchema>;\n\n// ── chatHistoryAnonymizationJobs/{jobId}/affectedChunks/{chunkOrdinal} ───────\n// The non-contiguous affected-chunk set (round-16 finding 7) — a crash after the\n// manifest swap resumes deletion from these rows + `deleteCursor` without re-listing R2.\nexport const ChatHistoryAnonymizationAffectedChunkSchema = z.object({\n chunkOrdinal: z.number(),\n sourceChunkKey: z.string(),\n sourceSha256: z.string(),\n replacementChunkKey: z.string().nullable(),\n replacementSha256: z.string().nullable(),\n rewriteState: z.enum(['pending', 'done']),\n deleteState: z.enum(['pending', 'done']),\n});\nexport type ChatHistoryAnonymizationAffectedChunk = z.infer<typeof ChatHistoryAnonymizationAffectedChunkSchema>;\n"]}
@@ -58,9 +58,9 @@ export declare const CommissionProposalSchema: z.ZodObject<{
58
58
  }, z.core.$strip>;
59
59
  createdOn: z.ZodNumber;
60
60
  status: z.ZodEnum<{
61
+ accepted: "accepted";
61
62
  rejected: "rejected";
62
63
  open: "open";
63
- accepted: "accepted";
64
64
  invited: "invited";
65
65
  }>;
66
66
  guildInviteId: z.ZodOptional<z.ZodString>;
@@ -86,9 +86,9 @@ export declare const CreateCommissionProposalTextResultSchema: z.ZodObject<{
86
86
  }, z.core.$strip>;
87
87
  createdOn: z.ZodNumber;
88
88
  status: z.ZodEnum<{
89
+ accepted: "accepted";
89
90
  rejected: "rejected";
90
91
  open: "open";
91
- accepted: "accepted";
92
92
  invited: "invited";
93
93
  }>;
94
94
  guildInviteId: z.ZodOptional<z.ZodString>;
@@ -14,6 +14,7 @@ export declare const MediaActivationJobSchema: z.ZodObject<{
14
14
  fileOrigin: z.ZodEnum<{
15
15
  "commission-proposal": "commission-proposal";
16
16
  "profile-picture": "profile-picture";
17
+ "conversation-file": "conversation-file";
17
18
  "audition-entry": "audition-entry";
18
19
  "work-asset": "work-asset";
19
20
  "craft-skill-media": "craft-skill-media";
@@ -30,7 +31,6 @@ export declare const MediaActivationJobSchema: z.ZodObject<{
30
31
  "tune-track-audio": "tune-track-audio";
31
32
  "television-episode-photo": "television-episode-photo";
32
33
  "television-episode-video": "television-episode-video";
33
- "guild-chat-message-attachment": "guild-chat-message-attachment";
34
34
  "ncii-evidence": "ncii-evidence";
35
35
  }>;
36
36
  authorityVersion: z.ZodNumber;
@@ -61,10 +61,10 @@ export declare const MediaActivationJobSchema: z.ZodObject<{
61
61
  commissionListing: "commissionListing";
62
62
  commissionProposal: "commissionProposal";
63
63
  auditionEntry: "auditionEntry";
64
+ conversationFile: "conversationFile";
64
65
  userProfile: "userProfile";
65
66
  squareStreetzPost: "squareStreetzPost";
66
67
  workContent: "workContent";
67
- guildChatAttachment: "guildChatAttachment";
68
68
  realmFile: "realmFile";
69
69
  safetyEvidence: "safetyEvidence";
70
70
  }>;
@@ -76,10 +76,6 @@ export declare const MediaActivationJobSchema: z.ZodObject<{
76
76
  kind: z.ZodLiteral<"workFileFolder">;
77
77
  workProjectId: z.ZodString;
78
78
  workFileFolderId: z.ZodString;
79
- }, z.core.$strict>, z.ZodObject<{
80
- kind: z.ZodLiteral<"guildChannel">;
81
- workProjectId: z.ZodString;
82
- guildChatChannelId: z.ZodString;
83
79
  }, z.core.$strict>, z.ZodObject<{
84
80
  kind: z.ZodLiteral<"guildInvite">;
85
81
  guildInviteId: z.ZodString;
@@ -98,7 +94,7 @@ export declare const MediaActivationJobSchema: z.ZodObject<{
98
94
  }, z.core.$strict>;
99
95
  publicationKind: z.ZodEnum<{
100
96
  workAsset: "workAsset";
101
- chatAttachment: "chatAttachment";
97
+ conversationFile: "conversationFile";
102
98
  profilePicture: "profilePicture";
103
99
  squarePostMedia: "squarePostMedia";
104
100
  hallCover: "hallCover";
@@ -108,7 +104,6 @@ export declare const MediaActivationJobSchema: z.ZodObject<{
108
104
  commissionListingMedia: "commissionListingMedia";
109
105
  commissionProposalMedia: "commissionProposalMedia";
110
106
  craftSkillMedia: "craftSkillMedia";
111
- adminSupportAttachment: "adminSupportAttachment";
112
107
  }>;
113
108
  publicationArgs: z.ZodUnknown;
114
109
  status: z.ZodEnum<{
@@ -1 +1 @@
1
- {"version":3,"file":"media-activation-jobs.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/media-activation-jobs.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,eAAO,MAAM,8BAA8B;;;;;EAKzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAkC1B,CAAC;AACZ,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
1
+ {"version":3,"file":"media-activation-jobs.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/media-activation-jobs.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,eAAO,MAAM,8BAA8B;;;;;EAKzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAkC1B,CAAC;AACZ,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
@@ -27,10 +27,10 @@ export declare const MediaAssetOwnerTypeSchema: z.ZodEnum<{
27
27
  commissionListing: "commissionListing";
28
28
  commissionProposal: "commissionProposal";
29
29
  auditionEntry: "auditionEntry";
30
+ conversationFile: "conversationFile";
30
31
  userProfile: "userProfile";
31
32
  squareStreetzPost: "squareStreetzPost";
32
33
  workContent: "workContent";
33
- guildChatAttachment: "guildChatAttachment";
34
34
  realmFile: "realmFile";
35
35
  safetyEvidence: "safetyEvidence";
36
36
  }>;
@@ -58,14 +58,18 @@ export declare const MediaVariantKeySchema: z.ZodEnum<{
58
58
  main: "main";
59
59
  }>;
60
60
  export type MediaVariantKey = z.infer<typeof MediaVariantKeySchema>;
61
- /** Why this asset was created from its source (A0). */
61
+ /** Why this asset was created from its source (A0).
62
+ *
63
+ * `chat_derivative` was REMOVED with the chat-attachment architecture: chat is
64
+ * text-only and owns no media, so no copy can be made "for a chat message". A
65
+ * Conversation File is an ORIGINAL (`original`), never a chat derivative; nothing
66
+ * ever set the retired value. */
62
67
  export declare const MediaCopyReasonSchema: z.ZodEnum<{
63
68
  other: "other";
64
69
  original: "original";
65
70
  variant: "variant";
66
71
  hall_publish: "hall_publish";
67
72
  profile_derivative: "profile_derivative";
68
- chat_derivative: "chat_derivative";
69
73
  moderation_copy: "moderation_copy";
70
74
  evidence_copy: "evidence_copy";
71
75
  }>;
@@ -102,7 +106,6 @@ export declare const MediaOriginLineageV1Schema: z.ZodObject<{
102
106
  variant: "variant";
103
107
  hall_publish: "hall_publish";
104
108
  profile_derivative: "profile_derivative";
105
- chat_derivative: "chat_derivative";
106
109
  moderation_copy: "moderation_copy";
107
110
  evidence_copy: "evidence_copy";
108
111
  }>;
@@ -114,10 +117,10 @@ export declare const MediaOriginLineageV1Schema: z.ZodObject<{
114
117
  commissionListing: "commissionListing";
115
118
  commissionProposal: "commissionProposal";
116
119
  auditionEntry: "auditionEntry";
120
+ conversationFile: "conversationFile";
117
121
  userProfile: "userProfile";
118
122
  squareStreetzPost: "squareStreetzPost";
119
123
  workContent: "workContent";
120
- guildChatAttachment: "guildChatAttachment";
121
124
  realmFile: "realmFile";
122
125
  safetyEvidence: "safetyEvidence";
123
126
  }>>;
@@ -131,10 +134,10 @@ export declare const MediaOriginLineageV1Schema: z.ZodObject<{
131
134
  commissionListing: "commissionListing";
132
135
  commissionProposal: "commissionProposal";
133
136
  auditionEntry: "auditionEntry";
137
+ conversationFile: "conversationFile";
134
138
  userProfile: "userProfile";
135
139
  squareStreetzPost: "squareStreetzPost";
136
140
  workContent: "workContent";
137
- guildChatAttachment: "guildChatAttachment";
138
141
  realmFile: "realmFile";
139
142
  safetyEvidence: "safetyEvidence";
140
143
  }>;
@@ -179,9 +182,8 @@ export type MediaAssetPublicationState = z.infer<typeof MediaAssetPublicationSta
179
182
  /**
180
183
  * Typed immutable serving scope for scoped-tier assets. The gateway Worker matches
181
184
  * a grant against the scope by `kind` — so a whole-Work `{w}` grant matches ONLY a
182
- * `workProject` scope, NEVER a `guildChannel` scope (even though both carry a
183
- * `workProjectId`): a restricted channel's attachment is not reachable by a plain
184
- * Work grant, and a chat grant is not reachable by a Work asset.
185
+ * `workProject` scope, never a conversation scope, and a conversation grant is never
186
+ * reachable by a Work asset.
185
187
  *
186
188
  * - `workProject` — pre-publish content media (hall covers / sub-item media during
187
189
  * authoring), scoped to project read membership. Carries the matchable
@@ -194,9 +196,10 @@ export type MediaAssetPublicationState = z.infer<typeof MediaAssetPublicationSta
194
196
  * the per-folder view check and the Worker EXACT-matches `{workProjectId,
195
197
  * workFileFolderId}` — a plain Work `{w}` grant NEVER matches a folder file, and a
196
198
  * folder grant NEVER matches a `workProject`-scoped content asset.
197
- * - `guildChannel` / `guildInvite` — guild-chat attachments; an EXACT channel/
198
- * invite scope (Contract E "Chat attachment authorization"). A guildChannel's
199
- * `workProjectId` lives ONLY inside this scope, never as a bare matchable field.
199
+ * - `guildInvite` / `adminSupport` — the two Conversation Files scopes; an EXACT
200
+ * conversation scope, matching the `ConversationFileRef` that owns the file. There is
201
+ * NO guildChannel scope: guild chat channels have no Conversation Files (guildmates
202
+ * share files through Work Files, which keeps its own workFileFolder scope).
200
203
  *
201
204
  * `null` scope = no scope match required beyond the access tier (e.g. broad).
202
205
  */
@@ -207,10 +210,6 @@ export declare const MediaServingScopeSchema: z.ZodDiscriminatedUnion<[z.ZodObje
207
210
  kind: z.ZodLiteral<"workFileFolder">;
208
211
  workProjectId: z.ZodString;
209
212
  workFileFolderId: z.ZodString;
210
- }, z.core.$strict>, z.ZodObject<{
211
- kind: z.ZodLiteral<"guildChannel">;
212
- workProjectId: z.ZodString;
213
- guildChatChannelId: z.ZodString;
214
213
  }, z.core.$strict>, z.ZodObject<{
215
214
  kind: z.ZodLiteral<"guildInvite">;
216
215
  guildInviteId: z.ZodString;
@@ -222,12 +221,11 @@ export type MediaServingScope = z.infer<typeof MediaServingScopeSchema>;
222
221
  /**
223
222
  * The typed owner adapter a publication goes through. The activation job
224
223
  * carries this kind; a server-side registry validates per-kind `publicationArgs`
225
- * and performs the idempotent owner write. Chat is the non-Firestore-owner
226
- * adapter (publishes via its durable attachmentFlip ack, not an owner txn).
224
+ * and performs the idempotent owner write. Every kind is a Firestore-owner adapter.
227
225
  */
228
226
  export declare const MediaPublicationKindSchema: z.ZodEnum<{
229
227
  workAsset: "workAsset";
230
- chatAttachment: "chatAttachment";
228
+ conversationFile: "conversationFile";
231
229
  profilePicture: "profilePicture";
232
230
  squarePostMedia: "squarePostMedia";
233
231
  hallCover: "hallCover";
@@ -237,7 +235,6 @@ export declare const MediaPublicationKindSchema: z.ZodEnum<{
237
235
  commissionListingMedia: "commissionListingMedia";
238
236
  commissionProposalMedia: "commissionProposalMedia";
239
237
  craftSkillMedia: "craftSkillMedia";
240
- adminSupportAttachment: "adminSupportAttachment";
241
238
  }>;
242
239
  export type MediaPublicationKind = z.infer<typeof MediaPublicationKindSchema>;
243
240
  /**
@@ -273,10 +270,10 @@ export declare const MediaServingAuthorityRecordSchema: z.ZodObject<{
273
270
  commissionListing: "commissionListing";
274
271
  commissionProposal: "commissionProposal";
275
272
  auditionEntry: "auditionEntry";
273
+ conversationFile: "conversationFile";
276
274
  userProfile: "userProfile";
277
275
  squareStreetzPost: "squareStreetzPost";
278
276
  workContent: "workContent";
279
- guildChatAttachment: "guildChatAttachment";
280
277
  realmFile: "realmFile";
281
278
  safetyEvidence: "safetyEvidence";
282
279
  }>;
@@ -288,10 +285,6 @@ export declare const MediaServingAuthorityRecordSchema: z.ZodObject<{
288
285
  kind: z.ZodLiteral<"workFileFolder">;
289
286
  workProjectId: z.ZodString;
290
287
  workFileFolderId: z.ZodString;
291
- }, z.core.$strict>, z.ZodObject<{
292
- kind: z.ZodLiteral<"guildChannel">;
293
- workProjectId: z.ZodString;
294
- guildChatChannelId: z.ZodString;
295
288
  }, z.core.$strict>, z.ZodObject<{
296
289
  kind: z.ZodLiteral<"guildInvite">;
297
290
  guildInviteId: z.ZodString;
@@ -319,6 +312,7 @@ export declare const MediaAssetSchema: z.ZodObject<{
319
312
  fileOrigin: z.ZodEnum<{
320
313
  "commission-proposal": "commission-proposal";
321
314
  "profile-picture": "profile-picture";
315
+ "conversation-file": "conversation-file";
322
316
  "audition-entry": "audition-entry";
323
317
  "work-asset": "work-asset";
324
318
  "craft-skill-media": "craft-skill-media";
@@ -335,7 +329,6 @@ export declare const MediaAssetSchema: z.ZodObject<{
335
329
  "tune-track-audio": "tune-track-audio";
336
330
  "television-episode-photo": "television-episode-photo";
337
331
  "television-episode-video": "television-episode-video";
338
- "guild-chat-message-attachment": "guild-chat-message-attachment";
339
332
  "ncii-evidence": "ncii-evidence";
340
333
  }>;
341
334
  ownerType: z.ZodEnum<{
@@ -346,10 +339,10 @@ export declare const MediaAssetSchema: z.ZodObject<{
346
339
  commissionListing: "commissionListing";
347
340
  commissionProposal: "commissionProposal";
348
341
  auditionEntry: "auditionEntry";
342
+ conversationFile: "conversationFile";
349
343
  userProfile: "userProfile";
350
344
  squareStreetzPost: "squareStreetzPost";
351
345
  workContent: "workContent";
352
- guildChatAttachment: "guildChatAttachment";
353
346
  realmFile: "realmFile";
354
347
  safetyEvidence: "safetyEvidence";
355
348
  }>;
@@ -409,7 +402,6 @@ export declare const MediaAssetSchema: z.ZodObject<{
409
402
  variant: "variant";
410
403
  hall_publish: "hall_publish";
411
404
  profile_derivative: "profile_derivative";
412
- chat_derivative: "chat_derivative";
413
405
  moderation_copy: "moderation_copy";
414
406
  evidence_copy: "evidence_copy";
415
407
  }>;
@@ -421,10 +413,10 @@ export declare const MediaAssetSchema: z.ZodObject<{
421
413
  commissionListing: "commissionListing";
422
414
  commissionProposal: "commissionProposal";
423
415
  auditionEntry: "auditionEntry";
416
+ conversationFile: "conversationFile";
424
417
  userProfile: "userProfile";
425
418
  squareStreetzPost: "squareStreetzPost";
426
419
  workContent: "workContent";
427
- guildChatAttachment: "guildChatAttachment";
428
420
  realmFile: "realmFile";
429
421
  safetyEvidence: "safetyEvidence";
430
422
  }>>;
@@ -438,10 +430,10 @@ export declare const MediaAssetSchema: z.ZodObject<{
438
430
  commissionListing: "commissionListing";
439
431
  commissionProposal: "commissionProposal";
440
432
  auditionEntry: "auditionEntry";
433
+ conversationFile: "conversationFile";
441
434
  userProfile: "userProfile";
442
435
  squareStreetzPost: "squareStreetzPost";
443
436
  workContent: "workContent";
444
- guildChatAttachment: "guildChatAttachment";
445
437
  realmFile: "realmFile";
446
438
  safetyEvidence: "safetyEvidence";
447
439
  }>;
@@ -471,10 +463,6 @@ export declare const MediaAssetSchema: z.ZodObject<{
471
463
  kind: z.ZodLiteral<"workFileFolder">;
472
464
  workProjectId: z.ZodString;
473
465
  workFileFolderId: z.ZodString;
474
- }, z.core.$strict>, z.ZodObject<{
475
- kind: z.ZodLiteral<"guildChannel">;
476
- workProjectId: z.ZodString;
477
- guildChatChannelId: z.ZodString;
478
466
  }, z.core.$strict>, z.ZodObject<{
479
467
  kind: z.ZodLiteral<"guildInvite">;
480
468
  guildInviteId: z.ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"media-assets.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/media-assets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"media-assets.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/media-assets.ts"],"names":[],"mappings":"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"}
@@ -26,7 +26,10 @@ export const MediaAssetOwnerTypeSchema = z.enum([
26
26
  'commissionProposal',
27
27
  'audition',
28
28
  'auditionEntry',
29
- 'guildChatAttachment',
29
+ // A file in a conversation's flat Conversation Files list (guild-invite or
30
+ // admin-support). Replaces the removed `guildChatAttachment` owner type — chat
31
+ // messages no longer own media.
32
+ 'conversationFile',
30
33
  'realmFile', // reserved seam — realm shared files are post-launch
31
34
  'safetyEvidence', // inert system sentinel — synthetic NCII-evidence assets (never an account surface)
32
35
  ]);
@@ -45,13 +48,17 @@ export const ContentMediaKindSchema = z.enum(['image', 'video', 'audio']);
45
48
  */
46
49
  export const MEDIA_VARIANT_KEYS = ['full', 'medium', 'small', 'main'];
47
50
  export const MediaVariantKeySchema = z.enum(MEDIA_VARIANT_KEYS);
48
- /** Why this asset was created from its source (A0). */
51
+ /** Why this asset was created from its source (A0).
52
+ *
53
+ * `chat_derivative` was REMOVED with the chat-attachment architecture: chat is
54
+ * text-only and owns no media, so no copy can be made "for a chat message". A
55
+ * Conversation File is an ORIGINAL (`original`), never a chat derivative; nothing
56
+ * ever set the retired value. */
49
57
  export const MediaCopyReasonSchema = z.enum([
50
58
  'original',
51
59
  'variant',
52
60
  'hall_publish',
53
61
  'profile_derivative',
54
- 'chat_derivative',
55
62
  'moderation_copy',
56
63
  'evidence_copy',
57
64
  'other',
@@ -123,9 +130,8 @@ export const MediaAssetPublicationStateSchema = z.enum(['unpublished', 'publishe
123
130
  /**
124
131
  * Typed immutable serving scope for scoped-tier assets. The gateway Worker matches
125
132
  * a grant against the scope by `kind` — so a whole-Work `{w}` grant matches ONLY a
126
- * `workProject` scope, NEVER a `guildChannel` scope (even though both carry a
127
- * `workProjectId`): a restricted channel's attachment is not reachable by a plain
128
- * Work grant, and a chat grant is not reachable by a Work asset.
133
+ * `workProject` scope, never a conversation scope, and a conversation grant is never
134
+ * reachable by a Work asset.
129
135
  *
130
136
  * - `workProject` — pre-publish content media (hall covers / sub-item media during
131
137
  * authoring), scoped to project read membership. Carries the matchable
@@ -138,9 +144,10 @@ export const MediaAssetPublicationStateSchema = z.enum(['unpublished', 'publishe
138
144
  * the per-folder view check and the Worker EXACT-matches `{workProjectId,
139
145
  * workFileFolderId}` — a plain Work `{w}` grant NEVER matches a folder file, and a
140
146
  * folder grant NEVER matches a `workProject`-scoped content asset.
141
- * - `guildChannel` / `guildInvite` — guild-chat attachments; an EXACT channel/
142
- * invite scope (Contract E "Chat attachment authorization"). A guildChannel's
143
- * `workProjectId` lives ONLY inside this scope, never as a bare matchable field.
147
+ * - `guildInvite` / `adminSupport` — the two Conversation Files scopes; an EXACT
148
+ * conversation scope, matching the `ConversationFileRef` that owns the file. There is
149
+ * NO guildChannel scope: guild chat channels have no Conversation Files (guildmates
150
+ * share files through Work Files, which keeps its own workFileFolder scope).
144
151
  *
145
152
  * `null` scope = no scope match required beyond the access tier (e.g. broad).
146
153
  */
@@ -154,11 +161,6 @@ export const MediaServingScopeSchema = z.discriminatedUnion('kind', [
154
161
  workProjectId: z.string().min(1),
155
162
  workFileFolderId: z.string().min(1),
156
163
  }).strict(),
157
- z.object({
158
- kind: z.literal('guildChannel'),
159
- workProjectId: z.string().min(1),
160
- guildChatChannelId: z.string().min(1),
161
- }).strict(),
162
164
  z.object({
163
165
  kind: z.literal('guildInvite'),
164
166
  guildInviteId: z.string().min(1),
@@ -171,8 +173,7 @@ export const MediaServingScopeSchema = z.discriminatedUnion('kind', [
171
173
  /**
172
174
  * The typed owner adapter a publication goes through. The activation job
173
175
  * carries this kind; a server-side registry validates per-kind `publicationArgs`
174
- * and performs the idempotent owner write. Chat is the non-Firestore-owner
175
- * adapter (publishes via its durable attachmentFlip ack, not an owner txn).
176
+ * and performs the idempotent owner write. Every kind is a Firestore-owner adapter.
176
177
  */
177
178
  export const MediaPublicationKindSchema = z.enum([
178
179
  'profilePicture',
@@ -187,11 +188,13 @@ export const MediaPublicationKindSchema = z.enum([
187
188
  'commissionListingMedia',
188
189
  'commissionProposalMedia',
189
190
  'craftSkillMedia',
190
- 'chatAttachment',
191
- // Admin-support thread attachment: Firestore-transported (no Durable Object), so its
192
- // publication adapter does a Firestore owner write (flips the dispatch message placeholder),
193
- // unlike DO-ack'd `chatAttachment`. Carries the typed `adminSupport` MediaServingScope.
194
- 'adminSupportAttachment',
191
+ // Conversation File: the ONE adapter that creates a visible Conversation File owner
192
+ // record ({conversationParent}/conversationFiles/{conversationFileId}) and transfers
193
+ // the quota reservation to published counters in the same transaction. Replaces the
194
+ // removed `chatAttachment` (Channel-DO flip) and `adminSupportAttachment` (message
195
+ // placeholder flip) kinds. Carries the typed `guildInvite` / `adminSupport`
196
+ // MediaServingScope of the owning conversation.
197
+ 'conversationFile',
195
198
  ]);
196
199
  /**
197
200
  * The normalized serving record — the SAME contract used to generate both
@@ -1 +1 @@
1
- {"version":3,"file":"media-assets.js","sourceRoot":"","sources":["../../src/doc-schemas/media-assets.ts"],"names":[],"mappings":"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","sourcesContent":["// mediaAssets/{mediaAssetId} — the canonical media registry. One doc per\n// logical uploaded media item; all variants inside. Content docs reference\n// media ONLY by `*AssetId` fields — never URLs. Serving authority is the\n// gateway Worker (cookie/grant + KV blocklist); this doc is the server-side\n// truth the edge records derive from. NO client reads, NO client writes.\n// See ttt-prod docs/design/media-assets-and-protected-serving.md.\n\nimport { z } from 'zod';\nimport { StructuredErrorSchema } from '@ttt-productions/edge-protocol-core';\nimport { FileOriginSchema } from '../media/file-origin.js';\n\n/** Who may be served the bytes (the Worker's tier check). */\nexport const MediaAccessTierSchema = z.enum(['broad', 'scoped', 'artisan', 'adminOnly']);\nexport type MediaAccessTier = z.infer<typeof MediaAccessTierSchema>;\n\n/** Canonical serving state. The edge record derives from this; hide/restore/\n * quarantine flows write it together with the blocklist. */\nexport const MediaServingStatusSchema = z.enum(['servable', 'hidden', 'quarantined', 'deleted']);\nexport type MediaServingStatus = z.infer<typeof MediaServingStatusSchema>;\n\n/** The surface that owns this asset. One asset never serves two scopes —\n * publishing to the Hall (or future realm promotion) creates a NEW asset\n * owned by the destination surface. */\nexport const MediaAssetOwnerTypeSchema = z.enum([\n 'userProfile',\n 'craftSkill',\n 'squareStreetzPost',\n 'workProject',\n 'workContent', // tale chapter / tune track / television episode media (pre-publish)\n 'hallItem',\n 'commissionListing',\n 'commissionProposal',\n 'audition',\n 'auditionEntry',\n 'guildChatAttachment',\n 'realmFile', // reserved seam — realm shared files are post-launch\n 'safetyEvidence', // inert system sentinel — synthetic NCII-evidence assets (never an account surface)\n]);\nexport type MediaAssetOwnerType = z.infer<typeof MediaAssetOwnerTypeSchema>;\n\n// ===== Media origin lineage (Appendix A0) =====\n// One canonical lineage used by media, CSAM, and safety. Embedded on every\n// media asset + every copy.\n\n/** The ONE canonical stored content media kind (what the pipeline produces and the\n * asset doc records). Distinct from the 4-value display/transport MediaTypeSchema\n * (doc-schemas/social.ts, adds 'other') and media-schemas' generic MediaKindSchema. */\nexport const ContentMediaKindSchema = z.enum(['image', 'video', 'audio']);\nexport type ContentMediaKind = z.infer<typeof ContentMediaKindSchema>;\n\n/**\n * The named-variant key set for `variantSha256s` — declared ONCE here; every declared\n * `image.variants[].key` in `TTT_MEDIA_SPECS` is compile-checked against this union\n * (the specs type their variant keys as `MediaVariantKey`), so an undeclared variant\n * name fails the BUILD — no sync test needed. Never an open `string`.\n */\nexport const MEDIA_VARIANT_KEYS = ['full', 'medium', 'small', 'main'] as const;\nexport const MediaVariantKeySchema = z.enum(MEDIA_VARIANT_KEYS);\nexport type MediaVariantKey = z.infer<typeof MediaVariantKeySchema>;\n\n/** Why this asset was created from its source (A0). */\nexport const MediaCopyReasonSchema = z.enum([\n 'original',\n 'variant',\n 'hall_publish',\n 'profile_derivative',\n 'chat_derivative',\n 'moderation_copy',\n 'evidence_copy',\n 'other',\n]);\nexport type MediaCopyReason = z.infer<typeof MediaCopyReasonSchema>;\n\n/**\n * Canonical media origin lineage (Appendix A0). A copy INHERITS\n * rootIngestId/rootAssetId/originatingUploaderUid/originatingUploadEventId/\n * originalUploadCreatedAt/rootSha256/originalSha256 unchanged; it sets its own\n * sourceAssetId/variantSha256s/copyReason/copyActorUid/currentOwner*. Client\n * requests can NEVER set or override any lineage field. Automatic account\n * action targets ONLY `originatingUploaderUid`; incident-wide blocking\n * enumerates by `rootIngestId`. Missing/corrupt lineage → safetyLocked +\n * manual decision, never a guessed ban.\n */\nexport const MediaOriginLineageV1Schema = z.object({\n lineageVersion: z.literal(1),\n rootIngestId: z.string().min(1), // first-accepted ingest event id; stable across all copies\n rootAssetId: z.string().min(1), // first asset created from that ingest\n sourceAssetId: z.string().min(1).optional(), // immediate parent copied from (absent on the root)\n originatingUploaderUid: z.string().min(1), // set server-side at first accepted ingest; IMMUTABLE; inherited\n // May be '' for a legacy copy synthesized from a pre-rollout source with no known upload event.\n originatingUploadEventId: z.string(),\n originalUploadCreatedAt: z.number(),\n // '' until content hashing backfills the real sha256 (Phase 5 PhotoDNA / evidence capture).\n // NOT z.string().min(1): the media pipeline does not compute a content hash at finalize yet,\n // so a freshly-ingested asset legitimately carries an empty rootSha256 until it is hashed.\n rootSha256: z.string(),\n originalSha256: z.string().min(1).optional(),\n // PARTIAL map: one hash per PRODUCED variant (an asset produces only the variants its\n // origin declares — e.g. full/medium/small for a profile picture, 'main' for others —\n // never all four). Typed keys, never an open string. `z.partialRecord` (NOT `z.record`):\n // in Zod 4 `z.record(enum,…)` is EXHAUSTIVE (demands every enum key), which would reject\n // every real asset's partial variant set; `partialRecord` makes the keys optional.\n variantSha256s: z.partialRecord(MediaVariantKeySchema, z.string().min(1)),\n copyReason: MediaCopyReasonSchema,\n createdFromOwnerType: MediaAssetOwnerTypeSchema.optional(), // never a bare string\n createdFromOwnerId: z.string().min(1).optional(),\n copyActorUid: z.string().min(1).optional(), // who triggered the copy (distinct from the original uploader)\n currentOwnerType: MediaAssetOwnerTypeSchema, // mutable; the asset's present owner\n currentOwnerId: z.string().min(1),\n}).strict();\nexport type MediaOriginLineageV1 = z.infer<typeof MediaOriginLineageV1Schema>;\n\nexport const MediaAssetVariantSchema = z.object({\n contentType: z.string().min(1),\n sizeBytes: z.number().int().nonnegative(),\n width: z.number().int().positive().optional(),\n height: z.number().int().positive().optional(),\n durationSec: z.number().positive().optional(),\n}).strict();\nexport type MediaAssetVariant = z.infer<typeof MediaAssetVariantSchema>;\n\nexport const MediaRetentionPolicySchema = z.enum([\n 'standard', // staging original deleted ~24h after verified mirror\n 'preserveForTrustAndSafety',\n 'legalHold',\n]);\nexport type MediaRetentionPolicy = z.infer<typeof MediaRetentionPolicySchema>;\n\n// Realm shared-files: a work file's standing in its realm's shared pool.\n// none — not shared to the realm (default)\n// nonCanon — shared to the realm's pool, non-canon\n// canon — shared and marked canon (realm steward/owner toggles canon ↔ nonCanon)\n// Moderation/takedown is NOT a value here — a hidden file is hidden via the shared\n// media path (`servingStatus: 'hidden'`), so the gallery filters on servingStatus.\nexport const RealmFileCanonStatusSchema = z.enum(['none', 'nonCanon', 'canon']);\nexport type RealmFileCanonStatus = z.infer<typeof RealmFileCanonStatusSchema>;\n\n// ===== Serving authority (Durable Object) + publication gating =====\n// See ttt-prod docs/design/media-assets-and-protected-serving.md (the design owner\n// for the Durable Object serving authority and publication gating).\n\n/** Whether the canonical serving record has been applied to the DO authority. */\nexport const MediaAuthoritySyncStateSchema = z.enum(['pending', 'applied', 'deadLetter']);\nexport type MediaAuthoritySyncState = z.infer<typeof MediaAuthoritySyncStateSchema>;\n\n/** Whether the asset is referenced by a visible owner doc. Orthogonal to the\n * upload's processing outcome (`pendingMedia.status`) and to `servingStatus`. */\nexport const MediaAssetPublicationStateSchema = z.enum(['unpublished', 'published', 'retired']);\nexport type MediaAssetPublicationState = z.infer<typeof MediaAssetPublicationStateSchema>;\n\n/**\n * Typed immutable serving scope for scoped-tier assets. The gateway Worker matches\n * a grant against the scope by `kind` — so a whole-Work `{w}` grant matches ONLY a\n * `workProject` scope, NEVER a `guildChannel` scope (even though both carry a\n * `workProjectId`): a restricted channel's attachment is not reachable by a plain\n * Work grant, and a chat grant is not reachable by a Work asset.\n *\n * - `workProject` — pre-publish content media (hall covers / sub-item media during\n * authoring), scoped to project read membership. Carries the matchable\n * `workProjectId`. This is the typed home for work scope on the strongly-consistent\n * serving record so the DO-fallback path can authorize it (the DO persists scope\n * only as `scopeJson`, no separate column).\n * - `workFileFolder` — a work-project FILE living in a folder. The EXACT folder scope,\n * NOT the whole-Work `{w}` grant: a custom folder's bytes must be unreachable by a\n * guildmate outside that folder's view trade-professions, so the grant callable runs\n * the per-folder view check and the Worker EXACT-matches `{workProjectId,\n * workFileFolderId}` — a plain Work `{w}` grant NEVER matches a folder file, and a\n * folder grant NEVER matches a `workProject`-scoped content asset.\n * - `guildChannel` / `guildInvite` — guild-chat attachments; an EXACT channel/\n * invite scope (Contract E \"Chat attachment authorization\"). A guildChannel's\n * `workProjectId` lives ONLY inside this scope, never as a bare matchable field.\n *\n * `null` scope = no scope match required beyond the access tier (e.g. broad).\n */\nexport const MediaServingScopeSchema = z.discriminatedUnion('kind', [\n z.object({\n kind: z.literal('workProject'),\n workProjectId: z.string().min(1),\n }).strict(),\n z.object({\n kind: z.literal('workFileFolder'),\n workProjectId: z.string().min(1),\n workFileFolderId: z.string().min(1),\n }).strict(),\n z.object({\n kind: z.literal('guildChannel'),\n workProjectId: z.string().min(1),\n guildChatChannelId: z.string().min(1),\n }).strict(),\n z.object({\n kind: z.literal('guildInvite'),\n guildInviteId: z.string().min(1),\n }).strict(),\n z.object({\n kind: z.literal('adminSupport'),\n adminDispatchId: z.string().min(1),\n }).strict(),\n]);\nexport type MediaServingScope = z.infer<typeof MediaServingScopeSchema>;\n\n/**\n * The typed owner adapter a publication goes through. The activation job\n * carries this kind; a server-side registry validates per-kind `publicationArgs`\n * and performs the idempotent owner write. Chat is the non-Firestore-owner\n * adapter (publishes via its durable attachmentFlip ack, not an owner txn).\n */\nexport const MediaPublicationKindSchema = z.enum([\n 'profilePicture',\n 'squarePostMedia',\n 'workAsset',\n 'hallCover',\n // Realm cover — Firestore-owner adapter writes `realmCoverAssetId` onto\n // workRealms/{workRealmId} (the 'realm-cover' upload origin).\n 'realmCover',\n 'workContentMedia', // sub-item media (tale chapter / tune track / television episode) — attaches the *AssetId field on the workContent doc; scoped to the work project\n 'auditionMedia',\n 'commissionListingMedia',\n 'commissionProposalMedia',\n 'craftSkillMedia',\n 'chatAttachment',\n // Admin-support thread attachment: Firestore-transported (no Durable Object), so its\n // publication adapter does a Firestore owner write (flips the dispatch message placeholder),\n // unlike DO-ack'd `chatAttachment`. Carries the typed `adminSupport` MediaServingScope.\n 'adminSupportAttachment',\n]);\nexport type MediaPublicationKind = z.infer<typeof MediaPublicationKindSchema>;\n\n/**\n * The normalized serving record — the SAME contract used to generate both\n * the DO authority row and the KV cache payload (one function, so they can't\n * drift). The R2 object key stays deterministic (`mediaAssets/{assetId}/{key}`)\n * and is NOT persisted here. `payloadHash` is computed over the canonical\n * payload EXCLUDING the hash itself (see edge-protocol-core `hashPayload`).\n */\nexport const MediaServingAuthorityRecordSchema = z.object({\n schemaVersion: z.number().int().positive(),\n assetId: z.string().min(1),\n authorityVersion: z.number().int().nonnegative(),\n operationId: z.string().min(1),\n payloadHash: z.string().min(1),\n\n servingStatus: MediaServingStatusSchema,\n accessTier: MediaAccessTierSchema,\n\n ownerType: MediaAssetOwnerTypeSchema,\n ownerId: z.string().min(1),\n scope: MediaServingScopeSchema.nullable(),\n\n variants: z.record(z.string(), MediaAssetVariantSchema),\n\n updatedAtMs: z.number(),\n}).strict();\nexport type MediaServingAuthorityRecord = z.infer<typeof MediaServingAuthorityRecordSchema>;\n\nexport const MediaAssetSchema = z.object({\n mediaAssetId: z.string().min(1),\n mediaKind: ContentMediaKindSchema,\n fileOrigin: FileOriginSchema,\n\n // Ownership / scope. ownerId is the owning doc's id within ownerType's\n // surface; scope ids let the Worker/grant layer match scoped access.\n ownerType: MediaAssetOwnerTypeSchema,\n ownerId: z.string().min(1),\n workProjectId: z.string().optional(),\n realmId: z.string().optional(),\n createdByUid: z.string().min(1),\n\n // Access + serving (canonical; edge records derive from these).\n accessTier: MediaAccessTierSchema,\n servingStatus: MediaServingStatusSchema,\n\n // Variants by key. The object key in R2 (and the Storage emulator) is\n // deterministic — mediaAssets/{mediaAssetId}/{variantKey} — never stored.\n variants: z.record(z.string(), MediaAssetVariantSchema),\n\n // Lifecycle / trust-and-safety.\n moderationStatus: z.enum(['approved', 'quarantined']),\n retentionPolicy: MediaRetentionPolicySchema,\n legalHold: z.boolean(),\n originalDeletedAt: z.number().optional(),\n\n // T&S provenance lineage (Appendix A0). Additive/optional so assets written\n // before the lineage rollout still parse; set server-side at first accepted\n // ingest, inherited unchanged by every copy/variant. Never client-supplied.\n originLineage: MediaOriginLineageV1Schema.optional(),\n\n // Realm shared-files seam. A file's standing in its realm's shared pool; set at\n // creation to 'none' and moved by the realm shared-files callables. Attribution\n // fields (who set canon, when) are added by that feature when it ships.\n realmFileCanonStatus: RealmFileCanonStatusSchema,\n\n // Serving authority + publication gating. Additive/optional so assets\n // written before the authority build still parse: absent authorityVersion ⇒\n // 0/never-applied, absent publicationState ⇒ 'unpublished'. Every\n // serving-record mutation increments authorityVersion in an authoritative txn.\n authorityVersion: z.number().int().nonnegative().optional(),\n authorityPayloadHash: z.string().optional(),\n authoritySyncState: MediaAuthoritySyncStateSchema.optional(),\n publicationState: MediaAssetPublicationStateSchema.optional(),\n scope: MediaServingScopeSchema.optional(),\n authorityAppliedAt: z.number().optional(),\n publishedAt: z.number().optional(),\n lastAuthorityError: StructuredErrorSchema.optional(),\n // Authority-sync retry ledger (M1): the scheduled worker bumps attemptCount + sets a backoff\n // nextAttemptAt on a transient apply failure, and dead-letters (authoritySyncState='deadLetter')\n // past a threshold. Absent ⇒ 0 attempts / immediately due.\n authoritySyncAttemptCount: z.number().int().nonnegative().optional(),\n authoritySyncNextAttemptAt: z.number().optional(),\n\n createdAt: z.number(),\n updatedAt: z.number(),\n}).strict();\nexport type MediaAsset = z.infer<typeof MediaAssetSchema>;\n"]}
1
+ {"version":3,"file":"media-assets.js","sourceRoot":"","sources":["../../src/doc-schemas/media-assets.ts"],"names":[],"mappings":"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","sourcesContent":["// mediaAssets/{mediaAssetId} — the canonical media registry. One doc per\n// logical uploaded media item; all variants inside. Content docs reference\n// media ONLY by `*AssetId` fields — never URLs. Serving authority is the\n// gateway Worker (cookie/grant + KV blocklist); this doc is the server-side\n// truth the edge records derive from. NO client reads, NO client writes.\n// See ttt-prod docs/design/media-assets-and-protected-serving.md.\n\nimport { z } from 'zod';\nimport { StructuredErrorSchema } from '@ttt-productions/edge-protocol-core';\nimport { FileOriginSchema } from '../media/file-origin.js';\n\n/** Who may be served the bytes (the Worker's tier check). */\nexport const MediaAccessTierSchema = z.enum(['broad', 'scoped', 'artisan', 'adminOnly']);\nexport type MediaAccessTier = z.infer<typeof MediaAccessTierSchema>;\n\n/** Canonical serving state. The edge record derives from this; hide/restore/\n * quarantine flows write it together with the blocklist. */\nexport const MediaServingStatusSchema = z.enum(['servable', 'hidden', 'quarantined', 'deleted']);\nexport type MediaServingStatus = z.infer<typeof MediaServingStatusSchema>;\n\n/** The surface that owns this asset. One asset never serves two scopes —\n * publishing to the Hall (or future realm promotion) creates a NEW asset\n * owned by the destination surface. */\nexport const MediaAssetOwnerTypeSchema = z.enum([\n 'userProfile',\n 'craftSkill',\n 'squareStreetzPost',\n 'workProject',\n 'workContent', // tale chapter / tune track / television episode media (pre-publish)\n 'hallItem',\n 'commissionListing',\n 'commissionProposal',\n 'audition',\n 'auditionEntry',\n // A file in a conversation's flat Conversation Files list (guild-invite or\n // admin-support). Replaces the removed `guildChatAttachment` owner type — chat\n // messages no longer own media.\n 'conversationFile',\n 'realmFile', // reserved seam — realm shared files are post-launch\n 'safetyEvidence', // inert system sentinel — synthetic NCII-evidence assets (never an account surface)\n]);\nexport type MediaAssetOwnerType = z.infer<typeof MediaAssetOwnerTypeSchema>;\n\n// ===== Media origin lineage (Appendix A0) =====\n// One canonical lineage used by media, CSAM, and safety. Embedded on every\n// media asset + every copy.\n\n/** The ONE canonical stored content media kind (what the pipeline produces and the\n * asset doc records). Distinct from the 4-value display/transport MediaTypeSchema\n * (doc-schemas/social.ts, adds 'other') and media-schemas' generic MediaKindSchema. */\nexport const ContentMediaKindSchema = z.enum(['image', 'video', 'audio']);\nexport type ContentMediaKind = z.infer<typeof ContentMediaKindSchema>;\n\n/**\n * The named-variant key set for `variantSha256s` — declared ONCE here; every declared\n * `image.variants[].key` in `TTT_MEDIA_SPECS` is compile-checked against this union\n * (the specs type their variant keys as `MediaVariantKey`), so an undeclared variant\n * name fails the BUILD — no sync test needed. Never an open `string`.\n */\nexport const MEDIA_VARIANT_KEYS = ['full', 'medium', 'small', 'main'] as const;\nexport const MediaVariantKeySchema = z.enum(MEDIA_VARIANT_KEYS);\nexport type MediaVariantKey = z.infer<typeof MediaVariantKeySchema>;\n\n/** Why this asset was created from its source (A0).\n *\n * `chat_derivative` was REMOVED with the chat-attachment architecture: chat is\n * text-only and owns no media, so no copy can be made \"for a chat message\". A\n * Conversation File is an ORIGINAL (`original`), never a chat derivative; nothing\n * ever set the retired value. */\nexport const MediaCopyReasonSchema = z.enum([\n 'original',\n 'variant',\n 'hall_publish',\n 'profile_derivative',\n 'moderation_copy',\n 'evidence_copy',\n 'other',\n]);\nexport type MediaCopyReason = z.infer<typeof MediaCopyReasonSchema>;\n\n/**\n * Canonical media origin lineage (Appendix A0). A copy INHERITS\n * rootIngestId/rootAssetId/originatingUploaderUid/originatingUploadEventId/\n * originalUploadCreatedAt/rootSha256/originalSha256 unchanged; it sets its own\n * sourceAssetId/variantSha256s/copyReason/copyActorUid/currentOwner*. Client\n * requests can NEVER set or override any lineage field. Automatic account\n * action targets ONLY `originatingUploaderUid`; incident-wide blocking\n * enumerates by `rootIngestId`. Missing/corrupt lineage → safetyLocked +\n * manual decision, never a guessed ban.\n */\nexport const MediaOriginLineageV1Schema = z.object({\n lineageVersion: z.literal(1),\n rootIngestId: z.string().min(1), // first-accepted ingest event id; stable across all copies\n rootAssetId: z.string().min(1), // first asset created from that ingest\n sourceAssetId: z.string().min(1).optional(), // immediate parent copied from (absent on the root)\n originatingUploaderUid: z.string().min(1), // set server-side at first accepted ingest; IMMUTABLE; inherited\n // May be '' for a legacy copy synthesized from a pre-rollout source with no known upload event.\n originatingUploadEventId: z.string(),\n originalUploadCreatedAt: z.number(),\n // '' until content hashing backfills the real sha256 (Phase 5 PhotoDNA / evidence capture).\n // NOT z.string().min(1): the media pipeline does not compute a content hash at finalize yet,\n // so a freshly-ingested asset legitimately carries an empty rootSha256 until it is hashed.\n rootSha256: z.string(),\n originalSha256: z.string().min(1).optional(),\n // PARTIAL map: one hash per PRODUCED variant (an asset produces only the variants its\n // origin declares — e.g. full/medium/small for a profile picture, 'main' for others —\n // never all four). Typed keys, never an open string. `z.partialRecord` (NOT `z.record`):\n // in Zod 4 `z.record(enum,…)` is EXHAUSTIVE (demands every enum key), which would reject\n // every real asset's partial variant set; `partialRecord` makes the keys optional.\n variantSha256s: z.partialRecord(MediaVariantKeySchema, z.string().min(1)),\n copyReason: MediaCopyReasonSchema,\n createdFromOwnerType: MediaAssetOwnerTypeSchema.optional(), // never a bare string\n createdFromOwnerId: z.string().min(1).optional(),\n copyActorUid: z.string().min(1).optional(), // who triggered the copy (distinct from the original uploader)\n currentOwnerType: MediaAssetOwnerTypeSchema, // mutable; the asset's present owner\n currentOwnerId: z.string().min(1),\n}).strict();\nexport type MediaOriginLineageV1 = z.infer<typeof MediaOriginLineageV1Schema>;\n\nexport const MediaAssetVariantSchema = z.object({\n contentType: z.string().min(1),\n sizeBytes: z.number().int().nonnegative(),\n width: z.number().int().positive().optional(),\n height: z.number().int().positive().optional(),\n durationSec: z.number().positive().optional(),\n}).strict();\nexport type MediaAssetVariant = z.infer<typeof MediaAssetVariantSchema>;\n\nexport const MediaRetentionPolicySchema = z.enum([\n 'standard', // staging original deleted ~24h after verified mirror\n 'preserveForTrustAndSafety',\n 'legalHold',\n]);\nexport type MediaRetentionPolicy = z.infer<typeof MediaRetentionPolicySchema>;\n\n// Realm shared-files: a work file's standing in its realm's shared pool.\n// none — not shared to the realm (default)\n// nonCanon — shared to the realm's pool, non-canon\n// canon — shared and marked canon (realm steward/owner toggles canon ↔ nonCanon)\n// Moderation/takedown is NOT a value here — a hidden file is hidden via the shared\n// media path (`servingStatus: 'hidden'`), so the gallery filters on servingStatus.\nexport const RealmFileCanonStatusSchema = z.enum(['none', 'nonCanon', 'canon']);\nexport type RealmFileCanonStatus = z.infer<typeof RealmFileCanonStatusSchema>;\n\n// ===== Serving authority (Durable Object) + publication gating =====\n// See ttt-prod docs/design/media-assets-and-protected-serving.md (the design owner\n// for the Durable Object serving authority and publication gating).\n\n/** Whether the canonical serving record has been applied to the DO authority. */\nexport const MediaAuthoritySyncStateSchema = z.enum(['pending', 'applied', 'deadLetter']);\nexport type MediaAuthoritySyncState = z.infer<typeof MediaAuthoritySyncStateSchema>;\n\n/** Whether the asset is referenced by a visible owner doc. Orthogonal to the\n * upload's processing outcome (`pendingMedia.status`) and to `servingStatus`. */\nexport const MediaAssetPublicationStateSchema = z.enum(['unpublished', 'published', 'retired']);\nexport type MediaAssetPublicationState = z.infer<typeof MediaAssetPublicationStateSchema>;\n\n/**\n * Typed immutable serving scope for scoped-tier assets. The gateway Worker matches\n * a grant against the scope by `kind` — so a whole-Work `{w}` grant matches ONLY a\n * `workProject` scope, never a conversation scope, and a conversation grant is never\n * reachable by a Work asset.\n *\n * - `workProject` — pre-publish content media (hall covers / sub-item media during\n * authoring), scoped to project read membership. Carries the matchable\n * `workProjectId`. This is the typed home for work scope on the strongly-consistent\n * serving record so the DO-fallback path can authorize it (the DO persists scope\n * only as `scopeJson`, no separate column).\n * - `workFileFolder` — a work-project FILE living in a folder. The EXACT folder scope,\n * NOT the whole-Work `{w}` grant: a custom folder's bytes must be unreachable by a\n * guildmate outside that folder's view trade-professions, so the grant callable runs\n * the per-folder view check and the Worker EXACT-matches `{workProjectId,\n * workFileFolderId}` — a plain Work `{w}` grant NEVER matches a folder file, and a\n * folder grant NEVER matches a `workProject`-scoped content asset.\n * - `guildInvite` / `adminSupport` — the two Conversation Files scopes; an EXACT\n * conversation scope, matching the `ConversationFileRef` that owns the file. There is\n * NO guildChannel scope: guild chat channels have no Conversation Files (guildmates\n * share files through Work Files, which keeps its own workFileFolder scope).\n *\n * `null` scope = no scope match required beyond the access tier (e.g. broad).\n */\nexport const MediaServingScopeSchema = z.discriminatedUnion('kind', [\n z.object({\n kind: z.literal('workProject'),\n workProjectId: z.string().min(1),\n }).strict(),\n z.object({\n kind: z.literal('workFileFolder'),\n workProjectId: z.string().min(1),\n workFileFolderId: z.string().min(1),\n }).strict(),\n z.object({\n kind: z.literal('guildInvite'),\n guildInviteId: z.string().min(1),\n }).strict(),\n z.object({\n kind: z.literal('adminSupport'),\n adminDispatchId: z.string().min(1),\n }).strict(),\n]);\nexport type MediaServingScope = z.infer<typeof MediaServingScopeSchema>;\n\n/**\n * The typed owner adapter a publication goes through. The activation job\n * carries this kind; a server-side registry validates per-kind `publicationArgs`\n * and performs the idempotent owner write. Every kind is a Firestore-owner adapter.\n */\nexport const MediaPublicationKindSchema = z.enum([\n 'profilePicture',\n 'squarePostMedia',\n 'workAsset',\n 'hallCover',\n // Realm cover — Firestore-owner adapter writes `realmCoverAssetId` onto\n // workRealms/{workRealmId} (the 'realm-cover' upload origin).\n 'realmCover',\n 'workContentMedia', // sub-item media (tale chapter / tune track / television episode) — attaches the *AssetId field on the workContent doc; scoped to the work project\n 'auditionMedia',\n 'commissionListingMedia',\n 'commissionProposalMedia',\n 'craftSkillMedia',\n // Conversation File: the ONE adapter that creates a visible Conversation File owner\n // record ({conversationParent}/conversationFiles/{conversationFileId}) and transfers\n // the quota reservation to published counters in the same transaction. Replaces the\n // removed `chatAttachment` (Channel-DO flip) and `adminSupportAttachment` (message\n // placeholder flip) kinds. Carries the typed `guildInvite` / `adminSupport`\n // MediaServingScope of the owning conversation.\n 'conversationFile',\n]);\nexport type MediaPublicationKind = z.infer<typeof MediaPublicationKindSchema>;\n\n/**\n * The normalized serving record — the SAME contract used to generate both\n * the DO authority row and the KV cache payload (one function, so they can't\n * drift). The R2 object key stays deterministic (`mediaAssets/{assetId}/{key}`)\n * and is NOT persisted here. `payloadHash` is computed over the canonical\n * payload EXCLUDING the hash itself (see edge-protocol-core `hashPayload`).\n */\nexport const MediaServingAuthorityRecordSchema = z.object({\n schemaVersion: z.number().int().positive(),\n assetId: z.string().min(1),\n authorityVersion: z.number().int().nonnegative(),\n operationId: z.string().min(1),\n payloadHash: z.string().min(1),\n\n servingStatus: MediaServingStatusSchema,\n accessTier: MediaAccessTierSchema,\n\n ownerType: MediaAssetOwnerTypeSchema,\n ownerId: z.string().min(1),\n scope: MediaServingScopeSchema.nullable(),\n\n variants: z.record(z.string(), MediaAssetVariantSchema),\n\n updatedAtMs: z.number(),\n}).strict();\nexport type MediaServingAuthorityRecord = z.infer<typeof MediaServingAuthorityRecordSchema>;\n\nexport const MediaAssetSchema = z.object({\n mediaAssetId: z.string().min(1),\n mediaKind: ContentMediaKindSchema,\n fileOrigin: FileOriginSchema,\n\n // Ownership / scope. ownerId is the owning doc's id within ownerType's\n // surface; scope ids let the Worker/grant layer match scoped access.\n ownerType: MediaAssetOwnerTypeSchema,\n ownerId: z.string().min(1),\n workProjectId: z.string().optional(),\n realmId: z.string().optional(),\n createdByUid: z.string().min(1),\n\n // Access + serving (canonical; edge records derive from these).\n accessTier: MediaAccessTierSchema,\n servingStatus: MediaServingStatusSchema,\n\n // Variants by key. The object key in R2 (and the Storage emulator) is\n // deterministic — mediaAssets/{mediaAssetId}/{variantKey} — never stored.\n variants: z.record(z.string(), MediaAssetVariantSchema),\n\n // Lifecycle / trust-and-safety.\n moderationStatus: z.enum(['approved', 'quarantined']),\n retentionPolicy: MediaRetentionPolicySchema,\n legalHold: z.boolean(),\n originalDeletedAt: z.number().optional(),\n\n // T&S provenance lineage (Appendix A0). Additive/optional so assets written\n // before the lineage rollout still parse; set server-side at first accepted\n // ingest, inherited unchanged by every copy/variant. Never client-supplied.\n originLineage: MediaOriginLineageV1Schema.optional(),\n\n // Realm shared-files seam. A file's standing in its realm's shared pool; set at\n // creation to 'none' and moved by the realm shared-files callables. Attribution\n // fields (who set canon, when) are added by that feature when it ships.\n realmFileCanonStatus: RealmFileCanonStatusSchema,\n\n // Serving authority + publication gating. Additive/optional so assets\n // written before the authority build still parse: absent authorityVersion ⇒\n // 0/never-applied, absent publicationState ⇒ 'unpublished'. Every\n // serving-record mutation increments authorityVersion in an authoritative txn.\n authorityVersion: z.number().int().nonnegative().optional(),\n authorityPayloadHash: z.string().optional(),\n authoritySyncState: MediaAuthoritySyncStateSchema.optional(),\n publicationState: MediaAssetPublicationStateSchema.optional(),\n scope: MediaServingScopeSchema.optional(),\n authorityAppliedAt: z.number().optional(),\n publishedAt: z.number().optional(),\n lastAuthorityError: StructuredErrorSchema.optional(),\n // Authority-sync retry ledger (M1): the scheduled worker bumps attemptCount + sets a backoff\n // nextAttemptAt on a transient apply failure, and dead-letters (authoritySyncState='deadLetter')\n // past a threshold. Absent ⇒ 0 attempts / immediately due.\n authoritySyncAttemptCount: z.number().int().nonnegative().optional(),\n authoritySyncNextAttemptAt: z.number().optional(),\n\n createdAt: z.number(),\n updatedAt: z.number(),\n}).strict();\nexport type MediaAsset = z.infer<typeof MediaAssetSchema>;\n"]}