@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.
- package/README.md +2 -2
- package/accepted-options/accepted-options.json +17 -3
- package/accepted-options/image-output-routes.json +1 -1
- package/availability/availability.json +97 -11
- package/code-builder/code-builder-metadata.json +120 -11
- package/dist/openapi/models/AccountLimitEntry.d.ts +1 -1
- package/dist/openapi/models/AccountLimitEntry.js +1 -1
- package/dist/openapi/models/AccountLimits.d.ts +15 -7
- package/dist/openapi/models/AccountLimits.js +1 -1
- package/dist/openapi/models/AccountLimitsLimits.d.ts +1 -1
- package/dist/openapi/models/AccountLimitsLimits.js +1 -1
- package/dist/openapi/models/AccountLimitsSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/AccountLimitsSuccessEnvelope.js +1 -1
- package/dist/openapi/models/AudioWatermarkDecodeRequest.d.ts +1 -1
- package/dist/openapi/models/AudioWatermarkDecodeRequest.js +1 -1
- package/dist/openapi/models/AudioWatermarkDecodeResponse.d.ts +1 -1
- package/dist/openapi/models/AudioWatermarkDecodeResponse.js +1 -1
- package/dist/openapi/models/AuthErrorResponse.d.ts +1 -1
- package/dist/openapi/models/AuthErrorResponse.js +1 -1
- package/dist/openapi/models/AuthErrorType.d.ts +1 -1
- package/dist/openapi/models/AuthErrorType.js +1 -1
- package/dist/openapi/models/AuthRejectionEnvelope.d.ts +1 -1
- package/dist/openapi/models/AuthRejectionEnvelope.js +1 -1
- package/dist/openapi/models/{TierDefaultsByAudience.d.ts → AuthenticatedIdentity.d.ts} +56 -40
- package/dist/openapi/models/{TierDefaultsByAudience.js → AuthenticatedIdentity.js} +31 -25
- package/dist/openapi/models/AvailabilityValue.d.ts +1 -1
- package/dist/openapi/models/AvailabilityValue.js +1 -1
- package/dist/openapi/models/BalanceExhaustedResponse.d.ts +1 -1
- package/dist/openapi/models/BalanceExhaustedResponse.js +1 -1
- package/dist/openapi/models/BalanceExhaustedResponseAllOfLinks.d.ts +1 -1
- package/dist/openapi/models/BalanceExhaustedResponseAllOfLinks.js +1 -1
- package/dist/openapi/models/BillingCheckoutRequest.d.ts +1 -1
- package/dist/openapi/models/BillingCheckoutRequest.js +1 -1
- package/dist/openapi/models/BillingCheckoutSession.d.ts +1 -1
- package/dist/openapi/models/BillingCheckoutSession.js +1 -1
- package/dist/openapi/models/BillingCheckoutSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/BillingCheckoutSuccessEnvelope.js +1 -1
- package/dist/openapi/models/CallbackEventType.d.ts +1 -1
- package/dist/openapi/models/CallbackEventType.js +1 -1
- package/dist/openapi/models/CancelAccountDeletion200Response.d.ts +1 -1
- package/dist/openapi/models/CancelAccountDeletion200Response.js +1 -1
- package/dist/openapi/models/CancelAccountDeletion200ResponseData.d.ts +1 -1
- package/dist/openapi/models/CancelAccountDeletion200ResponseData.js +1 -1
- package/dist/openapi/models/CapabilityCondition.d.ts +1 -1
- package/dist/openapi/models/CapabilityCondition.js +1 -1
- package/dist/openapi/models/CapabilityConditionOneOf.d.ts +1 -1
- package/dist/openapi/models/CapabilityConditionOneOf.js +1 -1
- package/dist/openapi/models/CapabilityConditionOneOf1.d.ts +1 -1
- package/dist/openapi/models/CapabilityConditionOneOf1.js +1 -1
- package/dist/openapi/models/CapabilityConditionOneOf2.d.ts +1 -1
- package/dist/openapi/models/CapabilityConditionOneOf2.js +1 -1
- package/dist/openapi/models/CapabilityConditionOneOf3.d.ts +1 -1
- package/dist/openapi/models/CapabilityConditionOneOf3.js +1 -1
- package/dist/openapi/models/CapabilityConditionOneOf4.d.ts +1 -1
- package/dist/openapi/models/CapabilityConditionOneOf4.js +1 -1
- package/dist/openapi/models/CapabilityConditionOneOf5.d.ts +1 -1
- package/dist/openapi/models/CapabilityConditionOneOf5.js +1 -1
- package/dist/openapi/models/CapabilityConditionOneOf6.d.ts +1 -1
- package/dist/openapi/models/CapabilityConditionOneOf6.js +1 -1
- package/dist/openapi/models/CapabilityConstraint.d.ts +1 -1
- package/dist/openapi/models/CapabilityConstraint.js +1 -1
- package/dist/openapi/models/CapabilityInputSpec.d.ts +1 -1
- package/dist/openapi/models/CapabilityInputSpec.js +1 -1
- package/dist/openapi/models/CapabilityProduces.d.ts +1 -1
- package/dist/openapi/models/CapabilityProduces.js +1 -1
- package/dist/openapi/models/CapabilityProducesOneOf.d.ts +1 -1
- package/dist/openapi/models/CapabilityProducesOneOf.js +1 -1
- package/dist/openapi/models/CapabilityProducesOneOf1.d.ts +1 -1
- package/dist/openapi/models/CapabilityProducesOneOf1.js +1 -1
- package/dist/openapi/models/CapabilityProducesOneOf2.d.ts +1 -1
- package/dist/openapi/models/CapabilityProducesOneOf2.js +1 -1
- package/dist/openapi/models/ChangePasswordRequest.d.ts +1 -1
- package/dist/openapi/models/ChangePasswordRequest.js +1 -1
- package/dist/openapi/models/CodegenSource.d.ts +1 -1
- package/dist/openapi/models/CodegenSource.js +1 -1
- package/dist/openapi/models/CodegenSourceInput.d.ts +1 -1
- package/dist/openapi/models/CodegenSourceInput.js +1 -1
- package/dist/openapi/models/CodegenSourceJob.d.ts +1 -1
- package/dist/openapi/models/CodegenSourceJob.js +1 -1
- package/dist/openapi/models/CodegenSourceJobSource.d.ts +1 -1
- package/dist/openapi/models/CodegenSourceJobSource.js +1 -1
- package/dist/openapi/models/CodegenSourceOperation.d.ts +1 -1
- package/dist/openapi/models/CodegenSourceOperation.js +1 -1
- package/dist/openapi/models/CodegenUploadPlaceholder.d.ts +1 -1
- package/dist/openapi/models/CodegenUploadPlaceholder.js +1 -1
- package/dist/openapi/models/CompositionPlan.d.ts +1 -1
- package/dist/openapi/models/CompositionPlan.js +1 -1
- package/dist/openapi/models/CompositionPlanJob.d.ts +1 -1
- package/dist/openapi/models/CompositionPlanJob.js +1 -1
- package/dist/openapi/models/CompositionPlanOperation.d.ts +1 -1
- package/dist/openapi/models/CompositionPlanOperation.js +1 -1
- package/dist/openapi/models/ConfirmEmailChange200Response.d.ts +1 -1
- package/dist/openapi/models/ConfirmEmailChange200Response.js +1 -1
- package/dist/openapi/models/ConfirmEmailChange200ResponseData.d.ts +1 -1
- package/dist/openapi/models/ConfirmEmailChange200ResponseData.js +1 -1
- package/dist/openapi/models/ConfirmEmailChangeRequest.d.ts +1 -1
- package/dist/openapi/models/ConfirmEmailChangeRequest.js +1 -1
- package/dist/openapi/models/ConnectionSource.d.ts +1 -1
- package/dist/openapi/models/ConnectionSource.js +1 -1
- package/dist/openapi/models/ContactRequest.d.ts +1 -1
- package/dist/openapi/models/ContactRequest.js +1 -1
- package/dist/openapi/models/ContactSubject.d.ts +1 -1
- package/dist/openapi/models/ContactSubject.js +1 -1
- package/dist/openapi/models/ContactValidationErrorResponse.d.ts +1 -1
- package/dist/openapi/models/ContactValidationErrorResponse.js +1 -1
- package/dist/openapi/models/CreateApiKey201Response.d.ts +1 -1
- package/dist/openapi/models/CreateApiKey201Response.js +1 -1
- package/dist/openapi/models/CreateApiKey201ResponseData.d.ts +1 -1
- package/dist/openapi/models/CreateApiKey201ResponseData.js +1 -1
- package/dist/openapi/models/CreateApiKeyRequest.d.ts +1 -1
- package/dist/openapi/models/CreateApiKeyRequest.js +1 -1
- package/dist/openapi/models/CreateBillingCheckoutSession422Response.d.ts +1 -1
- package/dist/openapi/models/CreateBillingCheckoutSession422Response.js +1 -1
- package/dist/openapi/models/CreateExternalImport403Response.d.ts +1 -1
- package/dist/openapi/models/CreateExternalImport403Response.js +1 -1
- package/dist/openapi/models/CreateExternalImport422Response.d.ts +1 -1
- package/dist/openapi/models/CreateExternalImport422Response.js +1 -1
- package/dist/openapi/models/CreateWorkflow401Response.d.ts +1 -1
- package/dist/openapi/models/CreateWorkflow401Response.js +1 -1
- package/dist/openapi/models/CreateWorkflow422Response.d.ts +1 -1
- package/dist/openapi/models/CreateWorkflow422Response.js +1 -1
- package/dist/openapi/models/CreditTransaction.d.ts +1 -1
- package/dist/openapi/models/CreditTransaction.js +1 -1
- package/dist/openapi/models/CreditTransactionSourceBucket.d.ts +1 -1
- package/dist/openapi/models/CreditTransactionSourceBucket.js +1 -1
- package/dist/openapi/models/CreditsBalanceResponse.d.ts +1 -1
- package/dist/openapi/models/CreditsBalanceResponse.js +1 -1
- package/dist/openapi/models/CreditsBalanceSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/CreditsBalanceSuccessEnvelope.js +1 -1
- package/dist/openapi/models/CreditsUsageResponse.d.ts +1 -1
- package/dist/openapi/models/CreditsUsageResponse.js +1 -1
- package/dist/openapi/models/CreditsUsageSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/CreditsUsageSuccessEnvelope.js +1 -1
- package/dist/openapi/models/Delivery.d.ts +1 -1
- package/dist/openapi/models/Delivery.js +1 -1
- package/dist/openapi/models/DeliveryOutputRef.d.ts +1 -1
- package/dist/openapi/models/DeliveryOutputRef.js +1 -1
- package/dist/openapi/models/DeliveryPlan.d.ts +1 -1
- package/dist/openapi/models/DeliveryPlan.js +1 -1
- package/dist/openapi/models/DeliveryPlanOutput.d.ts +1 -1
- package/dist/openapi/models/DeliveryPlanOutput.js +1 -1
- package/dist/openapi/models/DeliveryPlanReason.d.ts +1 -1
- package/dist/openapi/models/DeliveryPlanReason.js +1 -1
- package/dist/openapi/models/DeliverySelection.d.ts +1 -1
- package/dist/openapi/models/DeliverySelection.js +1 -1
- package/dist/openapi/models/DownloadBundle.d.ts +1 -1
- package/dist/openapi/models/DownloadBundle.js +1 -1
- package/dist/openapi/models/DroppedOption.d.ts +1 -1
- package/dist/openapi/models/DroppedOption.js +1 -1
- package/dist/openapi/models/EmailNotify.d.ts +1 -1
- package/dist/openapi/models/EmailNotify.js +1 -1
- package/dist/openapi/models/EmptySuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/EmptySuccessEnvelope.js +1 -1
- package/dist/openapi/models/EndpointProjection.d.ts +1 -1
- package/dist/openapi/models/EndpointProjection.js +1 -1
- package/dist/openapi/models/EndpointProjectionServersInner.d.ts +1 -1
- package/dist/openapi/models/EndpointProjectionServersInner.js +1 -1
- package/dist/openapi/models/ErrorEnvelope.d.ts +1 -1
- package/dist/openapi/models/ErrorEnvelope.js +1 -1
- package/dist/openapi/models/EstimateQuality.d.ts +1 -1
- package/dist/openapi/models/EstimateQuality.js +1 -1
- package/dist/openapi/models/EstimateRange.d.ts +1 -1
- package/dist/openapi/models/EstimateRange.js +1 -1
- package/dist/openapi/models/ExportAccountData200Response.d.ts +1 -1
- package/dist/openapi/models/ExportAccountData200Response.js +1 -1
- package/dist/openapi/models/ExportAccountData200ResponseData.d.ts +1 -1
- package/dist/openapi/models/ExportAccountData200ResponseData.js +1 -1
- package/dist/openapi/models/ExternalDestination.d.ts +1 -1
- package/dist/openapi/models/ExternalDestination.js +1 -1
- package/dist/openapi/models/ExternalImportCreatedResponse.d.ts +1 -1
- package/dist/openapi/models/ExternalImportCreatedResponse.js +1 -1
- package/dist/openapi/models/ExternalImportCreatedSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/ExternalImportCreatedSuccessEnvelope.js +1 -1
- package/dist/openapi/models/ExternalImportRequest.d.ts +1 -1
- package/dist/openapi/models/ExternalImportRequest.js +1 -1
- package/dist/openapi/models/ExternalImportToken.d.ts +1 -1
- package/dist/openapi/models/ExternalImportToken.js +1 -1
- package/dist/openapi/models/ExternalSource.d.ts +1 -1
- package/dist/openapi/models/ExternalSource.js +1 -1
- package/dist/openapi/models/FeatureNotAvailableResponse.d.ts +1 -1
- package/dist/openapi/models/FeatureNotAvailableResponse.js +1 -1
- package/dist/openapi/models/FeatureTierRestrictedResponse.d.ts +1 -1
- package/dist/openapi/models/FeatureTierRestrictedResponse.js +1 -1
- package/dist/openapi/models/FeatureViolation.d.ts +1 -1
- package/dist/openapi/models/FeatureViolation.js +1 -1
- package/dist/openapi/models/{MediaCategory.js → GetProfile200Response.d.ts} +31 -34
- package/dist/openapi/models/{TierDefaults.js → GetProfile200Response.js} +22 -17
- package/dist/openapi/models/{MediaCategory.d.ts → GetProfile200ResponseData.d.ts} +19 -17
- package/dist/openapi/models/{TierDefaultLimits.js → GetProfile200ResponseData.js} +13 -16
- package/dist/openapi/models/ImageEncodeCapabilities.d.ts +1 -1
- package/dist/openapi/models/ImageEncodeCapabilities.js +1 -1
- package/dist/openapi/models/JobDefinition.d.ts +1 -1
- package/dist/openapi/models/JobDefinition.js +1 -1
- package/dist/openapi/models/JobDownload.d.ts +1 -1
- package/dist/openapi/models/JobDownload.js +1 -1
- package/dist/openapi/models/JobInputV2.d.ts +1 -1
- package/dist/openapi/models/JobInputV2.js +1 -1
- package/dist/openapi/models/JobMediaClass.d.ts +1 -1
- package/dist/openapi/models/JobMediaClass.js +1 -1
- package/dist/openapi/models/JobOutputSource.d.ts +1 -1
- package/dist/openapi/models/JobOutputSource.js +1 -1
- package/dist/openapi/models/JobResponse.d.ts +1 -1
- package/dist/openapi/models/JobResponse.js +1 -1
- package/dist/openapi/models/JobStatus.d.ts +1 -1
- package/dist/openapi/models/JobStatus.js +1 -1
- package/dist/openapi/models/JobType.d.ts +1 -1
- package/dist/openapi/models/JobType.js +1 -1
- package/dist/openapi/models/LivenessResponse.d.ts +1 -1
- package/dist/openapi/models/LivenessResponse.js +1 -1
- package/dist/openapi/models/LoginUser200Response.d.ts +1 -1
- package/dist/openapi/models/LoginUser200Response.js +1 -1
- package/dist/openapi/models/LoginUser200ResponseData.d.ts +1 -1
- package/dist/openapi/models/LoginUser200ResponseData.js +1 -1
- package/dist/openapi/models/LoginUser200ResponseDataUser.d.ts +1 -1
- package/dist/openapi/models/LoginUser200ResponseDataUser.js +1 -1
- package/dist/openapi/models/LoginUser401Response.d.ts +1 -1
- package/dist/openapi/models/LoginUser401Response.js +1 -1
- package/dist/openapi/models/LoginUserRequest.d.ts +1 -1
- package/dist/openapi/models/LoginUserRequest.js +1 -1
- package/dist/openapi/models/LongFormConcurrencyLimitResponse.d.ts +1 -1
- package/dist/openapi/models/LongFormConcurrencyLimitResponse.js +1 -1
- package/dist/openapi/models/LongFormConcurrencyLimitResponseAllOfLinks.d.ts +1 -1
- package/dist/openapi/models/LongFormConcurrencyLimitResponseAllOfLinks.js +1 -1
- package/dist/openapi/models/MetadataResponse.d.ts +1 -1
- package/dist/openapi/models/MetadataResponse.js +1 -1
- package/dist/openapi/models/MetadataResponseDimensions.d.ts +1 -1
- package/dist/openapi/models/MetadataResponseDimensions.js +1 -1
- package/dist/openapi/models/MetadataResponseExif.d.ts +1 -1
- package/dist/openapi/models/MetadataResponseExif.js +1 -1
- package/dist/openapi/models/MetadataResponseExifGps.d.ts +1 -1
- package/dist/openapi/models/MetadataResponseExifGps.js +1 -1
- package/dist/openapi/models/MetadataSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/MetadataSuccessEnvelope.js +1 -1
- package/dist/openapi/models/MimeGroupSchema.d.ts +17 -8
- package/dist/openapi/models/MimeGroupSchema.js +1 -1
- package/dist/openapi/models/MultiInputSource.d.ts +1 -1
- package/dist/openapi/models/MultiInputSource.js +1 -1
- package/dist/openapi/models/MultipartCompleteRequest.d.ts +1 -1
- package/dist/openapi/models/MultipartCompleteRequest.js +1 -1
- package/dist/openapi/models/MultipartCompleteRequestPartsInner.d.ts +1 -1
- package/dist/openapi/models/MultipartCompleteRequestPartsInner.js +1 -1
- package/dist/openapi/models/MultipartCompleteResponse.d.ts +1 -1
- package/dist/openapi/models/MultipartCompleteResponse.js +1 -1
- package/dist/openapi/models/MultipartCompleteSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/MultipartCompleteSuccessEnvelope.js +1 -1
- package/dist/openapi/models/MultipartInitiateRequestMetadataHint.d.ts +1 -1
- package/dist/openapi/models/MultipartInitiateRequestMetadataHint.js +1 -1
- package/dist/openapi/models/MultipartInitiateResponse.d.ts +1 -1
- package/dist/openapi/models/MultipartInitiateResponse.js +1 -1
- package/dist/openapi/models/MultipartInitiateSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/MultipartInitiateSuccessEnvelope.js +1 -1
- package/dist/openapi/models/MultipartKeepaliveResponse.d.ts +1 -1
- package/dist/openapi/models/MultipartKeepaliveResponse.js +1 -1
- package/dist/openapi/models/MultipartKeepaliveSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/MultipartKeepaliveSuccessEnvelope.js +1 -1
- package/dist/openapi/models/MultipartPartListing.d.ts +1 -1
- package/dist/openapi/models/MultipartPartListing.js +1 -1
- package/dist/openapi/models/MultipartPresignRequest.d.ts +1 -1
- package/dist/openapi/models/MultipartPresignRequest.js +1 -1
- package/dist/openapi/models/MultipartPresignResponse.d.ts +1 -1
- package/dist/openapi/models/MultipartPresignResponse.js +1 -1
- package/dist/openapi/models/MultipartPresignSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/MultipartPresignSuccessEnvelope.js +1 -1
- package/dist/openapi/models/MultipartStatusResponse.d.ts +1 -1
- package/dist/openapi/models/MultipartStatusResponse.js +1 -1
- package/dist/openapi/models/MultipartStatusSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/MultipartStatusSuccessEnvelope.js +1 -1
- package/dist/openapi/models/NotifyConfig.d.ts +1 -1
- package/dist/openapi/models/NotifyConfig.js +1 -1
- package/dist/openapi/models/OperationCapability.d.ts +1 -1
- package/dist/openapi/models/OperationCapability.js +1 -1
- package/dist/openapi/models/OperationDefinition.d.ts +1 -1
- package/dist/openapi/models/OperationDefinition.js +1 -1
- package/dist/openapi/models/OperationDownload.d.ts +1 -1
- package/dist/openapi/models/OperationDownload.js +1 -1
- package/dist/openapi/models/OperationInputModel.d.ts +1 -1
- package/dist/openapi/models/OperationInputModel.js +1 -1
- package/dist/openapi/models/OperationResponse.d.ts +1 -1
- package/dist/openapi/models/OperationResponse.js +1 -1
- package/dist/openapi/models/OperationResult.d.ts +1 -1
- package/dist/openapi/models/OperationResult.js +1 -1
- package/dist/openapi/models/OperationResultMetadata.d.ts +1 -1
- package/dist/openapi/models/OperationResultMetadata.js +1 -1
- package/dist/openapi/models/OperationResultMetrics.d.ts +1 -1
- package/dist/openapi/models/OperationResultMetrics.js +1 -1
- package/dist/openapi/models/OperationSchemaDefinition.d.ts +1 -1
- package/dist/openapi/models/OperationSchemaDefinition.js +1 -1
- package/dist/openapi/models/OperationStatus.d.ts +1 -1
- package/dist/openapi/models/OperationStatus.js +1 -1
- package/dist/openapi/models/OperationType.d.ts +1 -1
- package/dist/openapi/models/OperationType.js +1 -1
- package/dist/openapi/models/OperationsSchemaResponse.d.ts +24 -7
- package/dist/openapi/models/OperationsSchemaResponse.js +3 -4
- package/dist/openapi/models/OperationsSchemaResponseWorkflowFeatures.d.ts +1 -1
- package/dist/openapi/models/OperationsSchemaResponseWorkflowFeatures.js +1 -1
- package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDelivery.d.ts +1 -1
- package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDelivery.js +1 -1
- package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDeliveryMode.d.ts +1 -1
- package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDeliveryMode.js +1 -1
- package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDeliverySelection.d.ts +1 -1
- package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDeliverySelection.js +1 -1
- package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesProcessing.d.ts +1 -1
- package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesProcessing.js +1 -1
- package/dist/openapi/models/OptionSchema.d.ts +1 -1
- package/dist/openapi/models/OptionSchema.js +1 -1
- package/dist/openapi/models/OutputProperties.d.ts +1 -1
- package/dist/openapi/models/OutputProperties.js +1 -1
- package/dist/openapi/models/OutputPropertiesIsAnimated.d.ts +1 -1
- package/dist/openapi/models/OutputPropertiesIsAnimated.js +1 -1
- package/dist/openapi/models/PerClassAvailabilityEntry.d.ts +1 -1
- package/dist/openapi/models/PerClassAvailabilityEntry.js +1 -1
- package/dist/openapi/models/PerRoleCardinalityEntry.d.ts +1 -1
- package/dist/openapi/models/PerRoleCardinalityEntry.js +1 -1
- package/dist/openapi/models/PerValueAvailabilityEntry.d.ts +1 -1
- package/dist/openapi/models/PerValueAvailabilityEntry.js +1 -1
- package/dist/openapi/models/PresignedUrlPart.d.ts +1 -1
- package/dist/openapi/models/PresignedUrlPart.js +1 -1
- package/dist/openapi/models/ProbePendingResponse.d.ts +1 -1
- package/dist/openapi/models/ProbePendingResponse.js +1 -1
- package/dist/openapi/models/ProcessingClass.d.ts +1 -1
- package/dist/openapi/models/ProcessingClass.js +1 -1
- package/dist/openapi/models/ProcessingClassBandViolation.d.ts +1 -1
- package/dist/openapi/models/ProcessingClassBandViolation.js +1 -1
- package/dist/openapi/models/ProcessingClassConstraints.d.ts +1 -1
- package/dist/openapi/models/ProcessingClassConstraints.js +1 -1
- package/dist/openapi/models/ProcessingClassEntry.d.ts +1 -1
- package/dist/openapi/models/ProcessingClassEntry.js +1 -1
- package/dist/openapi/models/ProcessingClassExceedsBandResponse.d.ts +1 -1
- package/dist/openapi/models/ProcessingClassExceedsBandResponse.js +1 -1
- package/dist/openapi/models/ProcessingClassHint.d.ts +1 -1
- package/dist/openapi/models/ProcessingClassHint.js +1 -1
- package/dist/openapi/models/ProcessingClassReason.d.ts +1 -1
- package/dist/openapi/models/ProcessingClassReason.js +1 -1
- package/dist/openapi/models/ProcessingClassRejectReason.d.ts +1 -1
- package/dist/openapi/models/ProcessingClassRejectReason.js +1 -1
- package/dist/openapi/models/ProcessingPlan.d.ts +1 -1
- package/dist/openapi/models/ProcessingPlan.js +1 -1
- package/dist/openapi/models/ProcessingPlanJob.d.ts +1 -1
- package/dist/openapi/models/ProcessingPlanJob.js +1 -1
- package/dist/openapi/models/ReEncodeDecision.d.ts +1 -1
- package/dist/openapi/models/ReEncodeDecision.js +1 -1
- package/dist/openapi/models/ReadinessResponse.d.ts +1 -1
- package/dist/openapi/models/ReadinessResponse.js +1 -1
- package/dist/openapi/models/RegisterUser422Response.d.ts +1 -1
- package/dist/openapi/models/RegisterUser422Response.js +1 -1
- package/dist/openapi/models/RegisterUserRequest.d.ts +1 -1
- package/dist/openapi/models/RegisterUserRequest.js +1 -1
- package/dist/openapi/models/RequestAccountDeletion200Response.d.ts +1 -1
- package/dist/openapi/models/RequestAccountDeletion200Response.js +1 -1
- package/dist/openapi/models/RequestAccountDeletion200ResponseData.d.ts +1 -1
- package/dist/openapi/models/RequestAccountDeletion200ResponseData.js +1 -1
- package/dist/openapi/models/RequestAccountDeletionRequest.d.ts +1 -1
- package/dist/openapi/models/RequestAccountDeletionRequest.js +1 -1
- package/dist/openapi/models/ResendVerificationEmailRequest.d.ts +1 -1
- package/dist/openapi/models/ResendVerificationEmailRequest.js +1 -1
- package/dist/openapi/models/ResetPasswordRequest.d.ts +1 -1
- package/dist/openapi/models/ResetPasswordRequest.js +1 -1
- package/dist/openapi/models/ResponseEnvelope.d.ts +1 -1
- package/dist/openapi/models/ResponseEnvelope.js +1 -1
- package/dist/openapi/models/RetryResponse.d.ts +1 -1
- package/dist/openapi/models/RetryResponse.js +1 -1
- package/dist/openapi/models/RetrySuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/RetrySuccessEnvelope.js +1 -1
- package/dist/openapi/models/SseCompletionBase.d.ts +1 -1
- package/dist/openapi/models/SseCompletionBase.js +1 -1
- package/dist/openapi/models/SseEventType.d.ts +1 -1
- package/dist/openapi/models/SseEventType.js +1 -1
- package/dist/openapi/models/SseJobCompletedData.d.ts +1 -1
- package/dist/openapi/models/SseJobCompletedData.js +1 -1
- package/dist/openapi/models/SseJobFailedData.d.ts +1 -1
- package/dist/openapi/models/SseJobFailedData.js +1 -1
- package/dist/openapi/models/SseMultiOutputCompletion.d.ts +1 -1
- package/dist/openapi/models/SseMultiOutputCompletion.js +1 -1
- package/dist/openapi/models/SseMultiOutputCompletionMetrics.d.ts +1 -1
- package/dist/openapi/models/SseMultiOutputCompletionMetrics.js +1 -1
- package/dist/openapi/models/SseMultiOutputCompletionWithKind.d.ts +1 -1
- package/dist/openapi/models/SseMultiOutputCompletionWithKind.js +1 -1
- package/dist/openapi/models/SseMultiOutputResultEntry.d.ts +1 -1
- package/dist/openapi/models/SseMultiOutputResultEntry.js +1 -1
- package/dist/openapi/models/SseOperationCompletedData.d.ts +1 -1
- package/dist/openapi/models/SseOperationCompletedData.js +1 -1
- package/dist/openapi/models/SseOperationCompletionResult.d.ts +1 -1
- package/dist/openapi/models/SseOperationCompletionResult.js +1 -1
- package/dist/openapi/models/SseOperationFailedData.d.ts +1 -1
- package/dist/openapi/models/SseOperationFailedData.js +1 -1
- package/dist/openapi/models/SseOperationProgressData.d.ts +1 -1
- package/dist/openapi/models/SseOperationProgressData.js +1 -1
- package/dist/openapi/models/SseSingleOutputCompletion.d.ts +1 -1
- package/dist/openapi/models/SseSingleOutputCompletion.js +1 -1
- package/dist/openapi/models/SseWorkflowTerminalData.d.ts +1 -1
- package/dist/openapi/models/SseWorkflowTerminalData.js +1 -1
- package/dist/openapi/models/TierRestrictionKind.d.ts +19 -5
- package/dist/openapi/models/TierRestrictionKind.js +19 -5
- package/dist/openapi/models/TierRestrictionResponse.d.ts +1 -1
- package/dist/openapi/models/TierRestrictionResponse.js +1 -1
- package/dist/openapi/models/UpdateProfile200Response.d.ts +1 -1
- package/dist/openapi/models/UpdateProfile200Response.js +1 -1
- package/dist/openapi/models/UpdateProfile200ResponseData.d.ts +1 -1
- package/dist/openapi/models/UpdateProfile200ResponseData.js +1 -1
- package/dist/openapi/models/UpdateProfile422Response.d.ts +1 -1
- package/dist/openapi/models/UpdateProfile422Response.js +1 -1
- package/dist/openapi/models/UpdateProfileRequest.d.ts +1 -1
- package/dist/openapi/models/UpdateProfileRequest.js +1 -1
- package/dist/openapi/models/UploadConstraintsApplied.d.ts +1 -1
- package/dist/openapi/models/UploadConstraintsApplied.js +1 -1
- package/dist/openapi/models/UploadDurationExceedsTierResponse.d.ts +1 -1
- package/dist/openapi/models/UploadDurationExceedsTierResponse.js +1 -1
- package/dist/openapi/models/UploadFile403Response.d.ts +1 -1
- package/dist/openapi/models/UploadFile403Response.js +1 -1
- package/dist/openapi/models/UploadFile422Response.d.ts +1 -1
- package/dist/openapi/models/UploadFile422Response.js +1 -1
- package/dist/openapi/models/UploadProbeMediaMetadata.d.ts +1 -1
- package/dist/openapi/models/UploadProbeMediaMetadata.js +1 -1
- package/dist/openapi/models/UploadProbeProcessingClass.d.ts +1 -1
- package/dist/openapi/models/UploadProbeProcessingClass.js +1 -1
- package/dist/openapi/models/UploadProbeResponse.d.ts +1 -1
- package/dist/openapi/models/UploadProbeResponse.js +1 -1
- package/dist/openapi/models/UploadProbeStatus.d.ts +1 -1
- package/dist/openapi/models/UploadProbeStatus.js +1 -1
- package/dist/openapi/models/UploadProbeSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/UploadProbeSuccessEnvelope.js +1 -1
- package/dist/openapi/models/UploadResponse.d.ts +1 -1
- package/dist/openapi/models/UploadResponse.js +1 -1
- package/dist/openapi/models/UploadSizeExceedsTierResponse.d.ts +1 -1
- package/dist/openapi/models/UploadSizeExceedsTierResponse.js +1 -1
- package/dist/openapi/models/UploadSource.d.ts +1 -1
- package/dist/openapi/models/UploadSource.js +1 -1
- package/dist/openapi/models/UploadSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/UploadSuccessEnvelope.js +1 -1
- package/dist/openapi/models/UploadThresholds.d.ts +1 -1
- package/dist/openapi/models/UploadThresholds.js +1 -1
- package/dist/openapi/models/UserTier.d.ts +66 -33
- package/dist/openapi/models/UserTier.js +66 -33
- package/dist/openapi/models/ValidationErrorEnvelope.d.ts +1 -1
- package/dist/openapi/models/ValidationErrorEnvelope.js +1 -1
- package/dist/openapi/models/ValidationErrorEnvelopeDetailsInner.d.ts +1 -1
- package/dist/openapi/models/ValidationErrorEnvelopeDetailsInner.js +1 -1
- package/dist/openapi/models/VerifyEmailRequest.d.ts +1 -1
- package/dist/openapi/models/VerifyEmailRequest.js +1 -1
- package/dist/openapi/models/WarningType.d.ts +1 -1
- package/dist/openapi/models/WarningType.js +1 -1
- package/dist/openapi/models/WebhookOperationContext.d.ts +1 -1
- package/dist/openapi/models/WebhookOperationContext.js +1 -1
- package/dist/openapi/models/WebhookPayload.d.ts +1 -1
- package/dist/openapi/models/WebhookPayload.js +1 -1
- package/dist/openapi/models/WorkflowArchiveResponse.d.ts +1 -1
- package/dist/openapi/models/WorkflowArchiveResponse.js +1 -1
- package/dist/openapi/models/WorkflowArchiveSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/WorkflowArchiveSuccessEnvelope.js +1 -1
- package/dist/openapi/models/WorkflowCancelBillingEffect.d.ts +1 -1
- package/dist/openapi/models/WorkflowCancelBillingEffect.js +1 -1
- package/dist/openapi/models/WorkflowCancelResponse.d.ts +1 -1
- package/dist/openapi/models/WorkflowCancelResponse.js +1 -1
- package/dist/openapi/models/WorkflowCancelSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/WorkflowCancelSuccessEnvelope.js +1 -1
- package/dist/openapi/models/WorkflowCreateRequest.d.ts +1 -1
- package/dist/openapi/models/WorkflowCreateRequest.js +1 -1
- package/dist/openapi/models/WorkflowCreateResponse.d.ts +1 -1
- package/dist/openapi/models/WorkflowCreateResponse.js +1 -1
- package/dist/openapi/models/WorkflowCreateSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/WorkflowCreateSuccessEnvelope.js +1 -1
- package/dist/openapi/models/WorkflowCreditSummary.d.ts +1 -1
- package/dist/openapi/models/WorkflowCreditSummary.js +1 -1
- package/dist/openapi/models/WorkflowDownloadResponse.d.ts +1 -1
- package/dist/openapi/models/WorkflowDownloadResponse.js +1 -1
- package/dist/openapi/models/WorkflowDownloadSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/WorkflowDownloadSuccessEnvelope.js +1 -1
- package/dist/openapi/models/WorkflowEdge.d.ts +1 -1
- package/dist/openapi/models/WorkflowEdge.js +1 -1
- package/dist/openapi/models/WorkflowExpiredResponse.d.ts +1 -1
- package/dist/openapi/models/WorkflowExpiredResponse.js +1 -1
- package/dist/openapi/models/WorkflowListResponse.d.ts +1 -1
- package/dist/openapi/models/WorkflowListResponse.js +1 -1
- package/dist/openapi/models/WorkflowListSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/WorkflowListSuccessEnvelope.js +1 -1
- package/dist/openapi/models/WorkflowPauseRequiredAction.d.ts +1 -1
- package/dist/openapi/models/WorkflowPauseRequiredAction.js +1 -1
- package/dist/openapi/models/WorkflowPausedDetail.d.ts +1 -1
- package/dist/openapi/models/WorkflowPausedDetail.js +1 -1
- package/dist/openapi/models/WorkflowPausedDetailLinks.d.ts +1 -1
- package/dist/openapi/models/WorkflowPausedDetailLinks.js +1 -1
- package/dist/openapi/models/WorkflowProcessing.d.ts +1 -1
- package/dist/openapi/models/WorkflowProcessing.js +1 -1
- package/dist/openapi/models/WorkflowRestoreResponse.d.ts +1 -1
- package/dist/openapi/models/WorkflowRestoreResponse.js +1 -1
- package/dist/openapi/models/WorkflowRestoreSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/WorkflowRestoreSuccessEnvelope.js +1 -1
- package/dist/openapi/models/WorkflowResumeResponse.d.ts +1 -1
- package/dist/openapi/models/WorkflowResumeResponse.js +1 -1
- package/dist/openapi/models/WorkflowResumeSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/WorkflowResumeSuccessEnvelope.js +1 -1
- package/dist/openapi/models/WorkflowSource.d.ts +1 -1
- package/dist/openapi/models/WorkflowSource.js +1 -1
- package/dist/openapi/models/WorkflowStatus.d.ts +1 -1
- package/dist/openapi/models/WorkflowStatus.js +1 -1
- package/dist/openapi/models/WorkflowStatusResponse.d.ts +1 -1
- package/dist/openapi/models/WorkflowStatusResponse.js +1 -1
- package/dist/openapi/models/WorkflowStatusSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/WorkflowStatusSuccessEnvelope.js +1 -1
- package/dist/openapi/models/WorkflowSummary.d.ts +1 -1
- package/dist/openapi/models/WorkflowSummary.js +1 -1
- package/dist/openapi/models/WorkflowSummaryJob.d.ts +1 -1
- package/dist/openapi/models/WorkflowSummaryJob.js +1 -1
- package/dist/openapi/models/WorkflowWarning.d.ts +1 -1
- package/dist/openapi/models/WorkflowWarning.js +1 -1
- package/dist/openapi/models/WorkflowWarningSeverity.d.ts +1 -1
- package/dist/openapi/models/WorkflowWarningSeverity.js +1 -1
- package/dist/openapi/models/index.d.ts +3 -4
- package/dist/openapi/models/index.js +3 -4
- package/dist/openapi/runtime.d.ts +1 -1
- package/dist/openapi/runtime.js +1 -1
- package/dist/operations/metadata-types.d.ts +1 -1
- package/dist/operations/thumbnail.d.ts +30 -7
- package/dist/operations/thumbnail.js +34 -17
- package/dist/operations/thumbnail.metadata.js +29 -1
- package/openapi/README.md +1 -1
- package/openapi/api.yaml +755 -214
- package/operation-capabilities/operation-capabilities.json +1 -1
- package/operations/schemas/compress.yaml +67 -10
- package/operations/schemas/thumbnail.yaml +100 -1
- package/package.json +7 -3
- package/dist/openapi/models/TierDefaultLimits.d.ts +0 -59
- 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.
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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:
|
|
333
|
+
max_size_bytes: 1048576
|
|
323
334
|
required_tier: "pro"
|
|
324
335
|
duration_exceeds_tier:
|
|
325
|
-
summary:
|
|
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
|
-
#
|
|
2422
|
-
#
|
|
2423
|
-
#
|
|
2424
|
-
# unproven
|
|
2425
|
-
#
|
|
2426
|
-
#
|
|
2427
|
-
#
|
|
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.**
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
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:
|
|
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:
|
|
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).
|
|
7389
|
-
|
|
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
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
the
|
|
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
|
-
|
|
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
|
-
|
|
8426
|
-
|
|
8427
|
-
|
|
8428
|
-
|
|
8429
|
-
|
|
8430
|
-
|
|
8431
|
-
|
|
8432
|
-
|
|
8433
|
-
|
|
8434
|
-
|
|
8435
|
-
|
|
8436
|
-
|
|
8437
|
-
|
|
8438
|
-
|
|
8439
|
-
|
|
8440
|
-
|
|
8441
|
-
|
|
8442
|
-
|
|
8443
|
-
**
|
|
8444
|
-
|
|
8445
|
-
|
|
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).
|
|
8448
|
-
|
|
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
|
-
|
|
8475
|
-
|
|
8476
|
-
|
|
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
|
|
13652
|
-
|
|
13653
|
-
|
|
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
|
-
|
|
13680
|
-
|
|
13681
|
-
|
|
13682
|
-
|
|
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: "
|
|
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.**
|
|
13705
|
-
|
|
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
|
-
|
|
14435
|
-
|
|
14436
|
-
|
|
14437
|
-
|
|
14438
|
-
|
|
14439
|
-
|
|
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
|