@giveitsmaller/contracts 0.65.0 → 0.68.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 (523) hide show
  1. package/README.md +2 -2
  2. package/accepted-options/accepted-options.json +17 -3
  3. package/accepted-options/image-output-routes.json +1 -1
  4. package/availability/availability.json +97 -11
  5. package/code-builder/code-builder-metadata.json +120 -11
  6. package/dist/openapi/models/AccountLimitEntry.d.ts +1 -1
  7. package/dist/openapi/models/AccountLimitEntry.js +1 -1
  8. package/dist/openapi/models/AccountLimits.d.ts +15 -7
  9. package/dist/openapi/models/AccountLimits.js +1 -1
  10. package/dist/openapi/models/AccountLimitsLimits.d.ts +1 -1
  11. package/dist/openapi/models/AccountLimitsLimits.js +1 -1
  12. package/dist/openapi/models/AccountLimitsSuccessEnvelope.d.ts +1 -1
  13. package/dist/openapi/models/AccountLimitsSuccessEnvelope.js +1 -1
  14. package/dist/openapi/models/AudioWatermarkDecodeRequest.d.ts +1 -1
  15. package/dist/openapi/models/AudioWatermarkDecodeRequest.js +1 -1
  16. package/dist/openapi/models/AudioWatermarkDecodeResponse.d.ts +1 -1
  17. package/dist/openapi/models/AudioWatermarkDecodeResponse.js +1 -1
  18. package/dist/openapi/models/AuthErrorResponse.d.ts +1 -1
  19. package/dist/openapi/models/AuthErrorResponse.js +1 -1
  20. package/dist/openapi/models/AuthErrorType.d.ts +1 -1
  21. package/dist/openapi/models/AuthErrorType.js +1 -1
  22. package/dist/openapi/models/AuthRejectionEnvelope.d.ts +1 -1
  23. package/dist/openapi/models/AuthRejectionEnvelope.js +1 -1
  24. package/dist/openapi/models/{TierDefaultsByAudience.d.ts → AuthenticatedIdentity.d.ts} +56 -40
  25. package/dist/openapi/models/{TierDefaultsByAudience.js → AuthenticatedIdentity.js} +31 -25
  26. package/dist/openapi/models/AvailabilityValue.d.ts +1 -1
  27. package/dist/openapi/models/AvailabilityValue.js +1 -1
  28. package/dist/openapi/models/BalanceExhaustedResponse.d.ts +1 -1
  29. package/dist/openapi/models/BalanceExhaustedResponse.js +1 -1
  30. package/dist/openapi/models/BalanceExhaustedResponseAllOfLinks.d.ts +1 -1
  31. package/dist/openapi/models/BalanceExhaustedResponseAllOfLinks.js +1 -1
  32. package/dist/openapi/models/BillingCheckoutRequest.d.ts +1 -1
  33. package/dist/openapi/models/BillingCheckoutRequest.js +1 -1
  34. package/dist/openapi/models/BillingCheckoutSession.d.ts +1 -1
  35. package/dist/openapi/models/BillingCheckoutSession.js +1 -1
  36. package/dist/openapi/models/BillingCheckoutSuccessEnvelope.d.ts +1 -1
  37. package/dist/openapi/models/BillingCheckoutSuccessEnvelope.js +1 -1
  38. package/dist/openapi/models/CallbackEventType.d.ts +1 -1
  39. package/dist/openapi/models/CallbackEventType.js +1 -1
  40. package/dist/openapi/models/CancelAccountDeletion200Response.d.ts +1 -1
  41. package/dist/openapi/models/CancelAccountDeletion200Response.js +1 -1
  42. package/dist/openapi/models/CancelAccountDeletion200ResponseData.d.ts +1 -1
  43. package/dist/openapi/models/CancelAccountDeletion200ResponseData.js +1 -1
  44. package/dist/openapi/models/CapabilityCondition.d.ts +1 -1
  45. package/dist/openapi/models/CapabilityCondition.js +1 -1
  46. package/dist/openapi/models/CapabilityConditionOneOf.d.ts +1 -1
  47. package/dist/openapi/models/CapabilityConditionOneOf.js +1 -1
  48. package/dist/openapi/models/CapabilityConditionOneOf1.d.ts +1 -1
  49. package/dist/openapi/models/CapabilityConditionOneOf1.js +1 -1
  50. package/dist/openapi/models/CapabilityConditionOneOf2.d.ts +1 -1
  51. package/dist/openapi/models/CapabilityConditionOneOf2.js +1 -1
  52. package/dist/openapi/models/CapabilityConditionOneOf3.d.ts +1 -1
  53. package/dist/openapi/models/CapabilityConditionOneOf3.js +1 -1
  54. package/dist/openapi/models/CapabilityConditionOneOf4.d.ts +1 -1
  55. package/dist/openapi/models/CapabilityConditionOneOf4.js +1 -1
  56. package/dist/openapi/models/CapabilityConditionOneOf5.d.ts +1 -1
  57. package/dist/openapi/models/CapabilityConditionOneOf5.js +1 -1
  58. package/dist/openapi/models/CapabilityConditionOneOf6.d.ts +1 -1
  59. package/dist/openapi/models/CapabilityConditionOneOf6.js +1 -1
  60. package/dist/openapi/models/CapabilityConstraint.d.ts +1 -1
  61. package/dist/openapi/models/CapabilityConstraint.js +1 -1
  62. package/dist/openapi/models/CapabilityInputSpec.d.ts +1 -1
  63. package/dist/openapi/models/CapabilityInputSpec.js +1 -1
  64. package/dist/openapi/models/CapabilityProduces.d.ts +1 -1
  65. package/dist/openapi/models/CapabilityProduces.js +1 -1
  66. package/dist/openapi/models/CapabilityProducesOneOf.d.ts +1 -1
  67. package/dist/openapi/models/CapabilityProducesOneOf.js +1 -1
  68. package/dist/openapi/models/CapabilityProducesOneOf1.d.ts +1 -1
  69. package/dist/openapi/models/CapabilityProducesOneOf1.js +1 -1
  70. package/dist/openapi/models/CapabilityProducesOneOf2.d.ts +1 -1
  71. package/dist/openapi/models/CapabilityProducesOneOf2.js +1 -1
  72. package/dist/openapi/models/ChangePasswordRequest.d.ts +1 -1
  73. package/dist/openapi/models/ChangePasswordRequest.js +1 -1
  74. package/dist/openapi/models/CodegenSource.d.ts +1 -1
  75. package/dist/openapi/models/CodegenSource.js +1 -1
  76. package/dist/openapi/models/CodegenSourceInput.d.ts +1 -1
  77. package/dist/openapi/models/CodegenSourceInput.js +1 -1
  78. package/dist/openapi/models/CodegenSourceJob.d.ts +1 -1
  79. package/dist/openapi/models/CodegenSourceJob.js +1 -1
  80. package/dist/openapi/models/CodegenSourceJobSource.d.ts +1 -1
  81. package/dist/openapi/models/CodegenSourceJobSource.js +1 -1
  82. package/dist/openapi/models/CodegenSourceOperation.d.ts +1 -1
  83. package/dist/openapi/models/CodegenSourceOperation.js +1 -1
  84. package/dist/openapi/models/CodegenUploadPlaceholder.d.ts +1 -1
  85. package/dist/openapi/models/CodegenUploadPlaceholder.js +1 -1
  86. package/dist/openapi/models/CompositionPlan.d.ts +1 -1
  87. package/dist/openapi/models/CompositionPlan.js +1 -1
  88. package/dist/openapi/models/CompositionPlanJob.d.ts +1 -1
  89. package/dist/openapi/models/CompositionPlanJob.js +1 -1
  90. package/dist/openapi/models/CompositionPlanOperation.d.ts +1 -1
  91. package/dist/openapi/models/CompositionPlanOperation.js +1 -1
  92. package/dist/openapi/models/ConfirmEmailChange200Response.d.ts +1 -1
  93. package/dist/openapi/models/ConfirmEmailChange200Response.js +1 -1
  94. package/dist/openapi/models/ConfirmEmailChange200ResponseData.d.ts +1 -1
  95. package/dist/openapi/models/ConfirmEmailChange200ResponseData.js +1 -1
  96. package/dist/openapi/models/ConfirmEmailChangeRequest.d.ts +1 -1
  97. package/dist/openapi/models/ConfirmEmailChangeRequest.js +1 -1
  98. package/dist/openapi/models/ConnectionSource.d.ts +1 -1
  99. package/dist/openapi/models/ConnectionSource.js +1 -1
  100. package/dist/openapi/models/ContactRequest.d.ts +1 -1
  101. package/dist/openapi/models/ContactRequest.js +1 -1
  102. package/dist/openapi/models/ContactSubject.d.ts +1 -1
  103. package/dist/openapi/models/ContactSubject.js +1 -1
  104. package/dist/openapi/models/ContactValidationErrorResponse.d.ts +1 -1
  105. package/dist/openapi/models/ContactValidationErrorResponse.js +1 -1
  106. package/dist/openapi/models/CreateApiKey201Response.d.ts +1 -1
  107. package/dist/openapi/models/CreateApiKey201Response.js +1 -1
  108. package/dist/openapi/models/CreateApiKey201ResponseData.d.ts +1 -1
  109. package/dist/openapi/models/CreateApiKey201ResponseData.js +1 -1
  110. package/dist/openapi/models/CreateApiKeyRequest.d.ts +1 -1
  111. package/dist/openapi/models/CreateApiKeyRequest.js +1 -1
  112. package/dist/openapi/models/CreateBillingCheckoutSession422Response.d.ts +1 -1
  113. package/dist/openapi/models/CreateBillingCheckoutSession422Response.js +1 -1
  114. package/dist/openapi/models/CreateExternalImport403Response.d.ts +1 -1
  115. package/dist/openapi/models/CreateExternalImport403Response.js +1 -1
  116. package/dist/openapi/models/CreateExternalImport422Response.d.ts +1 -1
  117. package/dist/openapi/models/CreateExternalImport422Response.js +1 -1
  118. package/dist/openapi/models/CreateWorkflow401Response.d.ts +1 -1
  119. package/dist/openapi/models/CreateWorkflow401Response.js +1 -1
  120. package/dist/openapi/models/CreateWorkflow422Response.d.ts +1 -1
  121. package/dist/openapi/models/CreateWorkflow422Response.js +1 -1
  122. package/dist/openapi/models/CreditTransaction.d.ts +1 -1
  123. package/dist/openapi/models/CreditTransaction.js +1 -1
  124. package/dist/openapi/models/CreditTransactionSourceBucket.d.ts +1 -1
  125. package/dist/openapi/models/CreditTransactionSourceBucket.js +1 -1
  126. package/dist/openapi/models/CreditsBalanceResponse.d.ts +1 -1
  127. package/dist/openapi/models/CreditsBalanceResponse.js +1 -1
  128. package/dist/openapi/models/CreditsBalanceSuccessEnvelope.d.ts +1 -1
  129. package/dist/openapi/models/CreditsBalanceSuccessEnvelope.js +1 -1
  130. package/dist/openapi/models/CreditsUsageResponse.d.ts +1 -1
  131. package/dist/openapi/models/CreditsUsageResponse.js +1 -1
  132. package/dist/openapi/models/CreditsUsageSuccessEnvelope.d.ts +1 -1
  133. package/dist/openapi/models/CreditsUsageSuccessEnvelope.js +1 -1
  134. package/dist/openapi/models/Delivery.d.ts +1 -1
  135. package/dist/openapi/models/Delivery.js +1 -1
  136. package/dist/openapi/models/DeliveryOutputRef.d.ts +1 -1
  137. package/dist/openapi/models/DeliveryOutputRef.js +1 -1
  138. package/dist/openapi/models/DeliveryPlan.d.ts +1 -1
  139. package/dist/openapi/models/DeliveryPlan.js +1 -1
  140. package/dist/openapi/models/DeliveryPlanOutput.d.ts +1 -1
  141. package/dist/openapi/models/DeliveryPlanOutput.js +1 -1
  142. package/dist/openapi/models/DeliveryPlanReason.d.ts +1 -1
  143. package/dist/openapi/models/DeliveryPlanReason.js +1 -1
  144. package/dist/openapi/models/DeliverySelection.d.ts +1 -1
  145. package/dist/openapi/models/DeliverySelection.js +1 -1
  146. package/dist/openapi/models/DownloadBundle.d.ts +1 -1
  147. package/dist/openapi/models/DownloadBundle.js +1 -1
  148. package/dist/openapi/models/DroppedOption.d.ts +1 -1
  149. package/dist/openapi/models/DroppedOption.js +1 -1
  150. package/dist/openapi/models/EmailNotify.d.ts +1 -1
  151. package/dist/openapi/models/EmailNotify.js +1 -1
  152. package/dist/openapi/models/EmptySuccessEnvelope.d.ts +1 -1
  153. package/dist/openapi/models/EmptySuccessEnvelope.js +1 -1
  154. package/dist/openapi/models/EndpointProjection.d.ts +1 -1
  155. package/dist/openapi/models/EndpointProjection.js +1 -1
  156. package/dist/openapi/models/EndpointProjectionServersInner.d.ts +1 -1
  157. package/dist/openapi/models/EndpointProjectionServersInner.js +1 -1
  158. package/dist/openapi/models/ErrorEnvelope.d.ts +1 -1
  159. package/dist/openapi/models/ErrorEnvelope.js +1 -1
  160. package/dist/openapi/models/EstimateQuality.d.ts +1 -1
  161. package/dist/openapi/models/EstimateQuality.js +1 -1
  162. package/dist/openapi/models/EstimateRange.d.ts +1 -1
  163. package/dist/openapi/models/EstimateRange.js +1 -1
  164. package/dist/openapi/models/ExportAccountData200Response.d.ts +1 -1
  165. package/dist/openapi/models/ExportAccountData200Response.js +1 -1
  166. package/dist/openapi/models/ExportAccountData200ResponseData.d.ts +1 -1
  167. package/dist/openapi/models/ExportAccountData200ResponseData.js +1 -1
  168. package/dist/openapi/models/ExternalDestination.d.ts +1 -1
  169. package/dist/openapi/models/ExternalDestination.js +1 -1
  170. package/dist/openapi/models/ExternalImportCreatedResponse.d.ts +1 -1
  171. package/dist/openapi/models/ExternalImportCreatedResponse.js +1 -1
  172. package/dist/openapi/models/ExternalImportCreatedSuccessEnvelope.d.ts +1 -1
  173. package/dist/openapi/models/ExternalImportCreatedSuccessEnvelope.js +1 -1
  174. package/dist/openapi/models/ExternalImportRequest.d.ts +1 -1
  175. package/dist/openapi/models/ExternalImportRequest.js +1 -1
  176. package/dist/openapi/models/ExternalImportToken.d.ts +1 -1
  177. package/dist/openapi/models/ExternalImportToken.js +1 -1
  178. package/dist/openapi/models/ExternalSource.d.ts +1 -1
  179. package/dist/openapi/models/ExternalSource.js +1 -1
  180. package/dist/openapi/models/FeatureNotAvailableResponse.d.ts +1 -1
  181. package/dist/openapi/models/FeatureNotAvailableResponse.js +1 -1
  182. package/dist/openapi/models/FeatureTierRestrictedResponse.d.ts +1 -1
  183. package/dist/openapi/models/FeatureTierRestrictedResponse.js +1 -1
  184. package/dist/openapi/models/FeatureViolation.d.ts +1 -1
  185. package/dist/openapi/models/FeatureViolation.js +1 -1
  186. package/dist/openapi/models/{MediaCategory.js → GetProfile200Response.d.ts} +31 -34
  187. package/dist/openapi/models/{TierDefaults.js → GetProfile200Response.js} +22 -17
  188. package/dist/openapi/models/{MediaCategory.d.ts → GetProfile200ResponseData.d.ts} +19 -17
  189. package/dist/openapi/models/{TierDefaultLimits.js → GetProfile200ResponseData.js} +13 -16
  190. package/dist/openapi/models/ImageEncodeCapabilities.d.ts +1 -1
  191. package/dist/openapi/models/ImageEncodeCapabilities.js +1 -1
  192. package/dist/openapi/models/JobDefinition.d.ts +1 -1
  193. package/dist/openapi/models/JobDefinition.js +1 -1
  194. package/dist/openapi/models/JobDownload.d.ts +1 -1
  195. package/dist/openapi/models/JobDownload.js +1 -1
  196. package/dist/openapi/models/JobInputV2.d.ts +1 -1
  197. package/dist/openapi/models/JobInputV2.js +1 -1
  198. package/dist/openapi/models/JobMediaClass.d.ts +1 -1
  199. package/dist/openapi/models/JobMediaClass.js +1 -1
  200. package/dist/openapi/models/JobOutputSource.d.ts +1 -1
  201. package/dist/openapi/models/JobOutputSource.js +1 -1
  202. package/dist/openapi/models/JobResponse.d.ts +1 -1
  203. package/dist/openapi/models/JobResponse.js +1 -1
  204. package/dist/openapi/models/JobStatus.d.ts +1 -1
  205. package/dist/openapi/models/JobStatus.js +1 -1
  206. package/dist/openapi/models/JobType.d.ts +1 -1
  207. package/dist/openapi/models/JobType.js +1 -1
  208. package/dist/openapi/models/LivenessResponse.d.ts +1 -1
  209. package/dist/openapi/models/LivenessResponse.js +1 -1
  210. package/dist/openapi/models/LoginUser200Response.d.ts +1 -1
  211. package/dist/openapi/models/LoginUser200Response.js +1 -1
  212. package/dist/openapi/models/LoginUser200ResponseData.d.ts +1 -1
  213. package/dist/openapi/models/LoginUser200ResponseData.js +1 -1
  214. package/dist/openapi/models/LoginUser200ResponseDataUser.d.ts +1 -1
  215. package/dist/openapi/models/LoginUser200ResponseDataUser.js +1 -1
  216. package/dist/openapi/models/LoginUser401Response.d.ts +1 -1
  217. package/dist/openapi/models/LoginUser401Response.js +1 -1
  218. package/dist/openapi/models/LoginUserRequest.d.ts +1 -1
  219. package/dist/openapi/models/LoginUserRequest.js +1 -1
  220. package/dist/openapi/models/LongFormConcurrencyLimitResponse.d.ts +1 -1
  221. package/dist/openapi/models/LongFormConcurrencyLimitResponse.js +1 -1
  222. package/dist/openapi/models/LongFormConcurrencyLimitResponseAllOfLinks.d.ts +1 -1
  223. package/dist/openapi/models/LongFormConcurrencyLimitResponseAllOfLinks.js +1 -1
  224. package/dist/openapi/models/MetadataResponse.d.ts +1 -1
  225. package/dist/openapi/models/MetadataResponse.js +1 -1
  226. package/dist/openapi/models/MetadataResponseDimensions.d.ts +1 -1
  227. package/dist/openapi/models/MetadataResponseDimensions.js +1 -1
  228. package/dist/openapi/models/MetadataResponseExif.d.ts +1 -1
  229. package/dist/openapi/models/MetadataResponseExif.js +1 -1
  230. package/dist/openapi/models/MetadataResponseExifGps.d.ts +1 -1
  231. package/dist/openapi/models/MetadataResponseExifGps.js +1 -1
  232. package/dist/openapi/models/MetadataSuccessEnvelope.d.ts +1 -1
  233. package/dist/openapi/models/MetadataSuccessEnvelope.js +1 -1
  234. package/dist/openapi/models/MimeGroupSchema.d.ts +17 -8
  235. package/dist/openapi/models/MimeGroupSchema.js +1 -1
  236. package/dist/openapi/models/MultiInputSource.d.ts +1 -1
  237. package/dist/openapi/models/MultiInputSource.js +1 -1
  238. package/dist/openapi/models/MultipartCompleteRequest.d.ts +1 -1
  239. package/dist/openapi/models/MultipartCompleteRequest.js +1 -1
  240. package/dist/openapi/models/MultipartCompleteRequestPartsInner.d.ts +1 -1
  241. package/dist/openapi/models/MultipartCompleteRequestPartsInner.js +1 -1
  242. package/dist/openapi/models/MultipartCompleteResponse.d.ts +1 -1
  243. package/dist/openapi/models/MultipartCompleteResponse.js +1 -1
  244. package/dist/openapi/models/MultipartCompleteSuccessEnvelope.d.ts +1 -1
  245. package/dist/openapi/models/MultipartCompleteSuccessEnvelope.js +1 -1
  246. package/dist/openapi/models/MultipartInitiateRequestMetadataHint.d.ts +1 -1
  247. package/dist/openapi/models/MultipartInitiateRequestMetadataHint.js +1 -1
  248. package/dist/openapi/models/MultipartInitiateResponse.d.ts +1 -1
  249. package/dist/openapi/models/MultipartInitiateResponse.js +1 -1
  250. package/dist/openapi/models/MultipartInitiateSuccessEnvelope.d.ts +1 -1
  251. package/dist/openapi/models/MultipartInitiateSuccessEnvelope.js +1 -1
  252. package/dist/openapi/models/MultipartKeepaliveResponse.d.ts +1 -1
  253. package/dist/openapi/models/MultipartKeepaliveResponse.js +1 -1
  254. package/dist/openapi/models/MultipartKeepaliveSuccessEnvelope.d.ts +1 -1
  255. package/dist/openapi/models/MultipartKeepaliveSuccessEnvelope.js +1 -1
  256. package/dist/openapi/models/MultipartPartListing.d.ts +1 -1
  257. package/dist/openapi/models/MultipartPartListing.js +1 -1
  258. package/dist/openapi/models/MultipartPresignRequest.d.ts +1 -1
  259. package/dist/openapi/models/MultipartPresignRequest.js +1 -1
  260. package/dist/openapi/models/MultipartPresignResponse.d.ts +1 -1
  261. package/dist/openapi/models/MultipartPresignResponse.js +1 -1
  262. package/dist/openapi/models/MultipartPresignSuccessEnvelope.d.ts +1 -1
  263. package/dist/openapi/models/MultipartPresignSuccessEnvelope.js +1 -1
  264. package/dist/openapi/models/MultipartStatusResponse.d.ts +1 -1
  265. package/dist/openapi/models/MultipartStatusResponse.js +1 -1
  266. package/dist/openapi/models/MultipartStatusSuccessEnvelope.d.ts +1 -1
  267. package/dist/openapi/models/MultipartStatusSuccessEnvelope.js +1 -1
  268. package/dist/openapi/models/NotifyConfig.d.ts +1 -1
  269. package/dist/openapi/models/NotifyConfig.js +1 -1
  270. package/dist/openapi/models/OperationCapability.d.ts +1 -1
  271. package/dist/openapi/models/OperationCapability.js +1 -1
  272. package/dist/openapi/models/OperationDefinition.d.ts +1 -1
  273. package/dist/openapi/models/OperationDefinition.js +1 -1
  274. package/dist/openapi/models/OperationDownload.d.ts +1 -1
  275. package/dist/openapi/models/OperationDownload.js +1 -1
  276. package/dist/openapi/models/OperationInputModel.d.ts +1 -1
  277. package/dist/openapi/models/OperationInputModel.js +1 -1
  278. package/dist/openapi/models/OperationResponse.d.ts +1 -1
  279. package/dist/openapi/models/OperationResponse.js +1 -1
  280. package/dist/openapi/models/OperationResult.d.ts +1 -1
  281. package/dist/openapi/models/OperationResult.js +1 -1
  282. package/dist/openapi/models/OperationResultMetadata.d.ts +1 -1
  283. package/dist/openapi/models/OperationResultMetadata.js +1 -1
  284. package/dist/openapi/models/OperationResultMetrics.d.ts +1 -1
  285. package/dist/openapi/models/OperationResultMetrics.js +1 -1
  286. package/dist/openapi/models/OperationSchemaDefinition.d.ts +1 -1
  287. package/dist/openapi/models/OperationSchemaDefinition.js +1 -1
  288. package/dist/openapi/models/OperationStatus.d.ts +1 -1
  289. package/dist/openapi/models/OperationStatus.js +1 -1
  290. package/dist/openapi/models/OperationType.d.ts +1 -1
  291. package/dist/openapi/models/OperationType.js +1 -1
  292. package/dist/openapi/models/OperationsSchemaResponse.d.ts +24 -7
  293. package/dist/openapi/models/OperationsSchemaResponse.js +3 -4
  294. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeatures.d.ts +1 -1
  295. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeatures.js +1 -1
  296. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDelivery.d.ts +1 -1
  297. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDelivery.js +1 -1
  298. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDeliveryMode.d.ts +1 -1
  299. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDeliveryMode.js +1 -1
  300. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDeliverySelection.d.ts +1 -1
  301. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDeliverySelection.js +1 -1
  302. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesProcessing.d.ts +1 -1
  303. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesProcessing.js +1 -1
  304. package/dist/openapi/models/OptionSchema.d.ts +1 -1
  305. package/dist/openapi/models/OptionSchema.js +1 -1
  306. package/dist/openapi/models/OutputProperties.d.ts +1 -1
  307. package/dist/openapi/models/OutputProperties.js +1 -1
  308. package/dist/openapi/models/OutputPropertiesIsAnimated.d.ts +1 -1
  309. package/dist/openapi/models/OutputPropertiesIsAnimated.js +1 -1
  310. package/dist/openapi/models/PerClassAvailabilityEntry.d.ts +1 -1
  311. package/dist/openapi/models/PerClassAvailabilityEntry.js +1 -1
  312. package/dist/openapi/models/PerRoleCardinalityEntry.d.ts +1 -1
  313. package/dist/openapi/models/PerRoleCardinalityEntry.js +1 -1
  314. package/dist/openapi/models/PerValueAvailabilityEntry.d.ts +1 -1
  315. package/dist/openapi/models/PerValueAvailabilityEntry.js +1 -1
  316. package/dist/openapi/models/PresignedUrlPart.d.ts +1 -1
  317. package/dist/openapi/models/PresignedUrlPart.js +1 -1
  318. package/dist/openapi/models/ProbePendingResponse.d.ts +1 -1
  319. package/dist/openapi/models/ProbePendingResponse.js +1 -1
  320. package/dist/openapi/models/ProcessingClass.d.ts +1 -1
  321. package/dist/openapi/models/ProcessingClass.js +1 -1
  322. package/dist/openapi/models/ProcessingClassBandViolation.d.ts +1 -1
  323. package/dist/openapi/models/ProcessingClassBandViolation.js +1 -1
  324. package/dist/openapi/models/ProcessingClassConstraints.d.ts +1 -1
  325. package/dist/openapi/models/ProcessingClassConstraints.js +1 -1
  326. package/dist/openapi/models/ProcessingClassEntry.d.ts +1 -1
  327. package/dist/openapi/models/ProcessingClassEntry.js +1 -1
  328. package/dist/openapi/models/ProcessingClassExceedsBandResponse.d.ts +1 -1
  329. package/dist/openapi/models/ProcessingClassExceedsBandResponse.js +1 -1
  330. package/dist/openapi/models/ProcessingClassHint.d.ts +1 -1
  331. package/dist/openapi/models/ProcessingClassHint.js +1 -1
  332. package/dist/openapi/models/ProcessingClassReason.d.ts +1 -1
  333. package/dist/openapi/models/ProcessingClassReason.js +1 -1
  334. package/dist/openapi/models/ProcessingClassRejectReason.d.ts +1 -1
  335. package/dist/openapi/models/ProcessingClassRejectReason.js +1 -1
  336. package/dist/openapi/models/ProcessingPlan.d.ts +1 -1
  337. package/dist/openapi/models/ProcessingPlan.js +1 -1
  338. package/dist/openapi/models/ProcessingPlanJob.d.ts +1 -1
  339. package/dist/openapi/models/ProcessingPlanJob.js +1 -1
  340. package/dist/openapi/models/ReEncodeDecision.d.ts +1 -1
  341. package/dist/openapi/models/ReEncodeDecision.js +1 -1
  342. package/dist/openapi/models/ReadinessResponse.d.ts +1 -1
  343. package/dist/openapi/models/ReadinessResponse.js +1 -1
  344. package/dist/openapi/models/RegisterUser422Response.d.ts +1 -1
  345. package/dist/openapi/models/RegisterUser422Response.js +1 -1
  346. package/dist/openapi/models/RegisterUserRequest.d.ts +1 -1
  347. package/dist/openapi/models/RegisterUserRequest.js +1 -1
  348. package/dist/openapi/models/RequestAccountDeletion200Response.d.ts +1 -1
  349. package/dist/openapi/models/RequestAccountDeletion200Response.js +1 -1
  350. package/dist/openapi/models/RequestAccountDeletion200ResponseData.d.ts +1 -1
  351. package/dist/openapi/models/RequestAccountDeletion200ResponseData.js +1 -1
  352. package/dist/openapi/models/RequestAccountDeletionRequest.d.ts +1 -1
  353. package/dist/openapi/models/RequestAccountDeletionRequest.js +1 -1
  354. package/dist/openapi/models/ResendVerificationEmailRequest.d.ts +1 -1
  355. package/dist/openapi/models/ResendVerificationEmailRequest.js +1 -1
  356. package/dist/openapi/models/ResetPasswordRequest.d.ts +1 -1
  357. package/dist/openapi/models/ResetPasswordRequest.js +1 -1
  358. package/dist/openapi/models/ResponseEnvelope.d.ts +1 -1
  359. package/dist/openapi/models/ResponseEnvelope.js +1 -1
  360. package/dist/openapi/models/RetryResponse.d.ts +1 -1
  361. package/dist/openapi/models/RetryResponse.js +1 -1
  362. package/dist/openapi/models/RetrySuccessEnvelope.d.ts +1 -1
  363. package/dist/openapi/models/RetrySuccessEnvelope.js +1 -1
  364. package/dist/openapi/models/SseCompletionBase.d.ts +1 -1
  365. package/dist/openapi/models/SseCompletionBase.js +1 -1
  366. package/dist/openapi/models/SseEventType.d.ts +1 -1
  367. package/dist/openapi/models/SseEventType.js +1 -1
  368. package/dist/openapi/models/SseJobCompletedData.d.ts +1 -1
  369. package/dist/openapi/models/SseJobCompletedData.js +1 -1
  370. package/dist/openapi/models/SseJobFailedData.d.ts +1 -1
  371. package/dist/openapi/models/SseJobFailedData.js +1 -1
  372. package/dist/openapi/models/SseMultiOutputCompletion.d.ts +1 -1
  373. package/dist/openapi/models/SseMultiOutputCompletion.js +1 -1
  374. package/dist/openapi/models/SseMultiOutputCompletionMetrics.d.ts +1 -1
  375. package/dist/openapi/models/SseMultiOutputCompletionMetrics.js +1 -1
  376. package/dist/openapi/models/SseMultiOutputCompletionWithKind.d.ts +1 -1
  377. package/dist/openapi/models/SseMultiOutputCompletionWithKind.js +1 -1
  378. package/dist/openapi/models/SseMultiOutputResultEntry.d.ts +1 -1
  379. package/dist/openapi/models/SseMultiOutputResultEntry.js +1 -1
  380. package/dist/openapi/models/SseOperationCompletedData.d.ts +1 -1
  381. package/dist/openapi/models/SseOperationCompletedData.js +1 -1
  382. package/dist/openapi/models/SseOperationCompletionResult.d.ts +1 -1
  383. package/dist/openapi/models/SseOperationCompletionResult.js +1 -1
  384. package/dist/openapi/models/SseOperationFailedData.d.ts +1 -1
  385. package/dist/openapi/models/SseOperationFailedData.js +1 -1
  386. package/dist/openapi/models/SseOperationProgressData.d.ts +1 -1
  387. package/dist/openapi/models/SseOperationProgressData.js +1 -1
  388. package/dist/openapi/models/SseSingleOutputCompletion.d.ts +1 -1
  389. package/dist/openapi/models/SseSingleOutputCompletion.js +1 -1
  390. package/dist/openapi/models/SseWorkflowTerminalData.d.ts +1 -1
  391. package/dist/openapi/models/SseWorkflowTerminalData.js +1 -1
  392. package/dist/openapi/models/TierRestrictionKind.d.ts +19 -5
  393. package/dist/openapi/models/TierRestrictionKind.js +19 -5
  394. package/dist/openapi/models/TierRestrictionResponse.d.ts +1 -1
  395. package/dist/openapi/models/TierRestrictionResponse.js +1 -1
  396. package/dist/openapi/models/UpdateProfile200Response.d.ts +1 -1
  397. package/dist/openapi/models/UpdateProfile200Response.js +1 -1
  398. package/dist/openapi/models/UpdateProfile200ResponseData.d.ts +1 -1
  399. package/dist/openapi/models/UpdateProfile200ResponseData.js +1 -1
  400. package/dist/openapi/models/UpdateProfile422Response.d.ts +1 -1
  401. package/dist/openapi/models/UpdateProfile422Response.js +1 -1
  402. package/dist/openapi/models/UpdateProfileRequest.d.ts +1 -1
  403. package/dist/openapi/models/UpdateProfileRequest.js +1 -1
  404. package/dist/openapi/models/UploadConstraintsApplied.d.ts +1 -1
  405. package/dist/openapi/models/UploadConstraintsApplied.js +1 -1
  406. package/dist/openapi/models/UploadDurationExceedsTierResponse.d.ts +1 -1
  407. package/dist/openapi/models/UploadDurationExceedsTierResponse.js +1 -1
  408. package/dist/openapi/models/UploadFile403Response.d.ts +1 -1
  409. package/dist/openapi/models/UploadFile403Response.js +1 -1
  410. package/dist/openapi/models/UploadFile422Response.d.ts +1 -1
  411. package/dist/openapi/models/UploadFile422Response.js +1 -1
  412. package/dist/openapi/models/UploadProbeMediaMetadata.d.ts +1 -1
  413. package/dist/openapi/models/UploadProbeMediaMetadata.js +1 -1
  414. package/dist/openapi/models/UploadProbeProcessingClass.d.ts +1 -1
  415. package/dist/openapi/models/UploadProbeProcessingClass.js +1 -1
  416. package/dist/openapi/models/UploadProbeResponse.d.ts +1 -1
  417. package/dist/openapi/models/UploadProbeResponse.js +1 -1
  418. package/dist/openapi/models/UploadProbeStatus.d.ts +1 -1
  419. package/dist/openapi/models/UploadProbeStatus.js +1 -1
  420. package/dist/openapi/models/UploadProbeSuccessEnvelope.d.ts +1 -1
  421. package/dist/openapi/models/UploadProbeSuccessEnvelope.js +1 -1
  422. package/dist/openapi/models/UploadResponse.d.ts +1 -1
  423. package/dist/openapi/models/UploadResponse.js +1 -1
  424. package/dist/openapi/models/UploadSizeExceedsTierResponse.d.ts +1 -1
  425. package/dist/openapi/models/UploadSizeExceedsTierResponse.js +1 -1
  426. package/dist/openapi/models/UploadSource.d.ts +1 -1
  427. package/dist/openapi/models/UploadSource.js +1 -1
  428. package/dist/openapi/models/UploadSuccessEnvelope.d.ts +1 -1
  429. package/dist/openapi/models/UploadSuccessEnvelope.js +1 -1
  430. package/dist/openapi/models/UploadThresholds.d.ts +1 -1
  431. package/dist/openapi/models/UploadThresholds.js +1 -1
  432. package/dist/openapi/models/UserTier.d.ts +66 -33
  433. package/dist/openapi/models/UserTier.js +66 -33
  434. package/dist/openapi/models/ValidationErrorEnvelope.d.ts +1 -1
  435. package/dist/openapi/models/ValidationErrorEnvelope.js +1 -1
  436. package/dist/openapi/models/ValidationErrorEnvelopeDetailsInner.d.ts +1 -1
  437. package/dist/openapi/models/ValidationErrorEnvelopeDetailsInner.js +1 -1
  438. package/dist/openapi/models/VerifyEmailRequest.d.ts +1 -1
  439. package/dist/openapi/models/VerifyEmailRequest.js +1 -1
  440. package/dist/openapi/models/WarningType.d.ts +1 -1
  441. package/dist/openapi/models/WarningType.js +1 -1
  442. package/dist/openapi/models/WebhookOperationContext.d.ts +1 -1
  443. package/dist/openapi/models/WebhookOperationContext.js +1 -1
  444. package/dist/openapi/models/WebhookPayload.d.ts +1 -1
  445. package/dist/openapi/models/WebhookPayload.js +1 -1
  446. package/dist/openapi/models/WorkflowArchiveResponse.d.ts +1 -1
  447. package/dist/openapi/models/WorkflowArchiveResponse.js +1 -1
  448. package/dist/openapi/models/WorkflowArchiveSuccessEnvelope.d.ts +1 -1
  449. package/dist/openapi/models/WorkflowArchiveSuccessEnvelope.js +1 -1
  450. package/dist/openapi/models/WorkflowCancelBillingEffect.d.ts +1 -1
  451. package/dist/openapi/models/WorkflowCancelBillingEffect.js +1 -1
  452. package/dist/openapi/models/WorkflowCancelResponse.d.ts +1 -1
  453. package/dist/openapi/models/WorkflowCancelResponse.js +1 -1
  454. package/dist/openapi/models/WorkflowCancelSuccessEnvelope.d.ts +1 -1
  455. package/dist/openapi/models/WorkflowCancelSuccessEnvelope.js +1 -1
  456. package/dist/openapi/models/WorkflowCreateRequest.d.ts +1 -1
  457. package/dist/openapi/models/WorkflowCreateRequest.js +1 -1
  458. package/dist/openapi/models/WorkflowCreateResponse.d.ts +1 -1
  459. package/dist/openapi/models/WorkflowCreateResponse.js +1 -1
  460. package/dist/openapi/models/WorkflowCreateSuccessEnvelope.d.ts +1 -1
  461. package/dist/openapi/models/WorkflowCreateSuccessEnvelope.js +1 -1
  462. package/dist/openapi/models/WorkflowCreditSummary.d.ts +1 -1
  463. package/dist/openapi/models/WorkflowCreditSummary.js +1 -1
  464. package/dist/openapi/models/WorkflowDownloadResponse.d.ts +1 -1
  465. package/dist/openapi/models/WorkflowDownloadResponse.js +1 -1
  466. package/dist/openapi/models/WorkflowDownloadSuccessEnvelope.d.ts +1 -1
  467. package/dist/openapi/models/WorkflowDownloadSuccessEnvelope.js +1 -1
  468. package/dist/openapi/models/WorkflowEdge.d.ts +1 -1
  469. package/dist/openapi/models/WorkflowEdge.js +1 -1
  470. package/dist/openapi/models/WorkflowExpiredResponse.d.ts +1 -1
  471. package/dist/openapi/models/WorkflowExpiredResponse.js +1 -1
  472. package/dist/openapi/models/WorkflowListResponse.d.ts +1 -1
  473. package/dist/openapi/models/WorkflowListResponse.js +1 -1
  474. package/dist/openapi/models/WorkflowListSuccessEnvelope.d.ts +1 -1
  475. package/dist/openapi/models/WorkflowListSuccessEnvelope.js +1 -1
  476. package/dist/openapi/models/WorkflowPauseRequiredAction.d.ts +1 -1
  477. package/dist/openapi/models/WorkflowPauseRequiredAction.js +1 -1
  478. package/dist/openapi/models/WorkflowPausedDetail.d.ts +1 -1
  479. package/dist/openapi/models/WorkflowPausedDetail.js +1 -1
  480. package/dist/openapi/models/WorkflowPausedDetailLinks.d.ts +1 -1
  481. package/dist/openapi/models/WorkflowPausedDetailLinks.js +1 -1
  482. package/dist/openapi/models/WorkflowProcessing.d.ts +1 -1
  483. package/dist/openapi/models/WorkflowProcessing.js +1 -1
  484. package/dist/openapi/models/WorkflowRestoreResponse.d.ts +1 -1
  485. package/dist/openapi/models/WorkflowRestoreResponse.js +1 -1
  486. package/dist/openapi/models/WorkflowRestoreSuccessEnvelope.d.ts +1 -1
  487. package/dist/openapi/models/WorkflowRestoreSuccessEnvelope.js +1 -1
  488. package/dist/openapi/models/WorkflowResumeResponse.d.ts +1 -1
  489. package/dist/openapi/models/WorkflowResumeResponse.js +1 -1
  490. package/dist/openapi/models/WorkflowResumeSuccessEnvelope.d.ts +1 -1
  491. package/dist/openapi/models/WorkflowResumeSuccessEnvelope.js +1 -1
  492. package/dist/openapi/models/WorkflowSource.d.ts +1 -1
  493. package/dist/openapi/models/WorkflowSource.js +1 -1
  494. package/dist/openapi/models/WorkflowStatus.d.ts +1 -1
  495. package/dist/openapi/models/WorkflowStatus.js +1 -1
  496. package/dist/openapi/models/WorkflowStatusResponse.d.ts +1 -1
  497. package/dist/openapi/models/WorkflowStatusResponse.js +1 -1
  498. package/dist/openapi/models/WorkflowStatusSuccessEnvelope.d.ts +1 -1
  499. package/dist/openapi/models/WorkflowStatusSuccessEnvelope.js +1 -1
  500. package/dist/openapi/models/WorkflowSummary.d.ts +1 -1
  501. package/dist/openapi/models/WorkflowSummary.js +1 -1
  502. package/dist/openapi/models/WorkflowSummaryJob.d.ts +1 -1
  503. package/dist/openapi/models/WorkflowSummaryJob.js +1 -1
  504. package/dist/openapi/models/WorkflowWarning.d.ts +1 -1
  505. package/dist/openapi/models/WorkflowWarning.js +1 -1
  506. package/dist/openapi/models/WorkflowWarningSeverity.d.ts +1 -1
  507. package/dist/openapi/models/WorkflowWarningSeverity.js +1 -1
  508. package/dist/openapi/models/index.d.ts +3 -4
  509. package/dist/openapi/models/index.js +3 -4
  510. package/dist/openapi/runtime.d.ts +1 -1
  511. package/dist/openapi/runtime.js +1 -1
  512. package/dist/operations/metadata-types.d.ts +1 -1
  513. package/dist/operations/thumbnail.d.ts +30 -7
  514. package/dist/operations/thumbnail.js +34 -17
  515. package/dist/operations/thumbnail.metadata.js +29 -1
  516. package/openapi/README.md +1 -1
  517. package/openapi/api.yaml +755 -214
  518. package/operation-capabilities/operation-capabilities.json +1 -1
  519. package/operations/schemas/compress.yaml +67 -10
  520. package/operations/schemas/thumbnail.yaml +100 -1
  521. package/package.json +7 -3
  522. package/dist/openapi/models/TierDefaultLimits.d.ts +0 -59
  523. package/dist/openapi/models/TierDefaults.d.ts +0 -66
