diff --git a/conformance/corpus/cases.json b/conformance/corpus/cases.json index 293b2322..b7d21d78 100644 --- a/conformance/corpus/cases.json +++ b/conformance/corpus/cases.json @@ -154,7 +154,7 @@ "enum.defined_only" ], "json": { - "reason": 8 + "reason": 10 } }, { diff --git a/gen/descriptor.binpb b/gen/descriptor.binpb index 7a66a6b6..a143437c 100644 Binary files a/gen/descriptor.binpb and b/gen/descriptor.binpb differ diff --git a/gen/go/ramp/v1/ramp.pb.go b/gen/go/ramp/v1/ramp.pb.go index e32bedf5..20e925a8 100644 --- a/gen/go/ramp/v1/ramp.pb.go +++ b/gen/go/ramp/v1/ramp.pb.go @@ -1493,7 +1493,17 @@ const ( CatalogRejectionReason_CATALOG_REJECTION_REASON_SIGNATURE_INVALID CatalogRejectionReason = 4 // request signature missing or invalid CatalogRejectionReason_CATALOG_REJECTION_REASON_MALFORMED_ENTRY CatalogRejectionReason = 5 // a resource entry failed schema/validation CatalogRejectionReason_CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN CatalogRejectionReason = 6 // an unregistered vocab token in a restriction/term - CatalogRejectionReason_CATALOG_REJECTION_REASON_QUOTA_EXCEEDED CatalogRejectionReason = 7 // contributor push quota exceeded + CatalogRejectionReason_CATALOG_REJECTION_REASON_QUOTA_EXCEEDED CatalogRejectionReason = 7 // contributor push quota exceeded (per-caller) + CatalogRejectionReason_CATALOG_REJECTION_REASON_TERMS_LIMIT_EXCEEDED CatalogRejectionReason = 8 // a single entry carries more license terms than allowed (per-entry cap) + // The URI cannot be claimed by this caller's entries. Named from the caller's + // own perspective ON PURPOSE: it MUST NOT disclose that another resource/ + // contributor already owns the URI. Within one publisher, mutually-untrusting + // contributors share a catalog, so an "owned by another" reason would be a + // confirmed-existence oracle a contributor could use to map a competitor's + // catalog. The conflict is resolvable only by the publisher (who is authorized + // to see full ownership); the human-readable message routes the caller there + // without confirming who, if anyone, holds the URI. + CatalogRejectionReason_CATALOG_REJECTION_REASON_URI_UNAVAILABLE CatalogRejectionReason = 9 ) // Enum value maps for CatalogRejectionReason. @@ -1507,6 +1517,8 @@ var ( 5: "CATALOG_REJECTION_REASON_MALFORMED_ENTRY", 6: "CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN", 7: "CATALOG_REJECTION_REASON_QUOTA_EXCEEDED", + 8: "CATALOG_REJECTION_REASON_TERMS_LIMIT_EXCEEDED", + 9: "CATALOG_REJECTION_REASON_URI_UNAVAILABLE", } CatalogRejectionReason_value = map[string]int32{ "CATALOG_REJECTION_REASON_UNSPECIFIED": 0, @@ -1517,6 +1529,8 @@ var ( "CATALOG_REJECTION_REASON_MALFORMED_ENTRY": 5, "CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN": 6, "CATALOG_REJECTION_REASON_QUOTA_EXCEEDED": 7, + "CATALOG_REJECTION_REASON_TERMS_LIMIT_EXCEEDED": 8, + "CATALOG_REJECTION_REASON_URI_UNAVAILABLE": 9, } ) @@ -9245,7 +9259,7 @@ const file_ramp_v1_ramp_proto_rawDesc = "" + "\x16RESOLUTION_TYPE_CREDIT\x10\x01\x12\x1e\n" + "\x1aRESOLUTION_TYPE_REDELIVERY\x10\x02\x12\x1c\n" + "\x18RESOLUTION_TYPE_REJECTED\x10\x03\x12!\n" + - "\x1dRESOLUTION_TYPE_INVESTIGATION\x10\x04*\x95\x03\n" + + "\x1dRESOLUTION_TYPE_INVESTIGATION\x10\x04*\xf6\x03\n" + "\x16CatalogRejectionReason\x12(\n" + "$CATALOG_REJECTION_REASON_UNSPECIFIED\x10\x00\x124\n" + "0CATALOG_REJECTION_REASON_NOT_CATALOG_CONTRIBUTOR\x10\x01\x12,\n" + @@ -9254,7 +9268,9 @@ const file_ramp_v1_ramp_proto_rawDesc = "" + "*CATALOG_REJECTION_REASON_SIGNATURE_INVALID\x10\x04\x12,\n" + "(CATALOG_REJECTION_REASON_MALFORMED_ENTRY\x10\x05\x120\n" + ",CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN\x10\x06\x12+\n" + - "'CATALOG_REJECTION_REASON_QUOTA_EXCEEDED\x10\a*\xc1\x02\n" + + "'CATALOG_REJECTION_REASON_QUOTA_EXCEEDED\x10\a\x121\n" + + "-CATALOG_REJECTION_REASON_TERMS_LIMIT_EXCEEDED\x10\b\x12,\n" + + "(CATALOG_REJECTION_REASON_URI_UNAVAILABLE\x10\t*\xc1\x02\n" + "\x19RegistrationFailureReason\x12+\n" + "'REGISTRATION_FAILURE_REASON_UNSPECIFIED\x10\x00\x123\n" + "/REGISTRATION_FAILURE_REASON_DOMAIN_NOT_VERIFIED\x10\x01\x12+\n" + diff --git a/gen/python/wire/models.py b/gen/python/wire/models.py index 01b14b63..38f1ffdc 100644 --- a/gen/python/wire/models.py +++ b/gen/python/wire/models.py @@ -93,6 +93,12 @@ class CatalogRejectionReason(Enum): 'CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN' ) CATALOG_REJECTION_REASON_QUOTA_EXCEEDED = 'CATALOG_REJECTION_REASON_QUOTA_EXCEEDED' + CATALOG_REJECTION_REASON_TERMS_LIMIT_EXCEEDED = ( + 'CATALOG_REJECTION_REASON_TERMS_LIMIT_EXCEEDED' + ) + CATALOG_REJECTION_REASON_URI_UNAVAILABLE = ( + 'CATALOG_REJECTION_REASON_URI_UNAVAILABLE' + ) class CitationFormat(Enum): diff --git a/gen/ts/wire/schemas.ts b/gen/ts/wire/schemas.ts index 48d9663c..277f1836 100644 --- a/gen/ts/wire/schemas.ts +++ b/gen/ts/wire/schemas.ts @@ -198,7 +198,7 @@ export const C2PAStatusSchema = z.enum(["C2PA_STATUS_TRUSTED","C2PA_STATUS_VALID export const CatalogContributorSchema = z.object({ "domain": z.string().describe("Canonical domain of the authorized contributor (e.g., \"doubleverify.com\").").default(""), "relationship": z.string().describe("Relationship of this contributor to the provider.\n Examples: \"verifier\" (resource intelligence vendor that attests to resource\n properties), \"exchange\" (an Exchange that enriches catalog entries).").default("") }).strict().describe("CatalogContributor — A third party authorized to push catalog metadata\n (including attestations) on behalf of a provider."); -export const CatalogRejectionSchema = z.object({ "reason": z.enum(["CATALOG_REJECTION_REASON_NOT_CATALOG_CONTRIBUTOR","CATALOG_REJECTION_REASON_TENANT_MISMATCH","CATALOG_REJECTION_REASON_DOMAIN_NOT_VERIFIED","CATALOG_REJECTION_REASON_SIGNATURE_INVALID","CATALOG_REJECTION_REASON_MALFORMED_ENTRY","CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN","CATALOG_REJECTION_REASON_QUOTA_EXCEEDED"]).describe("The rejection reason (defined-only, non-zero)"), "rejectedPaths": z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected.").optional() }).catchall(z.union([z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected."), z.never()])).superRefine((value, ctx) => { +export const CatalogRejectionSchema = z.object({ "reason": z.enum(["CATALOG_REJECTION_REASON_NOT_CATALOG_CONTRIBUTOR","CATALOG_REJECTION_REASON_TENANT_MISMATCH","CATALOG_REJECTION_REASON_DOMAIN_NOT_VERIFIED","CATALOG_REJECTION_REASON_SIGNATURE_INVALID","CATALOG_REJECTION_REASON_MALFORMED_ENTRY","CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN","CATALOG_REJECTION_REASON_QUOTA_EXCEEDED","CATALOG_REJECTION_REASON_TERMS_LIMIT_EXCEEDED","CATALOG_REJECTION_REASON_URI_UNAVAILABLE"]).describe("The rejection reason (defined-only, non-zero)"), "rejectedPaths": z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected.").optional() }).catchall(z.union([z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected."), z.never()])).superRefine((value, ctx) => { for (const key in value) { let evaluated = ["reason", "rejectedPaths"].includes(key) if (key.match(new RegExp("^(rejected_paths)$"))) { @@ -231,7 +231,7 @@ ctx.addIssue({ } }).describe("CatalogRejection — a CatalogService call could not be applied."); -export const CatalogRejectionReasonSchema = z.enum(["CATALOG_REJECTION_REASON_NOT_CATALOG_CONTRIBUTOR","CATALOG_REJECTION_REASON_TENANT_MISMATCH","CATALOG_REJECTION_REASON_DOMAIN_NOT_VERIFIED","CATALOG_REJECTION_REASON_SIGNATURE_INVALID","CATALOG_REJECTION_REASON_MALFORMED_ENTRY","CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN","CATALOG_REJECTION_REASON_QUOTA_EXCEEDED"]); +export const CatalogRejectionReasonSchema = z.enum(["CATALOG_REJECTION_REASON_NOT_CATALOG_CONTRIBUTOR","CATALOG_REJECTION_REASON_TENANT_MISMATCH","CATALOG_REJECTION_REASON_DOMAIN_NOT_VERIFIED","CATALOG_REJECTION_REASON_SIGNATURE_INVALID","CATALOG_REJECTION_REASON_MALFORMED_ENTRY","CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN","CATALOG_REJECTION_REASON_QUOTA_EXCEEDED","CATALOG_REJECTION_REASON_TERMS_LIMIT_EXCEEDED","CATALOG_REJECTION_REASON_URI_UNAVAILABLE"]); export const CitationFormatSchema = z.enum(["CITATION_FORMAT_LINK","CITATION_FORMAT_FOOTNOTE","CITATION_FORMAT_INLINE"]); @@ -4599,7 +4599,7 @@ ctx.addIssue({ } }).describe("DomainVerificationResult — Exchange confirms verification."); -export const ErrorDetailSchema = z.object({ "catalogRejection": z.object({ "reason": z.enum(["CATALOG_REJECTION_REASON_NOT_CATALOG_CONTRIBUTOR","CATALOG_REJECTION_REASON_TENANT_MISMATCH","CATALOG_REJECTION_REASON_DOMAIN_NOT_VERIFIED","CATALOG_REJECTION_REASON_SIGNATURE_INVALID","CATALOG_REJECTION_REASON_MALFORMED_ENTRY","CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN","CATALOG_REJECTION_REASON_QUOTA_EXCEEDED"]).describe("The rejection reason (defined-only, non-zero)"), "rejectedPaths": z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected.").optional() }).catchall(z.union([z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected."), z.never()])).superRefine((value, ctx) => { +export const ErrorDetailSchema = z.object({ "catalogRejection": z.object({ "reason": z.enum(["CATALOG_REJECTION_REASON_NOT_CATALOG_CONTRIBUTOR","CATALOG_REJECTION_REASON_TENANT_MISMATCH","CATALOG_REJECTION_REASON_DOMAIN_NOT_VERIFIED","CATALOG_REJECTION_REASON_SIGNATURE_INVALID","CATALOG_REJECTION_REASON_MALFORMED_ENTRY","CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN","CATALOG_REJECTION_REASON_QUOTA_EXCEEDED","CATALOG_REJECTION_REASON_TERMS_LIMIT_EXCEEDED","CATALOG_REJECTION_REASON_URI_UNAVAILABLE"]).describe("The rejection reason (defined-only, non-zero)"), "rejectedPaths": z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected.").optional() }).catchall(z.union([z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected."), z.never()])).superRefine((value, ctx) => { for (const key in value) { let evaluated = ["reason", "rejectedPaths"].includes(key) if (key.match(new RegExp("^(rejected_paths)$"))) { @@ -4675,7 +4675,7 @@ ctx.addIssue({ } } } -}).describe("`reason` oneof — ExecuteTransaction denial").optional(), "usageReportRejection": z.object({ "reason": z.enum(["USAGE_REPORT_REJECTION_REASON_TRANSACTION_NOT_FOUND","USAGE_REPORT_REJECTION_REASON_DUPLICATE","USAGE_REPORT_REJECTION_REASON_WINDOW_EXPIRED","USAGE_REPORT_REJECTION_REASON_MISSING_REQUIRED_FIELDS","USAGE_REPORT_REJECTION_REASON_MALFORMED"]).describe("The rejection reason (defined-only, non-zero)") }).strict().describe("`reason` oneof — ReportUsage filing rejected").optional() }).catchall(z.union([z.object({ "reason": z.enum(["CATALOG_REJECTION_REASON_NOT_CATALOG_CONTRIBUTOR","CATALOG_REJECTION_REASON_TENANT_MISMATCH","CATALOG_REJECTION_REASON_DOMAIN_NOT_VERIFIED","CATALOG_REJECTION_REASON_SIGNATURE_INVALID","CATALOG_REJECTION_REASON_MALFORMED_ENTRY","CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN","CATALOG_REJECTION_REASON_QUOTA_EXCEEDED"]).describe("The rejection reason (defined-only, non-zero)"), "rejectedPaths": z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected.").optional() }).catchall(z.union([z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected."), z.never()])).superRefine((value, ctx) => { +}).describe("`reason` oneof — ExecuteTransaction denial").optional(), "usageReportRejection": z.object({ "reason": z.enum(["USAGE_REPORT_REJECTION_REASON_TRANSACTION_NOT_FOUND","USAGE_REPORT_REJECTION_REASON_DUPLICATE","USAGE_REPORT_REJECTION_REASON_WINDOW_EXPIRED","USAGE_REPORT_REJECTION_REASON_MISSING_REQUIRED_FIELDS","USAGE_REPORT_REJECTION_REASON_MALFORMED"]).describe("The rejection reason (defined-only, non-zero)") }).strict().describe("`reason` oneof — ReportUsage filing rejected").optional() }).catchall(z.union([z.object({ "reason": z.enum(["CATALOG_REJECTION_REASON_NOT_CATALOG_CONTRIBUTOR","CATALOG_REJECTION_REASON_TENANT_MISMATCH","CATALOG_REJECTION_REASON_DOMAIN_NOT_VERIFIED","CATALOG_REJECTION_REASON_SIGNATURE_INVALID","CATALOG_REJECTION_REASON_MALFORMED_ENTRY","CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN","CATALOG_REJECTION_REASON_QUOTA_EXCEEDED","CATALOG_REJECTION_REASON_TERMS_LIMIT_EXCEEDED","CATALOG_REJECTION_REASON_URI_UNAVAILABLE"]).describe("The rejection reason (defined-only, non-zero)"), "rejectedPaths": z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected.").optional() }).catchall(z.union([z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected."), z.never()])).superRefine((value, ctx) => { for (const key in value) { let evaluated = ["reason", "rejectedPaths"].includes(key) if (key.match(new RegExp("^(rejected_paths)$"))) { @@ -4756,7 +4756,7 @@ for (const key in value) { let evaluated = ["catalogRejection", "disputeFailure", "domain", "domainVerificationFailure", "message", "metadata", "registrationFailure", "retrievalAuthFailure", "transactionDenial", "usageReportRejection"].includes(key) if (key.match(new RegExp("^(catalog_rejection)$"))) { evaluated = true -const result = z.object({ "reason": z.enum(["CATALOG_REJECTION_REASON_NOT_CATALOG_CONTRIBUTOR","CATALOG_REJECTION_REASON_TENANT_MISMATCH","CATALOG_REJECTION_REASON_DOMAIN_NOT_VERIFIED","CATALOG_REJECTION_REASON_SIGNATURE_INVALID","CATALOG_REJECTION_REASON_MALFORMED_ENTRY","CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN","CATALOG_REJECTION_REASON_QUOTA_EXCEEDED"]).describe("The rejection reason (defined-only, non-zero)"), "rejectedPaths": z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected.").optional() }).catchall(z.union([z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected."), z.never()])).superRefine((value, ctx) => { +const result = z.object({ "reason": z.enum(["CATALOG_REJECTION_REASON_NOT_CATALOG_CONTRIBUTOR","CATALOG_REJECTION_REASON_TENANT_MISMATCH","CATALOG_REJECTION_REASON_DOMAIN_NOT_VERIFIED","CATALOG_REJECTION_REASON_SIGNATURE_INVALID","CATALOG_REJECTION_REASON_MALFORMED_ENTRY","CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN","CATALOG_REJECTION_REASON_QUOTA_EXCEEDED","CATALOG_REJECTION_REASON_TERMS_LIMIT_EXCEEDED","CATALOG_REJECTION_REASON_URI_UNAVAILABLE"]).describe("The rejection reason (defined-only, non-zero)"), "rejectedPaths": z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected.").optional() }).catchall(z.union([z.array(z.string()).describe("For partial-batch failures: the entry paths that were rejected."), z.never()])).superRefine((value, ctx) => { for (const key in value) { let evaluated = ["reason", "rejectedPaths"].includes(key) if (key.match(new RegExp("^(rejected_paths)$"))) { diff --git a/proto/ramp/v1/ramp.proto b/proto/ramp/v1/ramp.proto index c4e430e9..6752ec9c 100644 --- a/proto/ramp/v1/ramp.proto +++ b/proto/ramp/v1/ramp.proto @@ -3034,7 +3034,17 @@ enum CatalogRejectionReason { CATALOG_REJECTION_REASON_SIGNATURE_INVALID = 4; // request signature missing or invalid CATALOG_REJECTION_REASON_MALFORMED_ENTRY = 5; // a resource entry failed schema/validation CATALOG_REJECTION_REASON_UNKNOWN_VOCAB_TOKEN = 6; // an unregistered vocab token in a restriction/term - CATALOG_REJECTION_REASON_QUOTA_EXCEEDED = 7; // contributor push quota exceeded + CATALOG_REJECTION_REASON_QUOTA_EXCEEDED = 7; // contributor push quota exceeded (per-caller) + CATALOG_REJECTION_REASON_TERMS_LIMIT_EXCEEDED = 8; // a single entry carries more license terms than allowed (per-entry cap) + // The URI cannot be claimed by this caller's entries. Named from the caller's + // own perspective ON PURPOSE: it MUST NOT disclose that another resource/ + // contributor already owns the URI. Within one publisher, mutually-untrusting + // contributors share a catalog, so an "owned by another" reason would be a + // confirmed-existence oracle a contributor could use to map a competitor's + // catalog. The conflict is resolvable only by the publisher (who is authorized + // to see full ownership); the human-readable message routes the caller there + // without confirming who, if anyone, holds the URI. + CATALOG_REJECTION_REASON_URI_UNAVAILABLE = 9; } // CatalogRejection — a CatalogService call could not be applied.