package/openapi/api.yaml CHANGED
@@ -89,7 +89,7 @@ info:
89
89
  of truth instead of hardcoding magic numbers. A runtime
90
90
  `GET /api/uploads/limits` endpoint for dynamic discovery
91
91
  (per-tier / per-environment overrides) is a deferred follow-up.
92
- version: 2.194.0
92
+ version: 2.198.0
93
93
  contact:
94
94
  name: API Support
95
95
 
@@ -168,7 +168,14 @@ paths:
168
168
  $ref: '#/components/schemas/SingleUploadRequest'
169
169
  responses:
170
170
  '200':
171
- description: File uploaded successfully
171
+ description: |
172
+ File uploaded successfully.
173
+
174
+ ⚠️ **SAMPLE VALUES BELOW ARE ILLUSTRATIVE AND NOT A LIMITS SOURCE.**
175
+ `constraints_applied` shows the SHAPE of what the server echoes; the
176
+ figures are not maintained against the API's tier enum and must not
177
+ be read as current caps. A caller's real, override-aware limits come
178
+ from `GET /api/v2/account/limits`.
172
179
  content:
173
180
  application/json:
174
181
  schema:
@@ -215,7 +222,7 @@ paths:
215
222
  feature_tier_restricted: '#/components/schemas/FeatureTierRestrictedResponse'
216
223
  examples:
217
224
  tier_restriction_mime:
218
- summary: Free tier uploading a video
225
+ summary: A caller's tier does not permit the uploaded MIME type
219
226
  value:
220
227
  success: false
221
228
  error: "Your tier does not permit this MIME type"
@@ -313,16 +320,24 @@ paths:
313
320
  upload_duration_exceeds_tier: '#/components/schemas/UploadDurationExceedsTierResponse'
314
321
  examples:
315
322
  size_exceeds_tier:
316
- summary: Free-tier caller uploads a 200MB file (cap is 10 MiB)
323
+ summary: >-
324
+ Envelope shape only — SAMPLE VALUES ARE ILLUSTRATIVE AND NOT
325
+ A LIMITS SOURCE. The figures below are not maintained against
326
+ the API's tier enum; a caller's real, override-aware limits
327
+ come from GET /api/v2/account/limits.
317
328
  value:
318
329
  success: false
319
- error: "Upload exceeds size cap for free tier (max 10 MiB; pro permits up to 5 GiB)."
330
+ error: "Upload exceeds the size cap for your tier."
320
331
  error_type: "upload_size_exceeds_tier"
321
332
  current_tier: "free"
322
- max_size_bytes: 10485760
333
+ max_size_bytes: 1048576
323
334
  required_tier: "pro"
324
335
  duration_exceeds_tier:
325
- summary: Pro-tier caller uploads a 30-minute video (cap is 5min on short_form)
336
+ summary: >-
337
+ Envelope shape only — SAMPLE VALUES ARE ILLUSTRATIVE AND NOT
338
+ A LIMITS SOURCE. The authoritative duration bands are
339
+ generated into each operation schema's processing_class
340
+ constraints.
326
341
  value:
327
342
  success: false
328
343
  error: "Upload exceeds short_form duration cap (max 5 minutes; long_form permits up to 12 hours)."
@@ -2418,13 +2433,24 @@ paths:
2418
2433
  # is the integration timeout firing to the millisecond. Measured AND
2419
2434
  # mechanistically explained, which is what the gate asked for.
2420
2435
  #
2421
- # ⚠️ THERE IS STILL DELIBERATELY NO PRODUCTION ENTRY, and the reason is
2422
- # UNCHANGED by the staging proof: PROD HAS NEVER HAD A PROVEN STREAM.
2423
- # Declaring a prod host would be a contract fact pointing at something
2424
- # unproven, which is worse than the gap because it LOOKS resolved — the
2425
- # same error this block exists to prevent, committed in the opposite
2426
- # direction. The gate is the same one, applied to prod: a first-byte
2427
- # timestamp on a heartbeat from the prod stream host.
2436
+ # HISTORY, kept because the reasoning is still live even though its
2437
+ # conclusion is not: from 2026-08-14 to 2026-08-18 there was DELIBERATELY
2438
+ # NO PRODUCTION ENTRY, on the rule that declaring a prod host would be a
2439
+ # contract fact pointing at something unproven — worse than the gap
2440
+ # because it LOOKS resolved.
2441
+ #
2442
+ # ⚠️ THAT RULE IS NOT REPEALED. What ended the withholding is that the gap
2443
+ # was found to be ALREADY OCCUPIED: `compression_frontend`'s prod deploy
2444
+ # hardcodes `VITE_SSE_BASE_URL` to the prod stream host, so the convention
2445
+ # was live and undeclared, and silence was preventing consumers from
2446
+ # KNOWING about a host they already depended on. The rule is now satisfied
2447
+ # a different way — the prod entry states, in itself, which half is proven
2448
+ # (ROUTING) and which is not (DURATION, the property the split host exists
2449
+ # for). See its description.
2450
+ #
2451
+ # ⇒ Do NOT read the prod entry as "prod SSE is proven". If you are about
2452
+ # to write that sentence, the discriminator is named in the entry and has
2453
+ # not been run.
2428
2454
  servers:
2429
2455
  - url: http://localhost:8080
2430
2456
  # WHICH ROOT SERVER THIS ENTRY REPLACES. Without it a client has to
@@ -2440,6 +2466,79 @@ paths:
2440
2466
  do NOT reproduce the split-host topology, so a client that works
2441
2467
  locally has **not** exercised the cross-origin path. Treat a local
2442
2468
  pass as evidence about your code and not about the routing.
2469
+ - url: https://stream.giveitsmaller.com
2470
+ x-replaces: https://api.giveitsmaller.com
2471
+ description: |
2472
+ Production stream host. Declared 2026-08-18 after **routing** was
2473
+ measured; see the two headings below for exactly what that does and
2474
+ does not cover.
2475
+
2476
+ 🔴 **THIS ENTRY WAS DELIBERATELY WITHHELD FROM 2026-08-14 TO
2477
+ 2026-08-18, AND THE REASON IT LANDED IS NOT THAT THE ORIGINAL GATE
2478
+ WAS MET.** The gate was *"prod has never had a proven stream; a
2479
+ declared host would be a contract fact pointing at nothing — worse
2480
+ than the gap, because it looks resolved."* What changed is that **the
2481
+ gap was found to be already occupied**:
2482
+ `compression_frontend/.github/workflows/deploy-env.yml` hardcodes
2483
+ `VITE_SSE_BASE_URL: https://stream.giveitsmaller.com` for prod, so
2484
+ **the production frontend has been routing SSE to this host all
2485
+ along, undeclared.** Contract silence was not preventing anyone from
2486
+ depending on the host; it was preventing them from *knowing* about
2487
+ it — which is the undeclared per-client convention this whole
2488
+ declaration exists to end.
2489
+
2490
+ ### WHAT IS MEASURED (2026-08-18, prod, by `compression_e2e`)
2491
+
2492
+ - An **authenticated stream against a real prod workflow** returned
2493
+ `200` with `content-type: text/event-stream`, replayed
2494
+ `operation.progress` at 10 / 50 / 90, then `operation.completed`
2495
+ carrying a real presigned S3 `download_url`, `size_bytes` 246217,
2496
+ `compression_ratio` 0.3288 — then `job.completed` and
2497
+ `workflow.completed`.
2498
+ - An **unauthenticated** request returns the full localised error
2499
+ envelope (`WORKFLOW_NOT_FOUND` with `message_key`,
2500
+ `Content-Language: en-GB`, `Vary`, HSTS), byte-identical to
2501
+ `api.giveitsmaller.com` — so this host reaches the **real
2502
+ application**, not an edge stub or a parked custom domain.
2503
+ - **CORS is correct on both hosts**: preflight `200`,
2504
+ `Access-Control-Allow-Origin` exactly
2505
+ `https://www.giveitsmaller.com`, `Allow-Credentials: true`,
2506
+ `Authorization` among the allowed headers.
2507
+
2508
+ ### ⚠️ WHAT IS **NOT** MEASURED: DURATION — THE PROPERTY THIS HOST EXISTS FOR
2509
+
2510
+ **The split host exists because `api.*` is an API Gateway HTTP API
2511
+ with a 30-second hard ceiling** (staging measured it `503`-ing at
2512
+ **29.35s**, to the millisecond) and `responseTransferMode: STREAM` is
2513
+ REST-only. **Nothing has yet shown that a stream on THIS host
2514
+ survives past that ceiling.**
2515
+
2516
+ The attempt was made and could not answer: prod holds exactly one
2517
+ workflow and it was already **terminal**, so the server correctly
2518
+ replayed history and closed on the terminal frame — total elapsed
2519
+ **0.355s**. ⇒ **A stream that closes at 0.4s because the job finished
2520
+ says nothing about whether a stream that WANTED to stay open would
2521
+ survive to 35s.** It is a non-answer, not a negative result.
2522
+
2523
+ **The discriminator, named so nobody re-derives it:** a
2524
+ **NON-TERMINAL** prod job, streamed and held, reporting either the
2525
+ last-byte timestamp or that the connection was still open at **35s+**.
2526
+ One request; no browser needed. Until then, treat long-lived prod
2527
+ streams as unproven on this host — and note that a client falling
2528
+ back to `api.giveitsmaller.com` is *provably* subject to the 30s
2529
+ ceiling, so this entry cannot be worse than the fallback.
2530
+
2531
+ ⚠️ **The BROWSER path is also unmeasured.** The evidence above is
2532
+ HTTP-layer. The CORS preflight is correct, which is the part a
2533
+ browser needs, but no browser client has been observed consuming this
2534
+ stream in production.
2535
+
2536
+ **This entry declares ROUTING. It does not assert that prod SSE
2537
+ works** — do not let it be quoted as though it did.
2538
+
2539
+ The CORS scope, auth and cross-origin caveats stated on the staging
2540
+ entry above apply here too, with one difference already noted there:
2541
+ **prod's API host has never permitted `localhost`.**
2443
2542
  - url: https://stream.staging.giveitsmaller.com
2444
2543
  x-replaces: https://api.staging.giveitsmaller.com
2445
2544
  description: |
@@ -2519,10 +2618,18 @@ paths:
2519
2618
  the preflight response.
2520
2619
 
2521
2620
  **None of that is verified by this contract, and contracts has not
2522
- measured it.** ⇒ **A browser client SHOULD prefer `bearerAuth` or
2523
- the anonymous capability header on this host**, and should treat
2524
- cookie-based session auth over it as unproven until somebody
2525
- measures a credentialed cross-origin stream.
2621
+ measured it.**
2622
+
2623
+ 🔴 **This passage used to conclude "a browser client SHOULD prefer
2624
+ `bearerAuth` or the anonymous capability header on this host, and
2625
+ should treat cookie-based session auth as unproven". DO NOT
2626
+ REINSTATE IT.** For an **owned** stream the shipped browser client
2627
+ has no bearer token on its runtime path at all, so that advice named
2628
+ a credential the caller does not possess — leaving a logged-in user
2629
+ with nothing to send. See **AUTH ON THE STREAM HOST** on the
2630
+ operation below, which is the single place this question is
2631
+ answered; the cross-origin caveats above remain true and are what
2632
+ that section is qualified by.
2526
2633
  description: |
2527
2634
  Server-Sent Events endpoint for real-time workflow progress. The server pushes
2528
2635
  events as workflow, job, and operation statuses change.
@@ -2580,7 +2687,85 @@ paths:
2580
2687
  the `data:` JSON payload of each event. The SSE envelope framing itself
2581
2688
  (the `id:` and `event:` lines) is transport-level and intentionally
2582
2689
  **not** schema-described.
2690
+
2691
+ ### AUTH ON THE STREAM HOST: the CREDENTIAL decides, not the caller
2692
+
2693
+ **Two axes, and conflating them is what made two earlier versions of this
2694
+ note wrong.** *Which credential is available to you* depends on the
2695
+ workflow and your runtime. *What the browser then requires of the
2696
+ request* depends only on **which credential you actually send**.
2697
+
2698
+ **Which credential you have:**
2699
+
2700
+ | workflow | caller | credential |
2701
+ |---|---|---|
2702
+ | null-owner | any runtime, server or browser | **`X-Workflow-Capability`** — bearer does NOT establish workflow ownership and is not a substitute |
2703
+ | owned | server-side | **`bearerAuth`** (or `sessionAuth`) |
2704
+ | owned | the shipped browser client | **the session cookie** — it carries no bearer token on its runtime path, so this is the only credential it possesses |
2705
+
2706
+ ⚠️ **The last row describes the SHIPPED CLIENT, not what the endpoint
2707
+ supports.** The endpoint accepts `bearerAuth` for an owned workflow; a
2708
+ browser build that obtains a bearer token can use it.
2709
+
2710
+ **What the credential then requires of the request:**
2711
+
2712
+ | credential sent | `credentials` mode | why |
2713
+ |---|---|---|
2714
+ | any **header** (bearer or capability) | **`omit`** | the header carries the auth; `include` would impose the credentialed-CORS requirement for nothing |
2715
+ | the **session cookie** | **`include`** | the cookie *is* the credential, and the browser only sends it in this mode |
2716
+
2717
+ ⇒ **The mode follows the CREDENTIAL, not the ownership and not the
2718
+ runtime.** An owned stream authenticated by bearer uses `omit`; only a
2719
+ cookie-authenticated request needs `include`.
2720
+
2721
+ **Where a header credential is available it is already the right answer** —
2722
+ headers are immune to `SameSite` and third-party-cookie policy and need no
2723
+ `Access-Control-Allow-Credentials`. What is NOT yet available is a
2724
+ **browser** bearer credential for an **owned** stream, and until one
2725
+ exists that one cell of the matrix cannot act on the advice.
2726
+
2727
+ 🔴 **Two earlier versions of this note stated a destination in the present
2728
+ tense and would have caused harm.** One concluded *"a browser client
2729
+ SHOULD prefer `bearerAuth` or the anonymous capability header on this
2730
+ host"*; a later revision restated it as *"cookie session auth is NOT
2731
+ supported on the stream host"*. **Both named a credential an owned browser
2732
+ caller does not possess**, and an implementer following either would have
2733
+ left every logged-in user with nothing to send. Verified in the shipped
2734
+ client, not inferred. **DO NOT REINSTATE EITHER.**
2735
+
2736
+ ⚠️ **`sessionAuth` therefore stays in the `security` list, and so does the
2737
+ anonymous `{}` alternative, pending the modelling fix noted below.**
2738
+ OpenAPI has **no per-server `security`**: an operation-level `servers`
2739
+ block does not scope it, so one list covers this operation on every host.
2740
+
2741
+ ⚠️ **`X-Workflow-Capability` is currently a HEADER PARAMETER, not a
2742
+ security scheme**, so the machine-readable contract does not express that
2743
+ a null-owner read requires it — the `{}` alternative advertises
2744
+ credential-free access that a successful null-owner read does not
2745
+ actually have. Promoting it to an `apiKey` scheme is available and is
2746
+ tracked separately; naming it in prose is documentation, and treating
2747
+ that as a declaration is the mistake this note exists to prevent.
2748
+
2749
+ ⚠️ **`credentials: 'include'` is a property of the REQUEST MODE, not of
2750
+ the credential you meant to send.** A `fetch` issued with it makes the
2751
+ browser require the response to carry `Access-Control-Allow-Credentials:
2752
+ true` **and** a non-wildcard origin — **or it blocks the response, whether
2753
+ or not a cookie was actually sent**. So a header-authenticated request
2754
+ that keeps `include` is browser-blocked against a host that does not
2755
+ return the header **while its authentication is perfectly fine** — a
2756
+ failure that reads as an auth bug and is not one. The shipped browser
2757
+ client already splits on exactly this.
2583
2758
  operationId: streamWorkflowEvents
2759
+ # ⚠️ `sessionAuth` IS LOAD-BEARING — the session cookie is the SOLE
2760
+ # credential for an OWNED stream on the shipped browser client, which
2761
+ # carries no bearer token on its runtime path. Do not remove it on the
2762
+ # strength of a "prefer headers" ruling; that ruling is a direction, and
2763
+ # for owned streams there is currently nothing to point at.
2764
+ # `{}` is the anonymous alternative and is currently OVER-PERMISSIVE: a
2765
+ # successful null-owner read requires `X-Workflow-Capability`, which is a
2766
+ # header PARAMETER rather than a security scheme, so the security list
2767
+ # cannot yet say so. Tracked separately.
2768
+ # See AUTH ON THE STREAM HOST in the description above.
2584
2769
  security: [{}, {bearerAuth: []}, {sessionAuth: []}] # optional (anon-OK; identity-scoped to workflow owner)
2585
2770
  x-identity-scoped: true # workflow-ownership-scoped per ADR-0016 D3
2586
2771
  tags:
@@ -2666,6 +2851,161 @@ paths:
2666
2851
  Server-Sent Events stream. Each event has an `event` field (type)
2667
2852
  and a `data` field (JSON payload). See endpoint description for
2668
2853
  event types and payload shapes.
2854
+ '429':
2855
+ description: |
2856
+ **The CALLER's own concurrent-stream allowance is exhausted.**
2857
+
2858
+ Consistent with `LONG_FORM_CONCURRENCY_LIMIT_EXCEEDED`, which this
2859
+ contract already returns `429` for and describes as *"the caller's
2860
+ tier concurrency allowance is exhausted"*. **Same semantics, same
2861
+ code** — this caller is holding too many streams open.
2862
+
2863
+ ⚠️ **NOT for a global-capacity refusal.** `429` tells a caller they
2864
+ went too fast; a caller who has opened nothing and is refused
2865
+ because the pool is full has not, and sending them to a slow-down
2866
+ remedy is a lie. That case is `503`.
2867
+ headers:
2868
+ Retry-After:
2869
+ description: Seconds to wait. Delta-seconds, not an HTTP-date.
2870
+ schema:
2871
+ type: integer
2872
+ content:
2873
+ application/json:
2874
+ schema:
2875
+ $ref: '#/components/schemas/ErrorEnvelope'
2876
+ example:
2877
+ success: false
2878
+ error: SSE_CONNECTION_LIMIT_EXCEEDED
2879
+ message: Too many open event streams for this caller.
2880
+ '503':
2881
+ description: |
2882
+ **Global stream capacity is exhausted — nothing about this caller.**
2883
+
2884
+ 🔴 **The cap this exists for is not a rate.** `events_stream` limits
2885
+ how fast streams START, not how many are OPEN, and a stream holds
2886
+ one PHP-FPM worker for its entire life. At 10 starts/min against a
2887
+ 570s deadline a single caller sustains roughly 95 concurrent streams
2888
+ on a 50-worker pool **without exceeding any documented limit** —
2889
+ uploads, `/status`, auth and the health probes queue behind it.
2890
+ ⇒ **An ordinary client can exhaust the pool using a documented
2891
+ feature within its documented limits.** No malice required.
2892
+
2893
+ 🔴 **RECONNECT BEHAVIOUR DEPENDS ON THE CLIENT KIND, AND SAYING
2894
+ SO IS THE WHOLE POINT OF THIS BLOCK.** A `text/event-stream`
2895
+ endpoint is not necessarily consumed by an `EventSource`. The
2896
+ WHATWG rules below are **user-agent behaviour of `EventSource`**
2897
+ and hold for **nothing else** — a `fetch`-based reader supplies its
2898
+ own policy, and the two behave oppositely under refusal.
2899
+
2900
+ **(a) A NATIVE `EventSource`.** From the WHATWG HTML spec,
2901
+ Server-sent events (read 2026-08-22, api searched it and this repo
2902
+ verified it independently rather than relaying):
2903
+
2904
+ - *"if res's status is not 200, or if res's `Content-Type` is not
2905
+ `text/event-stream`, then fail the connection."*
2906
+ - *"Once the user agent has failed the connection, it does not
2907
+ attempt to reconnect."*
2908
+ - *"…if res is not a network error, then reestablish the
2909
+ connection."* — this is `processEventSourceEndOfBody`, i.e. a
2910
+ **clean EOF on an already-established 200 stream.**
2911
+
2912
+ ⇒ For this client kind, refusing with a status does not storm, and
2913
+ **accept-then-close-with-an-in-band-error IS the reconnect path** —
2914
+ a clean EOF on an established stream is precisely what the spec
2915
+ reestablishes. ⭐ **The shape that reads as the gentler option is
2916
+ the one that amplifies**, and the intuition is backwards.
2917
+
2918
+ ⚠️ Its cost, which must not be sold as graceful degradation: a
2919
+ refused stream **dead-ends**, permanently, with no retry of its
2920
+ own. ⇒ **Such a UI must treat refusal as TERMINAL and offer an
2921
+ explicit user-visible retry — never a spinner**, which would wait
2922
+ forever on a connection that is never coming back. It also **cannot
2923
+ read this status** (`EventSource` does not expose it to page
2924
+ script), so it cannot tell `503` from `500`.
2925
+
2926
+ **(b) A `fetch`-BASED READER — WHICH IS WHAT OUR FRONTEND IS.**
2927
+ Measured at `compression_frontend` `origin/main` on 2026-08-25 by
2928
+ two independent parties: **zero `EventSource` references** across
2929
+ its source tree (positive control on the same enumeration: several
2930
+ files reference this endpoint), a plain `fetch()` whose own comment
2931
+ says *"a direct fetch, not an SDK call"*. It reads
2932
+ `response.status` fine.
2933
+
2934
+ Its refusal behaviour, **as a SHAPE — the counts and intervals are
2935
+ configurable defaults in that repo and are deliberately not
2936
+ restated here, because a number copied across a repo boundary rots
2937
+ silently**: a non-200 is raised as a *transport error*, retried a
2938
+ bounded number of times on a delay, and then falls through to
2939
+ `/status` polling with **adaptive backoff** — the interval GROWS
2940
+ while the server reports no movement.
2941
+
2942
+ ⚠️ **And the `/status` poll is NOT started by the fallback.** It
2943
+ runs **in parallel from the outset**, as resilience against a
2944
+ gateway that cannot proxy SSE, and **self-cancels on the stream's
2945
+ first event.** A refused stream never delivers one — so **refusal
2946
+ does not start a poll, it prevents an already-running poll from
2947
+ being cancelled.**
2948
+
2949
+ 🔴 **SO REFUSAL TRADES CONTINUOUS WORKER OCCUPANCY FOR A HIGHER
2950
+ REQUEST RATE.** Both halves matter: a held stream pins one PHP-FPM
2951
+ worker for its whole life and refusal genuinely sheds that — a
2952
+ short poll is not a held connection — while that client's
2953
+ connection attempts and polls go **up**.
2954
+ ⚠️ **Do not read either half alone.** "Refusal sheds load" invites
2955
+ a cap whose success metric moves the wrong way; "refusal increases
2956
+ load" argues against having a cap at all, and the occupancy it
2957
+ sheds is the resource this limit exists for.
2958
+
2959
+ ⚠️ **THAT IS PER-CLIENT AND MEASURED. THE AGGREGATE IS NEITHER.**
2960
+ Whether refusing many clients at once produces a synchronised burst
2961
+ is **UNMEASURED** — the retry delay is a fixed configured interval
2962
+ with no jitter, so refusals issued together are retried together,
2963
+ and nothing here has observed what that does in aggregate. **Do not
2964
+ read "not a storm" out of this section; it says the per-client cost
2965
+ is bounded and says nothing about the fleet.**
2966
+
2967
+ 📌 **WHAT A REFUSED `fetch` CLIENT SHOULD DO INSTEAD IS NOT YET
2968
+ SPECIFIED** — including whether `Retry-After` governs a fallback
2969
+ poll interval and not only a reconnect. Falling back to polling
2970
+ is also load, merely cheaper. Open on
2971
+ [`rLCBjojv`](https://trello.com/c/rLCBjojv); **this block states the
2972
+ measured behaviour and deliberately does not invent the
2973
+ obligation.**
2974
+
2975
+ 📌 **THE POPULATIONS SPLIT BY READER KIND, NOT BY
2976
+ BROWSER-VERSUS-NOT.** The WHATWG rule covers **native
2977
+ `EventSource` consumers** and nothing else. **A custom reader is
2978
+ safe only by its own code, inside a browser or outside one** — and
2979
+ a retry loop treating `429`/`503` as retryable on a fixed interval
2980
+ is where a storm is reachable. ⚠️ **Our own frontend is in that
2981
+ population, not exempt from it.**
2982
+
2983
+ ✅ **For OUR SDKs that is measured, not assumed** (sdks,
2984
+ 2026-08-22, driven through the BUILT client with a stubbed
2985
+ transport and a positive control): `429`, `503` and a `429` with no
2986
+ `Retry-After` each produce **exactly one request**; the control
2987
+ `200` also produces one, proving the stub was reached.
2988
+ `GislClient.request()` has no retry layer, `streamEvents` reaches
2989
+ none of the upload/probe retry predicates, and there is no
2990
+ Last-Event-ID reconnection in either language.
2991
+ ⚠️ **That is a property of the current SDK, not of the contract** —
2992
+ it can be undone by an ordinary change to a retry policy, and this
2993
+ endpoint would not notice.
2994
+ headers:
2995
+ Retry-After:
2996
+ description: |
2997
+ Seconds to wait before retrying. Delta-seconds, not an
2998
+ HTTP-date. **Also unreadable by `EventSource`** — see above.
2999
+ schema:
3000
+ type: integer
3001
+ content:
3002
+ application/json:
3003
+ schema:
3004
+ $ref: '#/components/schemas/ErrorEnvelope'
3005
+ example:
3006
+ success: false
3007
+ error: SSE_CAPACITY_EXHAUSTED
3008
+ message: Event stream capacity is temporarily exhausted.
2669
3009
  '404':
2670
3010
  description: Workflow not found
2671
3011
  content:
@@ -5004,6 +5344,70 @@ paths:
5004
5344
  $ref: '#/components/schemas/ErrorEnvelope'
5005
5345
 
5006
5346
  /api/auth/profile:
5347
+ get:
5348
+ summary: Get the authenticated identity (whoami)
5349
+ description: |
5350
+ Returns the caller's own identity. **This endpoint SHIPS and was
5351
+ undocumented until 2026-08-22** — the contract described only `PATCH`
5352
+ on this path, and three sessions independently concluded that no
5353
+ whoami capability existed because they read the contract rather than
5354
+ the API. **A contract that omits a shipped endpoint is exactly as
5355
+ dangerous as one that documents a missing one.**
5356
+
5357
+ ⚠️ **Documented from the producer, not from a test.** The response
5358
+ shape below is taken from `ProfileController::profile()` in
5359
+ `compression_api`. An e2e test asserts only `data.user.id` and
5360
+ `data.user.email`; writing the schema from it would have documented
5361
+ two of eight fields and called the rest absent.
5362
+
5363
+ 🔴 **`tier` is emitted through `UserTier::canonicalValue()`**, which
5364
+ returns the WIRE spelling of the base tier — see `UserTier` for the
5365
+ `basic`/`free` transition and why the two spellings are one tier.
5366
+ operationId: getProfile
5367
+ security:
5368
+ - bearerAuth: []
5369
+ - sessionAuth: []
5370
+ x-identity-scoped: true
5371
+ tags:
5372
+ - Auth
5373
+ responses:
5374
+ '200':
5375
+ description: The authenticated identity.
5376
+ content:
5377
+ application/json:
5378
+ schema:
5379
+ type: object
5380
+ required: [success, data]
5381
+ properties:
5382
+ success:
5383
+ type: boolean
5384
+ enum: [true]
5385
+ data:
5386
+ type: object
5387
+ required: [user]
5388
+ properties:
5389
+ user:
5390
+ $ref: '#/components/schemas/AuthenticatedIdentity'
5391
+ '401':
5392
+ description: No authenticated principal.
5393
+ content:
5394
+ application/json:
5395
+ schema:
5396
+ $ref: '#/components/schemas/ErrorEnvelope'
5397
+ '404':
5398
+ description: |
5399
+ The authenticated principal no longer resolves to a stored user
5400
+ (`error: USER_NOT_FOUND`).
5401
+ content:
5402
+ application/json:
5403
+ schema:
5404
+ $ref: '#/components/schemas/ErrorEnvelope'
5405
+ '500':
5406
+ description: Internal server error.
5407
+ content:
5408
+ application/json:
5409
+ schema:
5410
+ $ref: '#/components/schemas/ErrorEnvelope'
5007
5411
  patch:
5008
5412
  summary: Update the authenticated user's profile
5009
5413
  description: |
@@ -5748,7 +6152,13 @@ paths:
5748
6152
  $ref: '#/components/schemas/AccountLimitsSuccessEnvelope'
5749
6153
  examples:
5750
6154
  free_tier_defaults:
5751
- summary: Free tier, no overrides (effective == tier_default)
6155
+ summary: >-
6156
+ Free tier, no overrides (effective == tier_default) — SAMPLE
6157
+ VALUES ARE ILLUSTRATIVE AND NOT A LIMITS SOURCE. The field is
6158
+ named tier_default, which makes a stale figure here read as
6159
+ authoritative; the numbers are not maintained against the
6160
+ API's tier enum. The response itself is the source, per
6161
+ caller.
5752
6162
  value:
5753
6163
  success: true
5754
6164
  data:
@@ -5763,7 +6173,11 @@ paths:
5763
6173
  tier_default: 1073741824
5764
6174
  overridden: false
5765
6175
  enterprise_with_upload_override:
5766
- summary: Enterprise tier with a raised per-account upload override
6176
+ summary: >-
6177
+ Enterprise tier with a raised per-account upload override —
6178
+ SAMPLE VALUES ARE ILLUSTRATIVE AND NOT A LIMITS SOURCE. It
6179
+ demonstrates the override SHAPE (effective diverging from
6180
+ tier_default), not the current figures.
5767
6181
  value:
5768
6182
  success: true
5769
6183
  data:
@@ -7385,15 +7799,23 @@ components:
7385
7799
  (`UserTier.maxFileSizeBytes` — the request-level tier quota the
7386
7800
  upload endpoints enforce). **Distinct** from the per-operation
7387
7801
  processing ceiling `max_input_size_bytes` in operation schemas
7388
- (different axis AND number). Tier defaults: free 10 MiB, pro 5 GiB,
7389
- enterprise 100 GiB.
7802
+ (different axis AND number).
7803
+ ⚠️ **The per-tier byte defaults are deliberately NOT restated here.**
7804
+ This line used to list them for `free` / `pro` / `enterprise` and
7805
+ **silently omitted `max`** — a tier the `UserTier` enum declares. The
7806
+ response itself carries the answer per caller (`tier_default` beside
7807
+ `effective`), which is override-aware in a way a static table can
7808
+ never be.
7390
7809
  - `max_total_input_size_bytes`: the effective merge combined-input
7391
7810
  size cap (the summed-inputs ceiling). Same key as the
7392
7811
  operation-schema merge band; the band is processing-class +
7393
- tier dependent (`short_form_concat` baseline 1 GiB; the
7394
- `long_form_re_encode` band where the tier permits it — Pro 5 GB,
7395
- Enterprise 120 GB). The server resolves the effective value for
7396
- the caller.
7812
+ tier dependent. **The server resolves the effective value for the
7813
+ caller** and returns it here — that is the point of this endpoint.
7814
+ ⚠️ **A THIRD restated per-tier table lived on this line** (it named
7815
+ two tiers' band ceilings and, like the other two, omitted `max`). The
7816
+ machine-readable source is `per_tier_constraints` on the operation
7817
+ schema's `processing_class`; it is generated, so it cannot drift from
7818
+ the schemas the way a sentence here does.
7397
7819
  required:
7398
7820
  - tier
7399
7821
  - limits
@@ -7421,133 +7843,6 @@ components:
7421
7843
  # AccountLimitEntry.
7422
7844
  $ref: '#/components/schemas/AccountLimitEntry'
7423
7845
 
7424
- MediaCategory:
7425
- type: string
7426
- enum: [image, video, audio, document]
7427
- description: |
7428
- Coarse input media family, as used by the tier-default surface.
7429
- **Not** a MIME type and **not** an operation `mime_group` — those are
7430
- finer-grained and live in the operation schemas. This vocabulary
7431
- exists so a client can filter a file picker without enumerating MIMEs.
7432
-
7433
- TierDefaults:
7434
- type: object
7435
- additionalProperties: false
7436
- description: |
7437
- The **published default limits**, readable by an ANONYMOUS caller.
7438
-
7439
- **Why this exists separately from `GET /api/v2/account/limits`:** that
7440
- endpoint is per-account and override-aware, so it requires auth and
7441
- returns `401` to an anonymous caller — **correctly**, because
7442
- `effective` / `tier_default` / `overridden` is meaningless without an
7443
- account. What a logged-out visitor needs is the **tier defaults**,
7444
- which are not per-account. This publishes AS DATA what the `UserTier`
7445
- description already publishes as prose.
7446
-
7447
- **The server is authoritative for the values.** This contract declares
7448
- the SHAPE; the numbers are computed per environment and per tier
7449
- model, and a client MUST read them here rather than hard-coding a
7450
- table (the drift this field exists to end).
7451
- required:
7452
- - media_categories
7453
- - by_audience
7454
- properties:
7455
- media_categories:
7456
- type: array
7457
- minItems: 1
7458
- uniqueItems: true
7459
- items:
7460
- $ref: '#/components/schemas/MediaCategory'
7461
- description: |
7462
- The input media families available **to every audience,
7463
- including anonymous**. Declared ONCE, not per-tier, because it
7464
- does not vary — hub decision 25 made audio universal, and there
7465
- is now no tier boundary at which the category axis changes.
7466
-
7467
- ⚠️ **Deliberately NOT a per-audience allow-list.** A structure
7468
- with one row per tier, every row identical, is a gate whose every
7469
- row is open — it reads as an entitlement mechanism while
7470
- encoding no entitlement, and the next reader maintains it as
7471
- though it did. If a future tier DOES restrict categories, this
7472
- field moves into `by_audience` in a deliberate change, and that
7473
- change is where the restriction gets argued.
7474
- by_audience:
7475
- type: object
7476
- additionalProperties: false
7477
- description: |
7478
- The limits that genuinely DO vary, keyed by audience. Contains
7479
- only axes with real variance; an axis that is uniform belongs
7480
- beside `media_categories`, not here.
7481
-
7482
- **`anonymous` is a key here but deliberately NOT a `UserTier`
7483
- value.** `UserTier` is a subscription tier and anonymous is the
7484
- ABSENCE of one — putting it in that enum would place a
7485
- non-subscription value inside the ordering that drives upgrade
7486
- prompts (`free < pro < max < enterprise`), where it has no
7487
- position.
7488
- ⚠️ **And keeping them distinct is not pedantry — the conflation
7489
- has already shipped once.** This endpoint's `user_tier`
7490
- description used to say anonymous callers "receive the `free`
7491
- tier baseline view", which became false the moment the two were
7492
- allowed to differ. **A vocabulary that cannot express the
7493
- difference invites prose asserting they are the same.**
7494
- required:
7495
- - anonymous
7496
- - free
7497
- - pro
7498
- - max
7499
- - enterprise
7500
- properties:
7501
- anonymous:
7502
- $ref: '#/components/schemas/TierDefaultLimits'
7503
- free:
7504
- $ref: '#/components/schemas/TierDefaultLimits'
7505
- pro:
7506
- $ref: '#/components/schemas/TierDefaultLimits'
7507
- max:
7508
- $ref: '#/components/schemas/TierDefaultLimits'
7509
- enterprise:
7510
- $ref: '#/components/schemas/TierDefaultLimits'
7511
-
7512
- TierDefaultLimits:
7513
- type: object
7514
- additionalProperties: false
7515
- description: |
7516
- One audience's default limits. **Defaults, not entitlements** — a
7517
- specific account may carry an override, which only
7518
- `GET /api/v2/account/limits` can report.
7519
- required:
7520
- - max_upload_size_bytes
7521
- - max_duration_seconds
7522
- properties:
7523
- max_upload_size_bytes:
7524
- type: integer
7525
- format: int64
7526
- minimum: 1
7527
- description: |
7528
- Per-FILE upload cap. Same axis as
7529
- `AccountLimits.limits.max_upload_size_bytes`.
7530
-
7531
- ⚠️ **A client MUST NOT treat this as the only size bound.** The
7532
- per-operation processing ceilings (`max_input_size_bytes` in the
7533
- operation schemas) are a **different axis and a different
7534
- number**, and can be SMALLER than this cap — an upload that
7535
- succeeds may still be rejected at operation time. A picker that
7536
- shows one number without the other will let a user pick a file
7537
- the product cannot process.
7538
- max_duration_seconds:
7539
- type: [integer, "null"]
7540
- minimum: 0
7541
- description: |
7542
- Per-upload duration cap for time-based media. `null` where the
7543
- audience has no duration cap.
7544
-
7545
- ⚠️ **DISTINCT from `processing_class.short_form.max_input_duration`
7546
- (`PT5M`) in the operation schemas, which it may numerically
7547
- equal.** That is the short-form/long-form PROCESSING boundary and
7548
- applies to every audience; this is an entitlement. Two concepts,
7549
- one integer — read this one for entitlement.
7550
-
7551
7846
  AccountLimitEntry:
7552
7847
  type: object
7553
7848
  additionalProperties: false
@@ -8414,54 +8709,165 @@ components:
8414
8709
  # USER TIER + TIER RESTRICTION ENVELOPES
8415
8710
  # ============================================
8416
8711
 
8712
+ AuthenticatedIdentity:
8713
+ type: object
8714
+ description: |
8715
+ The caller's own identity, as returned by `GET /api/auth/profile`.
8716
+
8717
+ **Documented from `ProfileController::profile()` in `compression_api`,
8718
+ 2026-08-22, after the endpoint was found to ship undocumented.**
8719
+ Nullability is taken from `UserRecord`'s constructor promotion, not
8720
+ inferred from a sample response — a field that happens to be populated
8721
+ in one response says nothing about whether it can be null.
8722
+ required:
8723
+ - id
8724
+ - email
8725
+ - tier
8726
+ - email_verified
8727
+ - created_at
8728
+ properties:
8729
+ id:
8730
+ type: string
8731
+ description: Stable identifier for the user.
8732
+ email:
8733
+ type: string
8734
+ format: email
8735
+ name:
8736
+ type: string
8737
+ nullable: true
8738
+ description: Display name. Nullable — `UserRecord::$name` defaults to null.
8739
+ tier:
8740
+ allOf:
8741
+ - $ref: '#/components/schemas/UserTier'
8742
+ description: |
8743
+ 🔴 **Emitted through `UserTier::canonicalValue()`**, which returns the
8744
+ WIRE spelling of the base tier. See `UserTier` for why `basic` and
8745
+ `free` are one tier under two names and must rank identically.
8746
+ email_verified:
8747
+ type: boolean
8748
+ description: |
8749
+ Derived — true iff `UserRecord::$emailVerifiedAt` is set. The
8750
+ timestamp itself is NOT exposed on this endpoint.
8751
+ pending_email:
8752
+ type: string
8753
+ format: email
8754
+ nullable: true
8755
+ description: A requested email change awaiting confirmation, if any.
8756
+ created_at:
8757
+ type: string
8758
+ format: date-time
8759
+ delete_requested_at:
8760
+ type: string
8761
+ format: date-time
8762
+ nullable: true
8763
+ description: |
8764
+ Set when the user has requested account deletion and not cancelled
8765
+ it. Nullable in the normal case.
8417
8766
  UserTier:
8418
8767
  type: string
8419
8768
  description: |
8420
8769
  Subscription tier. Mirrors the API-side
8421
8770
  `App\Identity\Domain\Enums\UserTier` PHP enum.
8422
8771
 
8423
- Ordering is `free` < `pro` < `max` < `enterprise` (the
8772
+ `basic` is the base tier. **`free` is DEPRECATED and will be removed**
8773
+ ([`nD8fCPDy`](https://trello.com/c/nD8fCPDy)) — the two are one tier
8774
+ under two names, never two tiers, and a consumer must rank them
8775
+ identically. The dated record of the rename and of the rollout that
8776
+ carried it is
8777
+ [ADR-0028](../docs/decisions/0028-base-tier-rename-free-to-basic.md).
8778
+
8779
+ 🔴 **`guest` IS NOT AND MUST NOT BECOME A MEMBER OF THIS ENUM.** It is
8780
+ the *absence* of a subscription, not a tier. Putting it here places a
8781
+ non-subscription value inside the ordering that drives upgrade prompts,
8782
+ where it has no position — **that conflation already shipped once as a
8783
+ bug and was deliberately removed.** The audience key lives on
8784
+ the audience axis, which is NOT a `UserTier` value. Asserted by a
8785
+ test, not left to prose.
8786
+
8787
+ Ordering is `basic` < `pro` < `max` < `enterprise` (the
8424
8788
  upgrade-resolver / `isHigherThan` ordinal in `UserTier.php`).
8425
- `max` is the top **self-serve** tier — Pro plus audio + larger
8426
- long-form bands; Enterprise remains the negotiated tier above it.
8427
-
8428
- Tier capability summary (informational; canonical limits are
8429
- enforced server-side per `UserTier.php`):
8430
- - `free`: 10 MiB max upload; image MIMEs only; 50 monthly credits;
8431
- 0 overdraft; 1× rate-limit baseline. No long-form access
8432
- (video/audio are MIME-gated away from Free).
8433
- - `pro`: 5 GiB max upload; image + video + document MIMEs; 1000
8434
- monthly credits; 200 overdraft; 5× rate-limit; up to 2 concurrent
8435
- in-flight long-form jobs.
8436
- - `max`: 50 GiB max upload; image + video + document + audio MIMEs;
8437
- 7500 monthly credits; 2500 overdraft; 15× rate-limit; up to 5
8438
- concurrent in-flight long-form jobs.
8439
- - `enterprise`: 100 GiB max upload; image + video + document + audio
8440
- MIMEs; 10000 monthly credits; 5000 overdraft; 20× rate-limit;
8441
- uncapped concurrent long-form jobs.
8442
-
8443
- **Concurrent long-form jobs** is a hard per-tier ceiling on the
8444
- number of in-flight long-form (Fargate) workflows a caller may
8445
- hold at once — exceeding it returns a typed `429`
8789
+ **The ordering is the part this contract owns** — it is what
8790
+ `TierRestrictionResponse.current_tier` / `.required_tier` and
8791
+ `FeatureViolation.required_tier` are compared with.
8792
+
8793
+ 🔴 **THIS SCHEMA DELIBERATELY DOES NOT ENUMERATE WHAT EACH TIER MAY
8794
+ DO, IN EITHER DIRECTION.** It previously carried a per-tier capability
8795
+ summary — upload caps, permitted MIME families, monthly credits,
8796
+ overdraft, rate-limit multiples, concurrent long-form jobs. **That was a
8797
+ restated SNAPSHOT of another repository's code, and it drifted, twice:**
8798
+ once asserting a per-tier media restriction this contract does not own
8799
+ and cannot keep true, and once listing tier byte defaults while
8800
+ **silently omitting `max`**, a tier this very enum declares.
8801
+
8802
+ **A description ships to every SDK consumer as generated documentation**,
8803
+ so a stale sentence here is not an internal note — it is an assertion
8804
+ delivered to callers, and it outlives the code it describes. *Point at
8805
+ the gate, not at a snapshot of it.*
8806
+
8807
+ ⚠️ **No claim is made HERE about which media categories a tier permits.**
8808
+ That is a scoping statement about this description, **not a claim that
8809
+ the contract is silent on the subject**: hub decision 25 made audio
8810
+ universal, so there is no tier boundary at which the category axis
8811
+ changes. **Prose that restates another repository's enforcement is the
8812
+ defect; a single generated declaration is the fix**, and the two must
8813
+ not both exist.
8814
+
8815
+ **Where the answers actually live — and they are DIFFERENT SURFACES,
8816
+ which is why naming just one was wrong:**
8817
+
8818
+ - **Which media categories are available** — the capability
8819
+ endpoint's `operations` map, per operation and mime_group
8820
+ block. Declared **once, not per audience**, because the axis does not
8821
+ vary. ⚠️ **`GET /api/v2/account/limits` cannot answer this**: it
8822
+ carries numeric limit entries only and exposes no MIME entitlement
8823
+ data at all.
8824
+ - **A caller's own numeric limits** — override-aware, and the only
8825
+ source reflecting account-level overrides:
8826
+ `GET /api/v2/account/limits` (`AccountLimits`). Its `limits` map is
8827
+ typed-open, so new limit keys arrive additively.
8828
+ - **Enforcement of record**: the API's `UserTier` enum. A `403`
8829
+ `tier_restriction` carries `TierRestrictionKind` — `mime_type` or
8830
+ `file_size` — naming which quota refused the request.
8831
+ - **Per-operation processing ceilings** (a different axis and a
8832
+ different number from the per-file upload cap):
8833
+ `processing_class.constraints` and `per_tier_constraints` in the
8834
+ operation schemas.
8835
+
8836
+ **Concurrent long-form jobs** remain a hard per-tier ceiling enforced
8837
+ server-side; exceeding it returns a typed `429`
8446
8838
  `LONG_FORM_CONCURRENCY_LIMIT_EXCEEDED` (see the `POST /api/workflows`
8447
- 429 response). Pro's 2-job cap is enforced as of the Max-tier
8448
- launch.
8449
-
8450
- The "max upload" figures are the per-file upload cap
8451
- (`UserTier.maxFileSizeBytes`) — the request-level tier quota,
8452
- surfaced override-aware via `GET /api/v2/account/limits`
8453
- (`max_upload_size_bytes`). They are DISTINCT from the per-operation
8454
- processing-class band caps (`processing_class.constraints` in the
8455
- operation schemas; e.g. the 120 GB Enterprise merge combined band).
8456
-
8457
- Used by `TierRestrictionResponse.current_tier` /
8458
- `TierRestrictionResponse.required_tier` and by
8459
- `FeatureViolation.required_tier`.
8839
+ 429 response). **The per-tier numbers are deliberately not restated
8840
+ here** — read them from the source above.
8841
+
8460
8842
  enum:
8843
+ - basic
8461
8844
  - free
8462
8845
  - pro
8463
8846
  - max
8464
8847
  - enterprise
8848
+ # 🔴 MACHINE-READABLE, BECAUSE THE PROSE ABOVE IS NOT CHECKABLE.
8849
+ # OpenAPI has no per-member enum metadata, so a deprecation stated only
8850
+ # in `description` is a judgement call at removal time — and this repo
8851
+ # has now watched prose fail to prevent the same conflation twice.
8852
+ # Requested by `compression_api` so that removing `free` is a check
8853
+ # rather than an opinion.
8854
+ x-enum-deprecated:
8855
+ free:
8856
+ superseded_by: basic
8857
+ # Owner decision 2026-08-19: you can buy credits into the base tier,
8858
+ # so "free" is false. Same ordinal — one tier under two names.
8859
+ removal_ticket: nD8fCPDy
8860
+ # ⚠️ NOT A DATE. Removal is gated on every consumer having stopped
8861
+ # EMITTING and REQUIRING the value, which is evidence rather than a
8862
+ # calendar. A date here would be overtaken and then cited.
8863
+ # ⚠️ NOT A DATE, and now TWO conditions. `compression_api` measured
8864
+ # production on 2026-08-27: `users.tier` `column_default` is still
8865
+ # `'free'::character varying`. The persisted-value constant governs
8866
+ # what the application WRITES; the default is SCHEMA, baked into a
8867
+ # migration, so moving the constant never touched it. ⇒ "there are no
8868
+ # `free` rows" is a fact about today's CONTENTS, not a property of the
8869
+ # system — an INSERT omitting the column still manufactures one.
8870
+ removal_gate: "consumer evidence table on nD8fCPDy AND the users.tier column default migrated and drained"
8465
8871
 
8466
8872
  TierRestrictionKind:
8467
8873
  type: string
@@ -8470,10 +8876,24 @@ components:
8470
8876
  workflow-create endpoints. Mirrors the API-side
8471
8877
  `App\Identity\Domain\Enums\RestrictionKind` PHP enum.
8472
8878
 
8473
- - `mime_type`: caller's tier does not permit this MIME type
8474
- (e.g. free tier uploading a video).
8475
- - `file_size`: file exceeds caller's tier file-size cap
8476
- (e.g. pro tier uploading a 1 GB file).
8879
+ - `mime_type`: the caller's tier does not permit this MIME type.
8880
+ - `file_size`: the file exceeds the caller's tier file-size cap.
8881
+
8882
+ ⚠️ **Deliberately no worked example naming a tier and a media type.**
8883
+ Both bullets previously carried one, and an illustration of the form
8884
+ *"free tier uploading a video"* is a per-tier capability claim wearing an
8885
+ example's clothes — it reaches generated documentation exactly as an
8886
+ assertion would. **Which pairs are refused is api's to enforce**, not
8887
+ this schema's to illustrate.
8888
+
8889
+ ⚠️ **The two kinds resolve against DIFFERENT surfaces**, and an earlier
8890
+ version of this note named only the numeric one:
8891
+ - `mime_type` → the capability endpoint's `operations` map, which
8892
+ declares accepted MIMEs per operation. `GET /api/v2/account/limits`
8893
+ **cannot** answer a media question — it carries numeric limit entries
8894
+ and exposes no MIME entitlement data.
8895
+ - `file_size` → `GET /api/v2/account/limits` (`AccountLimits`), which is
8896
+ override-aware per caller.
8477
8897
  enum:
8478
8898
  - mime_type
8479
8899
  - file_size
@@ -13648,9 +14068,27 @@ components:
13648
14068
  description: |
13649
14069
  Monotonically-increasing capability matrix version. Bumps
13650
14070
  independently of `schema_version` whenever the underlying
13651
- availability matrix changes (Lambda capability flips, tier
13652
- policy updates, V2-planned op promotions). Used as part of the
13653
- cache key. Per ADR-0002.
14071
+ **availability matrix** changes — Lambda capability flips,
14072
+ V2-planned op promotions, an operation or mime_group changing
14073
+ its `availability` value. Used as part of the cache key.
14074
+ Per ADR-0002.
14075
+
14076
+ 🔴 **NEITHER VERSION IS AN ENVIRONMENT-EQUALITY PROXY, AND
14077
+ THAT IS MEASURED RATHER THAN THEORETICAL.** On 2026-08-20
14078
+ staging and production both served `schema_version 2.195.0`
14079
+ and `capabilities_version 182` **while enforcing different
14080
+ free-tier upload caps** (measured by `compression_e2e`:
14081
+ prod `10485760`, staging `157286400`). ⇒ **Two hosts
14082
+ reporting identical versions can behave differently**, and
14083
+ `capabilities_version` is an easy proxy to reach for.
14084
+
14085
+ ⚠️ **It bumps on AVAILABILITY, not on LIMITS.** A tier's caps,
14086
+ quotas and entitlements can change with no bump here, because
14087
+ they are not the availability matrix — *the gate is
14088
+ implementation, not contract.* The earlier wording said
14089
+ "tier policy updates", which reads as covering a cap change
14090
+ and does not. **Read a caller's own numbers from
14091
+ `GET /api/account/limits`, never from a version number.**
13654
14092
  example: 47
13655
14093
  generated_at:
13656
14094
  description: |
@@ -13676,19 +14114,104 @@ components:
13676
14114
  example: "c4d80fb"
13677
14115
  environment:
13678
14116
  description: |
13679
- Deployment environment identifier (`baseline` for the
13680
- committed sidecar; `staging` / `production` etc. when
13681
- substituted at deploy time per per-environment overlays —
13682
- future ticket).
14117
+ 🔴 **THIS FIELD IDENTIFIES NEITHER ENVIRONMENT TODAY, AND MUST NOT
14118
+ BE USED TO DETERMINE WHICH HOST YOU REACHED.**
14119
+
14120
+ Measured by `compression_e2e` on 2026-08-22, both read in the same
14121
+ moment, anonymously: **prod and staging BOTH return `baseline`.**
14122
+ The per-environment overlay that would substitute a real value is
14123
+ an unshipped ticket ([`befVmKN2`](https://trello.com/c/befVmKN2)),
14124
+ so every host serves the committed sidecar's literal.
14125
+
14126
+ ⚠️ **A VALUE THAT IS CONSTANT ACROSS ENVIRONMENTS LOOKS EXACTLY
14127
+ LIKE A VALUE THAT CONFIRMS ONE.** This field previously carried
14128
+ `example: production` — an example of a value it has never
14129
+ returned — which taught precisely the misreading it invites.
14130
+
14131
+ 🔑 **`fetch` follows redirects by default and does not report where
14132
+ it ended up**, so a production host redirecting to staging returns
14133
+ staging's schema and **nothing in this body reveals it**. The
14134
+ catastrophic outcome is not a failure; it is a green measured
14135
+ against staging and reported as prod. ⇒ **Assert the FINAL HOST at
14136
+ the transport layer** (`redirect: 'error'` plus an origin check).
14137
+ **A payload cannot corroborate which origin you reached.**
14138
+
14139
+ 🔑 **AND IT CANNOT BE FIXED IN PLACE, WHICH IS WHY IT IS BEING
14140
+ RENAMED RATHER THAN CORRECTED.** api traced the value:
14141
+ `OperationSchemaController` reads it from
14142
+ `CapabilitiesSidecar`, which reads
14143
+ `vendor/antoniocs/compression-contracts/availability/availability.json`
14144
+ — **a file in a VENDORED PACKAGE.** The same package is vendored
14145
+ everywhere, so the field is **constant BY CONSTRUCTION, not
14146
+ because somebody forgot to set it per environment.**
14147
+
14148
+ ⚠️ **That also corrects an earlier reading of `befVmKN2` — mine.**
14149
+ "Substituted at deploy time" describes a mechanism that does not
14150
+ exist for this source: a per-environment value would require
14151
+ shipping a DIFFERENT PACKAGE per environment, which is a far
14152
+ larger thing than an overlay. ⭐ **A label that is an INPUT to the
14153
+ build can never be evidence about the build's runtime behaviour**
14154
+ (frontend's line, one layer up).
14155
+
14156
+ ⇒ **Superseded by `capabilities_profile`**, which names what the
14157
+ value actually is. `environment` is **DEPRECATED and retained for
14158
+ the transition**; both carry the same value. A server-supplied
14159
+ ORIGIN field does not exist and is not what this becomes — if one
14160
+ is ever added it must come from the deployment (task metadata or an
14161
+ env var), never from a vendored file.
14162
+ oneOf:
14163
+ - type: string
14164
+ - type: 'null'
14165
+ # ⚠️ `baseline`, NOT `production`. An example is documentation, and an
14166
+ # example of a value the field has never returned is a false one.
14167
+ example: "baseline"
14168
+ deprecated: true
14169
+ # 🔴 MACHINE-READABLE SUCCESSOR, so the transition is checkable
14170
+ # rather than described. `tests/test_deprecated_fields_have_a_
14171
+ # reachable_successor.py` reads THIS, not the prose above: if the
14172
+ # deprecated key is in the sidecar, the successor must be there too
14173
+ # and carry the same value. Without it the successor was declared and
14174
+ # emitted NOWHERE, and nothing on either side could see that — it is
14175
+ # not `required` and the response sets no `additionalProperties`,
14176
+ # so omitting it validates clean.
14177
+ x-superseded-by: capabilities_profile
14178
+ capabilities_profile:
14179
+ description: |
14180
+ **Which capability profile the vendored contracts package carries**
14181
+ — the honest name for the value `environment` has always held.
14182
+
14183
+ Sourced from the committed sidecar, so it is a property of the
14184
+ PACKAGE, not of the host. ⚠️ **It does not identify an environment
14185
+ and never could**: the same package is vendored everywhere. To
14186
+ establish which host you reached, assert the FINAL HOST at the
14187
+ transport layer.
14188
+
14189
+ Carries the same value as the deprecated `environment` throughout
14190
+ the transition; consumers should move and `environment` is removed
14191
+ once no consumer reads it.
14192
+
14193
+ 🔴 **KNOWN READER OF `environment`, RECORDED SO THE REMOVAL
14194
+ CONDITION IS CHECKABLE RATHER THAN ASSUMED:**
14195
+ `compression_api` reads it — `CapabilitiesSidecar::fromArray`
14196
+ does `$raw['environment'] ?? null` and `OperationSchemaController`
14197
+ emits it conditionally (reported by that session, 2026-08-25).
14198
+
14199
+ ⚠️ **THEIR ONLY TRIPWIRE IS A TEST THAT REMOVAL TURNS RED AND
14200
+ DEPRECATION DOES NOT** — it asserts `environment === 'baseline'`
14201
+ against the real vendored sidecar. So the null-coalesce means a
14202
+ removal drops the field from `/api/operations/schema` **with no
14203
+ error anywhere**, and the deprecation window generates no signal
14204
+ they can act on.
14205
+
14206
+ ⇒ **REMOVAL IS A CO-LAND, NOT A CUT.** Tell every reader listed
14207
+ here BEFORE the removal ships, and remove a name from this list
14208
+ only when that session confirms it has stopped reading — never
14209
+ because the field looks unused. *"No consumer reads it"* is a claim
14210
+ about other repositories, and this contract cannot see them.
13683
14211
  oneOf:
13684
14212
  - type: string
13685
14213
  - type: 'null'
13686
- example: "production"
13687
- tier_defaults:
13688
- # Anonymous-readable. Declared here rather than on
13689
- # /api/v2/account/limits because that surface is per-account and
13690
- # override-aware, so it 401s an anonymous caller — correctly.
13691
- $ref: '#/components/schemas/TierDefaults'
14214
+ example: "baseline"
13692
14215
  user_tier:
13693
14216
  description: |
13694
14217
  Tier of the calling user. Anonymous (unauthenticated) callers
@@ -13701,8 +14224,17 @@ components:
13701
14224
  free limits were allowed to differ (hub decisions 22 + 25 —
13702
14225
  anonymous carries a shorter duration entitlement than a
13703
14226
  signed-in free user). **Anonymous is the ABSENCE of a tier, not
13704
- the lowest one.** Read `tier_defaults.by_audience.anonymous`
13705
- for what an unauthenticated caller may actually do.
14227
+ the lowest one.**
14228
+
14229
+ ⚠️ **AND THERE IS NOW NO DECLARED SURFACE CARRYING AN ANONYMOUS
14230
+ LIMITS ROW.** `tier_defaults.by_audience` used to hold one and was
14231
+ RETRACTED (`233A3CbV`, 2026-08-20) — it encoded per-audience SIZE
14232
+ limits, which the committed pricing model abolishes in favour of
14233
+ technical ceilings identical for everyone. It was never served, so
14234
+ nothing lost a value it had been reading. **Hub decision 27 required
14235
+ the anonymous/free distinction to be expressible; it is not
14236
+ expressible today, deliberately, and re-expressing it belongs to
14237
+ the pricing programme's tier-entitlement work.**
13706
14238
  oneOf:
13707
14239
  - $ref: '#/components/schemas/UserTier'
13708
14240
  - type: 'null'
@@ -14430,13 +14962,22 @@ components:
14430
14962
  description: |
14431
14963
  Optional mime-group-level INPUT-file size ceiling in BYTES
14432
14964
  (ticket [`uKsFzORi`](https://trello.com/c/uKsFzORi)). Sibling of
14433
- `max_output_pixels`. **Applies to the enclosing operation's input** —
14434
- currently authored on `compress` image/document groups (the API
14435
- enforces it on compress input only: AVIF 20 MiB, other images 500 MiB,
14436
- office/ODF/EPUB 100 MiB). A consumer MUST scope it to the operation
14437
- whose schema carries it and MUST NOT assume it applies to other
14438
- operations. An oversize input is rejected at create-time (ADR-0012
14439
- band-ceiling 422 family).
14965
+ `max_output_pixels`. **Applies to the enclosing operation's input**, and
14966
+ a consumer MUST scope it to the operation whose schema carries it —
14967
+ **the same MIME can carry different ceilings under different
14968
+ operations, because different workers process it.** ⚠️ This line
14969
+ previously said the ceilings were authored on `compress` only; they
14970
+ are not, and reading a `compress` number as the binding one for a
14971
+ `[compress, thumbnail]` chain is what let a 128 MB EPUB upload
14972
+ succeed and then be refused (`jLxWpQEZ`). **Do not enumerate the
14973
+ values here** — a restated table is one nothing re-measures; read
14974
+ them from the operation's own schema.
14975
+
14976
+ 🔴 **A GROUP WITH NO `max_input_size_bytes` HAS NOT SAID THERE IS NO
14977
+ LIMIT.** It has said nothing. A group whose worker imposes no byte
14978
+ ceiling declares `input_size_bound: processing_time` instead, and
14979
+ exactly one of the two keys is present when either is. An oversize
14980
+ input is rejected at create-time (ADR-0012 band-ceiling 422 family).
14440
14981
 
14441
14982
  **XOR with `processing_class` caps (ADR-0011):** a group carries this
14442
14983
  group-level cap ONLY when it has NO `processing_class` band. Banded