@peac/schema 0.12.3 → 0.12.5
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/dist/index.cjs +10 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +9 -5
- package/dist/index.mjs.map +1 -1
- package/dist/receipt-parser.cjs +5 -4
- package/dist/receipt-parser.cjs.map +1 -1
- package/dist/receipt-parser.mjs +5 -4
- package/dist/receipt-parser.mjs.map +1 -1
- package/dist/wire-02-extensions/commerce.d.ts +16 -0
- package/dist/wire-02-extensions/commerce.d.ts.map +1 -1
- package/dist/wire-02-extensions/index.d.ts +1 -1
- package/dist/wire-02-extensions/index.d.ts.map +1 -1
- package/dist/wire-02-extensions.d.ts +1 -1
- package/dist/wire-02-extensions.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/json.ts","../src/errors.ts","../src/purpose.ts","../src/validators.ts","../src/attestation-receipt.ts","../src/actor-binding.ts","../src/extensions/fingerprint-ref.ts","../src/wire-02-representation.ts","../src/wire-02-extensions/limits.ts","../src/wire-02-extensions/grammar.ts","../src/wire-02-extensions/commerce.ts","../src/wire-02-extensions/access.ts","../src/wire-02-extensions/challenge.ts","../src/wire-02-extensions/identity.ts","../src/wire-02-extensions/correlation.ts","../src/wire-02-extensions/shared-validators.ts","../src/wire-02-extensions/consent.ts","../src/wire-02-extensions/privacy.ts","../src/wire-02-extensions/safety.ts","../src/wire-02-extensions/compliance.ts","../src/wire-02-extensions/provenance.ts","../src/wire-02-extensions/attribution.ts","../src/wire-02-extensions/purpose-extension.ts","../src/wire-02-extensions/schema-map.ts","../src/wire-02-extensions/validation.ts","../src/wire-02-envelope.ts","../src/receipt-parser.ts"],"names":["z","httpsUrl","uuidv7","KERNEL_ERROR_CODES","EXTENSION_BUDGET","HASH","result"],"mappings":"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","file":"receipt-parser.mjs","sourcesContent":["/**\n * Wire format constants - FROZEN\n *\n * These constants are now sourced from @peac/kernel\n * (normative source: specs/kernel/constants.json)\n */\n\nimport { WIRE_TYPE, ALGORITHMS, HEADERS, POLICY, ISSUER_CONFIG, DISCOVERY } from '@peac/kernel';\n\n/**\n * Wire format version - peac-receipt/0.1\n * Normalized in v0.10.0 to peac-<artifact>/<major>.<minor> pattern\n */\nexport const PEAC_WIRE_TYP = WIRE_TYPE;\n\n/**\n * Signature algorithm - FROZEN forever\n */\nexport const PEAC_ALG = ALGORITHMS.default;\n\n/**\n * Canonical header name\n */\nexport const PEAC_RECEIPT_HEADER = HEADERS.receipt;\n\n/**\n * Purpose header names (v0.9.24+)\n */\nexport const PEAC_PURPOSE_HEADER = HEADERS.purpose;\nexport const PEAC_PURPOSE_APPLIED_HEADER = HEADERS.purposeApplied;\nexport const PEAC_PURPOSE_REASON_HEADER = HEADERS.purposeReason;\n\n/**\n * Policy manifest path (/.well-known/peac.txt)\n * @see docs/specs/PEAC-TXT.md\n */\nexport const PEAC_POLICY_PATH = POLICY.manifestPath;\n\n/**\n * Policy manifest fallback path (/peac.txt)\n */\nexport const PEAC_POLICY_FALLBACK_PATH = POLICY.fallbackPath;\n\n/**\n * Maximum policy manifest size\n */\nexport const PEAC_POLICY_MAX_BYTES = POLICY.maxBytes;\n\n/**\n * Issuer configuration path (/.well-known/peac-issuer.json)\n * @see docs/specs/PEAC-ISSUER.md\n */\nexport const PEAC_ISSUER_CONFIG_PATH = ISSUER_CONFIG.configPath;\n\n/**\n * Issuer configuration version\n */\nexport const PEAC_ISSUER_CONFIG_VERSION = ISSUER_CONFIG.configVersion;\n\n/**\n * Maximum issuer configuration size\n */\nexport const PEAC_ISSUER_CONFIG_MAX_BYTES = ISSUER_CONFIG.maxBytes;\n\n/**\n * @deprecated Use PEAC_POLICY_PATH instead. Will be removed in v1.0.\n */\nexport const PEAC_DISCOVERY_PATH = DISCOVERY.manifestPath;\n\n/**\n * @deprecated Use PEAC_POLICY_MAX_BYTES instead. Will be removed in v1.0.\n */\nexport const PEAC_DISCOVERY_MAX_BYTES = 2000 as const;\n\n/**\n * JSON Schema URL for PEAC receipt wire format v0.1\n *\n * This is the canonical $id for the root schema.\n * Use for schema references and cross-implementation validation.\n *\n * @since v0.10.0\n */\nexport const PEAC_RECEIPT_SCHEMA_URL =\n 'https://www.peacprotocol.org/schemas/wire/0.1/peac-receipt.0.1.schema.json' as const;\n","/**\n * JSON-safe validation schemas\n *\n * Provides Zod schemas that guarantee JSON roundtrip safety:\n * - Rejects NaN, Infinity, -Infinity (not valid JSON numbers)\n * - Rejects undefined (dropped by JSON.stringify)\n * - Rejects non-plain objects (Date, Map, Set, class instances)\n * - Rejects functions, symbols, bigints\n */\n\nimport { z } from 'zod';\nimport type { JsonValue, JsonObject, JsonArray } from '@peac/kernel';\nimport { KERNEL_CONSTRAINTS } from './constraints';\n\n/**\n * Check if value is a plain object (not Date, Map, Set, class instance, etc.)\n *\n * A plain object has prototype of Object.prototype or null.\n * This rejects Date, Map, Set, Array, and class instances even when\n * they have zero enumerable properties (which would pass z.record()).\n */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== 'object') {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * JSON number schema - rejects NaN and Infinity\n *\n * JSON.stringify(NaN) === \"null\" and JSON.stringify(Infinity) === \"null\"\n * which silently corrupts data. We reject these at validation time.\n */\nconst JsonNumberSchema = z.number().finite();\n\n/**\n * JSON primitive schema - string, finite number, boolean, null\n */\nexport const JsonPrimitiveSchema = z.union([z.string(), JsonNumberSchema, z.boolean(), z.null()]);\n\n/**\n * Plain object schema (internal) - validates object is plain before recursive validation\n */\nconst PlainObjectSchema = z.unknown().refine(isPlainObject, {\n message: 'Expected plain object, received non-plain object (Date, Map, Set, or class instance)',\n});\n\n/**\n * JSON value schema - recursive type for any valid JSON value\n *\n * Validates:\n * - Primitives: string, finite number, boolean, null\n * - Arrays: containing valid JSON values\n * - Objects: plain objects with string keys and valid JSON values\n *\n * Rejects:\n * - undefined (dropped by JSON.stringify)\n * - NaN, Infinity, -Infinity (become null in JSON)\n * - BigInt (throws in JSON.stringify)\n * - Date (becomes ISO string - implicit conversion)\n * - Map, Set (become {} in JSON)\n * - Functions, Symbols (dropped by JSON.stringify)\n * - Class instances (prototype chain lost)\n */\nexport const JsonValueSchema: z.ZodType<JsonValue> = z.lazy(() =>\n z.union([\n JsonPrimitiveSchema,\n z.array(JsonValueSchema),\n // Plain object check then record validation\n PlainObjectSchema.transform((obj) => obj as Record<string, unknown>).pipe(\n z.record(z.string(), JsonValueSchema)\n ),\n ])\n) as z.ZodType<JsonValue>;\n\n/**\n * JSON object schema - plain object with string keys and JSON values\n *\n * Rejects non-plain objects (Date, Map, Set, class instances).\n */\nexport const JsonObjectSchema: z.ZodType<JsonObject> = PlainObjectSchema.transform(\n (obj) => obj as Record<string, unknown>\n).pipe(z.record(z.string(), JsonValueSchema)) as z.ZodType<JsonObject>;\n\n/**\n * JSON array schema - array of JSON values\n */\nexport const JsonArraySchema: z.ZodType<JsonArray> = z.array(JsonValueSchema);\n\n/**\n * Default limits for JSON evidence validation.\n *\n * Derived from KERNEL_CONSTRAINTS (single source of truth).\n * These are conservative defaults to prevent DoS attacks via deeply nested\n * or excessively large JSON structures.\n */\nexport const JSON_EVIDENCE_LIMITS = {\n /** Maximum nesting depth (default: 32) */\n maxDepth: KERNEL_CONSTRAINTS.MAX_NESTED_DEPTH,\n /** Maximum array length (default: 10,000) */\n maxArrayLength: KERNEL_CONSTRAINTS.MAX_ARRAY_LENGTH,\n /** Maximum object keys (default: 1,000) */\n maxObjectKeys: KERNEL_CONSTRAINTS.MAX_OBJECT_KEYS,\n /** Maximum string length in code units (default: 65,536) */\n maxStringLength: KERNEL_CONSTRAINTS.MAX_STRING_LENGTH,\n /** Maximum total nodes to visit (default: 100,000) */\n maxTotalNodes: KERNEL_CONSTRAINTS.MAX_TOTAL_NODES,\n} as const;\n\n/**\n * Limits for JSON evidence validation\n *\n * @internal - Not part of public API. Use validateEvidence() with defaults.\n *\n * For testing only: import via UNSAFE_JsonEvidenceLimits\n */\nexport interface JsonEvidenceLimits {\n maxDepth?: number;\n maxArrayLength?: number;\n maxObjectKeys?: number;\n maxStringLength?: number;\n maxTotalNodes?: number;\n}\n\n/**\n * Result of JSON safety validation\n */\nexport type JsonSafetyResult =\n | { ok: true }\n | { ok: false; error: string; path: (string | number)[] };\n\n/**\n * Stack entry type for iterative traversal\n *\n * - \"enter\": entering an object/array, need to validate and push children\n * - \"exit\": exiting an object/array, remove from current path (for cycle detection)\n */\ntype StackEntry =\n | { type: 'enter'; value: unknown; path: (string | number)[]; depth: number }\n | { type: 'exit'; obj: object };\n\n/**\n * Iterative JSON safety validator\n *\n * Validates that a value is JSON-safe without using recursion, preventing\n * stack overflow on deeply nested structures. Uses an explicit stack for\n * traversal with entry/exit markers for correct cycle detection.\n *\n * Cycle Detection:\n * Uses a path-based approach where only objects on the current traversal\n * path are tracked. This correctly allows diamond structures (same object\n * referenced from multiple paths) while rejecting actual cycles (object\n * references itself through its descendants).\n *\n * Rejects:\n * - Cycles (object references itself directly or indirectly)\n * - Non-plain objects (Date, Map, Set, class instances)\n * - Non-finite numbers (NaN, Infinity, -Infinity)\n * - undefined, BigInt, functions, symbols\n * - Structures exceeding depth/size limits\n *\n * Allows:\n * - Diamond structures (same object referenced from multiple paths)\n *\n * @param value - Value to validate\n * @param limits - Optional limits (defaults to JSON_EVIDENCE_LIMITS)\n * @returns Result indicating success or failure with error details\n */\nexport function assertJsonSafeIterative(\n value: unknown,\n limits: JsonEvidenceLimits = {}\n): JsonSafetyResult {\n const maxDepth = limits.maxDepth ?? JSON_EVIDENCE_LIMITS.maxDepth;\n const maxArrayLength = limits.maxArrayLength ?? JSON_EVIDENCE_LIMITS.maxArrayLength;\n const maxObjectKeys = limits.maxObjectKeys ?? JSON_EVIDENCE_LIMITS.maxObjectKeys;\n const maxStringLength = limits.maxStringLength ?? JSON_EVIDENCE_LIMITS.maxStringLength;\n const maxTotalNodes = limits.maxTotalNodes ?? JSON_EVIDENCE_LIMITS.maxTotalNodes;\n\n // Track objects on the current traversal path for cycle detection.\n // An object appearing twice on the same path is a cycle.\n // An object appearing on different paths (diamond) is NOT a cycle.\n const pathSet = new WeakSet<object>();\n\n // Track total nodes visited for DoS protection\n let nodeCount = 0;\n\n // Stack with entry/exit markers for path tracking\n const stack: StackEntry[] = [{ type: 'enter', value, path: [], depth: 0 }];\n\n while (stack.length > 0) {\n const entry = stack.pop()!;\n\n // Handle exit marker - remove object from current path\n if (entry.type === 'exit') {\n pathSet.delete(entry.obj);\n continue;\n }\n\n const { value: current, path, depth } = entry;\n\n // Check total node limit\n nodeCount++;\n if (nodeCount > maxTotalNodes) {\n return {\n ok: false,\n error: `Maximum total nodes exceeded (limit: ${maxTotalNodes})`,\n path,\n };\n }\n\n // Check depth limit\n if (depth > maxDepth) {\n return {\n ok: false,\n error: `Maximum depth exceeded (limit: ${maxDepth})`,\n path,\n };\n }\n\n // Handle null (valid JSON)\n if (current === null) {\n continue;\n }\n\n // Handle primitives\n const type = typeof current;\n\n if (type === 'string') {\n if ((current as string).length > maxStringLength) {\n return {\n ok: false,\n error: `String exceeds maximum length (limit: ${maxStringLength})`,\n path,\n };\n }\n continue;\n }\n\n if (type === 'number') {\n if (!Number.isFinite(current as number)) {\n return {\n ok: false,\n error: `Non-finite number: ${current}`,\n path,\n };\n }\n continue;\n }\n\n if (type === 'boolean') {\n continue;\n }\n\n // Reject non-JSON types\n if (type === 'undefined') {\n return { ok: false, error: 'undefined is not valid JSON', path };\n }\n\n if (type === 'bigint') {\n return { ok: false, error: 'BigInt is not valid JSON', path };\n }\n\n if (type === 'function') {\n return { ok: false, error: 'Function is not valid JSON', path };\n }\n\n if (type === 'symbol') {\n return { ok: false, error: 'Symbol is not valid JSON', path };\n }\n\n // Handle objects (arrays and plain objects)\n if (type === 'object') {\n const obj = current as object;\n\n // Cycle detection - check if object is already on the current path\n // (not just visited anywhere, but specifically an ancestor)\n if (pathSet.has(obj)) {\n return { ok: false, error: 'Cycle detected in object graph', path };\n }\n\n // Add to current path and push exit marker to remove when done\n pathSet.add(obj);\n stack.push({ type: 'exit', obj });\n\n // Handle arrays\n if (Array.isArray(obj)) {\n if (obj.length > maxArrayLength) {\n return {\n ok: false,\n error: `Array exceeds maximum length (limit: ${maxArrayLength})`,\n path,\n };\n }\n // Push array elements to stack in reverse order for correct traversal\n for (let i = obj.length - 1; i >= 0; i--) {\n stack.push({ type: 'enter', value: obj[i], path: [...path, i], depth: depth + 1 });\n }\n continue;\n }\n\n // Check for non-plain objects (Date, Map, Set, class instances, etc.)\n const proto = Object.getPrototypeOf(obj);\n if (proto !== Object.prototype && proto !== null) {\n const constructorName = obj.constructor?.name ?? 'unknown';\n return {\n ok: false,\n error: `Non-plain object (${constructorName}) is not valid JSON`,\n path,\n };\n }\n\n // Handle plain objects\n const keys = Object.keys(obj);\n if (keys.length > maxObjectKeys) {\n return {\n ok: false,\n error: `Object exceeds maximum key count (limit: ${maxObjectKeys})`,\n path,\n };\n }\n // Push object values to stack\n for (let i = keys.length - 1; i >= 0; i--) {\n const key = keys[i];\n stack.push({\n type: 'enter',\n value: (obj as Record<string, unknown>)[key],\n path: [...path, key],\n depth: depth + 1,\n });\n }\n continue;\n }\n\n // Shouldn't reach here, but reject unknown types\n return { ok: false, error: `Unknown type: ${type}`, path };\n }\n\n return { ok: true };\n}\n","/**\n * PEAC Structured Error Model\n *\n * Standardized error responses for protocol failures.\n * See docs/specs/ERRORS.md for complete error registry.\n */\n\n// Import the generated categories from kernel (single source of truth: specs/kernel/errors.json)\n// Namespace import avoids tsup tree-shaking false positive in multi-entry builds\n// where ERROR_CATEGORIES appears unused in entry points that don't reference it.\nimport * as kernel from '@peac/kernel';\nimport type { ErrorCategory } from '@peac/kernel';\nexport type { ErrorCategory };\n\n/**\n * @deprecated Use ERROR_CATEGORIES from @peac/kernel instead.\n * Re-exported for backwards compatibility.\n */\nexport const ERROR_CATEGORIES_CANONICAL = kernel.ERROR_CATEGORIES;\n\n/**\n * Error severity\n */\nexport type ErrorSeverity = 'error' | 'warning';\n\n/**\n * Structured PEAC error\n *\n * Provides machine-readable error information with:\n * - Stable error codes\n * - Category classification\n * - Retryability hints\n * - Remediation guidance\n */\nexport interface PEACError {\n /**\n * Error code\n *\n * Stable identifier for this error type.\n * See docs/specs/ERRORS.md for registry.\n *\n * Examples:\n * - \"E_CONTROL_REQUIRED\"\n * - \"E_INVALID_SIGNATURE\"\n * - \"E_SSRF_BLOCKED\"\n * - \"E_DPOP_REPLAY\"\n */\n code: string;\n\n /**\n * Error category\n *\n * Broad classification for programmatic handling.\n */\n category: ErrorCategory;\n\n /**\n * Error severity\n *\n * - \"error\": Operation failed, cannot proceed\n * - \"warning\": Operation succeeded but with caveats\n */\n severity: ErrorSeverity;\n\n /**\n * Whether the operation is retryable\n *\n * - true: Client should retry (network, rate limit, transient)\n * - false: Client should not retry (validation, security, permanent)\n */\n retryable: boolean;\n\n /**\n * Suggested HTTP status code\n *\n * Maps error to appropriate HTTP response code.\n * Examples:\n * - 400: Validation errors\n * - 401: Verification failures (signature, attestation temporal)\n * - 403: Control denials (authorization)\n * - 502: Infrastructure failures (JWKS fetch, etc.)\n */\n http_status?: number;\n\n /**\n * JSON Pointer (RFC 6901) to problematic field\n *\n * Identifies the specific field that caused the error.\n * Examples:\n * - \"/auth/control\" - Missing control block\n * - \"/evidence/payment/amount\" - Invalid amount\n * - \"/auth/control/chain/0/result\" - Invalid result value\n */\n pointer?: string;\n\n /**\n * Human-readable remediation guidance\n *\n * Short hint for fixing the error.\n * Examples:\n * - \"Add control{} block when payment{} is present\"\n * - \"Ensure JWS signature is valid\"\n * - \"Retry after 60 seconds\"\n */\n remediation?: string;\n\n /**\n * Implementation-specific error details\n *\n * Additional context for debugging.\n * Structure varies by error code.\n */\n details?: unknown;\n}\n\n/**\n * Error code registry\n *\n * Well-known error codes. See docs/specs/ERRORS.md for complete list.\n */\nexport const ERROR_CODES = {\n // Validation errors (400)\n E_CONTROL_REQUIRED: 'E_CONTROL_REQUIRED',\n E_INVALID_ENVELOPE: 'E_INVALID_ENVELOPE',\n E_INVALID_CONTROL_CHAIN: 'E_INVALID_CONTROL_CHAIN',\n E_INVALID_PAYMENT: 'E_INVALID_PAYMENT',\n E_INVALID_POLICY_HASH: 'E_INVALID_POLICY_HASH',\n E_EXPIRED_RECEIPT: 'E_EXPIRED_RECEIPT',\n E_EVIDENCE_NOT_JSON: 'E_EVIDENCE_NOT_JSON',\n\n // Verification errors (401)\n E_INVALID_SIGNATURE: 'E_INVALID_SIGNATURE',\n E_SSRF_BLOCKED: 'E_SSRF_BLOCKED',\n E_DPOP_REPLAY: 'E_DPOP_REPLAY',\n E_DPOP_INVALID: 'E_DPOP_INVALID',\n\n // Control errors (403)\n E_CONTROL_DENIED: 'E_CONTROL_DENIED',\n\n // Infrastructure errors (502/503)\n E_JWKS_FETCH_FAILED: 'E_JWKS_FETCH_FAILED',\n E_POLICY_FETCH_FAILED: 'E_POLICY_FETCH_FAILED',\n E_NETWORK_ERROR: 'E_NETWORK_ERROR',\n\n // Workflow errors (400)\n E_WORKFLOW_CONTEXT_INVALID: 'E_WORKFLOW_CONTEXT_INVALID',\n E_WORKFLOW_DAG_INVALID: 'E_WORKFLOW_DAG_INVALID',\n E_WORKFLOW_LIMIT_EXCEEDED: 'E_WORKFLOW_LIMIT_EXCEEDED',\n E_WORKFLOW_ID_INVALID: 'E_WORKFLOW_ID_INVALID',\n E_WORKFLOW_STEP_ID_INVALID: 'E_WORKFLOW_STEP_ID_INVALID',\n E_WORKFLOW_PARENT_NOT_FOUND: 'E_WORKFLOW_PARENT_NOT_FOUND',\n E_WORKFLOW_SUMMARY_INVALID: 'E_WORKFLOW_SUMMARY_INVALID',\n E_WORKFLOW_CYCLE_DETECTED: 'E_WORKFLOW_CYCLE_DETECTED',\n\n // Constraint errors (400)\n E_CONSTRAINT_VIOLATION: 'E_CONSTRAINT_VIOLATION',\n\n // Wire 0.2 extension errors (400/)\n E_INVALID_EXTENSION_KEY: 'E_INVALID_EXTENSION_KEY',\n} as const;\n\n/**\n * Error code type\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\n/**\n * Helper to create a structured error\n */\nexport function createPEACError(\n code: ErrorCode,\n category: ErrorCategory,\n severity: ErrorSeverity,\n retryable: boolean,\n options?: {\n http_status?: number;\n pointer?: string;\n remediation?: string;\n details?: unknown;\n }\n): PEACError {\n return {\n code,\n category,\n severity,\n retryable,\n ...options,\n };\n}\n\n/**\n * Create an evidence validation error\n *\n * Used when evidence contains non-JSON-safe values like NaN, Infinity,\n * undefined, Date, Map, Set, BigInt, functions, or class instances.\n */\nexport function createEvidenceNotJsonError(message: string, path?: (string | number)[]): PEACError {\n return createPEACError(ERROR_CODES.E_EVIDENCE_NOT_JSON, 'validation', 'error', false, {\n http_status: 400,\n pointer: path ? '/' + path.join('/') : undefined,\n remediation:\n 'Ensure evidence contains only JSON-safe values (strings, finite numbers, booleans, null, arrays, plain objects)',\n details: { message },\n });\n}\n\n// ============================================================================\n// Workflow Error Helpers (v0.10.2+)\n// ============================================================================\n\n/**\n * Create a workflow context validation error\n *\n * Used when workflow_context does not conform to WorkflowContextSchema.\n */\nexport function createWorkflowContextInvalidError(details?: string): PEACError {\n return createPEACError(ERROR_CODES.E_WORKFLOW_CONTEXT_INVALID, 'validation', 'error', false, {\n http_status: 400,\n pointer: '/ext/org.peacprotocol~1workflow',\n remediation: 'Ensure workflow_context conforms to WorkflowContextSchema',\n details: { message: details ?? 'Invalid workflow context' },\n });\n}\n\n/**\n * Create a workflow DAG validation error\n *\n * Used when workflow DAG semantics are violated (self-parent, duplicate parents, cycle).\n */\nexport function createWorkflowDagInvalidError(\n reason: 'self_parent' | 'duplicate_parent' | 'cycle'\n): PEACError {\n const messages = {\n self_parent: 'Step cannot be its own parent',\n duplicate_parent: 'Parent step IDs must be unique',\n cycle: 'Workflow DAG contains a cycle',\n };\n return createPEACError(ERROR_CODES.E_WORKFLOW_DAG_INVALID, 'validation', 'error', false, {\n http_status: 400,\n pointer: '/ext/org.peacprotocol~1workflow/parent_step_ids',\n remediation: 'Ensure workflow forms a valid directed acyclic graph (DAG)',\n details: { reason, message: messages[reason] },\n });\n}\n\n// ============================================================================\n// Constraint Error Helpers (v0.11.0+)\n// ============================================================================\n\n/**\n * Create a kernel constraint violation error\n *\n * Used when receipt claims violate structural kernel constraints\n * (depth, array length, object keys, string length, total nodes).\n */\nexport function createConstraintViolationError(\n violations: Array<{\n constraint: string;\n actual: number;\n limit: number;\n path?: string;\n }>\n): PEACError {\n const first = violations[0];\n const summary = violations\n .map((v) => `${v.constraint} (actual: ${v.actual}, limit: ${v.limit})`)\n .join('; ');\n return createPEACError(ERROR_CODES.E_CONSTRAINT_VIOLATION, 'validation', 'error', false, {\n http_status: 400,\n pointer: first?.path,\n remediation: 'Reduce receipt claims size to stay within kernel constraints',\n details: { message: `Kernel constraint violated: ${summary}`, violations },\n });\n}\n","/**\n * PEAC Purpose Types (v0.9.24+)\n *\n * Purpose type hierarchy for forward-compatible purpose handling:\n * - PurposeToken: Wire format (string) - preserves unknown tokens\n * - CanonicalPurpose: PEAC's normative vocabulary - enforcement semantics\n * - PurposeReason: Audit spine for enforcement decisions\n *\n * @see specs/kernel/constants.json for canonical values\n */\n\n/**\n * PurposeToken - Wire format string with validation grammar\n *\n * Allows unknown tokens for forward compatibility. Any valid token\n * that matches the grammar is accepted and preserved.\n *\n * Grammar: lowercase, max 64 chars, [a-z0-9_-] + optional vendor prefix (vendor:token)\n * Hyphens allowed for interop with external systems (Cloudflare, IETF AIPREF, etc.)\n *\n * Examples: \"train\", \"search\", \"user_action\", \"user-action\", \"cf:ai_crawler\", \"cf:ai-crawler\"\n */\nexport type PurposeToken = string;\n\n/**\n * CanonicalPurpose - PEAC's normative vocabulary\n *\n * These are the only tokens PEAC enforces semantics for.\n * Matches specs/kernel/constants.json purpose.canonical_tokens.\n *\n * - train: Model training data collection\n * - search: Traditional search indexing\n * - user_action: Agent acting on user behalf (v0.9.24+)\n * - inference: Runtime inference / RAG\n * - index: Content indexing (store)\n */\nexport type CanonicalPurpose = 'train' | 'search' | 'user_action' | 'inference' | 'index';\n\n/**\n * Internal-only purpose value (never valid on wire)\n *\n * Applied when PEAC-Purpose header is missing or empty.\n * Explicit \"undeclared\" in request -> 400 Bad Request.\n */\nexport type InternalPurpose = 'undeclared';\n\n/**\n * PurposeReason - Audit spine for enforcement decisions\n *\n * Captures WHY a purpose was enforced differently than declared.\n * Matches specs/kernel/constants.json purpose.reason_values.\n */\nexport type PurposeReason =\n | 'allowed' // Purpose permitted as declared (happy path)\n | 'constrained' // Allowed with rate limits applied\n | 'denied' // Purpose rejected by policy\n | 'downgraded' // More restrictive purpose applied\n | 'undeclared_default' // No purpose declared, default applied\n | 'unknown_preserved'; // Unknown purpose token, preserved but flagged\n\n/**\n * Legacy purpose tokens from pre-v0.9.24\n *\n * These are mapped to CanonicalPurpose via mapLegacyToCanonical().\n * Retained for backward compatibility with existing ControlPurpose usage.\n */\nexport type LegacyPurpose = 'crawl' | 'ai_input' | 'ai_index';\n\n// ============================================================================\n// Validation Constants\n// ============================================================================\n\n/**\n * Grammar validation for PurposeToken\n *\n * Pattern: lowercase letter, optionally followed by alphanumeric/underscore/hyphen\n * characters that MUST end with a letter or digit (no trailing separators).\n * Optional vendor prefix separated by colon follows the same rules.\n *\n * Hyphens are allowed for interoperability with external systems (Cloudflare,\n * IETF AIPREF, etc.) that use hyphenated tokens like \"user-action\" or \"train-ai\".\n *\n * Valid: \"train\", \"user_action\", \"user-action\", \"cf:ai_crawler\", \"cf:ai-crawler\", \"a\", \"a1\"\n * Invalid: \"Train\", \"123abc\", \"\", \"-train\", \"train-\", \"train_\", \"cf:ai-\", \"cf:-ai\"\n */\nexport const PURPOSE_TOKEN_REGEX =\n /^[a-z](?:[a-z0-9_-]*[a-z0-9])?(?::[a-z](?:[a-z0-9_-]*[a-z0-9])?)?$/;\n\n/** Maximum length for a purpose token */\nexport const MAX_PURPOSE_TOKEN_LENGTH = 64;\n\n/** Maximum number of purpose tokens per request (RECOMMENDED, not MUST) */\nexport const MAX_PURPOSE_TOKENS_PER_REQUEST = 10;\n\n/** Canonical purpose tokens (from constants.json) */\nexport const CANONICAL_PURPOSES: readonly CanonicalPurpose[] = [\n 'train',\n 'search',\n 'user_action',\n 'inference',\n 'index',\n] as const;\n\n/** Purpose reason values (from constants.json) */\nexport const PURPOSE_REASONS: readonly PurposeReason[] = [\n 'allowed',\n 'constrained',\n 'denied',\n 'downgraded',\n 'undeclared_default',\n 'unknown_preserved',\n] as const;\n\n/** Internal-only purpose value */\nexport const INTERNAL_PURPOSE_UNDECLARED: InternalPurpose = 'undeclared';\n\n// ============================================================================\n// Validation Functions\n// ============================================================================\n\n/**\n * Check if a string is a valid PurposeToken\n *\n * Validates against the purpose token grammar:\n * - Lowercase letters, digits, underscores, hyphens\n * - Optional vendor prefix with colon\n * - Max 64 characters\n * - Must start with lowercase letter\n *\n * @param token - String to validate\n * @returns true if valid PurposeToken\n */\nexport function isValidPurposeToken(token: string): token is PurposeToken {\n if (typeof token !== 'string') return false;\n if (token.length === 0 || token.length > MAX_PURPOSE_TOKEN_LENGTH) return false;\n return PURPOSE_TOKEN_REGEX.test(token);\n}\n\n/**\n * Check if a PurposeToken is a CanonicalPurpose\n *\n * @param token - Token to check\n * @returns true if token is in canonical vocabulary\n */\nexport function isCanonicalPurpose(token: string): token is CanonicalPurpose {\n return (CANONICAL_PURPOSES as readonly string[]).includes(token);\n}\n\n/**\n * Check if a PurposeToken is a LegacyPurpose\n *\n * @param token - Token to check\n * @returns true if token is a legacy purpose\n */\nexport function isLegacyPurpose(token: string): token is LegacyPurpose {\n return token === 'crawl' || token === 'ai_input' || token === 'ai_index';\n}\n\n/**\n * Check if a string is a valid PurposeReason\n *\n * @param reason - String to check\n * @returns true if valid PurposeReason\n */\nexport function isValidPurposeReason(reason: string): reason is PurposeReason {\n return (PURPOSE_REASONS as readonly string[]).includes(reason);\n}\n\n/**\n * Check if a purpose token is the internal-only \"undeclared\" value\n *\n * Used to reject explicit \"undeclared\" on wire (400 Bad Request).\n *\n * @param token - Token to check\n * @returns true if token is \"undeclared\"\n */\nexport function isUndeclaredPurpose(token: string): boolean {\n return token === INTERNAL_PURPOSE_UNDECLARED;\n}\n\n// ============================================================================\n// Normalization Functions\n// ============================================================================\n\n/**\n * Normalize a purpose token\n *\n * Applies normalization rules:\n * - Trim whitespace\n * - Lowercase\n *\n * @param token - Raw token from header\n * @returns Normalized token\n */\nexport function normalizePurposeToken(token: string): string {\n return token.trim().toLowerCase();\n}\n\n/**\n * Parse PEAC-Purpose header value into array of tokens\n *\n * Applies parsing rules:\n * - Split on commas\n * - Trim optional whitespace (OWS) around tokens\n * - Lowercase all tokens\n * - Drop empty tokens\n * - Deduplicate\n * - Preserve input order\n *\n * @param headerValue - Raw PEAC-Purpose header value\n * @returns Array of normalized PurposeToken values\n */\nexport function parsePurposeHeader(headerValue: string): PurposeToken[] {\n if (!headerValue || typeof headerValue !== 'string') {\n return [];\n }\n\n const seen = new Set<string>();\n const tokens: PurposeToken[] = [];\n\n for (const part of headerValue.split(',')) {\n const normalized = normalizePurposeToken(part);\n if (normalized.length > 0 && !seen.has(normalized)) {\n seen.add(normalized);\n tokens.push(normalized);\n }\n }\n\n return tokens;\n}\n\n/**\n * Validate parsed purpose tokens\n *\n * Returns validation result with:\n * - valid: All tokens pass grammar validation\n * - tokens: All normalized tokens (including invalid ones)\n * - invalidTokens: Tokens that failed grammar validation\n * - undeclaredPresent: true if explicit \"undeclared\" was found (should reject)\n *\n * @param tokens - Array of parsed tokens\n * @returns Validation result\n */\nexport interface PurposeValidationResult {\n valid: boolean;\n tokens: PurposeToken[];\n invalidTokens: string[];\n undeclaredPresent: boolean;\n}\n\nexport function validatePurposeTokens(tokens: PurposeToken[]): PurposeValidationResult {\n const invalidTokens: string[] = [];\n let undeclaredPresent = false;\n\n for (const token of tokens) {\n if (isUndeclaredPurpose(token)) {\n undeclaredPresent = true;\n }\n if (!isValidPurposeToken(token)) {\n invalidTokens.push(token);\n }\n }\n\n return {\n valid: invalidTokens.length === 0 && !undeclaredPresent,\n tokens,\n invalidTokens,\n undeclaredPresent,\n };\n}\n\n/**\n * Derive known canonical purposes from declared tokens\n *\n * Filters purpose_declared to get only canonical purposes.\n * This is a helper derivation, NOT stored on wire.\n *\n * @param declared - Array of declared PurposeTokens\n * @returns Array of CanonicalPurpose tokens\n */\nexport function deriveKnownPurposes(declared: PurposeToken[]): CanonicalPurpose[] {\n return declared.filter(isCanonicalPurpose);\n}\n\n// ============================================================================\n// Legacy Mapping\n// ============================================================================\n\n/**\n * Legacy purpose to canonical mapping\n */\nconst LEGACY_TO_CANONICAL: Record<LegacyPurpose, CanonicalPurpose> = {\n crawl: 'index', // Crawl implies indexing\n ai_input: 'inference', // RAG/grounding -> inference context\n ai_index: 'index', // AI-powered indexing -> index\n};\n\n/**\n * Map legacy purpose to canonical purpose\n *\n * Used for backward compatibility with pre-v0.9.24 ControlPurpose values.\n *\n * @param legacy - Legacy purpose token\n * @returns Mapping result with canonical purpose and audit note\n */\nexport interface LegacyMappingResult {\n canonical: CanonicalPurpose;\n mapping_note: string;\n}\n\nexport function mapLegacyToCanonical(legacy: LegacyPurpose): LegacyMappingResult {\n const canonical = LEGACY_TO_CANONICAL[legacy];\n return {\n canonical,\n mapping_note: `Mapped legacy '${legacy}' to canonical '${canonical}'`,\n };\n}\n\n/**\n * Normalize any purpose token (canonical, legacy, or unknown)\n *\n * Returns the canonical form if known, otherwise preserves the token.\n *\n * @param token - Any valid PurposeToken\n * @returns Canonical purpose if mapped, otherwise original token\n */\nexport function normalizeToCanonicalOrPreserve(\n token: PurposeToken\n):\n | { purpose: CanonicalPurpose; mapped: false }\n | { purpose: PurposeToken; mapped: true; from: LegacyPurpose }\n | { purpose: PurposeToken; mapped: false; unknown: true } {\n if (isCanonicalPurpose(token)) {\n return { purpose: token, mapped: false };\n }\n if (isLegacyPurpose(token)) {\n return { purpose: LEGACY_TO_CANONICAL[token], mapped: true, from: token };\n }\n return { purpose: token, mapped: false, unknown: true };\n}\n\n// ============================================================================\n// Purpose Reason Determination (v0.9.24+)\n// ============================================================================\n\n/**\n * Decision type for purpose reason determination\n *\n * Maps to policy decisions that affect purpose enforcement.\n */\nexport type PurposeDecision = 'allowed' | 'constrained' | 'denied' | 'downgraded';\n\n/**\n * Context for determining purpose reason\n */\nexport interface PurposeReasonContext {\n /**\n * Whether purposes were declared (PEAC-Purpose header present and non-empty).\n * If false, reason will be 'undeclared_default'.\n */\n declared: boolean;\n\n /**\n * Whether any unknown (non-canonical) tokens are present in declared purposes.\n * If true and declared is true, reason will be 'unknown_preserved'.\n */\n hasUnknownTokens: boolean;\n\n /**\n * The policy decision (only used if declared and no unknown tokens).\n * Defaults to 'allowed' if not provided.\n */\n decision?: PurposeDecision;\n}\n\n/**\n * Determine the appropriate PurposeReason based on context\n *\n * This helper implements the decision logic for the audit spine:\n * 1. If no purposes declared -> 'undeclared_default'\n * 2. If unknown tokens present -> 'unknown_preserved'\n * 3. Otherwise -> maps to policy decision\n *\n * @param context - Context for determination\n * @returns The appropriate PurposeReason for the audit spine\n *\n * @example\n * ```typescript\n * // Missing PEAC-Purpose header\n * determinePurposeReason({ declared: false, hasUnknownTokens: false });\n * // => 'undeclared_default'\n *\n * // Has vendor-prefixed tokens\n * determinePurposeReason({ declared: true, hasUnknownTokens: true, decision: 'allowed' });\n * // => 'unknown_preserved'\n *\n * // All canonical tokens, allowed by policy\n * determinePurposeReason({ declared: true, hasUnknownTokens: false, decision: 'allowed' });\n * // => 'allowed'\n * ```\n */\nexport function determinePurposeReason(context: PurposeReasonContext): PurposeReason {\n // Priority 1: No purposes declared\n if (!context.declared) {\n return 'undeclared_default';\n }\n\n // Priority 2: Unknown tokens present (preserved for forward-compat)\n if (context.hasUnknownTokens) {\n return 'unknown_preserved';\n }\n\n // Priority 3: Map policy decision to reason\n const decision = context.decision ?? 'allowed';\n switch (decision) {\n case 'allowed':\n return 'allowed';\n case 'constrained':\n return 'constrained';\n case 'denied':\n return 'denied';\n case 'downgraded':\n return 'downgraded';\n default:\n return 'allowed';\n }\n}\n\n/**\n * Check if any tokens in an array are unknown (non-canonical)\n *\n * @param tokens - Array of purpose tokens\n * @returns true if any token is not a canonical purpose\n */\nexport function hasUnknownPurposeTokens(tokens: PurposeToken[]): boolean {\n return tokens.some((token) => !isCanonicalPurpose(token));\n}\n","/**\n * Zod validators for PEAC protocol types\n */\nimport { z } from 'zod';\nimport { PEAC_WIRE_TYP, PEAC_ALG } from './constants';\nimport {\n JsonValueSchema,\n JsonObjectSchema,\n assertJsonSafeIterative,\n type JsonEvidenceLimits,\n} from './json';\nimport { createEvidenceNotJsonError, type PEACError } from './errors';\nimport { PURPOSE_TOKEN_REGEX, MAX_PURPOSE_TOKEN_LENGTH } from './purpose';\n\nconst httpsUrl = z\n .string()\n .url()\n .refine((u) => u.startsWith('https://'), 'must be https://');\nconst iso4217 = z.string().regex(/^[A-Z]{3}$/);\nconst uuidv7 = z\n .string()\n .regex(/^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i);\n\nexport const NormalizedPayment = z\n .object({\n rail: z.string().min(1),\n reference: z.string().min(1),\n amount: z.number().int().nonnegative(),\n currency: iso4217,\n asset: z.string().optional(),\n env: z.string().optional(),\n evidence: JsonValueSchema.optional(),\n metadata: JsonObjectSchema.optional(),\n })\n .strict();\n\nexport const Subject = z.object({ uri: httpsUrl }).strict();\n\nexport const AIPREFSnapshot = z\n .object({\n url: httpsUrl,\n hash: z.string().min(8),\n })\n .strict();\n\n// Note: Extensions uses a forward reference pattern since ControlBlockSchema\n// is defined after this. We use catchall for now and validate control separately.\nexport const Extensions = z\n .object({\n aipref_snapshot: AIPREFSnapshot.optional(),\n // control block validated via ControlBlockSchema when present\n })\n .catchall(z.unknown());\n\n/**\n * Wire 0.1 JWS header Zod schema (canonical name, v0.12.0-preview.1+).\n *\n * Note: `@peac/crypto` exports a TypeScript discriminated-union type also\n * named `JWSHeader` that covers Wire 0.1, Wire 0.2, and UnTyped variants.\n * This schema validates the runtime shape of Wire 0.1 headers only.\n */\nexport const Wire01JWSHeaderSchema = z\n .object({\n typ: z.literal(PEAC_WIRE_TYP),\n alg: z.literal(PEAC_ALG),\n kid: z.string().min(8),\n })\n .strict();\n\n/**\n * @deprecated Use `Wire01JWSHeaderSchema`. Kept for backward compatibility;\n * will be removed at v1.0.\n */\nexport const JWSHeader = Wire01JWSHeaderSchema;\n\n// Forward-declare purpose validators used in ReceiptClaims\n// Full definitions are below\nconst CanonicalPurposeValues = ['train', 'search', 'user_action', 'inference', 'index'] as const;\nconst PurposeReasonValues = [\n 'allowed',\n 'constrained',\n 'denied',\n 'downgraded',\n 'undeclared_default',\n 'unknown_preserved',\n] as const;\n\nexport const ReceiptClaimsSchema = z\n .object({\n iss: httpsUrl,\n aud: httpsUrl,\n iat: z.number().int().nonnegative(),\n exp: z.number().int().optional(),\n rid: uuidv7,\n amt: z.number().int().nonnegative(),\n cur: iso4217,\n payment: NormalizedPayment,\n subject: Subject.optional(),\n ext: Extensions.optional(),\n // Purpose claims (v0.9.24+)\n // purpose_declared: string[] - preserves unknown tokens for forward-compat\n purpose_declared: z.array(z.string()).optional(),\n // purpose_enforced: CanonicalPurpose - must be one with enforcement semantics\n purpose_enforced: z.enum(CanonicalPurposeValues).optional(),\n // purpose_reason: PurposeReason - audit spine for enforcement decisions\n purpose_reason: z.enum(PurposeReasonValues).optional(),\n })\n .strict();\n\n/**\n * Schema-derived receipt claims type (v0.9.30+)\n *\n * This is the canonical type for receipt claims - derived from the Zod schema.\n * Use this type instead of manually-defined interfaces to ensure type/schema parity.\n */\nexport type ReceiptClaimsType = z.infer<typeof ReceiptClaimsSchema>;\n\n/**\n * @deprecated Use ReceiptClaimsSchema instead. Renamed in v0.9.30.\n */\nexport const ReceiptClaims = ReceiptClaimsSchema;\n\nexport const VerifyRequest = z\n .object({\n receipt_jws: z.string().min(16),\n })\n .strict();\n\n// -----------------------------------------------------------------------------\n// Control Abstraction Layer (CAL) Validators (v0.9.16+)\n// -----------------------------------------------------------------------------\n\n/**\n * Control purpose - what the access is for\n *\n * v0.9.17+: Added ai_input, search for RSL alignment\n * v0.9.18+: Added ai_index (RSL 1.0 canonical token). Removed ai_search.\n * v0.9.24+: Added user_action for agent-on-behalf-of-user scenarios.\n *\n * @see https://rslstandard.org/rsl for RSL 1.0 specification\n */\nexport const ControlPurposeSchema = z.enum([\n 'crawl',\n 'index',\n 'train',\n 'inference',\n 'user_action',\n 'ai_input',\n 'ai_index',\n 'search',\n]);\n\n/**\n * Control licensing mode - how access is licensed\n */\nexport const ControlLicensingModeSchema = z.enum([\n 'subscription',\n 'pay_per_crawl',\n 'pay_per_inference',\n]);\n\n/**\n * Control decision type\n */\nexport const ControlDecisionSchema = z.enum(['allow', 'deny', 'review']);\n\n/**\n * Single control step in governance chain\n */\nexport const ControlStepSchema = z.object({\n engine: z.string().min(1),\n version: z.string().optional(),\n policy_id: z.string().optional(),\n result: ControlDecisionSchema,\n reason: z.string().optional(),\n purpose: ControlPurposeSchema.optional(),\n licensing_mode: ControlLicensingModeSchema.optional(),\n scope: z.union([z.string(), z.array(z.string())]).optional(),\n limits_snapshot: z.unknown().optional(),\n evidence_ref: z.string().optional(),\n});\n\n/**\n * Composable control block - multi-party governance\n */\nexport const ControlBlockSchema = z\n .object({\n chain: z.array(ControlStepSchema).min(1),\n decision: ControlDecisionSchema,\n combinator: z.literal('any_can_veto').optional(),\n })\n .refine(\n (data) => {\n // Validate decision consistency with chain\n const hasAnyDeny = data.chain.some((step) => step.result === 'deny');\n const allAllow = data.chain.every((step) => step.result === 'allow');\n const hasReview = data.chain.some((step) => step.result === 'review');\n\n if (hasAnyDeny && data.decision !== 'deny') {\n return false;\n }\n if (allAllow && data.decision !== 'allow') {\n return false;\n }\n // If has review but no deny, decision can be review or allow\n if (hasReview && !hasAnyDeny && data.decision === 'deny') {\n return false;\n }\n return true;\n },\n {\n message: 'Control block decision must be consistent with chain results',\n }\n );\n\n// -----------------------------------------------------------------------------\n// Purpose Type Validators (v0.9.24+)\n// -----------------------------------------------------------------------------\n\n/**\n * Purpose token validator\n *\n * PurposeToken is a string that matches the purpose grammar:\n * - Lowercase letters, digits, underscores\n * - Optional vendor prefix with colon (e.g., \"cf:ai_crawler\")\n * - Max 64 characters\n *\n * Uses string type (not enum) to preserve unknown tokens for forward-compat.\n */\nexport const PurposeTokenSchema = z\n .string()\n .min(1)\n .max(MAX_PURPOSE_TOKEN_LENGTH)\n .refine((token) => PURPOSE_TOKEN_REGEX.test(token), {\n message:\n 'Invalid purpose token format. Must be lowercase, alphanumeric with underscores, optional vendor prefix.',\n });\n\n/**\n * Canonical purpose validator\n *\n * CanonicalPurpose is one of PEAC's normative purpose tokens.\n * Only these tokens have enforcement semantics.\n */\nexport const CanonicalPurposeSchema = z.enum([\n 'train',\n 'search',\n 'user_action',\n 'inference',\n 'index',\n]);\n\n/**\n * Purpose reason validator\n *\n * PurposeReason is the audit spine explaining enforcement decisions.\n */\nexport const PurposeReasonSchema = z.enum([\n 'allowed',\n 'constrained',\n 'denied',\n 'downgraded',\n 'undeclared_default',\n 'unknown_preserved',\n]);\n\n// -----------------------------------------------------------------------------\n// Payment Evidence Validators (v0.9.16+)\n// -----------------------------------------------------------------------------\n\n/**\n * Payment split schema\n *\n * Invariants:\n * - party is required (non-empty string)\n * - amount if present must be >= 0\n * - share if present must be in [0,1]\n * - At least one of amount or share must be specified\n */\nexport const PaymentSplitSchema = z\n .object({\n party: z.string().min(1),\n amount: z.number().int().nonnegative().optional(),\n currency: iso4217.optional(),\n share: z.number().min(0).max(1).optional(),\n rail: z.string().min(1).optional(),\n account_ref: z.string().min(1).optional(),\n metadata: JsonObjectSchema.optional(),\n })\n .strict()\n .refine((data) => data.amount !== undefined || data.share !== undefined, {\n message: 'At least one of amount or share must be specified',\n });\n\n/**\n * Payment routing mode schema (rail-agnostic)\n *\n * Describes how the payment is routed between payer, aggregator, and merchant.\n * This is a generic hint - specific rails populate it from their native formats.\n *\n * Values:\n * - \"direct\": Direct payment to merchant (no intermediary)\n * - \"callback\": Routed via callback URL / payment service\n * - \"role\": Role-based routing (e.g., \"publisher\", \"platform\")\n *\n * Examples of producers:\n * - x402 v2 `payTo.mode` -> routing\n * - Stripe Connect `destination` -> routing = 'direct' or 'callback'\n * - UPI `pa` (payee address) -> routing = 'direct'\n */\nexport const PaymentRoutingSchema = z.enum(['direct', 'callback', 'role']);\n\n/**\n * Payment evidence schema\n *\n * Full schema for PaymentEvidence including aggregator/splits support.\n */\nexport const PaymentEvidenceSchema = z\n .object({\n rail: z.string().min(1),\n reference: z.string().min(1),\n amount: z.number().int().nonnegative(),\n currency: iso4217,\n asset: z.string().min(1),\n env: z.enum(['live', 'test']),\n network: z.string().min(1).optional(),\n facilitator_ref: z.string().min(1).optional(),\n evidence: JsonValueSchema,\n aggregator: z.string().min(1).optional(),\n splits: z.array(PaymentSplitSchema).optional(),\n routing: PaymentRoutingSchema.optional(),\n })\n .strict();\n\n// -----------------------------------------------------------------------------\n// Subject Profile Validators (v0.9.16+)\n// -----------------------------------------------------------------------------\n\n/**\n * Subject type schema\n */\nexport const SubjectTypeSchema = z.enum(['human', 'org', 'agent']);\n\n/**\n * Subject profile schema\n *\n * Invariants:\n * - id is required (non-empty string)\n * - type is required (human, org, or agent)\n * - labels if present must be non-empty strings\n */\nexport const SubjectProfileSchema = z\n .object({\n id: z.string().min(1),\n type: SubjectTypeSchema,\n labels: z.array(z.string().min(1)).optional(),\n metadata: JsonObjectSchema.optional(),\n })\n .strict();\n\n/**\n * Subject profile snapshot schema\n *\n * Invariants:\n * - subject is required (valid SubjectProfile)\n * - captured_at is required (non-empty string)\n * MUST be RFC 3339 / ISO 8601 UTC; format not enforced in schema for v0.9.16\n */\nexport const SubjectProfileSnapshotSchema = z\n .object({\n subject: SubjectProfileSchema,\n captured_at: z.string().min(1),\n source: z.string().min(1).optional(),\n version: z.string().min(1).optional(),\n })\n .strict();\n\n// -----------------------------------------------------------------------------\n// Attestation Validators (v0.9.21+)\n// -----------------------------------------------------------------------------\n\n/**\n * Namespaced extensions schema\n *\n * Keys must be namespaced (e.g., \"com.example/field\", \"io.vendor/data\").\n * This provides a forward-compatible extension mechanism.\n */\nexport const ExtensionsSchema = z.record(\n z.string().regex(/^[a-z0-9_.-]+\\/[a-z0-9_.-]+$/),\n JsonValueSchema\n);\n\n/**\n * Generic attestation schema\n *\n * Invariants:\n * - issuer, type, issued_at, evidence are required\n * - issued_at and expires_at must be RFC 3339 date-time\n * - ref if present must be a valid URI\n */\nexport const AttestationSchema = z\n .object({\n issuer: z.string().min(1),\n type: z.string().min(1),\n issued_at: z.string().datetime(),\n expires_at: z.string().datetime().optional(),\n ref: z.string().url().optional(),\n evidence: JsonValueSchema,\n })\n .strict();\n\n// -----------------------------------------------------------------------------\n// Subject Snapshot Validation Helper (v0.9.17+)\n// -----------------------------------------------------------------------------\n\n// Module-level set for PII warning deduplication\nconst warnedSubjectIds = new Set<string>();\n\n/**\n * Heuristic check if a subject ID looks like PII (email/phone)\n */\nfunction looksLikePII(id: string): boolean {\n // Email pattern\n if (/^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(id)) {\n return true;\n }\n // Phone pattern (starts with + followed by digits)\n if (/^\\+?\\d{10,15}$/.test(id.replace(/[\\s\\-()]/g, ''))) {\n return true;\n }\n return false;\n}\n\n/**\n * Validate a subject snapshot (if present)\n *\n * - Returns validated snapshot or null if absent\n * - Throws ZodError for malformed data\n * - Logs advisory warning if id looks like PII (deduplicated)\n */\nexport function validateSubjectSnapshot(\n snapshot: unknown\n): z.infer<typeof SubjectProfileSnapshotSchema> | null {\n if (snapshot === undefined || snapshot === null) {\n return null;\n }\n\n // Validate against schema (throws on malformed data)\n const validated = SubjectProfileSnapshotSchema.parse(snapshot);\n\n // Advisory PII warning (deduplicated)\n const subjectId = validated.subject.id;\n if (looksLikePII(subjectId) && !warnedSubjectIds.has(subjectId)) {\n warnedSubjectIds.add(subjectId);\n console.warn(\n `[peac:subject] Advisory: subject.id \"${subjectId}\" looks like PII. ` +\n 'Prefer opaque identifiers (e.g., \"user:abc123\").'\n );\n }\n\n return validated;\n}\n\n// -----------------------------------------------------------------------------\n// Evidence Validation (v0.9.21+)\n// -----------------------------------------------------------------------------\n\n/**\n * Result type for evidence validation\n */\nexport type EvidenceValidationResult =\n | { ok: true; value: unknown }\n | { ok: false; error: PEACError };\n\n/**\n * Validate payment evidence for JSON safety\n *\n * Uses iterative validation (no recursion) to prevent stack overflow on\n * deeply nested structures. Enforces limits on depth, array length,\n * object keys, and string length.\n *\n * @param evidence - Evidence value to validate\n * @param limits - Optional limits (internal, not part of public API)\n * @returns Result indicating success with validated value, or failure with PEACError\n *\n * @example\n * ```ts\n * const result = validateEvidence({ txId: '123', amount: 100 });\n * if (!result.ok) {\n * console.error(result.error.code, result.error.remediation);\n * }\n * ```\n */\nexport function validateEvidence(\n evidence: unknown,\n limits?: JsonEvidenceLimits\n): EvidenceValidationResult {\n const result = assertJsonSafeIterative(evidence, limits);\n\n if (!result.ok) {\n return {\n ok: false,\n error: createEvidenceNotJsonError(result.error, result.path),\n };\n }\n\n return { ok: true, value: evidence };\n}\n","/**\n * PEAC Attestation Receipt Types (v0.10.8+)\n *\n * Attestation receipts are lightweight signed tokens that attest to API\n * interactions WITHOUT payment fields. This is a distinct profile from\n * full payment receipts (PEACReceiptClaims).\n *\n * Use cases:\n * - API interaction logging with evidentiary value\n * - Middleware-issued receipts for non-payment flows\n * - Audit trails for agent/tool interactions\n *\n * Claims structure:\n * - Core JWT claims: iss, aud, iat, exp\n * - PEAC claims: rid (UUIDv7 receipt ID)\n * - Optional: sub, ext (extensions including interaction binding)\n *\n * @see docs/specs/ATTESTATION-RECEIPTS.md\n */\n\nimport { z } from 'zod';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * Attestation receipt type constant\n */\nexport const ATTESTATION_RECEIPT_TYPE = 'peac/attestation-receipt' as const;\n\n/**\n * Extension key for minimal interaction binding (middleware profile)\n *\n * This is a simplified binding used by middleware packages. For full\n * interaction evidence, use INTERACTION_EXTENSION_KEY from ./interaction.ts\n */\nexport const MIDDLEWARE_INTERACTION_KEY = 'org.peacprotocol/middleware-interaction@0.1';\n\n/**\n * Limits for attestation receipt fields (DoS protection)\n */\nexport const ATTESTATION_LIMITS = {\n /** Maximum issuer URL length */\n maxIssuerLength: 2048,\n /** Maximum audience URL length */\n maxAudienceLength: 2048,\n /** Maximum subject length */\n maxSubjectLength: 256,\n /** Maximum path length in interaction binding */\n maxPathLength: 2048,\n /** Maximum method length */\n maxMethodLength: 16,\n /** Maximum HTTP status code */\n maxStatusCode: 599,\n /** Minimum HTTP status code */\n minStatusCode: 100,\n} as const;\n\n// ============================================================================\n// Zod Schemas\n// ============================================================================\n\n/**\n * HTTPS URL validation (reused from validators.ts pattern)\n */\nconst httpsUrl = z\n .string()\n .url()\n .max(ATTESTATION_LIMITS.maxIssuerLength)\n .refine((url) => url.startsWith('https://'), 'Must be HTTPS URL');\n\n/**\n * UUIDv7 format validation\n */\nconst uuidv7 = z\n .string()\n .regex(\n /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,\n 'Must be UUIDv7 format'\n );\n\n/**\n * Minimal interaction binding schema (for middleware use)\n *\n * This is a simplified version of full interaction evidence.\n * Contains only: method, path, status.\n *\n * Privacy note: Query strings are excluded by default to avoid\n * leaking sensitive data (API keys, tokens, PII in parameters).\n */\nexport const MinimalInteractionBindingSchema = z\n .object({\n /** HTTP method (uppercase, e.g., GET, POST) */\n method: z\n .string()\n .min(1)\n .max(ATTESTATION_LIMITS.maxMethodLength)\n .transform((m) => m.toUpperCase()),\n /** Request path (no query string by default) */\n path: z.string().min(1).max(ATTESTATION_LIMITS.maxPathLength),\n /** HTTP response status code */\n status: z\n .number()\n .int()\n .min(ATTESTATION_LIMITS.minStatusCode)\n .max(ATTESTATION_LIMITS.maxStatusCode),\n })\n .strict();\n\n/**\n * Attestation receipt extensions schema\n *\n * Allows interaction binding and other namespaced extensions.\n */\nexport const AttestationExtensionsSchema = z.record(z.string(), z.unknown());\n\n/**\n * PEAC Attestation Receipt Claims schema\n *\n * This is the claims structure for attestation receipts - lightweight\n * receipts without payment fields. For full payment receipts, use\n * ReceiptClaimsSchema from ./validators.ts\n */\nexport const AttestationReceiptClaimsSchema = z\n .object({\n /** Issuer URL (normalized, no trailing slash) */\n iss: httpsUrl,\n /** Audience URL */\n aud: httpsUrl,\n /** Issued at (Unix seconds) */\n iat: z.number().int().nonnegative(),\n /** Expiration (Unix seconds) */\n exp: z.number().int().nonnegative(),\n /** Receipt ID (UUIDv7) */\n rid: uuidv7,\n /** Subject identifier (optional) */\n sub: z.string().max(ATTESTATION_LIMITS.maxSubjectLength).optional(),\n /** Extensions (optional) */\n ext: AttestationExtensionsSchema.optional(),\n })\n .strict();\n\n// ============================================================================\n// TypeScript Types (inferred from Zod schemas)\n// ============================================================================\n\nexport type MinimalInteractionBinding = z.infer<typeof MinimalInteractionBindingSchema>;\nexport type AttestationExtensions = z.infer<typeof AttestationExtensionsSchema>;\nexport type AttestationReceiptClaims = z.infer<typeof AttestationReceiptClaimsSchema>;\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\n/**\n * Validation result type\n */\nexport interface AttestationValidationResult {\n valid: boolean;\n error_code?: string;\n error_message?: string;\n}\n\n/**\n * Validate attestation receipt claims\n *\n * @param input - Raw input to validate\n * @returns Validation result\n */\nexport function validateAttestationReceiptClaims(input: unknown): AttestationValidationResult {\n const result = AttestationReceiptClaimsSchema.safeParse(input);\n if (result.success) {\n return { valid: true };\n }\n const firstIssue = result.error.issues[0];\n return {\n valid: false,\n error_code: 'E_ATTESTATION_INVALID_CLAIMS',\n error_message: firstIssue?.message || 'Invalid attestation receipt claims',\n };\n}\n\n/**\n * Check if an object is valid attestation receipt claims (non-throwing)\n *\n * @param claims - Object to check\n * @returns True if valid AttestationReceiptClaims\n */\nexport function isAttestationReceiptClaims(claims: unknown): claims is AttestationReceiptClaims {\n return AttestationReceiptClaimsSchema.safeParse(claims).success;\n}\n\n/**\n * Validate minimal interaction binding\n *\n * @param input - Raw input to validate\n * @returns Validation result\n */\nexport function validateMinimalInteractionBinding(input: unknown): AttestationValidationResult {\n const result = MinimalInteractionBindingSchema.safeParse(input);\n if (result.success) {\n return { valid: true };\n }\n const firstIssue = result.error.issues[0];\n return {\n valid: false,\n error_code: 'E_ATTESTATION_INVALID_INTERACTION',\n error_message: firstIssue?.message || 'Invalid interaction binding',\n };\n}\n\n/**\n * Check if an object is valid minimal interaction binding (non-throwing)\n *\n * @param binding - Object to check\n * @returns True if valid MinimalInteractionBinding\n */\nexport function isMinimalInteractionBinding(\n binding: unknown\n): binding is MinimalInteractionBinding {\n return MinimalInteractionBindingSchema.safeParse(binding).success;\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Parameters for creating attestation receipt claims\n */\nexport interface CreateAttestationReceiptParams {\n /** Issuer URL (will be normalized) */\n issuer: string;\n /** Audience URL */\n audience: string;\n /** Receipt ID (UUIDv7) */\n rid: string;\n /** Subject identifier (optional) */\n sub?: string;\n /** Interaction binding (optional) */\n interaction?: MinimalInteractionBinding;\n /** Additional extensions (optional) */\n extensions?: Record<string, unknown>;\n /** Expiration in seconds from now (default: 300) */\n expiresIn?: number;\n}\n\n/**\n * Create validated attestation receipt claims\n *\n * @param params - Attestation receipt parameters\n * @returns Validated AttestationReceiptClaims\n * @throws ZodError if validation fails\n */\nexport function createAttestationReceiptClaims(\n params: CreateAttestationReceiptParams\n): AttestationReceiptClaims {\n const now = Math.floor(Date.now() / 1000);\n const expiresIn = params.expiresIn ?? 300;\n\n // Normalize issuer (remove trailing slashes)\n // Using explicit loop instead of regex to avoid ReDoS with quantifiers\n let normalizedIssuer = params.issuer;\n while (normalizedIssuer.endsWith('/')) {\n normalizedIssuer = normalizedIssuer.slice(0, -1);\n }\n\n // Build extensions\n const ext: Record<string, unknown> = { ...params.extensions };\n if (params.interaction) {\n ext[MIDDLEWARE_INTERACTION_KEY] = params.interaction;\n }\n\n const claims: AttestationReceiptClaims = {\n iss: normalizedIssuer,\n aud: params.audience,\n iat: now,\n exp: now + expiresIn,\n rid: params.rid,\n ...(params.sub && { sub: params.sub }),\n ...(Object.keys(ext).length > 0 && { ext }),\n };\n\n return AttestationReceiptClaimsSchema.parse(claims);\n}\n\n// ============================================================================\n// Type Guard for Receipt Profile Discrimination\n// ============================================================================\n\n/**\n * Check if claims are attestation-only (no payment fields)\n *\n * This helps discriminate between attestation receipts and\n * full payment receipts at runtime.\n *\n * @param claims - Receipt claims to check\n * @returns True if claims lack payment fields (amt, cur, payment)\n */\nexport function isAttestationOnly(claims: Record<string, unknown>): boolean {\n return !('amt' in claims) && !('cur' in claims) && !('payment' in claims);\n}\n\n/**\n * Check if claims are payment receipt (has payment fields)\n *\n * @param claims - Receipt claims to check\n * @returns True if claims have payment fields\n */\nexport function isPaymentReceipt(claims: Record<string, unknown>): boolean {\n return 'amt' in claims && 'cur' in claims && 'payment' in claims;\n}\n","/**\n * ActorBinding and MVIS (Minimum Viable Identity Set) Schemas (v0.11.3+)\n *\n * Implements (ActorBinding) (Multi-Root Proof Types),\n * and (MVIS) for the Agent Identity Profile.\n *\n * ActorBinding lives in ext[\"org.peacprotocol/actor_binding\"] in Wire 0.1.\n * ProofTypeSchema is SEPARATE from ProofMethodSchema (agent-identity.ts)\n * to avoid breaking the v0.9.25+ API. Unification deferred to v0.12.0.\n *\n * @see docs/specs/AGENT-IDENTITY-PROFILE.md for normative specification\n */\nimport { z } from 'zod';\n\n// =============================================================================\n// PROOF TYPES (Multi-Root Proof Types)\n// =============================================================================\n\n/**\n * Proof types for ActorBinding.\n *\n * 8 methods covering attestation chains, RATS, keyless signing,\n * decentralized identity, workload identity, PKI, and vendor-defined.\n *\n * SEPARATE from ProofMethodSchema (4 transport-level methods in agent-identity.ts).\n * ProofMethodSchema covers how proof is transported (HTTP sig, DPoP, mTLS, JWK thumbprint).\n * ProofTypeSchema covers the trust root model used to establish identity.\n *\n * The 'custom' type: implementers MUST document their proof semantics externally.\n * proof_ref SHOULD use a reverse-DNS namespace (e.g., 'com.example.vendor/proof-type-v1').\n */\nexport const PROOF_TYPES = [\n 'ed25519-cert-chain',\n 'eat-passport',\n 'eat-background-check',\n 'sigstore-oidc',\n 'did',\n 'spiffe',\n 'x509-pki',\n 'custom',\n] as const;\n\nexport const ProofTypeSchema = z.enum(PROOF_TYPES);\nexport type ProofType = z.infer<typeof ProofTypeSchema>;\n\n// =============================================================================\n// ORIGIN VALIDATION\n// =============================================================================\n\n/**\n * Validate that a string is an origin-only URL (scheme + host + optional port).\n * Rejects URLs with path (other than '/'), query, or fragment components.\n * This prevents correlation leakage and ambiguity in ActorBinding.\n *\n * Valid: \"https://example.com\", \"https://example.com:8443\"\n * Invalid: \"https://example.com/api/v1\", \"https://example.com?q=1\", \"https://example.com#frag\"\n */\nexport function isOriginOnly(value: string): boolean {\n try {\n const url = new URL(value);\n // Must be http or https\n if (url.protocol !== 'https:' && url.protocol !== 'http:') {\n return false;\n }\n // pathname must be exactly '/' (the implicit root)\n if (url.pathname !== '/') {\n return false;\n }\n // No search params\n if (url.search !== '') {\n return false;\n }\n // No fragment: url.hash is '' for both no-fragment and bare '#',\n // so also check the raw string for a trailing '#'\n if (url.hash !== '' || value.includes('#')) {\n return false;\n }\n // Reject userinfo (credentials in origins are a security risk)\n if (url.username !== '' || url.password !== '') {\n return false;\n }\n // Reject trailing dot in hostname (FQDN notation leaks DNS internals)\n if (url.hostname.endsWith('.')) {\n return false;\n }\n // URL API may normalize trailing dots; also check raw input\n const hostPart = value.replace(/^https?:\\/\\//, '').split(/[/:]/)[0];\n if (hostPart.endsWith('.')) {\n return false;\n }\n // Reject IPv6 zone identifiers (link-local, not valid origins)\n if (url.hostname.includes('%')) {\n return false;\n }\n return true;\n } catch {\n return false;\n }\n}\n\n// =============================================================================\n// ACTOR BINDING\n// =============================================================================\n\n/**\n * Extension key for ActorBinding in Wire 0.1 ext[].\n */\nexport const ACTOR_BINDING_EXTENSION_KEY = 'org.peacprotocol/actor_binding' as const;\n\n/**\n * ActorBinding schema.\n *\n * Binds an actor identity to a receipt via ext[\"org.peacprotocol/actor_binding\"].\n * Wire 0.2 moves this to a kernel field.\n *\n * - id: Stable actor identifier (opaque, no PII)\n * - proof_type: Trust root model from vocabulary\n * - proof_ref: Optional URI or hash of external proof artifact\n * - origin: Origin-only URL (scheme + host + optional port; no path/query/fragment)\n * - intent_hash: Optional SHA-256 hash of the intent (hash-first per )\n */\nexport const ActorBindingSchema = z\n .object({\n /** Stable actor identifier (opaque, no PII) */\n id: z.string().min(1).max(256),\n\n /** Proof type from multi-root vocabulary */\n proof_type: ProofTypeSchema,\n\n /** URI or hash of external proof artifact */\n proof_ref: z.string().max(2048).optional(),\n\n /** Origin-only URL: scheme + host + optional port; NO path, query, or fragment */\n origin: z.string().max(2048).refine(isOriginOnly, {\n message:\n 'origin must be an origin-only URL (scheme + host + optional port; no path, query, or fragment)',\n }),\n\n /** SHA-256 hash of the intent (hash-first per ) */\n intent_hash: z\n .string()\n .regex(/^sha256:[a-f0-9]{64}$/, {\n message: 'intent_hash must match sha256:<64 hex chars>',\n })\n .optional(),\n })\n .strict();\n\nexport type ActorBinding = z.infer<typeof ActorBindingSchema>;\n\n// =============================================================================\n// MVIS: Minimum Viable Identity Set\n// =============================================================================\n\n/**\n * MVIS (Minimum Viable Identity Set) fields.\n *\n * 5 required fields for any identity receipt to be considered complete.\n * validateMVIS() is a pure validation function with zero I/O.\n *\n * Fields:\n * - issuer: Who issued the identity assertion\n * - subject: Who the identity is about (opaque identifier)\n * - key_binding: Cryptographic binding to a key (kid or thumbprint)\n * - time_bounds: Validity period with not_before and not_after\n * - replay_protection: Unique token ID (jti) and optional nonce\n */\nexport const MVISTimeBoundsSchema = z\n .object({\n /** Earliest valid time (RFC 3339) */\n not_before: z.string().datetime(),\n /** Latest valid time (RFC 3339) */\n not_after: z.string().datetime(),\n })\n .strict();\n\nexport type MVISTimeBounds = z.infer<typeof MVISTimeBoundsSchema>;\n\nexport const MVISReplayProtectionSchema = z\n .object({\n /** Unique token identifier (jti from JWT or equivalent) */\n jti: z.string().min(1).max(256),\n /** Optional nonce for additional replay protection */\n nonce: z.string().max(256).optional(),\n })\n .strict();\n\nexport type MVISReplayProtection = z.infer<typeof MVISReplayProtectionSchema>;\n\nexport const MVISFieldsSchema = z\n .object({\n /** Who issued the identity assertion */\n issuer: z.string().min(1).max(2048),\n\n /** Who the identity is about (opaque identifier, no PII) */\n subject: z.string().min(1).max(256),\n\n /** Cryptographic binding: kid or JWK thumbprint */\n key_binding: z.string().min(1).max(256),\n\n /** Validity period */\n time_bounds: MVISTimeBoundsSchema,\n\n /** Replay protection */\n replay_protection: MVISReplayProtectionSchema,\n })\n .strict();\n\nexport type MVISFields = z.infer<typeof MVISFieldsSchema>;\n\n// =============================================================================\n// VALIDATION HELPERS\n// =============================================================================\n\n/**\n * Validate an ActorBinding object.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated ActorBinding or error message\n */\nexport function validateActorBinding(\n data: unknown\n): { ok: true; value: ActorBinding } | { ok: false; error: string } {\n const result = ActorBindingSchema.safeParse(data);\n if (result.success) {\n return { ok: true, value: result.data };\n }\n return { ok: false, error: result.error.message };\n}\n\n/**\n * Validate MVIS fields.\n *\n * Pure validation function with zero I/O.\n * Checks that all 5 required fields are present and valid.\n * Also validates that time_bounds.not_before < time_bounds.not_after.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated MVIS fields or error message\n */\nexport function validateMVIS(\n data: unknown\n): { ok: true; value: MVISFields } | { ok: false; error: string } {\n const result = MVISFieldsSchema.safeParse(data);\n if (!result.success) {\n return { ok: false, error: result.error.message };\n }\n\n // Semantic check: not_before must be before not_after\n const notBefore = new Date(result.data.time_bounds.not_before).getTime();\n const notAfter = new Date(result.data.time_bounds.not_after).getTime();\n if (notBefore >= notAfter) {\n return { ok: false, error: 'not_before must be before not_after' };\n }\n\n // Reject absurd durations (>100 years)\n const MAX_DURATION_MS = 100 * 365.25 * 24 * 60 * 60 * 1000;\n if (notAfter - notBefore > MAX_DURATION_MS) {\n return { ok: false, error: 'time_bounds duration must not exceed 100 years' };\n }\n\n return { ok: true, value: result.data };\n}\n","/**\n * Fingerprint Reference Conversion Functions (v0.11.3+)\n *\n * Pure string manipulation functions for converting between Wire 0.1\n * string form (\"alg:hex64\") and Wire 0.2 object form ({ alg, value, key_id? }).\n *\n * These are opaque references. The schema validates format only.\n * Issuers compute values externally; verifiers MUST NOT assume\n * they can recompute the reference.\n *\n * Lives in Layer 1 (@peac/schema) because it is pure string manipulation,\n * not cryptographic computation. Zero dependencies, zero I/O.\n */\n\n/**\n * Wire 0.2 object form of a fingerprint reference\n */\nexport interface FingerprintRefObject {\n /** Hash algorithm: 'sha256' or 'hmac-sha256' */\n alg: string;\n /** Base64url-encoded value */\n value: string;\n /** Optional key identifier (for hmac-sha256 references) */\n key_id?: string;\n}\n\n/**\n * Convert hex string to base64url encoding.\n * Pure function, no dependencies.\n */\nfunction hexToBase64url(hex: string): string {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);\n }\n // Use Buffer in Node, or manual encoding\n let base64: string;\n if (typeof Buffer !== 'undefined') {\n base64 = Buffer.from(bytes).toString('base64');\n } else {\n // Fallback for non-Node environments\n base64 = btoa(String.fromCharCode(...bytes));\n }\n // base64 -> base64url\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\n/**\n * Convert base64url string to hex encoding.\n * Pure function, no dependencies.\n */\nfunction base64urlToHex(b64url: string): string {\n // base64url -> base64\n let base64 = b64url.replace(/-/g, '+').replace(/_/g, '/');\n // Add padding\n while (base64.length % 4 !== 0) {\n base64 += '=';\n }\n let bytes: Uint8Array;\n if (typeof Buffer !== 'undefined') {\n bytes = Buffer.from(base64, 'base64');\n } else {\n const binary = atob(base64);\n bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n }\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * Supported algorithm prefixes\n */\nconst VALID_ALGS = ['sha256', 'hmac-sha256'] as const;\nconst STRING_FORM_PATTERN = /^(sha256|hmac-sha256):([a-f0-9]{64})$/;\n\n/**\n * Maximum length for fingerprint reference string form.\n * \"hmac-sha256:\" (12) + 64 hex chars = 76 chars max.\n */\nexport const MAX_FINGERPRINT_REF_LENGTH = 76;\n\n/**\n * Strict base64url character set (RFC 4648 section 5).\n * Only A-Z, a-z, 0-9, '-', '_'. No padding ('='), no whitespace.\n */\nconst BASE64URL_PATTERN = /^[A-Za-z0-9_-]+$/;\n\n/**\n * Parse a Wire 0.1 string form fingerprint reference (\"alg:hex64\")\n * into a Wire 0.2 object form ({ alg, value }).\n *\n * The hex value is converted to base64url for the object form.\n *\n * @param s - String form: \"sha256:<64 hex chars>\" or \"hmac-sha256:<64 hex chars>\"\n * @returns Object form with base64url value, or null if invalid\n */\nexport function stringToFingerprintRef(s: string): FingerprintRefObject | null {\n if (s.length > MAX_FINGERPRINT_REF_LENGTH) {\n return null;\n }\n const match = STRING_FORM_PATTERN.exec(s);\n if (!match) {\n return null;\n }\n const alg = match[1];\n const hex = match[2];\n return {\n alg,\n value: hexToBase64url(hex),\n };\n}\n\n/**\n * Convert a Wire 0.2 object form fingerprint reference back to\n * the Wire 0.1 string form (\"alg:hex64\").\n *\n * The base64url value is converted back to hex for the string form.\n *\n * @param obj - Object form with alg and base64url value\n * @returns String form \"alg:<64 hex chars>\", or null if invalid\n */\nexport function fingerprintRefToString(obj: FingerprintRefObject): string | null {\n if (!VALID_ALGS.includes(obj.alg as (typeof VALID_ALGS)[number])) {\n return null;\n }\n // Strict base64url validation (RFC 4648 section 5): no padding, no whitespace\n if (!BASE64URL_PATTERN.test(obj.value)) {\n return null;\n }\n try {\n const hex = base64urlToHex(obj.value);\n if (hex.length !== 64) {\n return null;\n }\n return `${obj.alg}:${hex}`;\n } catch {\n return null;\n }\n}\n","/**\n * Wire 0.2 RepresentationFields schema\n *\n * Records metadata about the content representation that was observed or served,\n * enabling reproducible content drift detection.\n *\n * Layer 1 (@peac/schema): pure Zod validation, zero I/O.\n *\n * content_hash validation uses stringToFingerprintRef() as the parser gate\n * and additionally requires alg === 'sha256'. The hmac-sha256 algorithm is\n * not permitted for representation hashes (sha256-only by design).\n */\n\nimport { z } from 'zod';\nimport {\n stringToFingerprintRef,\n MAX_FINGERPRINT_REF_LENGTH,\n} from './extensions/fingerprint-ref.js';\n\n// ---------------------------------------------------------------------------\n// Private helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Validate that a content_hash string is a valid sha256 FingerprintRef.\n *\n * Uses stringToFingerprintRef() as the parser gate (format correctness),\n * then additionally requires alg === 'sha256'. hmac-sha256 is rejected\n * for representation content hashes.\n */\nfunction isValidContentHash(s: string): boolean {\n const ref = stringToFingerprintRef(s);\n if (ref === null) return false;\n // Only sha256 is permitted for representation.content_hash\n return ref.alg === 'sha256';\n}\n\n/**\n * Conservative MIME type validation.\n *\n * Accepts the token/token form with optional parameters (type/subtype;key=value).\n * Does NOT attempt full RFC 9110/6838 grammar parsing.\n *\n * Valid examples: text/plain, application/json, application/json; charset=utf-8\n * Invalid examples: \"text\", \"text/\", \" text/plain\", \"\"\n */\nconst MIME_PATTERN =\n /^[a-zA-Z0-9][a-zA-Z0-9!#$&\\-^_.+]*\\/[a-zA-Z0-9][a-zA-Z0-9!#$&\\-^_.+]*(;\\s*[a-zA-Z0-9][a-zA-Z0-9!#$&\\-^_.+]*=[^\\s;]+)*$/;\n\nfunction isValidMimeType(s: string): boolean {\n return MIME_PATTERN.test(s);\n}\n\n// ---------------------------------------------------------------------------\n// Bounds constants (follows repo _LIMITS convention)\n// ---------------------------------------------------------------------------\n\n/**\n * Normative bounds for Wire 0.2 representation fields.\n *\n * Centralised to prevent magic numbers and allow external reference.\n */\nexport const REPRESENTATION_LIMITS = {\n /** Max content_hash string length (sha256:<64 hex> = 71 chars, capped at FingerprintRef max) */\n maxContentHashLength: MAX_FINGERPRINT_REF_LENGTH,\n /** Max content_type string length */\n maxContentTypeLength: 256,\n} as const;\n\n// ---------------------------------------------------------------------------\n// Wire02RepresentationFieldsSchema\n// ---------------------------------------------------------------------------\n\n/**\n * Zod schema for Wire 0.2 representation fields.\n *\n * All fields are optional; an empty object is valid.\n * Unknown keys are rejected (.strict()).\n *\n * Bounds:\n * - content_hash: max 76 chars (MAX_FINGERPRINT_REF_LENGTH), sha256-only\n * - content_type: max 256 chars, conservative MIME pattern\n * - content_length: non-negative integer, <= Number.MAX_SAFE_INTEGER\n */\nexport const Wire02RepresentationFieldsSchema = z\n .object({\n /**\n * FingerprintRef of the served content body.\n * Format: sha256:<64 lowercase hex>\n * hmac-sha256 is NOT permitted for representation hashes.\n */\n content_hash: z\n .string()\n .max(REPRESENTATION_LIMITS.maxContentHashLength)\n .refine(isValidContentHash, {\n message: 'content_hash must be a valid sha256 FingerprintRef (sha256:<64 lowercase hex>)',\n })\n .optional(),\n /**\n * MIME type of the served content (e.g., 'text/plain', 'application/json').\n * Conservative pattern validation: type/subtype with optional parameters.\n */\n content_type: z\n .string()\n .max(REPRESENTATION_LIMITS.maxContentTypeLength)\n .refine(isValidMimeType, {\n message: 'content_type must be a valid MIME type (type/subtype with optional parameters)',\n })\n .optional(),\n /**\n * Size of the served content in bytes.\n * Non-negative integer, bounded by Number.MAX_SAFE_INTEGER.\n */\n content_length: z.number().int().finite().nonnegative().max(Number.MAX_SAFE_INTEGER).optional(),\n })\n .strict();\n\n/** Inferred type for Wire 0.2 representation fields */\nexport type Wire02RepresentationFields = z.infer<typeof Wire02RepresentationFieldsSchema>;\n\n/**\n * Public export alias.\n * Internal name is Wire02RepresentationFieldsSchema to prevent wire-version\n * collisions; exported as RepresentationFieldsSchema for ergonomic use.\n */\nexport { Wire02RepresentationFieldsSchema as RepresentationFieldsSchema };\n","/**\n * Wire 0.2 Extension Group Limits\n *\n * Centralized per-field bounds for all Wire 0.2 extension group fields.\n * Prevents magic numbers and allows external reference.\n * Follows repo _LIMITS convention.\n *\n * Byte-budget constants are normative and live in @peac/kernel\n * (EXTENSION_BUDGET). Re-exported here for schema-layer convenience.\n */\n\n// Re-export kernel byte-budget constants for schema-layer consumers\nexport { EXTENSION_BUDGET } from '@peac/kernel';\n\n/**\n * Normative per-field bounds for Wire 0.2 extension group fields.\n */\nexport const EXTENSION_LIMITS = {\n // Extension key grammar\n maxExtensionKeyLength: 512,\n maxDnsLabelLength: 63,\n maxDnsDomainLength: 253,\n\n // Commerce\n maxPaymentRailLength: 128,\n maxCurrencyLength: 16,\n maxAmountMinorLength: 64,\n maxReferenceLength: 256,\n maxAssetLength: 256,\n maxCommerceEventLength: 64,\n\n // Access\n maxResourceLength: 2048,\n maxActionLength: 256,\n\n // Challenge\n maxProblemTypeLength: 2048,\n maxProblemTitleLength: 256,\n maxProblemDetailLength: 4096,\n maxProblemInstanceLength: 2048,\n\n // Identity\n maxProofRefLength: 256,\n\n // Correlation\n maxTraceIdLength: 32,\n maxSpanIdLength: 16,\n maxWorkflowIdLength: 256,\n maxParentJtiLength: 256,\n maxDependsOnLength: 64,\n\n // Consent\n maxConsentBasisLength: 128,\n maxConsentMethodLength: 128,\n maxDataCategoriesCount: 64,\n maxDataCategoryLength: 128,\n maxConsentScopeLength: 256,\n maxJurisdictionLength: 16,\n\n // Compliance\n maxFrameworkLength: 256,\n maxAuditRefLength: 256,\n maxAuditorLength: 256,\n maxComplianceScopeLength: 512,\n\n // Privacy\n maxDataClassificationLength: 128,\n maxProcessingBasisLength: 128,\n maxAnonymizationMethodLength: 128,\n maxDataSubjectCategoryLength: 128,\n maxTransferMechanismLength: 128,\n\n // Safety\n maxAssessmentMethodLength: 256,\n maxSafetyMeasuresCount: 32,\n maxSafetyMeasureLength: 256,\n maxIncidentRefLength: 256,\n maxModelRefLength: 256,\n maxSafetyCategoryLength: 128,\n\n // Provenance\n maxSourceTypeLength: 128,\n maxSourceRefLength: 256,\n maxVerificationMethodLength: 128,\n maxCustodyChainCount: 16,\n maxCustodianLength: 256,\n maxCustodyActionLength: 128,\n maxSlsaTrackLength: 64,\n maxSlsaVersionLength: 16,\n\n // Attribution\n maxCreatorRefLength: 256,\n maxObligationTypeLength: 128,\n maxAttributionTextLength: 1024,\n maxContentSignalSourceLength: 128,\n\n // Purpose\n maxExternalPurposesCount: 32,\n maxExternalPurposeLength: 128,\n maxPurposeBasisLength: 128,\n maxCompatiblePurposesCount: 32,\n\n // Shared field bounds\n maxHttpsUriLength: 2048,\n maxSha256DigestLength: 71, // \"sha256:\" (7) + 64 hex = 71 chars\n maxIso8601DurationLength: 64,\n maxIso8601DateLength: 10,\n maxSpdxExpressionLength: 128,\n} as const;\n","/**\n * Wire 0.2 Extension Key Grammar Validator\n *\n * Validates that extension keys conform to the Wire 0.2 reverse-DNS\n * extension key grammar: `<domain>/<segment>`.\n *\n * Extracted from the monolithic wire-02-extensions.ts for maintainability.\n */\n\nimport { EXTENSION_LIMITS } from './limits.js';\n\n/**\n * DNS label pattern: lowercase alphanumeric, may contain hyphens but not at\n * start or end. Single-char labels are valid (e.g., \"a\").\n */\nconst DNS_LABEL = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;\n\n/**\n * Segment pattern: lowercase alphanumeric start, may contain lowercase\n * alphanumeric, underscores, and hyphens.\n */\nconst SEGMENT_PATTERN = /^[a-z0-9][a-z0-9_-]*$/;\n\n/**\n * Validate that an extension key conforms to the Wire 0.2 extension key\n * grammar: `<domain>/<segment>`.\n *\n * Domain rules:\n * - At least one dot (distinguishes from single-label paths)\n * - Each label matches [a-z0-9]([a-z0-9-]*[a-z0-9])? (lowercase only)\n * - No uppercase letters anywhere in the domain\n *\n * Segment rules:\n * - Matches [a-z0-9][a-z0-9_-]* (lowercase only)\n * - Underscores are permitted (for extension names like credential_event)\n *\n * @param key - Extension key to validate\n * @returns true if valid extension key grammar; false otherwise\n */\nexport function isValidExtensionKey(key: string): boolean {\n if (key.length === 0 || key.length > EXTENSION_LIMITS.maxExtensionKeyLength) return false;\n\n const slashIdx = key.indexOf('/');\n if (slashIdx <= 0) return false;\n\n const domain = key.slice(0, slashIdx);\n const segment = key.slice(slashIdx + 1);\n\n if (!domain.includes('.')) return false;\n if (domain.length > EXTENSION_LIMITS.maxDnsDomainLength) return false;\n\n if (segment.length === 0) return false;\n if (!SEGMENT_PATTERN.test(segment)) return false;\n\n const labels = domain.split('.');\n for (const label of labels) {\n if (label.length === 0 || label.length > EXTENSION_LIMITS.maxDnsLabelLength) return false;\n if (!DNS_LABEL.test(label)) return false;\n }\n\n return true;\n}\n\n/**\n * Escape a single path segment per RFC 6901.\n * '~' -> '~0', '/' -> '~1'\n */\nexport function escapePointerSegment(s: string): string {\n return s.replace(/~/g, '~0').replace(/\\//g, '~1');\n}\n\n/**\n * Build a leaf-precise RFC 6901 JSON Pointer from a group key and Zod\n * issue path.\n *\n * @param groupKey - Extension group key (e.g., 'org.peacprotocol/commerce')\n * @param zodPath - Path array from the first Zod issue\n * @returns RFC 6901 pointer string\n */\nexport function zodPathToPointer(groupKey: string, zodPath: readonly PropertyKey[]): string {\n const escaped = escapePointerSegment(groupKey);\n const segments = zodPath.map((s) => escapePointerSegment(String(s)));\n return `/extensions/${escaped}` + (segments.length > 0 ? '/' + segments.join('/') : '');\n}\n","/**\n * Commerce Extension Group (org.peacprotocol/commerce)\n *\n * Records payment transaction evidence.\n * Shipped in v0.12.0-preview.1.\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\n\nexport const COMMERCE_EXTENSION_KEY = 'org.peacprotocol/commerce' as const;\n\n/** Base-10 integer string: optional leading minus, one or more digits */\nconst AMOUNT_MINOR_PATTERN = /^-?[0-9]+$/;\n\nexport const CommerceExtensionSchema = z\n .object({\n /** Payment rail identifier (e.g., 'stripe', 'x402', 'lightning') */\n payment_rail: z.string().min(1).max(EXTENSION_LIMITS.maxPaymentRailLength),\n /**\n * Amount in smallest currency unit as a string for arbitrary precision.\n * Base-10 integer: optional leading minus, one or more digits.\n * Decimals and empty strings are rejected.\n */\n amount_minor: z\n .string()\n .min(1)\n .max(EXTENSION_LIMITS.maxAmountMinorLength)\n .regex(\n AMOUNT_MINOR_PATTERN,\n 'amount_minor must be a base-10 integer string (e.g., \"1000\", \"-50\")'\n ),\n /** ISO 4217 currency code or asset identifier */\n currency: z.string().min(1).max(EXTENSION_LIMITS.maxCurrencyLength),\n /** Caller-assigned payment reference */\n reference: z.string().max(EXTENSION_LIMITS.maxReferenceLength).optional(),\n /** Asset identifier for non-fiat (e.g., token address) */\n asset: z.string().max(EXTENSION_LIMITS.maxAssetLength).optional(),\n /** Environment discriminant */\n env: z.enum(['live', 'test']).optional(),\n /** Commerce lifecycle phase. Observational metadata only: does not encode settlement finality or protocol state transitions */\n event: z\n .enum(['authorization', 'capture', 'settlement', 'refund', 'void', 'chargeback'])\n .optional(),\n })\n .strict();\n\nexport type CommerceExtension = z.infer<typeof CommerceExtensionSchema>;\n","/**\n * Access Extension Group (org.peacprotocol/access)\n *\n * Records access control decision evidence.\n * Shipped in v0.12.0-preview.1.\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\n\nexport const ACCESS_EXTENSION_KEY = 'org.peacprotocol/access' as const;\n\nexport const AccessExtensionSchema = z\n .object({\n /** Resource being accessed (URI or identifier) */\n resource: z.string().min(1).max(EXTENSION_LIMITS.maxResourceLength),\n /** Action performed on the resource */\n action: z.string().min(1).max(EXTENSION_LIMITS.maxActionLength),\n /** Access decision */\n decision: z.enum(['allow', 'deny', 'review']),\n })\n .strict();\n\nexport type AccessExtension = z.infer<typeof AccessExtensionSchema>;\n","/**\n * Challenge Extension Group (org.peacprotocol/challenge)\n *\n * Records challenge issuance with RFC 9457 Problem Details.\n * Shipped in v0.12.0-preview.1.\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\n\nexport const CHALLENGE_EXTENSION_KEY = 'org.peacprotocol/challenge' as const;\n\n/**\n * Challenge type values (7 total, P0-6).\n * Includes purpose_disallowed (reviewer fix: 7 not 6).\n */\nexport const CHALLENGE_TYPES = [\n 'payment_required',\n 'identity_required',\n 'consent_required',\n 'attestation_required',\n 'rate_limited',\n 'purpose_disallowed',\n 'custom',\n] as const;\n\nexport const ChallengeTypeSchema = z.enum(CHALLENGE_TYPES);\nexport type ChallengeType = z.infer<typeof ChallengeTypeSchema>;\n\n/**\n * RFC 9457 Problem Details schema (P0-5).\n *\n * Uses .passthrough() for extension members per RFC 9457 Section 6.2.\n * Required fields: status (HTTP status code), type (problem type URI).\n * Optional fields: title, detail, instance.\n */\nexport const ProblemDetailsSchema = z\n .object({\n /** HTTP status code (100-599) */\n status: z.number().int().min(100).max(599),\n /** Problem type URI */\n type: z.string().min(1).max(EXTENSION_LIMITS.maxProblemTypeLength).url(),\n /** Short human-readable summary */\n title: z.string().max(EXTENSION_LIMITS.maxProblemTitleLength).optional(),\n /** Human-readable explanation specific to this occurrence */\n detail: z.string().max(EXTENSION_LIMITS.maxProblemDetailLength).optional(),\n /** URI reference identifying the specific occurrence */\n instance: z.string().max(EXTENSION_LIMITS.maxProblemInstanceLength).optional(),\n })\n .passthrough();\n\nexport const ChallengeExtensionSchema = z\n .object({\n /** Challenge type (7 values) */\n challenge_type: ChallengeTypeSchema,\n /** RFC 9457 Problem Details */\n problem: ProblemDetailsSchema,\n /** Resource that triggered the challenge */\n resource: z.string().max(EXTENSION_LIMITS.maxResourceLength).optional(),\n /** Action that triggered the challenge */\n action: z.string().max(EXTENSION_LIMITS.maxActionLength).optional(),\n /** Caller-defined requirements for resolving the challenge */\n requirements: z.record(z.string(), z.unknown()).optional(),\n })\n .strict();\n\nexport type ChallengeExtension = z.infer<typeof ChallengeExtensionSchema>;\n","/**\n * Identity Extension Group (org.peacprotocol/identity)\n *\n * Records identity verification or attestation evidence.\n * Shipped in v0.12.0-preview.1.\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\n\nexport const IDENTITY_EXTENSION_KEY = 'org.peacprotocol/identity' as const;\n\nexport const IdentityExtensionSchema = z\n .object({\n /** Proof reference (opaque string; no actor_binding: top-level actor is sole location) */\n proof_ref: z.string().max(EXTENSION_LIMITS.maxProofRefLength).optional(),\n })\n .strict();\n\nexport type IdentityExtension = z.infer<typeof IdentityExtensionSchema>;\n","/**\n * Correlation Extension Group (org.peacprotocol/correlation)\n *\n * Records workflow correlation and traceability metadata.\n * OpenTelemetry-compatible trace and span IDs.\n * Shipped in v0.12.0-preview.1.\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\n\nexport const CORRELATION_EXTENSION_KEY = 'org.peacprotocol/correlation' as const;\n\n/** OpenTelemetry trace ID: exactly 32 lowercase hex chars */\nconst TRACE_ID_PATTERN = /^[0-9a-f]{32}$/;\n\n/** OpenTelemetry span ID: exactly 16 lowercase hex chars */\nconst SPAN_ID_PATTERN = /^[0-9a-f]{16}$/;\n\nexport const CorrelationExtensionSchema = z\n .object({\n /** OpenTelemetry-compatible trace ID (32 lowercase hex chars) */\n trace_id: z\n .string()\n .length(EXTENSION_LIMITS.maxTraceIdLength)\n .regex(TRACE_ID_PATTERN, 'trace_id must be 32 lowercase hex characters')\n .optional(),\n /** OpenTelemetry-compatible span ID (16 lowercase hex chars) */\n span_id: z\n .string()\n .length(EXTENSION_LIMITS.maxSpanIdLength)\n .regex(SPAN_ID_PATTERN, 'span_id must be 16 lowercase hex characters')\n .optional(),\n /** Workflow identifier */\n workflow_id: z.string().min(1).max(EXTENSION_LIMITS.maxWorkflowIdLength).optional(),\n /** Parent receipt JTI for causal chains */\n parent_jti: z.string().min(1).max(EXTENSION_LIMITS.maxParentJtiLength).optional(),\n /** JTIs this receipt depends on */\n depends_on: z\n .array(z.string().min(1).max(EXTENSION_LIMITS.maxParentJtiLength))\n .max(EXTENSION_LIMITS.maxDependsOnLength)\n .optional(),\n })\n .strict();\n\nexport type CorrelationExtension = z.infer<typeof CorrelationExtensionSchema>;\n","/**\n * Wire 0.2 Shared Validator Schemas\n *\n * Protocol-grade Zod validators for common field patterns reused across\n * multiple extension groups. Consolidated to prevent drift, improve interop,\n * and keep Layer 1 clean.\n *\n * All validators are pure Zod schemas with zero I/O.\n *\n * @see HASH.pattern from @peac/kernel for SHA-256 digest grammar\n * @see PolicyBlockSchema.uri for HTTPS URI hint pattern origin\n */\n\nimport { z } from 'zod';\nimport { HASH } from '@peac/kernel';\n\n// ---------------------------------------------------------------------------\n// SHA-256 Digest (hash-first content references)\n// ---------------------------------------------------------------------------\n\n/**\n * Validates a SHA-256 digest string in the canonical PEAC format.\n *\n * Format: `sha256:<64 lowercase hex chars>`\n * Max length: 71 chars (\"sha256:\" = 7 chars + 64 hex chars = 71 total)\n *\n * Reuses `HASH.pattern` from `@peac/kernel` (same regex used in\n * `PolicyBlockSchema.digest` and `ReceiptRefSchema`).\n *\n * INTEROPERABILITY NOTE: This is a PEAC-internal self-describing digest\n * string grammar. It is NOT the same as:\n * - RFC 9530 `Content-Digest` / `Repr-Digest`, which use structured\n * HTTP fields with base64 encoding (e.g., `sha-256=:base64:`)\n * - RFC 9421 HTTP Message Signatures digest components\n * PEAC digest strings are used within JWS payloads and extension fields,\n * not as HTTP headers. When bridging to HTTP digest headers, adapters\n * (Layer 4+) must convert between formats.\n */\nexport const Sha256DigestSchema = z\n .string()\n .max(71)\n .regex(HASH.pattern, 'must be a valid SHA-256 digest (sha256:<64 lowercase hex>)');\n\n// ---------------------------------------------------------------------------\n// HTTPS URI Hint (locator hints only, SSRF prevention)\n// ---------------------------------------------------------------------------\n\n/**\n * Control character ranges that must not appear in URI hints.\n * Covers C0 controls (U+0000-U+001F) and DEL (U+007F).\n */\nconst CONTROL_CHAR_PATTERN = /[\\x00-\\x1f\\x7f]/;\n\n/**\n * Validates an HTTPS URI hint field.\n *\n * Security hardening beyond basic URL validation:\n * - MUST be https:// scheme (rejects http, ftp, data, javascript, file)\n * - MUST NOT contain embedded credentials (userinfo@)\n * - MUST NOT contain fragment identifiers (#)\n * - MUST NOT contain ASCII control characters (U+0000-U+001F, U+007F)\n * - Max 2048 chars (aligned with POLICY_BLOCK.uriMaxLength)\n *\n * These are locator hints only: callers MUST NOT auto-fetch.\n *\n * NORMATIVE: Localhost and private-network hosts (e.g., 10.x, 192.168.x,\n * localhost) are intentionally accepted at Layer 1 (schema). URI hints\n * are metadata, not fetch targets; restricting to public hosts would\n * break enterprise/internal deployments without improving security at\n * this layer. SSRF prevention is enforced by the non-fetch invariant\n *, not by host filtering in schema validation.\n *\n * Test suite covers: IDN/punycode, IPv6 literals, localhost-style\n * hosts, percent-encoded confusion, and parser ambiguity cases.\n */\nexport const HttpsUriHintSchema = z\n .string()\n .min(1)\n .max(2048)\n .refine(\n (value) => {\n // Reject control characters before URL parsing (prevents parser confusion)\n if (CONTROL_CHAR_PATTERN.test(value)) return false;\n\n // Reject fragments (not meaningful for locator hints)\n if (value.includes('#')) return false;\n\n try {\n const url = new URL(value);\n\n // MUST be https:// only\n if (url.protocol !== 'https:') return false;\n\n // MUST NOT contain embedded credentials\n if (url.username !== '' || url.password !== '') return false;\n\n // MUST have a non-empty hostname\n if (!url.hostname) return false;\n\n return true;\n } catch {\n return false;\n }\n },\n {\n message: 'must be a valid HTTPS URI (no credentials, no fragments, no control characters)',\n }\n );\n\n// ---------------------------------------------------------------------------\n// ISO 8601 Duration (parser-grade, strict)\n// ---------------------------------------------------------------------------\n\n/**\n * ISO 8601 duration component descriptor.\n */\ninterface DurationComponents {\n years: number;\n months: number;\n weeks: number;\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n}\n\n/**\n * Valid date-part designators in canonical order.\n * ISO 8601 requires Y before M before W before D.\n */\nconst DATE_DESIGNATOR_ORDER = ['Y', 'M', 'W', 'D'] as const;\n\n/**\n * Valid time-part designators in canonical order.\n * ISO 8601 requires H before M before S.\n */\nconst TIME_DESIGNATOR_ORDER = ['H', 'M', 'S'] as const;\n\n/**\n * Parse an ISO 8601 duration string into components.\n *\n * Enforces:\n * - No duplicate designators (P1Y2Y rejected)\n * - Canonical component ordering (P1D1Y rejected; must be P1Y1D)\n * - Weeks cannot be combined with other date components (ISO 8601)\n * - At least one component must be present (bare P rejected)\n * - At least one time component after T (bare PT rejected)\n * - Zero-value durations are accepted (P0D, PT0S are valid ISO 8601)\n *\n * Zero durations: P0D and PT0S are valid per ISO 8601. The spec says\n * \"a zero duration\" is representable. Consumers decide if a zero\n * duration is semantically meaningful for their use case.\n *\n * @param value - String to parse\n * @returns Parsed components, or null if invalid\n */\nexport function parseIso8601Duration(value: string): DurationComponents | null {\n if (typeof value !== 'string' || value.length === 0 || value.length > 64) {\n return null;\n }\n\n if (value.charAt(0) !== 'P') return null;\n\n let pos = 1;\n const len = value.length;\n\n // Bare \"P\" is invalid\n if (pos >= len) return null;\n\n const result: DurationComponents = {\n years: 0,\n months: 0,\n weeks: 0,\n days: 0,\n hours: 0,\n minutes: 0,\n seconds: 0,\n };\n\n let inTimePart = false;\n let hasAnyComponent = false;\n\n // Track seen designators to reject duplicates\n const seenDesignators = new Set<string>();\n\n // Track ordering: index into the relevant order array\n let dateOrderIdx = 0;\n let timeOrderIdx = 0;\n\n while (pos < len) {\n if (value.charAt(pos) === 'T') {\n if (inTimePart) return null; // Double T\n inTimePart = true;\n pos++;\n if (pos >= len) return null; // Bare \"PT\"\n continue;\n }\n\n // Parse digits\n const numStart = pos;\n while (pos < len && value.charAt(pos) >= '0' && value.charAt(pos) <= '9') {\n pos++;\n }\n if (pos === numStart) return null; // No digits before designator\n\n const digits = value.slice(numStart, pos);\n // Reject components that would lose precision as JS numbers.\n // Number.MAX_SAFE_INTEGER = 9007199254740991 (16 digits).\n // Duration components beyond this are structurally malformed for any\n // real-world use and would silently truncate.\n if (digits.length > 15) return null;\n const num = parseInt(digits, 10);\n if (!Number.isFinite(num) || num < 0) return null;\n\n if (pos >= len) return null; // No designator after number\n\n const designator = value.charAt(pos);\n pos++;\n\n // Reject duplicate designators\n const designatorKey = (inTimePart ? 'T' : '') + designator;\n if (seenDesignators.has(designatorKey)) return null;\n seenDesignators.add(designatorKey);\n\n if (inTimePart) {\n // Enforce canonical time ordering: H before M before S\n const timeIdx = TIME_DESIGNATOR_ORDER.indexOf(designator as 'H' | 'M' | 'S');\n if (timeIdx === -1) return null; // Invalid time designator\n if (timeIdx < timeOrderIdx) return null; // Out of order\n timeOrderIdx = timeIdx + 1;\n\n switch (designator) {\n case 'H':\n result.hours = num;\n break;\n case 'M':\n result.minutes = num;\n break;\n case 'S':\n result.seconds = num;\n break;\n }\n } else {\n // Enforce canonical date ordering: Y before M before W before D\n const dateIdx = DATE_DESIGNATOR_ORDER.indexOf(designator as 'Y' | 'M' | 'W' | 'D');\n if (dateIdx === -1) return null; // Invalid date designator\n if (dateIdx < dateOrderIdx) return null; // Out of order\n dateOrderIdx = dateIdx + 1;\n\n switch (designator) {\n case 'Y':\n result.years = num;\n break;\n case 'M':\n result.months = num;\n break;\n case 'W':\n result.weeks = num;\n break;\n case 'D':\n result.days = num;\n break;\n }\n }\n\n hasAnyComponent = true;\n }\n\n if (!hasAnyComponent) return null;\n\n // ISO 8601: weeks cannot be combined with other date components\n if (result.weeks > 0 && (result.years > 0 || result.months > 0 || result.days > 0)) {\n return null;\n }\n\n return result;\n}\n\n/**\n * Validates an ISO 8601 duration string.\n *\n * Parser-grade strict validation:\n * - Rejects bare P, bare PT\n * - Rejects duplicate designators (P1Y2Y)\n * - Enforces canonical component ordering (P1D1Y rejected)\n * - Rejects mixed weeks and other date components\n * - Accepts zero-value durations (P0D, PT0S are valid ISO 8601)\n * - Only non-negative integer components (no decimals, no negatives)\n *\n * Examples:\n * Valid: \"P30D\", \"P1Y\", \"P1Y6M\", \"PT1H30M\", \"P1W\", \"P0D\", \"PT0S\"\n * Invalid: \"P\", \"PT\", \"30D\", \"\", \"P1D1Y\", \"P1Y2Y\", \"P1WD3\", \"P-1D\"\n */\nexport const Iso8601DurationSchema = z\n .string()\n .min(2)\n .max(64)\n .refine((value) => parseIso8601Duration(value) !== null, {\n message: 'must be a valid ISO 8601 duration (e.g., P30D, P1Y6M, PT1H30M)',\n });\n\n// ---------------------------------------------------------------------------\n// ISO 8601 Date String (YYYY-MM-DD, structural only)\n// ---------------------------------------------------------------------------\n\n/**\n * Validates a structurally valid ISO 8601 date string (YYYY-MM-DD).\n *\n * Structural validation only: checks 4-digit year, 2-digit month 01-12,\n * 2-digit day 01-31. Does NOT validate calendar correctness (e.g.,\n * Feb 30 or Jun 31 would pass structural check). Calendar validation\n * is left to the application layer since this is an evidence record,\n * not a scheduling system.\n *\n * Named \"StructuralDate\" to avoid implying full calendar validation.\n */\nexport const Iso8601DateStringSchema = z\n .string()\n .length(10)\n .regex(/^\\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\\d|3[01])$/, {\n message: 'must be a structurally valid date string (YYYY-MM-DD)',\n });\n\n/**\n * @deprecated Use Iso8601DateStringSchema. Alias preserved for backward compat.\n */\nexport const Iso8601DateSchema = Iso8601DateStringSchema;\n\n// ---------------------------------------------------------------------------\n// ISO 8601 DateTime with Offset (Zod 4 top-level API)\n// ---------------------------------------------------------------------------\n\n/**\n * Validates an ISO 8601 datetime string with timezone offset.\n *\n * Uses Zod 4 top-level `z.iso.datetime({ offset: true })` (preferred\n * over the deprecated method-style `z.string().datetime()`).\n *\n * This is NOT strictly RFC 3339: it accepts minute-precision timestamps\n * (e.g., `2026-03-14T12:00+05:30` without seconds), which ISO 8601\n * allows but RFC 3339 does not. Use Rfc3339DateTimeSchema for strict\n * RFC 3339 compliance.\n *\n * Consistent with Wire 0.2 `occurred_at` field validation semantics.\n */\nexport const Iso8601OffsetDateTimeSchema = z.iso.datetime({ offset: true });\n\n// ---------------------------------------------------------------------------\n// RFC 3339 DateTime (strict: offset + seconds required, fractional optional)\n// ---------------------------------------------------------------------------\n\n/**\n * RFC 3339 seconds-presence pattern.\n * Matches the `T<HH>:<MM>:<SS>` portion, ensuring seconds are present.\n * Fractional seconds (.nnn) are optional per RFC 3339 Section 5.6.\n */\nconst RFC3339_SECONDS_PATTERN = /T\\d{2}:\\d{2}:\\d{2}/;\n\n/**\n * Validates a datetime string against a practical strict RFC 3339 profile.\n *\n * Enforces the key RFC 3339 Section 5.6 constraints:\n * - Timezone offset always present (Z or +/-HH:MM)\n * - Seconds always present (minute-only timestamps rejected)\n * - Fractional seconds optional (after the seconds component)\n * - No local timestamps\n *\n * This is a practical strict profile, not a proven ABNF implementation.\n * It uses `z.iso.datetime({ offset: true })` as the base (which handles\n * most RFC 3339 grammar) plus a seconds-presence refine. Edge cases\n * like leap seconds or two-digit year forms are not explicitly tested.\n *\n * @see https://www.rfc-editor.org/rfc/rfc3339#section-5.6\n */\nexport const Rfc3339DateTimeSchema = z.iso\n .datetime({ offset: true })\n .refine((value: string) => RFC3339_SECONDS_PATTERN.test(value), {\n message: 'RFC 3339 requires seconds precision (e.g., 2026-03-14T12:00:00Z)',\n });\n\n/**\n * @deprecated Use Iso8601OffsetDateTimeSchema or Rfc3339DateTimeSchema.\n * This alias points to Iso8601OffsetDateTimeSchema (which accepts\n * minute-precision and is therefore NOT strictly RFC 3339). Preserved\n * for backward compatibility only. Remove-not-before: v0.13.0.\n */\nexport const Rfc3339TimestampSchema = Iso8601OffsetDateTimeSchema;\n\n// ---------------------------------------------------------------------------\n// SPDX License Expression (documented structural subset)\n// ---------------------------------------------------------------------------\n\n/**\n * SPDX License Expression validator: documented structural subset.\n *\n * This is a structural subset validator for v0.12.2, NOT full SPDX 3.0.1\n * support. It validates expression grammar without checking license IDs\n * against the SPDX license list.\n *\n * Supported subset:\n * - Simple license IDs: MIT, Apache-2.0, GPL-3.0-only\n * - LicenseRef custom references: LicenseRef-custom\n * - Or-later suffix: GPL-2.0+\n * - Compound expressions: MIT AND Apache-2.0, MIT OR GPL-2.0-only\n * - Exception clauses: Apache-2.0 WITH Classpath-exception-2.0\n * - Parenthesized sub-expressions: (MIT OR Apache-2.0) AND GPL-3.0-only\n *\n * NOT supported (deferred to attribution extension PR, v0.12.2 PR 4):\n * - DocumentRef-*: prefixes (rare in practice; not seen in npm/PyPI/crates.io)\n *\n * @see https://spdx.github.io/spdx-spec/v3.0.1/annexes/spdx-license-expressions/\n */\nfunction isValidSpdxSubsetExpression(expr: string): boolean {\n if (typeof expr !== 'string' || expr.length === 0 || expr.length > 128) {\n return false;\n }\n\n // Tokenize: split on whitespace, preserving parentheses as separate tokens\n const tokens: string[] = [];\n let current = '';\n\n for (let i = 0; i < expr.length; i++) {\n const ch = expr.charAt(i);\n if (ch === '(' || ch === ')') {\n if (current.length > 0) {\n tokens.push(current);\n current = '';\n }\n tokens.push(ch);\n } else if (ch === ' ' || ch === '\\t') {\n if (current.length > 0) {\n tokens.push(current);\n current = '';\n }\n } else {\n current += ch;\n }\n }\n if (current.length > 0) {\n tokens.push(current);\n }\n\n if (tokens.length === 0) return false;\n\n // Recursive-descent parser\n let pos = 0;\n\n function peek(): string | undefined {\n return tokens[pos];\n }\n\n function advance(): string {\n return tokens[pos++];\n }\n\n // license-id: [A-Za-z0-9][A-Za-z0-9.-]* with optional + suffix\n // LicenseRef-: LicenseRef-[A-Za-z0-9.-]+\n function isLicenseId(token: string): boolean {\n const base = token.endsWith('+') ? token.slice(0, -1) : token;\n if (base.length === 0) return false;\n\n if (base.startsWith('LicenseRef-')) {\n const ref = base.slice(11);\n return ref.length > 0 && /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(ref);\n }\n\n return /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(base);\n }\n\n function isExceptionId(token: string): boolean {\n return /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(token);\n }\n\n // expr = term ((AND | OR) term)*\n function parseExpr(): boolean {\n if (!parseTerm()) return false;\n while (pos < tokens.length) {\n const op = peek();\n if (op === 'AND' || op === 'OR') {\n advance();\n if (!parseTerm()) return false;\n } else {\n break;\n }\n }\n return true;\n }\n\n // term = atom (WITH exception-id)?\n function parseTerm(): boolean {\n if (!parseAtom()) return false;\n if (peek() === 'WITH') {\n advance();\n const exception = peek();\n if (exception === undefined || !isExceptionId(exception)) return false;\n advance();\n }\n return true;\n }\n\n // atom = '(' expr ')' | license-id\n function parseAtom(): boolean {\n const token = peek();\n if (token === undefined) return false;\n\n if (token === '(') {\n advance();\n if (!parseExpr()) return false;\n if (peek() !== ')') return false;\n advance();\n return true;\n }\n\n if (token === ')' || token === 'AND' || token === 'OR' || token === 'WITH') {\n return false;\n }\n\n if (!isLicenseId(token)) return false;\n advance();\n return true;\n }\n\n const result = parseExpr();\n return result && pos === tokens.length;\n}\n\n/**\n * Validates an SPDX license expression (documented structural subset).\n *\n * Uses a recursive-descent parser for the supported grammar subset.\n * Does NOT validate against the SPDX license list (structure only).\n * Does NOT support DocumentRef-* prefixes (deferred).\n *\n * @see isValidSpdxSubsetExpression for the supported grammar\n */\nexport const SpdxExpressionSchema = z.string().min(1).max(128).refine(isValidSpdxSubsetExpression, {\n message:\n 'must be a valid SPDX license expression (e.g., MIT, Apache-2.0, MIT AND Apache-2.0). DocumentRef-* not yet supported.',\n});\n\n// ---------------------------------------------------------------------------\n// Exported internals for testing\n// ---------------------------------------------------------------------------\n\n/** @internal Exported for testing only */\nexport { parseIso8601Duration as _parseIso8601Duration };\n\n/** @internal Exported for testing only */\nexport { isValidSpdxSubsetExpression as _isValidSpdxExpression };\n","/**\n * Consent Extension Group (org.peacprotocol/consent)\n *\n * Records consent collection or withdrawal as an observation.\n * Jurisdiction-neutral. Aligned with ISO/IEC 29184:2020 concepts.\n *\n * Design:\n * - Open taxonomy for consent_basis, consent_method (jurisdiction-specific)\n * - Closed enum for consent_status (universal lifecycle states)\n * - URI fields are locator hints only; callers MUST NOT auto-fetch\n * - ISO 8601 durations for retention periods\n * - Observation-only semantics: records events, never enforces policy\n *\n * @see docs/specs/WIRE-0.2.md Section 12.10\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\nimport { HttpsUriHintSchema, Iso8601DurationSchema } from './shared-validators.js';\n\nexport const CONSENT_EXTENSION_KEY = 'org.peacprotocol/consent' as const;\n\n/**\n * Consent status: universal lifecycle states across GDPR Art 7,\n * CCPA Sec 1798.120, LGPD Art 8, ISO/IEC 29184.\n *\n * Closed enum: these 4 states cover all consent lifecycle transitions.\n */\nexport const CONSENT_STATUSES = ['granted', 'withdrawn', 'denied', 'expired'] as const;\nexport const ConsentStatusSchema = z.enum(CONSENT_STATUSES);\nexport type ConsentStatus = z.infer<typeof ConsentStatusSchema>;\n\nexport const ConsentExtensionSchema = z\n .object({\n /**\n * Legal basis identifier for consent.\n * Open string: jurisdictions define different bases\n * (e.g., explicit, implied, opt_out, legitimate_interest, contractual, legal_obligation).\n */\n consent_basis: z.string().min(1).max(EXTENSION_LIMITS.maxConsentBasisLength),\n\n /** Consent lifecycle state (closed vocabulary) */\n consent_status: ConsentStatusSchema,\n\n /**\n * Data categories covered by this consent.\n * Open vocabulary (e.g., personal, sensitive, biometric).\n */\n data_categories: z\n .array(z.string().min(1).max(EXTENSION_LIMITS.maxDataCategoryLength))\n .max(EXTENSION_LIMITS.maxDataCategoriesCount)\n .optional(),\n\n /** Data retention period as ISO 8601 duration. */\n retention_period: Iso8601DurationSchema.optional(),\n\n /**\n * How consent was collected.\n * Open vocabulary (e.g., click_through, double_opt_in, verbal, written).\n */\n consent_method: z.string().min(1).max(EXTENSION_LIMITS.maxConsentMethodLength).optional(),\n\n /**\n * HTTPS URI hint for consent withdrawal.\n * Locator hint only: callers MUST NOT auto-fetch.\n * Rejects non-HTTPS, embedded credentials, fragments, control chars.\n */\n withdrawal_uri: HttpsUriHintSchema.optional(),\n\n /** Free-text scope description */\n scope: z.string().min(1).max(EXTENSION_LIMITS.maxConsentScopeLength).optional(),\n\n /**\n * Jurisdiction code: ISO 3166-1 alpha-2 or composite.\n * Examples: EU, US-CA, BR, GB, DE, JP, IN.\n */\n jurisdiction: z.string().min(1).max(EXTENSION_LIMITS.maxJurisdictionLength).optional(),\n })\n .strict();\n\nexport type ConsentExtension = z.infer<typeof ConsentExtensionSchema>;\n","/**\n * Privacy Extension Group (org.peacprotocol/privacy)\n *\n * Records data classification and handling observations.\n * Aligned with ISO/IEC 27701 concepts.\n *\n * Design:\n * - Open taxonomy for data_classification, processing_basis, methods\n * - Closed enums for retention_mode, recipient_scope (universal categories)\n * - retention_period (ISO 8601 duration) and retention_mode are separate fields\n * to keep duration grammar and non-duration semantics distinct\n * - Observation-only semantics: records events, never enforces policy\n *\n * @see docs/specs/WIRE-0.2.md Section 12.11\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\nimport { Iso8601DurationSchema } from './shared-validators.js';\n\nexport const PRIVACY_EXTENSION_KEY = 'org.peacprotocol/privacy' as const;\n\n/**\n * Retention mode: non-duration retention semantics.\n * Separate from retention_period to keep duration grammar distinct.\n *\n * Closed enum: 3 values cover all non-duration retention patterns.\n */\nexport const RETENTION_MODES = ['time_bound', 'indefinite', 'session_only'] as const;\nexport const RetentionModeSchema = z.enum(RETENTION_MODES);\nexport type RetentionMode = z.infer<typeof RetentionModeSchema>;\n\n/**\n * Recipient scope: aligned with GDPR Art 13-14 disclosure categories.\n *\n * Closed enum: 4 values cover standard data recipient classifications.\n */\nexport const RECIPIENT_SCOPES = ['internal', 'processor', 'third_party', 'public'] as const;\nexport const RecipientScopeSchema = z.enum(RECIPIENT_SCOPES);\nexport type RecipientScope = z.infer<typeof RecipientScopeSchema>;\n\nexport const PrivacyExtensionSchema = z\n .object({\n /**\n * Data classification level.\n * Open taxonomy (e.g., public, internal, confidential, restricted, pii, sensitive_pii).\n */\n data_classification: z.string().min(1).max(EXTENSION_LIMITS.maxDataClassificationLength),\n\n /**\n * Legal basis for data processing.\n * Open vocabulary (e.g., consent, legitimate_interest, contract, legal_obligation).\n */\n processing_basis: z.string().min(1).max(EXTENSION_LIMITS.maxProcessingBasisLength).optional(),\n\n /**\n * Data retention period as ISO 8601 duration.\n * For non-duration retention semantics, use retention_mode instead.\n */\n retention_period: Iso8601DurationSchema.optional(),\n\n /**\n * Retention mode for non-duration semantics.\n * Closed enum: time_bound, indefinite, session_only.\n * When time_bound, retention_period SHOULD also be present.\n */\n retention_mode: RetentionModeSchema.optional(),\n\n /**\n * Data recipient classification.\n * Closed enum aligned with GDPR Art 13-14 disclosure categories.\n */\n recipient_scope: RecipientScopeSchema.optional(),\n\n /**\n * Anonymization or pseudonymization method applied.\n * Open vocabulary (e.g., k_anonymity, differential_privacy, pseudonymization,\n * tokenization, aggregation).\n */\n anonymization_method: z\n .string()\n .min(1)\n .max(EXTENSION_LIMITS.maxAnonymizationMethodLength)\n .optional(),\n\n /**\n * Data subject category.\n * Open vocabulary (e.g., customer, employee, minor, patient, student).\n */\n data_subject_category: z\n .string()\n .min(1)\n .max(EXTENSION_LIMITS.maxDataSubjectCategoryLength)\n .optional(),\n\n /**\n * Cross-border data transfer mechanism.\n * Open vocabulary (e.g., adequacy_decision, scc, bcr, derogation, consent).\n */\n transfer_mechanism: z\n .string()\n .min(1)\n .max(EXTENSION_LIMITS.maxTransferMechanismLength)\n .optional(),\n })\n .strict();\n\nexport type PrivacyExtension = z.infer<typeof PrivacyExtensionSchema>;\n","/**\n * Safety Extension Group (org.peacprotocol/safety)\n *\n * Records safety assessment evidence. Jurisdiction-neutral design.\n * Usage profiles decide when regulatory-specific fields become required.\n *\n * Design:\n * - review_status required (universal assessment lifecycle)\n * - risk_level optional at schema layer; usage profiles may require it\n * - Open taxonomy for assessment_method, safety_measures, category\n * - Observation-only semantics: records events, never enforces policy\n *\n * @see docs/specs/WIRE-0.2.md Section 12.12\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\n\nexport const SAFETY_EXTENSION_KEY = 'org.peacprotocol/safety' as const;\n\n/**\n * Review status: universal safety assessment lifecycle.\n *\n * Closed enum: 4 states cover the assessment lifecycle across\n * EU AI Act, NIST AI RMF, ISO 23894, and general safety review.\n */\nexport const REVIEW_STATUSES = ['reviewed', 'pending', 'flagged', 'not_applicable'] as const;\nexport const ReviewStatusSchema = z.enum(REVIEW_STATUSES);\nexport type ReviewStatus = z.infer<typeof ReviewStatusSchema>;\n\n/**\n * Risk level: converges across EU AI Act Art 6, NIST AI RMF, ISO 23894.\n *\n * Closed enum: 4 risk tiers. Optional at schema level to maintain\n * jurisdiction neutrality; usage profiles may require this field.\n */\nexport const RISK_LEVELS = ['unacceptable', 'high', 'limited', 'minimal'] as const;\nexport const RiskLevelSchema = z.enum(RISK_LEVELS);\nexport type RiskLevel = z.infer<typeof RiskLevelSchema>;\n\nexport const SafetyExtensionSchema = z\n .object({\n /** Safety review status (closed vocabulary, universal lifecycle) */\n review_status: ReviewStatusSchema,\n\n /**\n * Risk classification level.\n * Optional at schema level; usage profiles may require it.\n * Converges across EU AI Act Art 6, NIST AI RMF, ISO 23894.\n */\n risk_level: RiskLevelSchema.optional(),\n\n /**\n * Assessment method used.\n * Open vocabulary (e.g., automated_scan, human_review, red_team,\n * penetration_test, static_analysis, model_evaluation).\n */\n assessment_method: z.string().min(1).max(EXTENSION_LIMITS.maxAssessmentMethodLength).optional(),\n\n /**\n * Safety measures applied.\n * Open vocabulary. Array bounded by maxSafetyMeasuresCount.\n */\n safety_measures: z\n .array(z.string().min(1).max(EXTENSION_LIMITS.maxSafetyMeasureLength))\n .max(EXTENSION_LIMITS.maxSafetyMeasuresCount)\n .optional(),\n\n /** Incident report reference. Opaque identifier (e.g., ticket ID or digest). */\n incident_ref: z.string().min(1).max(EXTENSION_LIMITS.maxIncidentRefLength).optional(),\n\n /** AI model reference. Opaque identifier (e.g., model version string). */\n model_ref: z.string().min(1).max(EXTENSION_LIMITS.maxModelRefLength).optional(),\n\n /**\n * Safety category.\n * Open vocabulary (e.g., content_safety, bias, hallucination,\n * toxicity, fairness, robustness, privacy_risk).\n */\n category: z.string().min(1).max(EXTENSION_LIMITS.maxSafetyCategoryLength).optional(),\n })\n .strict();\n\nexport type SafetyExtension = z.infer<typeof SafetyExtensionSchema>;\n","/**\n * Compliance Extension Group (org.peacprotocol/compliance)\n *\n * Records regulatory compliance check evidence as an observation.\n * Framework-neutral. Does not assert or certify compliance; records\n * that a check occurred, what framework was evaluated, and what the\n * observed outcome was.\n *\n * Design:\n * - Open taxonomy for framework, auditor, scope (domain-specific)\n * - Closed enum for compliance_status (universal audit conclusion categories)\n * - ISO 8601 durations for validity periods\n * - Observation-only semantics: records events, never enforces policy\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\nimport {\n Iso8601DateStringSchema,\n Iso8601DurationSchema,\n Sha256DigestSchema,\n} from './shared-validators.js';\n\nexport const COMPLIANCE_EXTENSION_KEY = 'org.peacprotocol/compliance' as const;\n\n/**\n * Compliance status: maps to ISO 19011 audit conclusion categories.\n *\n * Closed enum: 5 values cover the universal compliance assessment\n * lifecycle across regulatory frameworks.\n */\nexport const COMPLIANCE_STATUSES = [\n 'compliant',\n 'non_compliant',\n 'partial',\n 'under_review',\n 'exempt',\n] as const;\nexport const ComplianceStatusSchema = z.enum(COMPLIANCE_STATUSES);\nexport type ComplianceStatus = z.infer<typeof ComplianceStatusSchema>;\n\nexport const ComplianceExtensionSchema = z\n .object({\n /**\n * Framework identifier evaluated.\n * Open string: preferred grammar is lowercase slugs with hyphens\n * (e.g., eu-ai-act, soc2-type2, iso-27001, nist-ai-rmf, gdpr, hipaa).\n */\n framework: z.string().min(1).max(EXTENSION_LIMITS.maxFrameworkLength),\n\n /** Observed compliance status (closed vocabulary) */\n compliance_status: ComplianceStatusSchema,\n\n /** Opaque reference to audit report or evidence (e.g., report ID, ticket number). */\n audit_ref: z.string().min(1).max(EXTENSION_LIMITS.maxAuditRefLength).optional(),\n\n /** Auditor identifier (organization name or DID). */\n auditor: z.string().min(1).max(EXTENSION_LIMITS.maxAuditorLength).optional(),\n\n /** Date the compliance check was performed (YYYY-MM-DD). */\n audit_date: Iso8601DateStringSchema.optional(),\n\n /** Scope of the compliance check. */\n scope: z.string().min(1).max(EXTENSION_LIMITS.maxComplianceScopeLength).optional(),\n\n /** How long this finding remains valid as an ISO 8601 duration. */\n validity_period: Iso8601DurationSchema.optional(),\n\n /** SHA-256 digest of supporting evidence document. */\n evidence_ref: Sha256DigestSchema.optional(),\n })\n .strict();\n\nexport type ComplianceExtension = z.infer<typeof ComplianceExtensionSchema>;\n","/**\n * Provenance Extension Group (org.peacprotocol/provenance)\n *\n * Records origin tracking and chain of custody as observations.\n *\n * Design:\n * - source_type required, open vocabulary for derivation categories\n * - custody_chain: ordered array of strict nested entries\n * - slsa: structured object recording SLSA-aligned metadata\n * (track-based model; does not certify SLSA compliance)\n * - URI fields are locator hints only; callers MUST NOT auto-fetch\n * - Observation-only semantics: records events, never enforces policy\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\nimport { HttpsUriHintSchema, Rfc3339DateTimeSchema } from './shared-validators.js';\n\nexport const PROVENANCE_EXTENSION_KEY = 'org.peacprotocol/provenance' as const;\n\n// ---------------------------------------------------------------------------\n// Nested schemas\n// ---------------------------------------------------------------------------\n\n/**\n * A single entry in the custody chain.\n *\n * Records one transfer-of-custody event: who held it, what action\n * occurred, and when. Ordered within the custody_chain array.\n */\nexport const CustodyEntrySchema = z\n .object({\n /** Custodian identifier (organization name, DID, or opaque ID). */\n custodian: z.string().min(1).max(EXTENSION_LIMITS.maxCustodianLength),\n\n /** Action performed (e.g., received, transformed, verified, released). */\n action: z.string().min(1).max(EXTENSION_LIMITS.maxCustodyActionLength),\n\n /** When the custody event occurred (RFC 3339 with seconds). */\n timestamp: Rfc3339DateTimeSchema,\n })\n .strict();\n\nexport type CustodyEntry = z.infer<typeof CustodyEntrySchema>;\n\n/**\n * Structured SLSA-aligned provenance metadata.\n *\n * Uses a track-based model rather than a flat scalar.\n * Records metadata; does not certify compliance.\n */\nexport const SlsaLevelSchema = z\n .object({\n /** SLSA track identifier (e.g., build, source). */\n track: z.string().min(1).max(EXTENSION_LIMITS.maxSlsaTrackLength),\n\n /** SLSA level within the track (0-4). */\n level: z.number().int().min(0).max(4),\n\n /** SLSA spec version this metadata references (e.g., 1.0, 1.2). */\n version: z.string().min(1).max(EXTENSION_LIMITS.maxSlsaVersionLength),\n })\n .strict();\n\nexport type SlsaLevel = z.infer<typeof SlsaLevelSchema>;\n\n// ---------------------------------------------------------------------------\n// Main schema\n// ---------------------------------------------------------------------------\n\nexport const ProvenanceExtensionSchema = z\n .object({\n /**\n * Type of source or derivation.\n * Open vocabulary (e.g., original, derived, curated, synthetic, aggregated, transformed).\n */\n source_type: z.string().min(1).max(EXTENSION_LIMITS.maxSourceTypeLength),\n\n /** Opaque source reference identifier (e.g., commit hash, artifact ID). */\n source_ref: z.string().min(1).max(EXTENSION_LIMITS.maxSourceRefLength).optional(),\n\n /**\n * HTTPS URI hint for the source artifact.\n * Locator hint only: callers MUST NOT auto-fetch.\n */\n source_uri: HttpsUriHintSchema.optional(),\n\n /**\n * HTTPS URI hint for build provenance metadata.\n * Locator hint only: callers MUST NOT auto-fetch.\n */\n build_provenance_uri: HttpsUriHintSchema.optional(),\n\n /**\n * How provenance was verified.\n * Open vocabulary (e.g., signature_check, hash_chain,\n * manual_attestation, transparency_log).\n */\n verification_method: z\n .string()\n .min(1)\n .max(EXTENSION_LIMITS.maxVerificationMethodLength)\n .optional(),\n\n /**\n * Ordered custody chain entries.\n * Each entry records a custodian, action, and timestamp.\n */\n custody_chain: z\n .array(CustodyEntrySchema)\n .max(EXTENSION_LIMITS.maxCustodyChainCount)\n .optional(),\n\n /**\n * Structured SLSA-aligned provenance metadata.\n * Records track, level, and spec version.\n */\n slsa: SlsaLevelSchema.optional(),\n })\n .strict();\n\nexport type ProvenanceExtension = z.infer<typeof ProvenanceExtensionSchema>;\n","/**\n * Attribution Extension Group (org.peacprotocol/attribution)\n *\n * Records credit, obligations, and content signal observations.\n *\n * Design:\n * - Identifier and reference-based fields; not identity attestation\n * - Closed enum for content_signal_source (known observation sources)\n * - SPDX license expressions via parser-grade shared validator\n * - Observation-only semantics: records events, never enforces policy\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\nimport { Sha256DigestSchema, SpdxExpressionSchema } from './shared-validators.js';\n\nexport const ATTRIBUTION_EXTENSION_KEY = 'org.peacprotocol/attribution' as const;\n\n/**\n * Content signal observation source.\n *\n * Closed enum: maps to the known observation sources in the\n * content signals precedence chain.\n */\nexport const CONTENT_SIGNAL_SOURCES = [\n 'tdmrep_json',\n 'content_signal_header',\n 'content_usage_header',\n 'robots_txt',\n 'custom',\n] as const;\nexport const ContentSignalSourceSchema = z.enum(CONTENT_SIGNAL_SOURCES);\nexport type ContentSignalSource = z.infer<typeof ContentSignalSourceSchema>;\n\nexport const AttributionExtensionSchema = z\n .object({\n /**\n * Creator identifier (DID, URI, or opaque ID).\n * Not an identity attestation; records observed attribution metadata.\n */\n creator_ref: z.string().min(1).max(EXTENSION_LIMITS.maxCreatorRefLength),\n\n /** SPDX license expression (parser-grade structural subset validator). */\n license_spdx: SpdxExpressionSchema.optional(),\n\n /**\n * Obligation type.\n * Open vocabulary (e.g., attribution_required, share_alike, non_commercial).\n */\n obligation_type: z.string().min(1).max(EXTENSION_LIMITS.maxObligationTypeLength).optional(),\n\n /** Required attribution text. */\n attribution_text: z.string().min(1).max(EXTENSION_LIMITS.maxAttributionTextLength).optional(),\n\n /** Content signal observation source (closed vocabulary). */\n content_signal_source: ContentSignalSourceSchema.optional(),\n\n /** SHA-256 digest of the attributed content. */\n content_digest: Sha256DigestSchema.optional(),\n })\n .strict();\n\nexport type AttributionExtension = z.infer<typeof AttributionExtensionSchema>;\n","/**\n * Purpose Extension Group (org.peacprotocol/purpose)\n *\n * Records external/legal/business purpose declarations as observations.\n * Explicitly separated from PEAC operational purpose tokens\n * (CanonicalPurpose in purpose.ts).\n *\n * Design:\n * - external_purposes: token-based array (machine-safe, bounded, unique)\n * - peac_purpose_mapping: optional bridge to PEAC operational tokens\n * via PURPOSE_TOKEN_REGEX\n * - No prose-heavy fields at schema layer\n * - Observation-only semantics: records events, never enforces policy\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\nimport { PURPOSE_TOKEN_REGEX, MAX_PURPOSE_TOKEN_LENGTH } from '../purpose.js';\n\nexport const PURPOSE_EXTENSION_KEY = 'org.peacprotocol/purpose' as const;\n\n/**\n * Machine-safe token schema for purpose label arrays.\n *\n * Reuses PURPOSE_TOKEN_REGEX from purpose.ts for the lexical grammar\n * (lowercase alphanumeric, underscores, hyphens, optional vendor prefix).\n * Semantically independent from PEAC operational CanonicalPurpose tokens.\n */\nconst MachineSafePurposeTokenSchema = z\n .string()\n .min(1)\n .max(EXTENSION_LIMITS.maxExternalPurposeLength)\n .regex(PURPOSE_TOKEN_REGEX, 'must be a machine-safe lowercase token');\n\n/**\n * Check that all items in a string array are unique.\n */\nfunction hasUniqueItems(items: string[]): boolean {\n return new Set(items).size === items.length;\n}\n\nexport const PurposeExtensionSchema = z\n .object({\n /**\n * External/legal/business purpose labels.\n * Machine-safe tokens: lowercase alphanumeric with underscores, hyphens,\n * and optional vendor prefix (e.g., ai_training, analytics, marketing).\n * Not PEAC operational tokens; use peac_purpose_mapping for bridging.\n * Items must be unique.\n */\n external_purposes: z\n .array(MachineSafePurposeTokenSchema)\n .min(1)\n .max(EXTENSION_LIMITS.maxExternalPurposesCount)\n .refine(hasUniqueItems, { message: 'external_purposes must contain unique items' }),\n\n /**\n * Legal or policy basis for the declared purposes.\n * Open vocabulary (e.g., consent, legitimate_interest, contract).\n */\n purpose_basis: z.string().min(1).max(EXTENSION_LIMITS.maxPurposeBasisLength).optional(),\n\n /** Whether purpose limitation applies. */\n purpose_limitation: z.boolean().optional(),\n\n /** Whether data minimization was applied. */\n data_minimization: z.boolean().optional(),\n\n /**\n * Compatible purposes for secondary use.\n * Same machine-safe token grammar as external_purposes.\n * Items must be unique.\n */\n compatible_purposes: z\n .array(MachineSafePurposeTokenSchema)\n .max(EXTENSION_LIMITS.maxCompatiblePurposesCount)\n .refine(hasUniqueItems, { message: 'compatible_purposes must contain unique items' })\n .optional(),\n\n /**\n * Explicit mapping to a PEAC operational CanonicalPurpose token.\n * Validated against PURPOSE_TOKEN_REGEX from purpose.ts.\n * Bridges external purpose vocabulary to operational tokens.\n */\n peac_purpose_mapping: z\n .string()\n .min(1)\n .max(MAX_PURPOSE_TOKEN_LENGTH)\n .regex(PURPOSE_TOKEN_REGEX, 'must be a valid PEAC purpose token')\n .optional(),\n })\n .strict();\n\nexport type PurposeExtension = z.infer<typeof PurposeExtensionSchema>;\n","/**\n * Wire 0.2 Extension Schema Map\n *\n * Maps known extension group keys to their Zod schemas.\n * Used by validateKnownExtensions() for group-level validation\n * and by type-to-extension enforcement.\n *\n * This file is the single mutation point for group registration.\n */\n\nimport type { z } from 'zod';\n\nimport { COMMERCE_EXTENSION_KEY, CommerceExtensionSchema } from './commerce.js';\nimport { ACCESS_EXTENSION_KEY, AccessExtensionSchema } from './access.js';\nimport { CHALLENGE_EXTENSION_KEY, ChallengeExtensionSchema } from './challenge.js';\nimport { IDENTITY_EXTENSION_KEY, IdentityExtensionSchema } from './identity.js';\nimport { CORRELATION_EXTENSION_KEY, CorrelationExtensionSchema } from './correlation.js';\nimport { CONSENT_EXTENSION_KEY, ConsentExtensionSchema } from './consent.js';\nimport { PRIVACY_EXTENSION_KEY, PrivacyExtensionSchema } from './privacy.js';\nimport { SAFETY_EXTENSION_KEY, SafetyExtensionSchema } from './safety.js';\nimport { COMPLIANCE_EXTENSION_KEY, ComplianceExtensionSchema } from './compliance.js';\nimport { PROVENANCE_EXTENSION_KEY, ProvenanceExtensionSchema } from './provenance.js';\nimport { ATTRIBUTION_EXTENSION_KEY, AttributionExtensionSchema } from './attribution.js';\nimport { PURPOSE_EXTENSION_KEY, PurposeExtensionSchema } from './purpose-extension.js';\n\n/** Map from known extension key to its Zod schema */\nexport const EXTENSION_SCHEMA_MAP = new Map<string, z.ZodTypeAny>();\nEXTENSION_SCHEMA_MAP.set(COMMERCE_EXTENSION_KEY, CommerceExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(ACCESS_EXTENSION_KEY, AccessExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(CHALLENGE_EXTENSION_KEY, ChallengeExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(IDENTITY_EXTENSION_KEY, IdentityExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(CORRELATION_EXTENSION_KEY, CorrelationExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(CONSENT_EXTENSION_KEY, ConsentExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(PRIVACY_EXTENSION_KEY, PrivacyExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(SAFETY_EXTENSION_KEY, SafetyExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(COMPLIANCE_EXTENSION_KEY, ComplianceExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(PROVENANCE_EXTENSION_KEY, ProvenanceExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(ATTRIBUTION_EXTENSION_KEY, AttributionExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(PURPOSE_EXTENSION_KEY, PurposeExtensionSchema);\n","/**\n * Wire 0.2 Extension Validation (envelope-level superRefine helper)\n *\n * Validates the extensions record inside Wire02ClaimsSchema.superRefine():\n * 1. Extension key grammar validation\n * 2. Recursive plain-JSON-value guard (rejects non-JSON-safe values)\n * 3. Known extension group schema validation\n * 4. Byte-budget enforcement\n *\n * NORMATIVE: Extension group values MUST be plain JSON values all the\n * way down (objects, arrays, strings, finite numbers, booleans, null).\n * Arbitrary JavaScript objects (functions, Symbols, Dates, BigInt,\n * objects with toJSON(), circular references, non-finite numbers, etc.)\n * are not a supported input class and are rejected at the validation\n * boundary via E_EXTENSION_NON_JSON_VALUE. This ensures cross-language\n * portability and reproducible byte-budget measurement.\n *\n * MEASUREMENT BASIS: Byte budgets are measured as the UTF-8 byte length\n * of ECMAScript JSON.stringify() output on plain JSON data. This is\n * explicitly ECMAScript-defined, not language-neutral canonical JSON.\n * Equivalent objects with different member order can yield different\n * byte counts; if cross-language reproducibility is needed in the\n * future, a canonical JSON profile (e.g., JCS / RFC 8785) can be\n * adopted via a future DD without changing the budget constants.\n * See EXTENSION_BUDGET in @peac/kernel for the full specification.\n *\n * Schema does NOT emit warnings (unknown_extension_preserved belongs\n * in @peac/protocol.verifyLocal(), Layer 3).\n *\n * Layer 1 (@peac/schema): pure Zod validation, zero I/O.\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_BUDGET, ERROR_CODES as KERNEL_ERROR_CODES } from '@peac/kernel';\nimport { ERROR_CODES } from '../errors.js';\nimport { isValidExtensionKey } from './grammar.js';\nimport { EXTENSION_SCHEMA_MAP } from './schema-map.js';\n\n// ---------------------------------------------------------------------------\n// UTF-8 byte measurement (browser-safe, no Buffer dependency)\n// ---------------------------------------------------------------------------\n\n/** Shared TextEncoder instance (Layer 1 safe: no I/O, no fetch) */\nconst textEncoder = new TextEncoder();\n\n/**\n * Measure UTF-8 byte length of a JSON-serialized value.\n *\n * Returns Infinity if serialization fails (circular references, BigInt,\n * etc.). Callers treat Infinity as over-budget, which produces a clear\n * E_EXTENSION_SIZE_EXCEEDED error.\n */\nfunction jsonUtf8ByteLength(value: unknown): number {\n try {\n return textEncoder.encode(JSON.stringify(value)).byteLength;\n } catch {\n return Infinity;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Recursive plain-JSON-value guard\n// ---------------------------------------------------------------------------\n\n/**\n * Maximum recursion depth for the plain-JSON guard. Prevents stack\n * overflow on pathologically deep but structurally valid JSON trees.\n * 64 levels deep is far beyond any reasonable extension group shape.\n */\nconst MAX_JSON_GUARD_DEPTH = 64;\n\n/**\n * Recursively check whether a value is a plain JSON value.\n *\n * A plain JSON value is one of:\n * - null\n * - boolean\n * - finite number (NaN, Infinity, -Infinity rejected)\n * - string\n * - plain array where every element is a plain JSON value\n * - plain object (prototype === Object.prototype or null, no toJSON)\n * where every own enumerable value is a plain JSON value\n *\n * Rejects:\n * - Functions, Symbols, BigInt, undefined\n * - Non-finite numbers (NaN, Infinity, -Infinity)\n * - Date, RegExp, Map, Set, TypedArray, Error, Promise\n * - Objects with toJSON() methods (non-reproducible serialization)\n * - Any object with a non-plain prototype\n * - Circular references (detected via depth limit + seen set)\n *\n * @param value - Value to check\n * @param depth - Current recursion depth (bounded by MAX_JSON_GUARD_DEPTH)\n * @param seen - WeakSet for circular reference detection\n * @returns true if the value is a plain JSON value all the way down\n */\nfunction isPlainJsonValueRecursive(value: unknown, depth: number, seen: WeakSet<object>): boolean {\n // Depth guard: reject pathologically deep structures\n if (depth > MAX_JSON_GUARD_DEPTH) return false;\n\n // Primitives\n if (value === null) return true;\n const t = typeof value;\n if (t === 'string' || t === 'boolean') return true;\n if (t === 'number') return Number.isFinite(value as number);\n if (t === 'function' || t === 'symbol' || t === 'bigint' || t === 'undefined') return false;\n\n // Must be an object type from here\n if (t !== 'object') return false;\n const obj = value as object;\n\n // Reference cycle / shared-reference detection.\n // Intentionally rejects shared-but-acyclic subobjects (same JS reference\n // appearing in two places). JSON has no concept of object identity;\n // extensions must be JSON trees, not arbitrary JS object graphs. If the\n // same object appears twice, JSON.stringify would serialize it twice\n // (inflating byte count), and the data model is ambiguous. Rejecting\n // shared references ensures the extension tree matches a true JSON tree.\n if (seen.has(obj)) return false;\n seen.add(obj);\n\n // Array: recursively check every element\n if (Array.isArray(obj)) {\n for (let i = 0; i < obj.length; i++) {\n if (!isPlainJsonValueRecursive(obj[i], depth + 1, seen)) return false;\n }\n return true;\n }\n\n // Must be a plain object (no exotic prototype, no toJSON)\n const proto = Object.getPrototypeOf(obj);\n if (proto !== Object.prototype && proto !== null) return false;\n if (typeof (obj as Record<string, unknown>).toJSON === 'function') return false;\n\n // Recursively check every own enumerable value\n const keys = Object.keys(obj);\n for (const key of keys) {\n if (!isPlainJsonValueRecursive((obj as Record<string, unknown>)[key], depth + 1, seen)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Check whether a value is a plain JSON value all the way down.\n *\n * This is the public entry point for the recursive guard. It initializes\n * the depth counter and circular-reference detection set.\n *\n * @param value - Value to check\n * @returns true if the entire value tree is plain JSON\n */\nfunction isPlainJsonValue(value: unknown): boolean {\n return isPlainJsonValueRecursive(value, 0, new WeakSet());\n}\n\n// ---------------------------------------------------------------------------\n// Envelope-level extension validation\n// ---------------------------------------------------------------------------\n\n/**\n * Validate extensions record in Wire02ClaimsSchema.superRefine().\n *\n * Steps:\n * 1. Validate extension key grammar\n * 2. Recursive guard: reject non-plain-JSON values (E_EXTENSION_NON_JSON_VALUE)\n * 3. Validate known extension groups against their Zod schemas\n * 4. Unconditional byte-budget enforcement\n *\n * @param extensions - The extensions record from Wire 0.2 claims\n * @param ctx - Zod refinement context\n */\nexport function validateKnownExtensions(\n extensions: Record<string, unknown> | undefined,\n ctx: z.RefinementCtx\n): void {\n if (extensions === undefined) return;\n\n const keys = Object.keys(extensions);\n\n for (const key of keys) {\n // Step 1: Validate extension key grammar\n if (!isValidExtensionKey(key)) {\n ctx.addIssue({\n code: 'custom',\n message: ERROR_CODES.E_INVALID_EXTENSION_KEY,\n path: ['extensions', key],\n });\n continue;\n }\n\n // Step 2: Recursive plain-JSON guard\n if (!isPlainJsonValue(extensions[key])) {\n ctx.addIssue({\n code: 'custom',\n message: KERNEL_ERROR_CODES.E_EXTENSION_NON_JSON_VALUE,\n path: ['extensions', key],\n });\n continue;\n }\n\n // Step 3: Validate known extension groups against their schemas\n const schema = EXTENSION_SCHEMA_MAP.get(key);\n if (schema !== undefined) {\n const result = schema.safeParse(extensions[key]);\n if (!result.success) {\n const firstIssue = result.error.issues[0];\n const issuePath: PropertyKey[] = firstIssue?.path ?? [];\n ctx.addIssue({\n code: 'custom',\n message: firstIssue?.message ?? 'Invalid extension value',\n path: ['extensions', key, ...issuePath],\n });\n }\n }\n }\n\n // Step 4: Byte-budget enforcement (unconditional)\n const totalBytes = jsonUtf8ByteLength(extensions);\n if (totalBytes > EXTENSION_BUDGET.maxTotalBytes) {\n ctx.addIssue({\n code: 'custom',\n message: KERNEL_ERROR_CODES.E_EXTENSION_SIZE_EXCEEDED,\n path: ['extensions'],\n });\n return;\n }\n\n for (const key of keys) {\n const groupBytes = jsonUtf8ByteLength(extensions[key]);\n if (groupBytes > EXTENSION_BUDGET.maxGroupBytes) {\n ctx.addIssue({\n code: 'custom',\n message: KERNEL_ERROR_CODES.E_EXTENSION_SIZE_EXCEEDED,\n path: ['extensions', key],\n });\n }\n }\n}\n\n// Exported for testing only\nexport { isPlainJsonValue as _isPlainJsonValue };\n","/**\n * Wire 0.2 Zod schemas and types (v0.12.0-preview.1)\n *\n * This file contains:\n * - Wire02ClaimsSchema: the canonical Zod schema for Wire 0.2 envelopes\n * - Wire02Claims: inferred TypeScript type (z.infer<typeof Wire02ClaimsSchema>)\n * - Supporting schemas: EvidencePillarSchema, PillarsSchema, Wire02KindSchema,\n * ReceiptTypeSchema, CanonicalIssSchema, PolicyBlockSchema\n * - isCanonicalIss(): exported canonical-iss validator\n * - isValidReceiptType(): exported type-grammar validator\n * - checkOccurredAtSkew(): cross-field skew check helper\n *\n * Wire02Claims does NOT live in @peac/kernel (layer violation);\n * it lives here because it references schema-layer types (Correction 4).\n */\n\nimport { z } from 'zod';\nimport {\n ISS_CANONICAL,\n TYPE_GRAMMAR,\n POLICY_BLOCK,\n OCCURRED_AT_TOLERANCE_SECONDS,\n HASH,\n} from '@peac/kernel';\nimport type { EvidencePillar, VerificationWarning } from '@peac/kernel';\nimport { ActorBindingSchema } from './actor-binding.js';\nimport { Wire02RepresentationFieldsSchema } from './wire-02-representation.js';\nimport { validateKnownExtensions } from './wire-02-extensions.js';\n\n// ---------------------------------------------------------------------------\n// Private helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Check that an array is sorted in ascending order with no duplicates.\n * Used to validate the pillars array.\n */\nfunction isSortedAndUnique(arr: readonly string[]): boolean {\n for (let i = 1; i < arr.length; i++) {\n if (arr[i] <= arr[i - 1]) return false;\n }\n return true;\n}\n\n// ---------------------------------------------------------------------------\n// isCanonicalIss (exported helper)\n// ---------------------------------------------------------------------------\n\n/**\n * Validate that an issuer (iss) claim is in canonical form.\n *\n * Accepted schemes:\n * - `https://`: ASCII origin (lowercase scheme+host, no explicit default port\n * (:443 rejected), origin-only, no path/query/fragment/userinfo).\n * Raw Unicode hosts are rejected; punycode (xn--...) is accepted.\n * - `did:`: DID Core identifier (`did:<method>:<id>`) where method is\n * `[a-z0-9]+` and the method-specific-id contains no `#`, `?`, or `/`.\n *\n * All other schemes produce E_ISS_NOT_CANONICAL.\n *\n * @param iss - Issuer claim value to validate\n * @returns true if canonical form; false otherwise\n */\nexport function isCanonicalIss(iss: string): boolean {\n if (typeof iss !== 'string' || iss.length === 0 || iss.length > ISS_CANONICAL.maxLength) {\n return false;\n }\n\n // did: branch: check before URL parsing (did: is a valid URL scheme in some parsers)\n if (iss.startsWith('did:')) {\n // did:<method>:<method-specific-id>\n // Method: lowercase letters and digits only ([a-z0-9]+)\n // Method-specific-id: non-empty, no literal '/', '?', or '#'\n return /^did:[a-z0-9]+:[^#?/]+$/.test(iss);\n }\n\n // https:// branch: try URL constructor for comprehensive validation\n try {\n const url = new URL(iss);\n\n // Must be https: scheme only\n if (url.protocol !== 'https:') return false;\n\n // Non-empty host required\n if (!url.hostname) return false;\n\n // No userinfo (credentials in origins are a security risk)\n if (url.username !== '' || url.password !== '') return false;\n\n // Reconstruct canonical origin (URL spec normalizes hostname to lowercase\n // and removes the default port 443 from url.host).\n // Exact match rejects: uppercase host, trailing slash, default port (:443),\n // path, query, fragment, userinfo, raw Unicode hostname.\n const origin = `${url.protocol}//${url.host}`;\n return iss === origin;\n } catch {\n return false;\n }\n}\n\n// ---------------------------------------------------------------------------\n// isValidReceiptType (exported helper)\n// ---------------------------------------------------------------------------\n\n/** Absolute URI pattern: scheme followed by '://' (RFC 3986 generic-URI) */\nconst ABS_URI_PATTERN = /^[a-z][a-z0-9+.-]*:\\/\\//;\n\n/**\n * Validate that a type claim conforms to the Wire 0.2 type grammar.\n *\n * Accepted forms:\n * - Reverse-DNS notation: `<domain>/<segment>` where `<domain>` has at\n * least one dot (e.g., `org.peacprotocol/commerce`, `com.example/flow`)\n * - Absolute URI: starts with `scheme://` (e.g., `https://example.com/type`)\n *\n * @param value - Type claim value to validate\n * @returns true if valid type grammar; false otherwise\n */\nexport function isValidReceiptType(value: string): boolean {\n if (value.length === 0 || value.length > TYPE_GRAMMAR.maxLength) return false;\n\n // Absolute URI form\n if (ABS_URI_PATTERN.test(value)) return true;\n\n // Reverse-DNS form: <domain>/<segment>\n const slashIdx = value.indexOf('/');\n if (slashIdx <= 0) return false; // no slash, or slash at position 0\n\n const domain = value.slice(0, slashIdx);\n const segment = value.slice(slashIdx + 1);\n\n // Domain must have at least one dot (distinguishes from single-label paths)\n if (!domain.includes('.')) return false;\n\n // Segment must be non-empty\n if (segment.length === 0) return false;\n\n // Domain: letters, digits, dots, hyphens; must start with alphanumeric\n if (!/^[a-zA-Z0-9][a-zA-Z0-9.-]*$/.test(domain)) return false;\n\n // Segment: letters, digits, hyphens, underscores, dots.\n // Additional slashes are NOT permitted in the reverse-DNS form; use an\n // absolute URI (handled by ABS_URI_PATTERN above) for multi-segment paths.\n if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(segment)) return false;\n\n return true;\n}\n\n// ---------------------------------------------------------------------------\n// EvidencePillar schema (closed 10-value taxonomy)\n// ---------------------------------------------------------------------------\n\n/** All 10 registered pillar values in ascending lexicographic order */\nconst EVIDENCE_PILLARS: readonly EvidencePillar[] = [\n 'access',\n 'attribution',\n 'commerce',\n 'compliance',\n 'consent',\n 'identity',\n 'privacy',\n 'provenance',\n 'purpose',\n 'safety',\n];\n\nexport const EvidencePillarSchema = z.enum(\n EVIDENCE_PILLARS as [EvidencePillar, ...EvidencePillar[]]\n);\n\n// ---------------------------------------------------------------------------\n// PillarsSchema (non-empty array, sorted + unique)\n// ---------------------------------------------------------------------------\n\nexport const PillarsSchema = z\n .array(EvidencePillarSchema)\n .min(1)\n .superRefine((arr, ctx) => {\n if (!isSortedAndUnique(arr)) {\n ctx.addIssue({\n code: 'custom',\n message: 'E_PILLARS_NOT_SORTED',\n });\n }\n });\n\n// ---------------------------------------------------------------------------\n// Wire02KindSchema\n// ---------------------------------------------------------------------------\n\nexport const Wire02KindSchema = z.enum(['evidence', 'challenge']);\n\n// ---------------------------------------------------------------------------\n// ReceiptTypeSchema\n// ---------------------------------------------------------------------------\n\nexport const ReceiptTypeSchema = z.string().max(TYPE_GRAMMAR.maxLength).refine(isValidReceiptType, {\n message: 'type must be reverse-DNS notation (e.g., org.example/flow) or an absolute URI',\n});\n\n// ---------------------------------------------------------------------------\n// CanonicalIssSchema\n// ---------------------------------------------------------------------------\n\nexport const CanonicalIssSchema = z.string().max(ISS_CANONICAL.maxLength).refine(isCanonicalIss, {\n message: 'E_ISS_NOT_CANONICAL',\n});\n\n// ---------------------------------------------------------------------------\n// PolicyBlockSchema\n// ---------------------------------------------------------------------------\n\nexport const PolicyBlockSchema = z.object({\n /** JCS+SHA-256 digest: 'sha256:<64 lowercase hex>' */\n digest: z.string().regex(HASH.pattern, 'digest must be sha256:<64 lowercase hex>'),\n /**\n * HTTPS locator hint for the policy document.\n * MUST be an https:// URL (max 2048 chars).\n * MUST NOT trigger auto-fetch; callers use this as a hint only.\n */\n uri: z\n .string()\n .max(POLICY_BLOCK.uriMaxLength)\n .url()\n .refine((u) => u.startsWith('https://'), 'policy.uri must be an https:// URL')\n .optional(),\n /** Caller-assigned version label (max 256 chars) */\n version: z.string().max(POLICY_BLOCK.versionMaxLength).optional(),\n});\n\n// RepresentationFieldsSchema: see wire-02-representation.ts (PR 15)\n\n// ---------------------------------------------------------------------------\n// Wire02ClaimsSchema\n// ---------------------------------------------------------------------------\n\nexport const Wire02ClaimsSchema = z\n .object({\n /** Wire format version discriminant; always '0.2' for Wire 0.2 */\n peac_version: z.literal('0.2'),\n /** Structural kind: 'evidence' or 'challenge' */\n kind: Wire02KindSchema,\n /** Open semantic type (reverse-DNS or absolute URI) */\n type: ReceiptTypeSchema,\n /** Canonical issuer (https:// ASCII origin or did: identifier) */\n iss: CanonicalIssSchema,\n /** Issued-at time (Unix seconds). REQUIRED. */\n iat: z.number().int(),\n /** Unique receipt identifier; 1 to 256 chars */\n jti: z.string().min(1).max(256),\n /** Subject identifier; max 2048 chars */\n sub: z.string().max(2048).optional(),\n /** Evidence pillars (closed 10-value taxonomy); sorted ascending, unique */\n pillars: PillarsSchema.optional(),\n /** Top-level actor binding (sole location for ActorBinding in Wire 0.2) */\n actor: ActorBindingSchema.optional(),\n /** Policy binding block */\n policy: PolicyBlockSchema.optional(),\n /** Representation fields: FingerprintRef validation, sha256-only, strict */\n representation: Wire02RepresentationFieldsSchema.optional(),\n /** ISO 8601 / RFC 3339 timestamp when the interaction occurred; evidence kind only */\n occurred_at: z.string().datetime({ offset: true }).optional(),\n /** Declared purpose string; max 256 chars */\n purpose_declared: z.string().max(256).optional(),\n /** Extension groups (open; known group keys validated by group schema) */\n extensions: z.record(z.string(), z.unknown()).optional(),\n })\n .superRefine((data, ctx) => {\n // occurred_at is prohibited on challenge-kind receipts\n if (data.kind === 'challenge' && data.occurred_at !== undefined) {\n ctx.addIssue({\n code: 'custom',\n message: 'E_OCCURRED_AT_ON_CHALLENGE',\n });\n }\n // Validate known extension groups + reject malformed key grammar\n validateKnownExtensions(data.extensions, ctx);\n })\n .strict();\n\n/** Inferred type for Wire 0.2 receipt claims */\nexport type Wire02Claims = z.infer<typeof Wire02ClaimsSchema>;\n\n// ---------------------------------------------------------------------------\n// checkOccurredAtSkew (Correction 5)\n// ---------------------------------------------------------------------------\n\n/**\n * Check the occurred_at field for temporal consistency.\n *\n * Rules (evidence kind only; caller must not call for challenge kind):\n * - If occurred_at > now + tolerance: hard error (E_OCCURRED_AT_FUTURE)\n * - If occurred_at > iat (within tolerance): warning (occurred_at_skew)\n * - If occurred_at <= iat: valid, no warning\n * - If occurred_at is undefined: no check performed\n *\n * @param occurredAt - Value of the occurred_at claim, or undefined\n * @param iat - iat claim value (Unix seconds)\n * @param now - Current time (Unix seconds)\n * @param tolerance - Allowed future skew in seconds (default: OCCURRED_AT_TOLERANCE_SECONDS)\n * @returns 'future_error' for hard error, VerificationWarning for skew warning, null for valid\n */\nexport function checkOccurredAtSkew(\n occurredAt: string | undefined,\n iat: number,\n now: number,\n tolerance: number = OCCURRED_AT_TOLERANCE_SECONDS\n): VerificationWarning | 'future_error' | null {\n if (occurredAt === undefined) return null;\n\n const ts = Date.parse(occurredAt) / 1000;\n if (isNaN(ts)) return null; // unparseable; parse error surfaces from schema validation\n\n if (ts > now + tolerance) return 'future_error';\n\n if (ts > iat) {\n return {\n code: 'occurred_at_skew',\n message: 'occurred_at is after iat',\n pointer: '/occurred_at',\n };\n }\n\n return null;\n}\n","/**\n * Unified Receipt Parser\n *\n * Single entry point for classifying and validating receipt claims.\n * Supports Wire 0.1 (commerce and attestation) and Wire 0.2 receipts.\n *\n * Wire 0.1 classification uses key presence ('amt' in obj), NOT truthy values.\n * If any of amt|cur|payment are present, the receipt is classified as commerce.\n * If commerce validation fails, it returns a commerce error -- never falls\n * through to attestation.\n *\n * Wire 0.2 detection uses the peac_version field (value '0.2').\n */\n\nimport { ZodError } from 'zod';\nimport type { VerificationWarning } from '@peac/kernel';\nimport { ReceiptClaimsSchema, type ReceiptClaimsType } from './validators.js';\nimport {\n AttestationReceiptClaimsSchema,\n type AttestationReceiptClaims,\n} from './attestation-receipt.js';\nimport { Wire02ClaimsSchema, type Wire02Claims } from './wire-02-envelope.js';\n\n/**\n * Receipt variant discriminator for Wire 0.1\n */\nexport type ReceiptVariant = 'commerce' | 'attestation' | 'wire-02';\n\n/**\n * Parse error with canonical error code\n */\nexport interface PEACParseError {\n /** Canonical error code from specs/kernel/errors.json */\n code: string;\n /** Human-readable message */\n message: string;\n /** Zod issues (if schema validation failed) */\n issues?: ZodError['issues'];\n}\n\n/**\n * Successful parse result (v0.12.0-preview.1: adds wireVersion and warnings)\n */\nexport interface ParseSuccess {\n ok: true;\n variant: ReceiptVariant;\n /** Wire version of the parsed receipt */\n wireVersion: '0.1' | '0.2';\n /** Verification warnings collected during parsing (Wire 0.1: always []) */\n warnings: VerificationWarning[];\n claims: ReceiptClaimsType | AttestationReceiptClaims | Wire02Claims;\n}\n\n/**\n * Failed parse result\n */\nexport interface ParseFailure {\n ok: false;\n error: PEACParseError;\n}\n\n/**\n * Parse result type\n */\nexport type ParseReceiptResult = ParseSuccess | ParseFailure;\n\n/**\n * Options for parseReceiptClaims\n */\nexport interface ParseReceiptOptions {\n /** Wire version hint; if provided, skips auto-detection */\n wireVersion?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Wire version detection\n// ---------------------------------------------------------------------------\n\n/**\n * Detect the wire version of a receipt payload.\n *\n * Wire 0.2 receipts contain a `peac_version: '0.2'` field.\n * Wire 0.1 receipts have no `peac_version` field.\n *\n * @param obj - Raw claims object\n * @returns '0.2' if Wire 0.2, '0.1' if Wire 0.1, null if indeterminate\n */\nexport function detectWireVersion(obj: unknown): '0.1' | '0.2' | null {\n if (obj === null || obj === undefined || typeof obj !== 'object' || Array.isArray(obj)) {\n return null;\n }\n const record = obj as Record<string, unknown>;\n if (record.peac_version === '0.2') return '0.2';\n if ('peac_version' in record) return null; // peac_version present but not '0.2'\n return '0.1';\n}\n\n// ---------------------------------------------------------------------------\n// Wire 0.1 helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Classify a Wire 0.1 claims object as commerce or attestation.\n *\n * Uses key presence (not truthiness). If ANY of amt, cur, payment\n * are present as keys, the receipt is classified as commerce.\n */\nfunction classifyWire01Receipt(obj: Record<string, unknown>): 'commerce' | 'attestation' {\n if ('amt' in obj || 'cur' in obj || 'payment' in obj) {\n return 'commerce';\n }\n return 'attestation';\n}\n\n// ---------------------------------------------------------------------------\n// Main parser\n// ---------------------------------------------------------------------------\n\n/**\n * Parse and validate receipt claims.\n *\n * Unified entry point for Wire 0.1 (commerce + attestation) and Wire 0.2\n * receipt validation. Wire version is auto-detected from the `peac_version`\n * field unless `opts.wireVersion` overrides it.\n *\n * Wire 0.1 classification is strict: if any commerce key (amt, cur, payment)\n * is present, the receipt MUST validate as commerce. There is no fallback to\n * attestation for Wire 0.1.\n *\n * @param input - Raw claims object (typically decoded from JWS payload)\n * @param opts - Optional parse options\n * @returns Parse result with variant discrimination, wireVersion, warnings, and validated claims\n */\nexport function parseReceiptClaims(input: unknown, opts?: ParseReceiptOptions): ParseReceiptResult {\n // Guard: input must be a non-null object\n if (input === null || input === undefined || typeof input !== 'object' || Array.isArray(input)) {\n return {\n ok: false,\n error: {\n code: 'E_PARSE_INVALID_INPUT',\n message: 'Input must be a non-null object',\n },\n };\n }\n\n const obj = input as Record<string, unknown>;\n\n // Determine wire version\n const wireVersion =\n opts?.wireVersion === '0.2' || opts?.wireVersion === '0.1'\n ? opts.wireVersion\n : detectWireVersion(obj);\n\n if (wireVersion === null) {\n return {\n ok: false,\n error: {\n code: 'E_UNSUPPORTED_WIRE_VERSION',\n message: `Unsupported or unrecognized peac_version: ${JSON.stringify(obj['peac_version'])}`,\n },\n };\n }\n\n // ---------------------------------------------------------------------------\n // Wire 0.2 path\n // ---------------------------------------------------------------------------\n if (wireVersion === '0.2') {\n const result = Wire02ClaimsSchema.safeParse(obj);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: 'E_INVALID_FORMAT',\n message: `Wire 0.2 receipt validation failed: ${result.error.issues.map((i) => i.message).join('; ')}`,\n issues: result.error.issues,\n },\n };\n }\n return {\n ok: true,\n variant: 'wire-02',\n wireVersion: '0.2',\n warnings: [],\n claims: result.data,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Wire 0.1 path (existing logic unchanged)\n // ---------------------------------------------------------------------------\n const variant = classifyWire01Receipt(obj);\n\n if (variant === 'commerce') {\n const result = ReceiptClaimsSchema.safeParse(obj);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: 'E_PARSE_COMMERCE_INVALID',\n message: `Commerce receipt validation failed: ${result.error.issues.map((i) => i.message).join('; ')}`,\n issues: result.error.issues,\n },\n };\n }\n return {\n ok: true,\n variant: 'commerce',\n wireVersion: '0.1',\n warnings: [],\n claims: result.data,\n };\n }\n\n // Attestation path\n const result = AttestationReceiptClaimsSchema.safeParse(obj);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: 'E_PARSE_ATTESTATION_INVALID',\n message: `Attestation receipt validation failed: ${result.error.issues.map((i) => i.message).join('; ')}`,\n issues: result.error.issues,\n },\n };\n }\n return {\n ok: true,\n variant: 'attestation',\n wireVersion: '0.1',\n warnings: [],\n claims: result.data,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/json.ts","../src/errors.ts","../src/purpose.ts","../src/validators.ts","../src/attestation-receipt.ts","../src/actor-binding.ts","../src/extensions/fingerprint-ref.ts","../src/wire-02-representation.ts","../src/wire-02-extensions/limits.ts","../src/wire-02-extensions/grammar.ts","../src/wire-02-extensions/commerce.ts","../src/wire-02-extensions/access.ts","../src/wire-02-extensions/challenge.ts","../src/wire-02-extensions/identity.ts","../src/wire-02-extensions/correlation.ts","../src/wire-02-extensions/shared-validators.ts","../src/wire-02-extensions/consent.ts","../src/wire-02-extensions/privacy.ts","../src/wire-02-extensions/safety.ts","../src/wire-02-extensions/compliance.ts","../src/wire-02-extensions/provenance.ts","../src/wire-02-extensions/attribution.ts","../src/wire-02-extensions/purpose-extension.ts","../src/wire-02-extensions/schema-map.ts","../src/wire-02-extensions/validation.ts","../src/wire-02-envelope.ts","../src/receipt-parser.ts"],"names":["z","httpsUrl","uuidv7","KERNEL_ERROR_CODES","EXTENSION_BUDGET","HASH","result"],"mappings":"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","file":"receipt-parser.mjs","sourcesContent":["/**\n * Wire format constants - FROZEN\n *\n * These constants are now sourced from @peac/kernel\n * (normative source: specs/kernel/constants.json)\n */\n\nimport { WIRE_TYPE, ALGORITHMS, HEADERS, POLICY, ISSUER_CONFIG, DISCOVERY } from '@peac/kernel';\n\n/**\n * Wire format version - peac-receipt/0.1\n * Normalized in v0.10.0 to peac-<artifact>/<major>.<minor> pattern\n */\nexport const PEAC_WIRE_TYP = WIRE_TYPE;\n\n/**\n * Signature algorithm - FROZEN forever\n */\nexport const PEAC_ALG = ALGORITHMS.default;\n\n/**\n * Canonical header name\n */\nexport const PEAC_RECEIPT_HEADER = HEADERS.receipt;\n\n/**\n * Purpose header names (v0.9.24+)\n */\nexport const PEAC_PURPOSE_HEADER = HEADERS.purpose;\nexport const PEAC_PURPOSE_APPLIED_HEADER = HEADERS.purposeApplied;\nexport const PEAC_PURPOSE_REASON_HEADER = HEADERS.purposeReason;\n\n/**\n * Policy manifest path (/.well-known/peac.txt)\n * @see docs/specs/PEAC-TXT.md\n */\nexport const PEAC_POLICY_PATH = POLICY.manifestPath;\n\n/**\n * Policy manifest fallback path (/peac.txt)\n */\nexport const PEAC_POLICY_FALLBACK_PATH = POLICY.fallbackPath;\n\n/**\n * Maximum policy manifest size\n */\nexport const PEAC_POLICY_MAX_BYTES = POLICY.maxBytes;\n\n/**\n * Issuer configuration path (/.well-known/peac-issuer.json)\n * @see docs/specs/PEAC-ISSUER.md\n */\nexport const PEAC_ISSUER_CONFIG_PATH = ISSUER_CONFIG.configPath;\n\n/**\n * Issuer configuration version\n */\nexport const PEAC_ISSUER_CONFIG_VERSION = ISSUER_CONFIG.configVersion;\n\n/**\n * Maximum issuer configuration size\n */\nexport const PEAC_ISSUER_CONFIG_MAX_BYTES = ISSUER_CONFIG.maxBytes;\n\n/**\n * @deprecated Use PEAC_POLICY_PATH instead. Will be removed in v1.0.\n */\nexport const PEAC_DISCOVERY_PATH = DISCOVERY.manifestPath;\n\n/**\n * @deprecated Use PEAC_POLICY_MAX_BYTES instead. Will be removed in v1.0.\n */\nexport const PEAC_DISCOVERY_MAX_BYTES = 2000 as const;\n\n/**\n * JSON Schema URL for PEAC receipt wire format v0.1\n *\n * This is the canonical $id for the root schema.\n * Use for schema references and cross-implementation validation.\n *\n * @since v0.10.0\n */\nexport const PEAC_RECEIPT_SCHEMA_URL =\n 'https://www.peacprotocol.org/schemas/wire/0.1/peac-receipt.0.1.schema.json' as const;\n","/**\n * JSON-safe validation schemas\n *\n * Provides Zod schemas that guarantee JSON roundtrip safety:\n * - Rejects NaN, Infinity, -Infinity (not valid JSON numbers)\n * - Rejects undefined (dropped by JSON.stringify)\n * - Rejects non-plain objects (Date, Map, Set, class instances)\n * - Rejects functions, symbols, bigints\n */\n\nimport { z } from 'zod';\nimport type { JsonValue, JsonObject, JsonArray } from '@peac/kernel';\nimport { KERNEL_CONSTRAINTS } from './constraints';\n\n/**\n * Check if value is a plain object (not Date, Map, Set, class instance, etc.)\n *\n * A plain object has prototype of Object.prototype or null.\n * This rejects Date, Map, Set, Array, and class instances even when\n * they have zero enumerable properties (which would pass z.record()).\n */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== 'object') {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * JSON number schema - rejects NaN and Infinity\n *\n * JSON.stringify(NaN) === \"null\" and JSON.stringify(Infinity) === \"null\"\n * which silently corrupts data. We reject these at validation time.\n */\nconst JsonNumberSchema = z.number().finite();\n\n/**\n * JSON primitive schema - string, finite number, boolean, null\n */\nexport const JsonPrimitiveSchema = z.union([z.string(), JsonNumberSchema, z.boolean(), z.null()]);\n\n/**\n * Plain object schema (internal) - validates object is plain before recursive validation\n */\nconst PlainObjectSchema = z.unknown().refine(isPlainObject, {\n message: 'Expected plain object, received non-plain object (Date, Map, Set, or class instance)',\n});\n\n/**\n * JSON value schema - recursive type for any valid JSON value\n *\n * Validates:\n * - Primitives: string, finite number, boolean, null\n * - Arrays: containing valid JSON values\n * - Objects: plain objects with string keys and valid JSON values\n *\n * Rejects:\n * - undefined (dropped by JSON.stringify)\n * - NaN, Infinity, -Infinity (become null in JSON)\n * - BigInt (throws in JSON.stringify)\n * - Date (becomes ISO string - implicit conversion)\n * - Map, Set (become {} in JSON)\n * - Functions, Symbols (dropped by JSON.stringify)\n * - Class instances (prototype chain lost)\n */\nexport const JsonValueSchema: z.ZodType<JsonValue> = z.lazy(() =>\n z.union([\n JsonPrimitiveSchema,\n z.array(JsonValueSchema),\n // Plain object check then record validation\n PlainObjectSchema.transform((obj) => obj as Record<string, unknown>).pipe(\n z.record(z.string(), JsonValueSchema)\n ),\n ])\n) as z.ZodType<JsonValue>;\n\n/**\n * JSON object schema - plain object with string keys and JSON values\n *\n * Rejects non-plain objects (Date, Map, Set, class instances).\n */\nexport const JsonObjectSchema: z.ZodType<JsonObject> = PlainObjectSchema.transform(\n (obj) => obj as Record<string, unknown>\n).pipe(z.record(z.string(), JsonValueSchema)) as z.ZodType<JsonObject>;\n\n/**\n * JSON array schema - array of JSON values\n */\nexport const JsonArraySchema: z.ZodType<JsonArray> = z.array(JsonValueSchema);\n\n/**\n * Default limits for JSON evidence validation.\n *\n * Derived from KERNEL_CONSTRAINTS (single source of truth).\n * These are conservative defaults to prevent DoS attacks via deeply nested\n * or excessively large JSON structures.\n */\nexport const JSON_EVIDENCE_LIMITS = {\n /** Maximum nesting depth (default: 32) */\n maxDepth: KERNEL_CONSTRAINTS.MAX_NESTED_DEPTH,\n /** Maximum array length (default: 10,000) */\n maxArrayLength: KERNEL_CONSTRAINTS.MAX_ARRAY_LENGTH,\n /** Maximum object keys (default: 1,000) */\n maxObjectKeys: KERNEL_CONSTRAINTS.MAX_OBJECT_KEYS,\n /** Maximum string length in code units (default: 65,536) */\n maxStringLength: KERNEL_CONSTRAINTS.MAX_STRING_LENGTH,\n /** Maximum total nodes to visit (default: 100,000) */\n maxTotalNodes: KERNEL_CONSTRAINTS.MAX_TOTAL_NODES,\n} as const;\n\n/**\n * Limits for JSON evidence validation\n *\n * @internal - Not part of public API. Use validateEvidence() with defaults.\n *\n * For testing only: import via UNSAFE_JsonEvidenceLimits\n */\nexport interface JsonEvidenceLimits {\n maxDepth?: number;\n maxArrayLength?: number;\n maxObjectKeys?: number;\n maxStringLength?: number;\n maxTotalNodes?: number;\n}\n\n/**\n * Result of JSON safety validation\n */\nexport type JsonSafetyResult =\n | { ok: true }\n | { ok: false; error: string; path: (string | number)[] };\n\n/**\n * Stack entry type for iterative traversal\n *\n * - \"enter\": entering an object/array, need to validate and push children\n * - \"exit\": exiting an object/array, remove from current path (for cycle detection)\n */\ntype StackEntry =\n | { type: 'enter'; value: unknown; path: (string | number)[]; depth: number }\n | { type: 'exit'; obj: object };\n\n/**\n * Iterative JSON safety validator\n *\n * Validates that a value is JSON-safe without using recursion, preventing\n * stack overflow on deeply nested structures. Uses an explicit stack for\n * traversal with entry/exit markers for correct cycle detection.\n *\n * Cycle Detection:\n * Uses a path-based approach where only objects on the current traversal\n * path are tracked. This correctly allows diamond structures (same object\n * referenced from multiple paths) while rejecting actual cycles (object\n * references itself through its descendants).\n *\n * Rejects:\n * - Cycles (object references itself directly or indirectly)\n * - Non-plain objects (Date, Map, Set, class instances)\n * - Non-finite numbers (NaN, Infinity, -Infinity)\n * - undefined, BigInt, functions, symbols\n * - Structures exceeding depth/size limits\n *\n * Allows:\n * - Diamond structures (same object referenced from multiple paths)\n *\n * @param value - Value to validate\n * @param limits - Optional limits (defaults to JSON_EVIDENCE_LIMITS)\n * @returns Result indicating success or failure with error details\n */\nexport function assertJsonSafeIterative(\n value: unknown,\n limits: JsonEvidenceLimits = {}\n): JsonSafetyResult {\n const maxDepth = limits.maxDepth ?? JSON_EVIDENCE_LIMITS.maxDepth;\n const maxArrayLength = limits.maxArrayLength ?? JSON_EVIDENCE_LIMITS.maxArrayLength;\n const maxObjectKeys = limits.maxObjectKeys ?? JSON_EVIDENCE_LIMITS.maxObjectKeys;\n const maxStringLength = limits.maxStringLength ?? JSON_EVIDENCE_LIMITS.maxStringLength;\n const maxTotalNodes = limits.maxTotalNodes ?? JSON_EVIDENCE_LIMITS.maxTotalNodes;\n\n // Track objects on the current traversal path for cycle detection.\n // An object appearing twice on the same path is a cycle.\n // An object appearing on different paths (diamond) is NOT a cycle.\n const pathSet = new WeakSet<object>();\n\n // Track total nodes visited for DoS protection\n let nodeCount = 0;\n\n // Stack with entry/exit markers for path tracking\n const stack: StackEntry[] = [{ type: 'enter', value, path: [], depth: 0 }];\n\n while (stack.length > 0) {\n const entry = stack.pop()!;\n\n // Handle exit marker - remove object from current path\n if (entry.type === 'exit') {\n pathSet.delete(entry.obj);\n continue;\n }\n\n const { value: current, path, depth } = entry;\n\n // Check total node limit\n nodeCount++;\n if (nodeCount > maxTotalNodes) {\n return {\n ok: false,\n error: `Maximum total nodes exceeded (limit: ${maxTotalNodes})`,\n path,\n };\n }\n\n // Check depth limit\n if (depth > maxDepth) {\n return {\n ok: false,\n error: `Maximum depth exceeded (limit: ${maxDepth})`,\n path,\n };\n }\n\n // Handle null (valid JSON)\n if (current === null) {\n continue;\n }\n\n // Handle primitives\n const type = typeof current;\n\n if (type === 'string') {\n if ((current as string).length > maxStringLength) {\n return {\n ok: false,\n error: `String exceeds maximum length (limit: ${maxStringLength})`,\n path,\n };\n }\n continue;\n }\n\n if (type === 'number') {\n if (!Number.isFinite(current as number)) {\n return {\n ok: false,\n error: `Non-finite number: ${current}`,\n path,\n };\n }\n continue;\n }\n\n if (type === 'boolean') {\n continue;\n }\n\n // Reject non-JSON types\n if (type === 'undefined') {\n return { ok: false, error: 'undefined is not valid JSON', path };\n }\n\n if (type === 'bigint') {\n return { ok: false, error: 'BigInt is not valid JSON', path };\n }\n\n if (type === 'function') {\n return { ok: false, error: 'Function is not valid JSON', path };\n }\n\n if (type === 'symbol') {\n return { ok: false, error: 'Symbol is not valid JSON', path };\n }\n\n // Handle objects (arrays and plain objects)\n if (type === 'object') {\n const obj = current as object;\n\n // Cycle detection - check if object is already on the current path\n // (not just visited anywhere, but specifically an ancestor)\n if (pathSet.has(obj)) {\n return { ok: false, error: 'Cycle detected in object graph', path };\n }\n\n // Add to current path and push exit marker to remove when done\n pathSet.add(obj);\n stack.push({ type: 'exit', obj });\n\n // Handle arrays\n if (Array.isArray(obj)) {\n if (obj.length > maxArrayLength) {\n return {\n ok: false,\n error: `Array exceeds maximum length (limit: ${maxArrayLength})`,\n path,\n };\n }\n // Push array elements to stack in reverse order for correct traversal\n for (let i = obj.length - 1; i >= 0; i--) {\n stack.push({ type: 'enter', value: obj[i], path: [...path, i], depth: depth + 1 });\n }\n continue;\n }\n\n // Check for non-plain objects (Date, Map, Set, class instances, etc.)\n const proto = Object.getPrototypeOf(obj);\n if (proto !== Object.prototype && proto !== null) {\n const constructorName = obj.constructor?.name ?? 'unknown';\n return {\n ok: false,\n error: `Non-plain object (${constructorName}) is not valid JSON`,\n path,\n };\n }\n\n // Handle plain objects\n const keys = Object.keys(obj);\n if (keys.length > maxObjectKeys) {\n return {\n ok: false,\n error: `Object exceeds maximum key count (limit: ${maxObjectKeys})`,\n path,\n };\n }\n // Push object values to stack\n for (let i = keys.length - 1; i >= 0; i--) {\n const key = keys[i];\n stack.push({\n type: 'enter',\n value: (obj as Record<string, unknown>)[key],\n path: [...path, key],\n depth: depth + 1,\n });\n }\n continue;\n }\n\n // Shouldn't reach here, but reject unknown types\n return { ok: false, error: `Unknown type: ${type}`, path };\n }\n\n return { ok: true };\n}\n","/**\n * PEAC Structured Error Model\n *\n * Standardized error responses for protocol failures.\n * See docs/specs/ERRORS.md for complete error registry.\n */\n\n// Import the generated categories from kernel (single source of truth: specs/kernel/errors.json)\n// Namespace import avoids tsup tree-shaking false positive in multi-entry builds\n// where ERROR_CATEGORIES appears unused in entry points that don't reference it.\nimport * as kernel from '@peac/kernel';\nimport type { ErrorCategory } from '@peac/kernel';\nexport type { ErrorCategory };\n\n/**\n * @deprecated Use ERROR_CATEGORIES from @peac/kernel instead.\n * Re-exported for backwards compatibility.\n */\nexport const ERROR_CATEGORIES_CANONICAL = kernel.ERROR_CATEGORIES;\n\n/**\n * Error severity\n */\nexport type ErrorSeverity = 'error' | 'warning';\n\n/**\n * Structured PEAC error\n *\n * Provides machine-readable error information with:\n * - Stable error codes\n * - Category classification\n * - Retryability hints\n * - Remediation guidance\n */\nexport interface PEACError {\n /**\n * Error code\n *\n * Stable identifier for this error type.\n * See docs/specs/ERRORS.md for registry.\n *\n * Examples:\n * - \"E_CONTROL_REQUIRED\"\n * - \"E_INVALID_SIGNATURE\"\n * - \"E_SSRF_BLOCKED\"\n * - \"E_DPOP_REPLAY\"\n */\n code: string;\n\n /**\n * Error category\n *\n * Broad classification for programmatic handling.\n */\n category: ErrorCategory;\n\n /**\n * Error severity\n *\n * - \"error\": Operation failed, cannot proceed\n * - \"warning\": Operation succeeded but with caveats\n */\n severity: ErrorSeverity;\n\n /**\n * Whether the operation is retryable\n *\n * - true: Client should retry (network, rate limit, transient)\n * - false: Client should not retry (validation, security, permanent)\n */\n retryable: boolean;\n\n /**\n * Suggested HTTP status code\n *\n * Maps error to appropriate HTTP response code.\n * Examples:\n * - 400: Validation errors\n * - 401: Verification failures (signature, attestation temporal)\n * - 403: Control denials (authorization)\n * - 502: Infrastructure failures (JWKS fetch, etc.)\n */\n http_status?: number;\n\n /**\n * JSON Pointer (RFC 6901) to problematic field\n *\n * Identifies the specific field that caused the error.\n * Examples:\n * - \"/auth/control\" - Missing control block\n * - \"/evidence/payment/amount\" - Invalid amount\n * - \"/auth/control/chain/0/result\" - Invalid result value\n */\n pointer?: string;\n\n /**\n * Human-readable remediation guidance\n *\n * Short hint for fixing the error.\n * Examples:\n * - \"Add control{} block when payment{} is present\"\n * - \"Ensure JWS signature is valid\"\n * - \"Retry after 60 seconds\"\n */\n remediation?: string;\n\n /**\n * Implementation-specific error details\n *\n * Additional context for debugging.\n * Structure varies by error code.\n */\n details?: unknown;\n}\n\n/**\n * Error code registry\n *\n * Well-known error codes. See docs/specs/ERRORS.md for complete list.\n */\nexport const ERROR_CODES = {\n // Validation errors (400)\n E_CONTROL_REQUIRED: 'E_CONTROL_REQUIRED',\n E_INVALID_ENVELOPE: 'E_INVALID_ENVELOPE',\n E_INVALID_CONTROL_CHAIN: 'E_INVALID_CONTROL_CHAIN',\n E_INVALID_PAYMENT: 'E_INVALID_PAYMENT',\n E_INVALID_POLICY_HASH: 'E_INVALID_POLICY_HASH',\n E_EXPIRED_RECEIPT: 'E_EXPIRED_RECEIPT',\n E_EVIDENCE_NOT_JSON: 'E_EVIDENCE_NOT_JSON',\n\n // Verification errors (401)\n E_INVALID_SIGNATURE: 'E_INVALID_SIGNATURE',\n E_SSRF_BLOCKED: 'E_SSRF_BLOCKED',\n E_DPOP_REPLAY: 'E_DPOP_REPLAY',\n E_DPOP_INVALID: 'E_DPOP_INVALID',\n\n // Control errors (403)\n E_CONTROL_DENIED: 'E_CONTROL_DENIED',\n\n // Infrastructure errors (502/503)\n E_JWKS_FETCH_FAILED: 'E_JWKS_FETCH_FAILED',\n E_POLICY_FETCH_FAILED: 'E_POLICY_FETCH_FAILED',\n E_NETWORK_ERROR: 'E_NETWORK_ERROR',\n\n // Workflow errors (400)\n E_WORKFLOW_CONTEXT_INVALID: 'E_WORKFLOW_CONTEXT_INVALID',\n E_WORKFLOW_DAG_INVALID: 'E_WORKFLOW_DAG_INVALID',\n E_WORKFLOW_LIMIT_EXCEEDED: 'E_WORKFLOW_LIMIT_EXCEEDED',\n E_WORKFLOW_ID_INVALID: 'E_WORKFLOW_ID_INVALID',\n E_WORKFLOW_STEP_ID_INVALID: 'E_WORKFLOW_STEP_ID_INVALID',\n E_WORKFLOW_PARENT_NOT_FOUND: 'E_WORKFLOW_PARENT_NOT_FOUND',\n E_WORKFLOW_SUMMARY_INVALID: 'E_WORKFLOW_SUMMARY_INVALID',\n E_WORKFLOW_CYCLE_DETECTED: 'E_WORKFLOW_CYCLE_DETECTED',\n\n // Constraint errors (400)\n E_CONSTRAINT_VIOLATION: 'E_CONSTRAINT_VIOLATION',\n\n // Wire 0.2 extension errors (400/)\n E_INVALID_EXTENSION_KEY: 'E_INVALID_EXTENSION_KEY',\n} as const;\n\n/**\n * Error code type\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\n/**\n * Helper to create a structured error\n */\nexport function createPEACError(\n code: ErrorCode,\n category: ErrorCategory,\n severity: ErrorSeverity,\n retryable: boolean,\n options?: {\n http_status?: number;\n pointer?: string;\n remediation?: string;\n details?: unknown;\n }\n): PEACError {\n return {\n code,\n category,\n severity,\n retryable,\n ...options,\n };\n}\n\n/**\n * Create an evidence validation error\n *\n * Used when evidence contains non-JSON-safe values like NaN, Infinity,\n * undefined, Date, Map, Set, BigInt, functions, or class instances.\n */\nexport function createEvidenceNotJsonError(message: string, path?: (string | number)[]): PEACError {\n return createPEACError(ERROR_CODES.E_EVIDENCE_NOT_JSON, 'validation', 'error', false, {\n http_status: 400,\n pointer: path ? '/' + path.join('/') : undefined,\n remediation:\n 'Ensure evidence contains only JSON-safe values (strings, finite numbers, booleans, null, arrays, plain objects)',\n details: { message },\n });\n}\n\n// ============================================================================\n// Workflow Error Helpers (v0.10.2+)\n// ============================================================================\n\n/**\n * Create a workflow context validation error\n *\n * Used when workflow_context does not conform to WorkflowContextSchema.\n */\nexport function createWorkflowContextInvalidError(details?: string): PEACError {\n return createPEACError(ERROR_CODES.E_WORKFLOW_CONTEXT_INVALID, 'validation', 'error', false, {\n http_status: 400,\n pointer: '/ext/org.peacprotocol~1workflow',\n remediation: 'Ensure workflow_context conforms to WorkflowContextSchema',\n details: { message: details ?? 'Invalid workflow context' },\n });\n}\n\n/**\n * Create a workflow DAG validation error\n *\n * Used when workflow DAG semantics are violated (self-parent, duplicate parents, cycle).\n */\nexport function createWorkflowDagInvalidError(\n reason: 'self_parent' | 'duplicate_parent' | 'cycle'\n): PEACError {\n const messages = {\n self_parent: 'Step cannot be its own parent',\n duplicate_parent: 'Parent step IDs must be unique',\n cycle: 'Workflow DAG contains a cycle',\n };\n return createPEACError(ERROR_CODES.E_WORKFLOW_DAG_INVALID, 'validation', 'error', false, {\n http_status: 400,\n pointer: '/ext/org.peacprotocol~1workflow/parent_step_ids',\n remediation: 'Ensure workflow forms a valid directed acyclic graph (DAG)',\n details: { reason, message: messages[reason] },\n });\n}\n\n// ============================================================================\n// Constraint Error Helpers (v0.11.0+)\n// ============================================================================\n\n/**\n * Create a kernel constraint violation error\n *\n * Used when receipt claims violate structural kernel constraints\n * (depth, array length, object keys, string length, total nodes).\n */\nexport function createConstraintViolationError(\n violations: Array<{\n constraint: string;\n actual: number;\n limit: number;\n path?: string;\n }>\n): PEACError {\n const first = violations[0];\n const summary = violations\n .map((v) => `${v.constraint} (actual: ${v.actual}, limit: ${v.limit})`)\n .join('; ');\n return createPEACError(ERROR_CODES.E_CONSTRAINT_VIOLATION, 'validation', 'error', false, {\n http_status: 400,\n pointer: first?.path,\n remediation: 'Reduce receipt claims size to stay within kernel constraints',\n details: { message: `Kernel constraint violated: ${summary}`, violations },\n });\n}\n","/**\n * PEAC Purpose Types (v0.9.24+)\n *\n * Purpose type hierarchy for forward-compatible purpose handling:\n * - PurposeToken: Wire format (string) - preserves unknown tokens\n * - CanonicalPurpose: PEAC's normative vocabulary - enforcement semantics\n * - PurposeReason: Audit spine for enforcement decisions\n *\n * @see specs/kernel/constants.json for canonical values\n */\n\n/**\n * PurposeToken - Wire format string with validation grammar\n *\n * Allows unknown tokens for forward compatibility. Any valid token\n * that matches the grammar is accepted and preserved.\n *\n * Grammar: lowercase, max 64 chars, [a-z0-9_-] + optional vendor prefix (vendor:token)\n * Hyphens allowed for interop with external systems (Cloudflare, IETF AIPREF, etc.)\n *\n * Examples: \"train\", \"search\", \"user_action\", \"user-action\", \"cf:ai_crawler\", \"cf:ai-crawler\"\n */\nexport type PurposeToken = string;\n\n/**\n * CanonicalPurpose - PEAC's normative vocabulary\n *\n * These are the only tokens PEAC enforces semantics for.\n * Matches specs/kernel/constants.json purpose.canonical_tokens.\n *\n * - train: Model training data collection\n * - search: Traditional search indexing\n * - user_action: Agent acting on user behalf (v0.9.24+)\n * - inference: Runtime inference / RAG\n * - index: Content indexing (store)\n */\nexport type CanonicalPurpose = 'train' | 'search' | 'user_action' | 'inference' | 'index';\n\n/**\n * Internal-only purpose value (never valid on wire)\n *\n * Applied when PEAC-Purpose header is missing or empty.\n * Explicit \"undeclared\" in request -> 400 Bad Request.\n */\nexport type InternalPurpose = 'undeclared';\n\n/**\n * PurposeReason - Audit spine for enforcement decisions\n *\n * Captures WHY a purpose was enforced differently than declared.\n * Matches specs/kernel/constants.json purpose.reason_values.\n */\nexport type PurposeReason =\n | 'allowed' // Purpose permitted as declared (happy path)\n | 'constrained' // Allowed with rate limits applied\n | 'denied' // Purpose rejected by policy\n | 'downgraded' // More restrictive purpose applied\n | 'undeclared_default' // No purpose declared, default applied\n | 'unknown_preserved'; // Unknown purpose token, preserved but flagged\n\n/**\n * Legacy purpose tokens from pre-v0.9.24\n *\n * These are mapped to CanonicalPurpose via mapLegacyToCanonical().\n * Retained for backward compatibility with existing ControlPurpose usage.\n */\nexport type LegacyPurpose = 'crawl' | 'ai_input' | 'ai_index';\n\n// ============================================================================\n// Validation Constants\n// ============================================================================\n\n/**\n * Grammar validation for PurposeToken\n *\n * Pattern: lowercase letter, optionally followed by alphanumeric/underscore/hyphen\n * characters that MUST end with a letter or digit (no trailing separators).\n * Optional vendor prefix separated by colon follows the same rules.\n *\n * Hyphens are allowed for interoperability with external systems (Cloudflare,\n * IETF AIPREF, etc.) that use hyphenated tokens like \"user-action\" or \"train-ai\".\n *\n * Valid: \"train\", \"user_action\", \"user-action\", \"cf:ai_crawler\", \"cf:ai-crawler\", \"a\", \"a1\"\n * Invalid: \"Train\", \"123abc\", \"\", \"-train\", \"train-\", \"train_\", \"cf:ai-\", \"cf:-ai\"\n */\nexport const PURPOSE_TOKEN_REGEX =\n /^[a-z](?:[a-z0-9_-]*[a-z0-9])?(?::[a-z](?:[a-z0-9_-]*[a-z0-9])?)?$/;\n\n/** Maximum length for a purpose token */\nexport const MAX_PURPOSE_TOKEN_LENGTH = 64;\n\n/** Maximum number of purpose tokens per request (RECOMMENDED, not MUST) */\nexport const MAX_PURPOSE_TOKENS_PER_REQUEST = 10;\n\n/** Canonical purpose tokens (from constants.json) */\nexport const CANONICAL_PURPOSES: readonly CanonicalPurpose[] = [\n 'train',\n 'search',\n 'user_action',\n 'inference',\n 'index',\n] as const;\n\n/** Purpose reason values (from constants.json) */\nexport const PURPOSE_REASONS: readonly PurposeReason[] = [\n 'allowed',\n 'constrained',\n 'denied',\n 'downgraded',\n 'undeclared_default',\n 'unknown_preserved',\n] as const;\n\n/** Internal-only purpose value */\nexport const INTERNAL_PURPOSE_UNDECLARED: InternalPurpose = 'undeclared';\n\n// ============================================================================\n// Validation Functions\n// ============================================================================\n\n/**\n * Check if a string is a valid PurposeToken\n *\n * Validates against the purpose token grammar:\n * - Lowercase letters, digits, underscores, hyphens\n * - Optional vendor prefix with colon\n * - Max 64 characters\n * - Must start with lowercase letter\n *\n * @param token - String to validate\n * @returns true if valid PurposeToken\n */\nexport function isValidPurposeToken(token: string): token is PurposeToken {\n if (typeof token !== 'string') return false;\n if (token.length === 0 || token.length > MAX_PURPOSE_TOKEN_LENGTH) return false;\n return PURPOSE_TOKEN_REGEX.test(token);\n}\n\n/**\n * Check if a PurposeToken is a CanonicalPurpose\n *\n * @param token - Token to check\n * @returns true if token is in canonical vocabulary\n */\nexport function isCanonicalPurpose(token: string): token is CanonicalPurpose {\n return (CANONICAL_PURPOSES as readonly string[]).includes(token);\n}\n\n/**\n * Check if a PurposeToken is a LegacyPurpose\n *\n * @param token - Token to check\n * @returns true if token is a legacy purpose\n */\nexport function isLegacyPurpose(token: string): token is LegacyPurpose {\n return token === 'crawl' || token === 'ai_input' || token === 'ai_index';\n}\n\n/**\n * Check if a string is a valid PurposeReason\n *\n * @param reason - String to check\n * @returns true if valid PurposeReason\n */\nexport function isValidPurposeReason(reason: string): reason is PurposeReason {\n return (PURPOSE_REASONS as readonly string[]).includes(reason);\n}\n\n/**\n * Check if a purpose token is the internal-only \"undeclared\" value\n *\n * Used to reject explicit \"undeclared\" on wire (400 Bad Request).\n *\n * @param token - Token to check\n * @returns true if token is \"undeclared\"\n */\nexport function isUndeclaredPurpose(token: string): boolean {\n return token === INTERNAL_PURPOSE_UNDECLARED;\n}\n\n// ============================================================================\n// Normalization Functions\n// ============================================================================\n\n/**\n * Normalize a purpose token\n *\n * Applies normalization rules:\n * - Trim whitespace\n * - Lowercase\n *\n * @param token - Raw token from header\n * @returns Normalized token\n */\nexport function normalizePurposeToken(token: string): string {\n return token.trim().toLowerCase();\n}\n\n/**\n * Parse PEAC-Purpose header value into array of tokens\n *\n * Applies parsing rules:\n * - Split on commas\n * - Trim optional whitespace (OWS) around tokens\n * - Lowercase all tokens\n * - Drop empty tokens\n * - Deduplicate\n * - Preserve input order\n *\n * @param headerValue - Raw PEAC-Purpose header value\n * @returns Array of normalized PurposeToken values\n */\nexport function parsePurposeHeader(headerValue: string): PurposeToken[] {\n if (!headerValue || typeof headerValue !== 'string') {\n return [];\n }\n\n const seen = new Set<string>();\n const tokens: PurposeToken[] = [];\n\n for (const part of headerValue.split(',')) {\n const normalized = normalizePurposeToken(part);\n if (normalized.length > 0 && !seen.has(normalized)) {\n seen.add(normalized);\n tokens.push(normalized);\n }\n }\n\n return tokens;\n}\n\n/**\n * Validate parsed purpose tokens\n *\n * Returns validation result with:\n * - valid: All tokens pass grammar validation\n * - tokens: All normalized tokens (including invalid ones)\n * - invalidTokens: Tokens that failed grammar validation\n * - undeclaredPresent: true if explicit \"undeclared\" was found (should reject)\n *\n * @param tokens - Array of parsed tokens\n * @returns Validation result\n */\nexport interface PurposeValidationResult {\n valid: boolean;\n tokens: PurposeToken[];\n invalidTokens: string[];\n undeclaredPresent: boolean;\n}\n\nexport function validatePurposeTokens(tokens: PurposeToken[]): PurposeValidationResult {\n const invalidTokens: string[] = [];\n let undeclaredPresent = false;\n\n for (const token of tokens) {\n if (isUndeclaredPurpose(token)) {\n undeclaredPresent = true;\n }\n if (!isValidPurposeToken(token)) {\n invalidTokens.push(token);\n }\n }\n\n return {\n valid: invalidTokens.length === 0 && !undeclaredPresent,\n tokens,\n invalidTokens,\n undeclaredPresent,\n };\n}\n\n/**\n * Derive known canonical purposes from declared tokens\n *\n * Filters purpose_declared to get only canonical purposes.\n * This is a helper derivation, NOT stored on wire.\n *\n * @param declared - Array of declared PurposeTokens\n * @returns Array of CanonicalPurpose tokens\n */\nexport function deriveKnownPurposes(declared: PurposeToken[]): CanonicalPurpose[] {\n return declared.filter(isCanonicalPurpose);\n}\n\n// ============================================================================\n// Legacy Mapping\n// ============================================================================\n\n/**\n * Legacy purpose to canonical mapping\n */\nconst LEGACY_TO_CANONICAL: Record<LegacyPurpose, CanonicalPurpose> = {\n crawl: 'index', // Crawl implies indexing\n ai_input: 'inference', // RAG/grounding -> inference context\n ai_index: 'index', // AI-powered indexing -> index\n};\n\n/**\n * Map legacy purpose to canonical purpose\n *\n * Used for backward compatibility with pre-v0.9.24 ControlPurpose values.\n *\n * @param legacy - Legacy purpose token\n * @returns Mapping result with canonical purpose and audit note\n */\nexport interface LegacyMappingResult {\n canonical: CanonicalPurpose;\n mapping_note: string;\n}\n\nexport function mapLegacyToCanonical(legacy: LegacyPurpose): LegacyMappingResult {\n const canonical = LEGACY_TO_CANONICAL[legacy];\n return {\n canonical,\n mapping_note: `Mapped legacy '${legacy}' to canonical '${canonical}'`,\n };\n}\n\n/**\n * Normalize any purpose token (canonical, legacy, or unknown)\n *\n * Returns the canonical form if known, otherwise preserves the token.\n *\n * @param token - Any valid PurposeToken\n * @returns Canonical purpose if mapped, otherwise original token\n */\nexport function normalizeToCanonicalOrPreserve(\n token: PurposeToken\n):\n | { purpose: CanonicalPurpose; mapped: false }\n | { purpose: PurposeToken; mapped: true; from: LegacyPurpose }\n | { purpose: PurposeToken; mapped: false; unknown: true } {\n if (isCanonicalPurpose(token)) {\n return { purpose: token, mapped: false };\n }\n if (isLegacyPurpose(token)) {\n return { purpose: LEGACY_TO_CANONICAL[token], mapped: true, from: token };\n }\n return { purpose: token, mapped: false, unknown: true };\n}\n\n// ============================================================================\n// Purpose Reason Determination (v0.9.24+)\n// ============================================================================\n\n/**\n * Decision type for purpose reason determination\n *\n * Maps to policy decisions that affect purpose enforcement.\n */\nexport type PurposeDecision = 'allowed' | 'constrained' | 'denied' | 'downgraded';\n\n/**\n * Context for determining purpose reason\n */\nexport interface PurposeReasonContext {\n /**\n * Whether purposes were declared (PEAC-Purpose header present and non-empty).\n * If false, reason will be 'undeclared_default'.\n */\n declared: boolean;\n\n /**\n * Whether any unknown (non-canonical) tokens are present in declared purposes.\n * If true and declared is true, reason will be 'unknown_preserved'.\n */\n hasUnknownTokens: boolean;\n\n /**\n * The policy decision (only used if declared and no unknown tokens).\n * Defaults to 'allowed' if not provided.\n */\n decision?: PurposeDecision;\n}\n\n/**\n * Determine the appropriate PurposeReason based on context\n *\n * This helper implements the decision logic for the audit spine:\n * 1. If no purposes declared -> 'undeclared_default'\n * 2. If unknown tokens present -> 'unknown_preserved'\n * 3. Otherwise -> maps to policy decision\n *\n * @param context - Context for determination\n * @returns The appropriate PurposeReason for the audit spine\n *\n * @example\n * ```typescript\n * // Missing PEAC-Purpose header\n * determinePurposeReason({ declared: false, hasUnknownTokens: false });\n * // => 'undeclared_default'\n *\n * // Has vendor-prefixed tokens\n * determinePurposeReason({ declared: true, hasUnknownTokens: true, decision: 'allowed' });\n * // => 'unknown_preserved'\n *\n * // All canonical tokens, allowed by policy\n * determinePurposeReason({ declared: true, hasUnknownTokens: false, decision: 'allowed' });\n * // => 'allowed'\n * ```\n */\nexport function determinePurposeReason(context: PurposeReasonContext): PurposeReason {\n // Priority 1: No purposes declared\n if (!context.declared) {\n return 'undeclared_default';\n }\n\n // Priority 2: Unknown tokens present (preserved for forward-compat)\n if (context.hasUnknownTokens) {\n return 'unknown_preserved';\n }\n\n // Priority 3: Map policy decision to reason\n const decision = context.decision ?? 'allowed';\n switch (decision) {\n case 'allowed':\n return 'allowed';\n case 'constrained':\n return 'constrained';\n case 'denied':\n return 'denied';\n case 'downgraded':\n return 'downgraded';\n default:\n return 'allowed';\n }\n}\n\n/**\n * Check if any tokens in an array are unknown (non-canonical)\n *\n * @param tokens - Array of purpose tokens\n * @returns true if any token is not a canonical purpose\n */\nexport function hasUnknownPurposeTokens(tokens: PurposeToken[]): boolean {\n return tokens.some((token) => !isCanonicalPurpose(token));\n}\n","/**\n * Zod validators for PEAC protocol types\n */\nimport { z } from 'zod';\nimport { PEAC_WIRE_TYP, PEAC_ALG } from './constants';\nimport {\n JsonValueSchema,\n JsonObjectSchema,\n assertJsonSafeIterative,\n type JsonEvidenceLimits,\n} from './json';\nimport { createEvidenceNotJsonError, type PEACError } from './errors';\nimport { PURPOSE_TOKEN_REGEX, MAX_PURPOSE_TOKEN_LENGTH } from './purpose';\n\nconst httpsUrl = z\n .string()\n .url()\n .refine((u) => u.startsWith('https://'), 'must be https://');\nconst iso4217 = z.string().regex(/^[A-Z]{3}$/);\nconst uuidv7 = z\n .string()\n .regex(/^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i);\n\nexport const NormalizedPayment = z\n .object({\n rail: z.string().min(1),\n reference: z.string().min(1),\n amount: z.number().int().nonnegative(),\n currency: iso4217,\n asset: z.string().optional(),\n env: z.string().optional(),\n evidence: JsonValueSchema.optional(),\n metadata: JsonObjectSchema.optional(),\n })\n .strict();\n\nexport const Subject = z.object({ uri: httpsUrl }).strict();\n\nexport const AIPREFSnapshot = z\n .object({\n url: httpsUrl,\n hash: z.string().min(8),\n })\n .strict();\n\n// Note: Extensions uses a forward reference pattern since ControlBlockSchema\n// is defined after this. We use catchall for now and validate control separately.\nexport const Extensions = z\n .object({\n aipref_snapshot: AIPREFSnapshot.optional(),\n // control block validated via ControlBlockSchema when present\n })\n .catchall(z.unknown());\n\n/**\n * Wire 0.1 JWS header Zod schema (canonical name, v0.12.0-preview.1+).\n *\n * Note: `@peac/crypto` exports a TypeScript discriminated-union type also\n * named `JWSHeader` that covers Wire 0.1, Wire 0.2, and UnTyped variants.\n * This schema validates the runtime shape of Wire 0.1 headers only.\n */\nexport const Wire01JWSHeaderSchema = z\n .object({\n typ: z.literal(PEAC_WIRE_TYP),\n alg: z.literal(PEAC_ALG),\n kid: z.string().min(8),\n })\n .strict();\n\n/**\n * @deprecated Use `Wire01JWSHeaderSchema`. Kept for backward compatibility;\n * will be removed at v1.0.\n */\nexport const JWSHeader = Wire01JWSHeaderSchema;\n\n// Forward-declare purpose validators used in ReceiptClaims\n// Full definitions are below\nconst CanonicalPurposeValues = ['train', 'search', 'user_action', 'inference', 'index'] as const;\nconst PurposeReasonValues = [\n 'allowed',\n 'constrained',\n 'denied',\n 'downgraded',\n 'undeclared_default',\n 'unknown_preserved',\n] as const;\n\nexport const ReceiptClaimsSchema = z\n .object({\n iss: httpsUrl,\n aud: httpsUrl,\n iat: z.number().int().nonnegative(),\n exp: z.number().int().optional(),\n rid: uuidv7,\n amt: z.number().int().nonnegative(),\n cur: iso4217,\n payment: NormalizedPayment,\n subject: Subject.optional(),\n ext: Extensions.optional(),\n // Purpose claims (v0.9.24+)\n // purpose_declared: string[] - preserves unknown tokens for forward-compat\n purpose_declared: z.array(z.string()).optional(),\n // purpose_enforced: CanonicalPurpose - must be one with enforcement semantics\n purpose_enforced: z.enum(CanonicalPurposeValues).optional(),\n // purpose_reason: PurposeReason - audit spine for enforcement decisions\n purpose_reason: z.enum(PurposeReasonValues).optional(),\n })\n .strict();\n\n/**\n * Schema-derived receipt claims type (v0.9.30+)\n *\n * This is the canonical type for receipt claims - derived from the Zod schema.\n * Use this type instead of manually-defined interfaces to ensure type/schema parity.\n */\nexport type ReceiptClaimsType = z.infer<typeof ReceiptClaimsSchema>;\n\n/**\n * @deprecated Use ReceiptClaimsSchema instead. Renamed in v0.9.30.\n */\nexport const ReceiptClaims = ReceiptClaimsSchema;\n\nexport const VerifyRequest = z\n .object({\n receipt_jws: z.string().min(16),\n })\n .strict();\n\n// -----------------------------------------------------------------------------\n// Control Abstraction Layer (CAL) Validators (v0.9.16+)\n// -----------------------------------------------------------------------------\n\n/**\n * Control purpose - what the access is for\n *\n * v0.9.17+: Added ai_input, search for RSL alignment\n * v0.9.18+: Added ai_index (RSL 1.0 canonical token). Removed ai_search.\n * v0.9.24+: Added user_action for agent-on-behalf-of-user scenarios.\n *\n * @see https://rslstandard.org/rsl for RSL 1.0 specification\n */\nexport const ControlPurposeSchema = z.enum([\n 'crawl',\n 'index',\n 'train',\n 'inference',\n 'user_action',\n 'ai_input',\n 'ai_index',\n 'search',\n]);\n\n/**\n * Control licensing mode - how access is licensed\n */\nexport const ControlLicensingModeSchema = z.enum([\n 'subscription',\n 'pay_per_crawl',\n 'pay_per_inference',\n]);\n\n/**\n * Control decision type\n */\nexport const ControlDecisionSchema = z.enum(['allow', 'deny', 'review']);\n\n/**\n * Single control step in governance chain\n */\nexport const ControlStepSchema = z.object({\n engine: z.string().min(1),\n version: z.string().optional(),\n policy_id: z.string().optional(),\n result: ControlDecisionSchema,\n reason: z.string().optional(),\n purpose: ControlPurposeSchema.optional(),\n licensing_mode: ControlLicensingModeSchema.optional(),\n scope: z.union([z.string(), z.array(z.string())]).optional(),\n limits_snapshot: z.unknown().optional(),\n evidence_ref: z.string().optional(),\n});\n\n/**\n * Composable control block - multi-party governance\n */\nexport const ControlBlockSchema = z\n .object({\n chain: z.array(ControlStepSchema).min(1),\n decision: ControlDecisionSchema,\n combinator: z.literal('any_can_veto').optional(),\n })\n .refine(\n (data) => {\n // Validate decision consistency with chain\n const hasAnyDeny = data.chain.some((step) => step.result === 'deny');\n const allAllow = data.chain.every((step) => step.result === 'allow');\n const hasReview = data.chain.some((step) => step.result === 'review');\n\n if (hasAnyDeny && data.decision !== 'deny') {\n return false;\n }\n if (allAllow && data.decision !== 'allow') {\n return false;\n }\n // If has review but no deny, decision can be review or allow\n if (hasReview && !hasAnyDeny && data.decision === 'deny') {\n return false;\n }\n return true;\n },\n {\n message: 'Control block decision must be consistent with chain results',\n }\n );\n\n// -----------------------------------------------------------------------------\n// Purpose Type Validators (v0.9.24+)\n// -----------------------------------------------------------------------------\n\n/**\n * Purpose token validator\n *\n * PurposeToken is a string that matches the purpose grammar:\n * - Lowercase letters, digits, underscores\n * - Optional vendor prefix with colon (e.g., \"cf:ai_crawler\")\n * - Max 64 characters\n *\n * Uses string type (not enum) to preserve unknown tokens for forward-compat.\n */\nexport const PurposeTokenSchema = z\n .string()\n .min(1)\n .max(MAX_PURPOSE_TOKEN_LENGTH)\n .refine((token) => PURPOSE_TOKEN_REGEX.test(token), {\n message:\n 'Invalid purpose token format. Must be lowercase, alphanumeric with underscores, optional vendor prefix.',\n });\n\n/**\n * Canonical purpose validator\n *\n * CanonicalPurpose is one of PEAC's normative purpose tokens.\n * Only these tokens have enforcement semantics.\n */\nexport const CanonicalPurposeSchema = z.enum([\n 'train',\n 'search',\n 'user_action',\n 'inference',\n 'index',\n]);\n\n/**\n * Purpose reason validator\n *\n * PurposeReason is the audit spine explaining enforcement decisions.\n */\nexport const PurposeReasonSchema = z.enum([\n 'allowed',\n 'constrained',\n 'denied',\n 'downgraded',\n 'undeclared_default',\n 'unknown_preserved',\n]);\n\n// -----------------------------------------------------------------------------\n// Payment Evidence Validators (v0.9.16+)\n// -----------------------------------------------------------------------------\n\n/**\n * Payment split schema\n *\n * Invariants:\n * - party is required (non-empty string)\n * - amount if present must be >= 0\n * - share if present must be in [0,1]\n * - At least one of amount or share must be specified\n */\nexport const PaymentSplitSchema = z\n .object({\n party: z.string().min(1),\n amount: z.number().int().nonnegative().optional(),\n currency: iso4217.optional(),\n share: z.number().min(0).max(1).optional(),\n rail: z.string().min(1).optional(),\n account_ref: z.string().min(1).optional(),\n metadata: JsonObjectSchema.optional(),\n })\n .strict()\n .refine((data) => data.amount !== undefined || data.share !== undefined, {\n message: 'At least one of amount or share must be specified',\n });\n\n/**\n * Payment routing mode schema (rail-agnostic)\n *\n * Describes how the payment is routed between payer, aggregator, and merchant.\n * This is a generic hint - specific rails populate it from their native formats.\n *\n * Values:\n * - \"direct\": Direct payment to merchant (no intermediary)\n * - \"callback\": Routed via callback URL / payment service\n * - \"role\": Role-based routing (e.g., \"publisher\", \"platform\")\n *\n * Examples of producers:\n * - x402 v2 `payTo.mode` -> routing\n * - Stripe Connect `destination` -> routing = 'direct' or 'callback'\n * - UPI `pa` (payee address) -> routing = 'direct'\n */\nexport const PaymentRoutingSchema = z.enum(['direct', 'callback', 'role']);\n\n/**\n * Payment evidence schema\n *\n * Full schema for PaymentEvidence including aggregator/splits support.\n */\nexport const PaymentEvidenceSchema = z\n .object({\n rail: z.string().min(1),\n reference: z.string().min(1),\n amount: z.number().int().nonnegative(),\n currency: iso4217,\n asset: z.string().min(1),\n env: z.enum(['live', 'test']),\n network: z.string().min(1).optional(),\n facilitator_ref: z.string().min(1).optional(),\n evidence: JsonValueSchema,\n aggregator: z.string().min(1).optional(),\n splits: z.array(PaymentSplitSchema).optional(),\n routing: PaymentRoutingSchema.optional(),\n })\n .strict();\n\n// -----------------------------------------------------------------------------\n// Subject Profile Validators (v0.9.16+)\n// -----------------------------------------------------------------------------\n\n/**\n * Subject type schema\n */\nexport const SubjectTypeSchema = z.enum(['human', 'org', 'agent']);\n\n/**\n * Subject profile schema\n *\n * Invariants:\n * - id is required (non-empty string)\n * - type is required (human, org, or agent)\n * - labels if present must be non-empty strings\n */\nexport const SubjectProfileSchema = z\n .object({\n id: z.string().min(1),\n type: SubjectTypeSchema,\n labels: z.array(z.string().min(1)).optional(),\n metadata: JsonObjectSchema.optional(),\n })\n .strict();\n\n/**\n * Subject profile snapshot schema\n *\n * Invariants:\n * - subject is required (valid SubjectProfile)\n * - captured_at is required (non-empty string)\n * MUST be RFC 3339 / ISO 8601 UTC; format not enforced in schema for v0.9.16\n */\nexport const SubjectProfileSnapshotSchema = z\n .object({\n subject: SubjectProfileSchema,\n captured_at: z.string().min(1),\n source: z.string().min(1).optional(),\n version: z.string().min(1).optional(),\n })\n .strict();\n\n// -----------------------------------------------------------------------------\n// Attestation Validators (v0.9.21+)\n// -----------------------------------------------------------------------------\n\n/**\n * Namespaced extensions schema\n *\n * Keys must be namespaced (e.g., \"com.example/field\", \"io.vendor/data\").\n * This provides a forward-compatible extension mechanism.\n */\nexport const ExtensionsSchema = z.record(\n z.string().regex(/^[a-z0-9_.-]+\\/[a-z0-9_.-]+$/),\n JsonValueSchema\n);\n\n/**\n * Generic attestation schema\n *\n * Invariants:\n * - issuer, type, issued_at, evidence are required\n * - issued_at and expires_at must be RFC 3339 date-time\n * - ref if present must be a valid URI\n */\nexport const AttestationSchema = z\n .object({\n issuer: z.string().min(1),\n type: z.string().min(1),\n issued_at: z.string().datetime(),\n expires_at: z.string().datetime().optional(),\n ref: z.string().url().optional(),\n evidence: JsonValueSchema,\n })\n .strict();\n\n// -----------------------------------------------------------------------------\n// Subject Snapshot Validation Helper (v0.9.17+)\n// -----------------------------------------------------------------------------\n\n// Module-level set for PII warning deduplication\nconst warnedSubjectIds = new Set<string>();\n\n/**\n * Heuristic check if a subject ID looks like PII (email/phone)\n */\nfunction looksLikePII(id: string): boolean {\n // Email pattern\n if (/^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(id)) {\n return true;\n }\n // Phone pattern (starts with + followed by digits)\n if (/^\\+?\\d{10,15}$/.test(id.replace(/[\\s\\-()]/g, ''))) {\n return true;\n }\n return false;\n}\n\n/**\n * Validate a subject snapshot (if present)\n *\n * - Returns validated snapshot or null if absent\n * - Throws ZodError for malformed data\n * - Logs advisory warning if id looks like PII (deduplicated)\n */\nexport function validateSubjectSnapshot(\n snapshot: unknown\n): z.infer<typeof SubjectProfileSnapshotSchema> | null {\n if (snapshot === undefined || snapshot === null) {\n return null;\n }\n\n // Validate against schema (throws on malformed data)\n const validated = SubjectProfileSnapshotSchema.parse(snapshot);\n\n // Advisory PII warning (deduplicated)\n const subjectId = validated.subject.id;\n if (looksLikePII(subjectId) && !warnedSubjectIds.has(subjectId)) {\n warnedSubjectIds.add(subjectId);\n console.warn(\n `[peac:subject] Advisory: subject.id \"${subjectId}\" looks like PII. ` +\n 'Prefer opaque identifiers (e.g., \"user:abc123\").'\n );\n }\n\n return validated;\n}\n\n// -----------------------------------------------------------------------------\n// Evidence Validation (v0.9.21+)\n// -----------------------------------------------------------------------------\n\n/**\n * Result type for evidence validation\n */\nexport type EvidenceValidationResult =\n | { ok: true; value: unknown }\n | { ok: false; error: PEACError };\n\n/**\n * Validate payment evidence for JSON safety\n *\n * Uses iterative validation (no recursion) to prevent stack overflow on\n * deeply nested structures. Enforces limits on depth, array length,\n * object keys, and string length.\n *\n * @param evidence - Evidence value to validate\n * @param limits - Optional limits (internal, not part of public API)\n * @returns Result indicating success with validated value, or failure with PEACError\n *\n * @example\n * ```ts\n * const result = validateEvidence({ txId: '123', amount: 100 });\n * if (!result.ok) {\n * console.error(result.error.code, result.error.remediation);\n * }\n * ```\n */\nexport function validateEvidence(\n evidence: unknown,\n limits?: JsonEvidenceLimits\n): EvidenceValidationResult {\n const result = assertJsonSafeIterative(evidence, limits);\n\n if (!result.ok) {\n return {\n ok: false,\n error: createEvidenceNotJsonError(result.error, result.path),\n };\n }\n\n return { ok: true, value: evidence };\n}\n","/**\n * PEAC Attestation Receipt Types (v0.10.8+)\n *\n * Attestation receipts are lightweight signed tokens that attest to API\n * interactions WITHOUT payment fields. This is a distinct profile from\n * full payment receipts (PEACReceiptClaims).\n *\n * Use cases:\n * - API interaction logging with evidentiary value\n * - Middleware-issued receipts for non-payment flows\n * - Audit trails for agent/tool interactions\n *\n * Claims structure:\n * - Core JWT claims: iss, aud, iat, exp\n * - PEAC claims: rid (UUIDv7 receipt ID)\n * - Optional: sub, ext (extensions including interaction binding)\n *\n * @see docs/specs/ATTESTATION-RECEIPTS.md\n */\n\nimport { z } from 'zod';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * Attestation receipt type constant\n */\nexport const ATTESTATION_RECEIPT_TYPE = 'peac/attestation-receipt' as const;\n\n/**\n * Extension key for minimal interaction binding (middleware profile)\n *\n * This is a simplified binding used by middleware packages. For full\n * interaction evidence, use INTERACTION_EXTENSION_KEY from ./interaction.ts\n */\nexport const MIDDLEWARE_INTERACTION_KEY = 'org.peacprotocol/middleware-interaction@0.1';\n\n/**\n * Limits for attestation receipt fields (DoS protection)\n */\nexport const ATTESTATION_LIMITS = {\n /** Maximum issuer URL length */\n maxIssuerLength: 2048,\n /** Maximum audience URL length */\n maxAudienceLength: 2048,\n /** Maximum subject length */\n maxSubjectLength: 256,\n /** Maximum path length in interaction binding */\n maxPathLength: 2048,\n /** Maximum method length */\n maxMethodLength: 16,\n /** Maximum HTTP status code */\n maxStatusCode: 599,\n /** Minimum HTTP status code */\n minStatusCode: 100,\n} as const;\n\n// ============================================================================\n// Zod Schemas\n// ============================================================================\n\n/**\n * HTTPS URL validation (reused from validators.ts pattern)\n */\nconst httpsUrl = z\n .string()\n .url()\n .max(ATTESTATION_LIMITS.maxIssuerLength)\n .refine((url) => url.startsWith('https://'), 'Must be HTTPS URL');\n\n/**\n * UUIDv7 format validation\n */\nconst uuidv7 = z\n .string()\n .regex(\n /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,\n 'Must be UUIDv7 format'\n );\n\n/**\n * Minimal interaction binding schema (for middleware use)\n *\n * This is a simplified version of full interaction evidence.\n * Contains only: method, path, status.\n *\n * Privacy note: Query strings are excluded by default to avoid\n * leaking sensitive data (API keys, tokens, PII in parameters).\n */\nexport const MinimalInteractionBindingSchema = z\n .object({\n /** HTTP method (uppercase, e.g., GET, POST) */\n method: z\n .string()\n .min(1)\n .max(ATTESTATION_LIMITS.maxMethodLength)\n .transform((m) => m.toUpperCase()),\n /** Request path (no query string by default) */\n path: z.string().min(1).max(ATTESTATION_LIMITS.maxPathLength),\n /** HTTP response status code */\n status: z\n .number()\n .int()\n .min(ATTESTATION_LIMITS.minStatusCode)\n .max(ATTESTATION_LIMITS.maxStatusCode),\n })\n .strict();\n\n/**\n * Attestation receipt extensions schema\n *\n * Allows interaction binding and other namespaced extensions.\n */\nexport const AttestationExtensionsSchema = z.record(z.string(), z.unknown());\n\n/**\n * PEAC Attestation Receipt Claims schema\n *\n * This is the claims structure for attestation receipts - lightweight\n * receipts without payment fields. For full payment receipts, use\n * ReceiptClaimsSchema from ./validators.ts\n */\nexport const AttestationReceiptClaimsSchema = z\n .object({\n /** Issuer URL (normalized, no trailing slash) */\n iss: httpsUrl,\n /** Audience URL */\n aud: httpsUrl,\n /** Issued at (Unix seconds) */\n iat: z.number().int().nonnegative(),\n /** Expiration (Unix seconds) */\n exp: z.number().int().nonnegative(),\n /** Receipt ID (UUIDv7) */\n rid: uuidv7,\n /** Subject identifier (optional) */\n sub: z.string().max(ATTESTATION_LIMITS.maxSubjectLength).optional(),\n /** Extensions (optional) */\n ext: AttestationExtensionsSchema.optional(),\n })\n .strict();\n\n// ============================================================================\n// TypeScript Types (inferred from Zod schemas)\n// ============================================================================\n\nexport type MinimalInteractionBinding = z.infer<typeof MinimalInteractionBindingSchema>;\nexport type AttestationExtensions = z.infer<typeof AttestationExtensionsSchema>;\nexport type AttestationReceiptClaims = z.infer<typeof AttestationReceiptClaimsSchema>;\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\n/**\n * Validation result type\n */\nexport interface AttestationValidationResult {\n valid: boolean;\n error_code?: string;\n error_message?: string;\n}\n\n/**\n * Validate attestation receipt claims\n *\n * @param input - Raw input to validate\n * @returns Validation result\n */\nexport function validateAttestationReceiptClaims(input: unknown): AttestationValidationResult {\n const result = AttestationReceiptClaimsSchema.safeParse(input);\n if (result.success) {\n return { valid: true };\n }\n const firstIssue = result.error.issues[0];\n return {\n valid: false,\n error_code: 'E_ATTESTATION_INVALID_CLAIMS',\n error_message: firstIssue?.message || 'Invalid attestation receipt claims',\n };\n}\n\n/**\n * Check if an object is valid attestation receipt claims (non-throwing)\n *\n * @param claims - Object to check\n * @returns True if valid AttestationReceiptClaims\n */\nexport function isAttestationReceiptClaims(claims: unknown): claims is AttestationReceiptClaims {\n return AttestationReceiptClaimsSchema.safeParse(claims).success;\n}\n\n/**\n * Validate minimal interaction binding\n *\n * @param input - Raw input to validate\n * @returns Validation result\n */\nexport function validateMinimalInteractionBinding(input: unknown): AttestationValidationResult {\n const result = MinimalInteractionBindingSchema.safeParse(input);\n if (result.success) {\n return { valid: true };\n }\n const firstIssue = result.error.issues[0];\n return {\n valid: false,\n error_code: 'E_ATTESTATION_INVALID_INTERACTION',\n error_message: firstIssue?.message || 'Invalid interaction binding',\n };\n}\n\n/**\n * Check if an object is valid minimal interaction binding (non-throwing)\n *\n * @param binding - Object to check\n * @returns True if valid MinimalInteractionBinding\n */\nexport function isMinimalInteractionBinding(\n binding: unknown\n): binding is MinimalInteractionBinding {\n return MinimalInteractionBindingSchema.safeParse(binding).success;\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Parameters for creating attestation receipt claims\n */\nexport interface CreateAttestationReceiptParams {\n /** Issuer URL (will be normalized) */\n issuer: string;\n /** Audience URL */\n audience: string;\n /** Receipt ID (UUIDv7) */\n rid: string;\n /** Subject identifier (optional) */\n sub?: string;\n /** Interaction binding (optional) */\n interaction?: MinimalInteractionBinding;\n /** Additional extensions (optional) */\n extensions?: Record<string, unknown>;\n /** Expiration in seconds from now (default: 300) */\n expiresIn?: number;\n}\n\n/**\n * Create validated attestation receipt claims\n *\n * @param params - Attestation receipt parameters\n * @returns Validated AttestationReceiptClaims\n * @throws ZodError if validation fails\n */\nexport function createAttestationReceiptClaims(\n params: CreateAttestationReceiptParams\n): AttestationReceiptClaims {\n const now = Math.floor(Date.now() / 1000);\n const expiresIn = params.expiresIn ?? 300;\n\n // Normalize issuer (remove trailing slashes)\n // Using explicit loop instead of regex to avoid ReDoS with quantifiers\n let normalizedIssuer = params.issuer;\n while (normalizedIssuer.endsWith('/')) {\n normalizedIssuer = normalizedIssuer.slice(0, -1);\n }\n\n // Build extensions\n const ext: Record<string, unknown> = { ...params.extensions };\n if (params.interaction) {\n ext[MIDDLEWARE_INTERACTION_KEY] = params.interaction;\n }\n\n const claims: AttestationReceiptClaims = {\n iss: normalizedIssuer,\n aud: params.audience,\n iat: now,\n exp: now + expiresIn,\n rid: params.rid,\n ...(params.sub && { sub: params.sub }),\n ...(Object.keys(ext).length > 0 && { ext }),\n };\n\n return AttestationReceiptClaimsSchema.parse(claims);\n}\n\n// ============================================================================\n// Type Guard for Receipt Profile Discrimination\n// ============================================================================\n\n/**\n * Check if claims are attestation-only (no payment fields)\n *\n * This helps discriminate between attestation receipts and\n * full payment receipts at runtime.\n *\n * @param claims - Receipt claims to check\n * @returns True if claims lack payment fields (amt, cur, payment)\n */\nexport function isAttestationOnly(claims: Record<string, unknown>): boolean {\n return !('amt' in claims) && !('cur' in claims) && !('payment' in claims);\n}\n\n/**\n * Check if claims are payment receipt (has payment fields)\n *\n * @param claims - Receipt claims to check\n * @returns True if claims have payment fields\n */\nexport function isPaymentReceipt(claims: Record<string, unknown>): boolean {\n return 'amt' in claims && 'cur' in claims && 'payment' in claims;\n}\n","/**\n * ActorBinding and MVIS (Minimum Viable Identity Set) Schemas (v0.11.3+)\n *\n * Implements (ActorBinding) (Multi-Root Proof Types),\n * and (MVIS) for the Agent Identity Profile.\n *\n * ActorBinding lives in ext[\"org.peacprotocol/actor_binding\"] in Wire 0.1.\n * ProofTypeSchema is SEPARATE from ProofMethodSchema (agent-identity.ts)\n * to avoid breaking the v0.9.25+ API. Unification deferred to v0.12.0.\n *\n * @see docs/specs/AGENT-IDENTITY-PROFILE.md for normative specification\n */\nimport { z } from 'zod';\n\n// =============================================================================\n// PROOF TYPES (Multi-Root Proof Types)\n// =============================================================================\n\n/**\n * Proof types for ActorBinding.\n *\n * 8 methods covering attestation chains, RATS, keyless signing,\n * decentralized identity, workload identity, PKI, and vendor-defined.\n *\n * SEPARATE from ProofMethodSchema (4 transport-level methods in agent-identity.ts).\n * ProofMethodSchema covers how proof is transported (HTTP sig, DPoP, mTLS, JWK thumbprint).\n * ProofTypeSchema covers the trust root model used to establish identity.\n *\n * The 'custom' type: implementers MUST document their proof semantics externally.\n * proof_ref SHOULD use a reverse-DNS namespace (e.g., 'com.example.vendor/proof-type-v1').\n */\nexport const PROOF_TYPES = [\n 'ed25519-cert-chain',\n 'eat-passport',\n 'eat-background-check',\n 'sigstore-oidc',\n 'did',\n 'spiffe',\n 'x509-pki',\n 'custom',\n] as const;\n\nexport const ProofTypeSchema = z.enum(PROOF_TYPES);\nexport type ProofType = z.infer<typeof ProofTypeSchema>;\n\n// =============================================================================\n// ORIGIN VALIDATION\n// =============================================================================\n\n/**\n * Validate that a string is an origin-only URL (scheme + host + optional port).\n * Rejects URLs with path (other than '/'), query, or fragment components.\n * This prevents correlation leakage and ambiguity in ActorBinding.\n *\n * Valid: \"https://example.com\", \"https://example.com:8443\"\n * Invalid: \"https://example.com/api/v1\", \"https://example.com?q=1\", \"https://example.com#frag\"\n */\nexport function isOriginOnly(value: string): boolean {\n try {\n const url = new URL(value);\n // Must be http or https\n if (url.protocol !== 'https:' && url.protocol !== 'http:') {\n return false;\n }\n // pathname must be exactly '/' (the implicit root)\n if (url.pathname !== '/') {\n return false;\n }\n // No search params\n if (url.search !== '') {\n return false;\n }\n // No fragment: url.hash is '' for both no-fragment and bare '#',\n // so also check the raw string for a trailing '#'\n if (url.hash !== '' || value.includes('#')) {\n return false;\n }\n // Reject userinfo (credentials in origins are a security risk)\n if (url.username !== '' || url.password !== '') {\n return false;\n }\n // Reject trailing dot in hostname (FQDN notation leaks DNS internals)\n if (url.hostname.endsWith('.')) {\n return false;\n }\n // URL API may normalize trailing dots; also check raw input\n const hostPart = value.replace(/^https?:\\/\\//, '').split(/[/:]/)[0];\n if (hostPart.endsWith('.')) {\n return false;\n }\n // Reject IPv6 zone identifiers (link-local, not valid origins)\n if (url.hostname.includes('%')) {\n return false;\n }\n return true;\n } catch {\n return false;\n }\n}\n\n// =============================================================================\n// ACTOR BINDING\n// =============================================================================\n\n/**\n * Extension key for ActorBinding in Wire 0.1 ext[].\n */\nexport const ACTOR_BINDING_EXTENSION_KEY = 'org.peacprotocol/actor_binding' as const;\n\n/**\n * ActorBinding schema.\n *\n * Binds an actor identity to a receipt via ext[\"org.peacprotocol/actor_binding\"].\n * Wire 0.2 moves this to a kernel field.\n *\n * - id: Stable actor identifier (opaque, no PII)\n * - proof_type: Trust root model from vocabulary\n * - proof_ref: Optional URI or hash of external proof artifact\n * - origin: Origin-only URL (scheme + host + optional port; no path/query/fragment)\n * - intent_hash: Optional SHA-256 hash of the intent (hash-first per )\n */\nexport const ActorBindingSchema = z\n .object({\n /** Stable actor identifier (opaque, no PII) */\n id: z.string().min(1).max(256),\n\n /** Proof type from multi-root vocabulary */\n proof_type: ProofTypeSchema,\n\n /** URI or hash of external proof artifact */\n proof_ref: z.string().max(2048).optional(),\n\n /** Origin-only URL: scheme + host + optional port; NO path, query, or fragment */\n origin: z.string().max(2048).refine(isOriginOnly, {\n message:\n 'origin must be an origin-only URL (scheme + host + optional port; no path, query, or fragment)',\n }),\n\n /** SHA-256 hash of the intent (hash-first per ) */\n intent_hash: z\n .string()\n .regex(/^sha256:[a-f0-9]{64}$/, {\n message: 'intent_hash must match sha256:<64 hex chars>',\n })\n .optional(),\n })\n .strict();\n\nexport type ActorBinding = z.infer<typeof ActorBindingSchema>;\n\n// =============================================================================\n// MVIS: Minimum Viable Identity Set\n// =============================================================================\n\n/**\n * MVIS (Minimum Viable Identity Set) fields.\n *\n * 5 required fields for any identity receipt to be considered complete.\n * validateMVIS() is a pure validation function with zero I/O.\n *\n * Fields:\n * - issuer: Who issued the identity assertion\n * - subject: Who the identity is about (opaque identifier)\n * - key_binding: Cryptographic binding to a key (kid or thumbprint)\n * - time_bounds: Validity period with not_before and not_after\n * - replay_protection: Unique token ID (jti) and optional nonce\n */\nexport const MVISTimeBoundsSchema = z\n .object({\n /** Earliest valid time (RFC 3339) */\n not_before: z.string().datetime(),\n /** Latest valid time (RFC 3339) */\n not_after: z.string().datetime(),\n })\n .strict();\n\nexport type MVISTimeBounds = z.infer<typeof MVISTimeBoundsSchema>;\n\nexport const MVISReplayProtectionSchema = z\n .object({\n /** Unique token identifier (jti from JWT or equivalent) */\n jti: z.string().min(1).max(256),\n /** Optional nonce for additional replay protection */\n nonce: z.string().max(256).optional(),\n })\n .strict();\n\nexport type MVISReplayProtection = z.infer<typeof MVISReplayProtectionSchema>;\n\nexport const MVISFieldsSchema = z\n .object({\n /** Who issued the identity assertion */\n issuer: z.string().min(1).max(2048),\n\n /** Who the identity is about (opaque identifier, no PII) */\n subject: z.string().min(1).max(256),\n\n /** Cryptographic binding: kid or JWK thumbprint */\n key_binding: z.string().min(1).max(256),\n\n /** Validity period */\n time_bounds: MVISTimeBoundsSchema,\n\n /** Replay protection */\n replay_protection: MVISReplayProtectionSchema,\n })\n .strict();\n\nexport type MVISFields = z.infer<typeof MVISFieldsSchema>;\n\n// =============================================================================\n// VALIDATION HELPERS\n// =============================================================================\n\n/**\n * Validate an ActorBinding object.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated ActorBinding or error message\n */\nexport function validateActorBinding(\n data: unknown\n): { ok: true; value: ActorBinding } | { ok: false; error: string } {\n const result = ActorBindingSchema.safeParse(data);\n if (result.success) {\n return { ok: true, value: result.data };\n }\n return { ok: false, error: result.error.message };\n}\n\n/**\n * Validate MVIS fields.\n *\n * Pure validation function with zero I/O.\n * Checks that all 5 required fields are present and valid.\n * Also validates that time_bounds.not_before < time_bounds.not_after.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated MVIS fields or error message\n */\nexport function validateMVIS(\n data: unknown\n): { ok: true; value: MVISFields } | { ok: false; error: string } {\n const result = MVISFieldsSchema.safeParse(data);\n if (!result.success) {\n return { ok: false, error: result.error.message };\n }\n\n // Semantic check: not_before must be before not_after\n const notBefore = new Date(result.data.time_bounds.not_before).getTime();\n const notAfter = new Date(result.data.time_bounds.not_after).getTime();\n if (notBefore >= notAfter) {\n return { ok: false, error: 'not_before must be before not_after' };\n }\n\n // Reject absurd durations (>100 years)\n const MAX_DURATION_MS = 100 * 365.25 * 24 * 60 * 60 * 1000;\n if (notAfter - notBefore > MAX_DURATION_MS) {\n return { ok: false, error: 'time_bounds duration must not exceed 100 years' };\n }\n\n return { ok: true, value: result.data };\n}\n","/**\n * Fingerprint Reference Conversion Functions (v0.11.3+)\n *\n * Pure string manipulation functions for converting between Wire 0.1\n * string form (\"alg:hex64\") and Wire 0.2 object form ({ alg, value, key_id? }).\n *\n * These are opaque references. The schema validates format only.\n * Issuers compute values externally; verifiers MUST NOT assume\n * they can recompute the reference.\n *\n * Lives in Layer 1 (@peac/schema) because it is pure string manipulation,\n * not cryptographic computation. Zero dependencies, zero I/O.\n */\n\n/**\n * Wire 0.2 object form of a fingerprint reference\n */\nexport interface FingerprintRefObject {\n /** Hash algorithm: 'sha256' or 'hmac-sha256' */\n alg: string;\n /** Base64url-encoded value */\n value: string;\n /** Optional key identifier (for hmac-sha256 references) */\n key_id?: string;\n}\n\n/**\n * Convert hex string to base64url encoding.\n * Pure function, no dependencies.\n */\nfunction hexToBase64url(hex: string): string {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);\n }\n // Use Buffer in Node, or manual encoding\n let base64: string;\n if (typeof Buffer !== 'undefined') {\n base64 = Buffer.from(bytes).toString('base64');\n } else {\n // Fallback for non-Node environments\n base64 = btoa(String.fromCharCode(...bytes));\n }\n // base64 -> base64url\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\n/**\n * Convert base64url string to hex encoding.\n * Pure function, no dependencies.\n */\nfunction base64urlToHex(b64url: string): string {\n // base64url -> base64\n let base64 = b64url.replace(/-/g, '+').replace(/_/g, '/');\n // Add padding\n while (base64.length % 4 !== 0) {\n base64 += '=';\n }\n let bytes: Uint8Array;\n if (typeof Buffer !== 'undefined') {\n bytes = Buffer.from(base64, 'base64');\n } else {\n const binary = atob(base64);\n bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n }\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * Supported algorithm prefixes\n */\nconst VALID_ALGS = ['sha256', 'hmac-sha256'] as const;\nconst STRING_FORM_PATTERN = /^(sha256|hmac-sha256):([a-f0-9]{64})$/;\n\n/**\n * Maximum length for fingerprint reference string form.\n * \"hmac-sha256:\" (12) + 64 hex chars = 76 chars max.\n */\nexport const MAX_FINGERPRINT_REF_LENGTH = 76;\n\n/**\n * Strict base64url character set (RFC 4648 section 5).\n * Only A-Z, a-z, 0-9, '-', '_'. No padding ('='), no whitespace.\n */\nconst BASE64URL_PATTERN = /^[A-Za-z0-9_-]+$/;\n\n/**\n * Parse a Wire 0.1 string form fingerprint reference (\"alg:hex64\")\n * into a Wire 0.2 object form ({ alg, value }).\n *\n * The hex value is converted to base64url for the object form.\n *\n * @param s - String form: \"sha256:<64 hex chars>\" or \"hmac-sha256:<64 hex chars>\"\n * @returns Object form with base64url value, or null if invalid\n */\nexport function stringToFingerprintRef(s: string): FingerprintRefObject | null {\n if (s.length > MAX_FINGERPRINT_REF_LENGTH) {\n return null;\n }\n const match = STRING_FORM_PATTERN.exec(s);\n if (!match) {\n return null;\n }\n const alg = match[1];\n const hex = match[2];\n return {\n alg,\n value: hexToBase64url(hex),\n };\n}\n\n/**\n * Convert a Wire 0.2 object form fingerprint reference back to\n * the Wire 0.1 string form (\"alg:hex64\").\n *\n * The base64url value is converted back to hex for the string form.\n *\n * @param obj - Object form with alg and base64url value\n * @returns String form \"alg:<64 hex chars>\", or null if invalid\n */\nexport function fingerprintRefToString(obj: FingerprintRefObject): string | null {\n if (!VALID_ALGS.includes(obj.alg as (typeof VALID_ALGS)[number])) {\n return null;\n }\n // Strict base64url validation (RFC 4648 section 5): no padding, no whitespace\n if (!BASE64URL_PATTERN.test(obj.value)) {\n return null;\n }\n try {\n const hex = base64urlToHex(obj.value);\n if (hex.length !== 64) {\n return null;\n }\n return `${obj.alg}:${hex}`;\n } catch {\n return null;\n }\n}\n","/**\n * Wire 0.2 RepresentationFields schema\n *\n * Records metadata about the content representation that was observed or served,\n * enabling reproducible content drift detection.\n *\n * Layer 1 (@peac/schema): pure Zod validation, zero I/O.\n *\n * content_hash validation uses stringToFingerprintRef() as the parser gate\n * and additionally requires alg === 'sha256'. The hmac-sha256 algorithm is\n * not permitted for representation hashes (sha256-only by design).\n */\n\nimport { z } from 'zod';\nimport {\n stringToFingerprintRef,\n MAX_FINGERPRINT_REF_LENGTH,\n} from './extensions/fingerprint-ref.js';\n\n// ---------------------------------------------------------------------------\n// Private helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Validate that a content_hash string is a valid sha256 FingerprintRef.\n *\n * Uses stringToFingerprintRef() as the parser gate (format correctness),\n * then additionally requires alg === 'sha256'. hmac-sha256 is rejected\n * for representation content hashes.\n */\nfunction isValidContentHash(s: string): boolean {\n const ref = stringToFingerprintRef(s);\n if (ref === null) return false;\n // Only sha256 is permitted for representation.content_hash\n return ref.alg === 'sha256';\n}\n\n/**\n * Conservative MIME type validation.\n *\n * Accepts the token/token form with optional parameters (type/subtype;key=value).\n * Does NOT attempt full RFC 9110/6838 grammar parsing.\n *\n * Valid examples: text/plain, application/json, application/json; charset=utf-8\n * Invalid examples: \"text\", \"text/\", \" text/plain\", \"\"\n */\nconst MIME_PATTERN =\n /^[a-zA-Z0-9][a-zA-Z0-9!#$&\\-^_.+]*\\/[a-zA-Z0-9][a-zA-Z0-9!#$&\\-^_.+]*(;\\s*[a-zA-Z0-9][a-zA-Z0-9!#$&\\-^_.+]*=[^\\s;]+)*$/;\n\nfunction isValidMimeType(s: string): boolean {\n return MIME_PATTERN.test(s);\n}\n\n// ---------------------------------------------------------------------------\n// Bounds constants (follows repo _LIMITS convention)\n// ---------------------------------------------------------------------------\n\n/**\n * Normative bounds for Wire 0.2 representation fields.\n *\n * Centralised to prevent magic numbers and allow external reference.\n */\nexport const REPRESENTATION_LIMITS = {\n /** Max content_hash string length (sha256:<64 hex> = 71 chars, capped at FingerprintRef max) */\n maxContentHashLength: MAX_FINGERPRINT_REF_LENGTH,\n /** Max content_type string length */\n maxContentTypeLength: 256,\n} as const;\n\n// ---------------------------------------------------------------------------\n// Wire02RepresentationFieldsSchema\n// ---------------------------------------------------------------------------\n\n/**\n * Zod schema for Wire 0.2 representation fields.\n *\n * All fields are optional; an empty object is valid.\n * Unknown keys are rejected (.strict()).\n *\n * Bounds:\n * - content_hash: max 76 chars (MAX_FINGERPRINT_REF_LENGTH), sha256-only\n * - content_type: max 256 chars, conservative MIME pattern\n * - content_length: non-negative integer, <= Number.MAX_SAFE_INTEGER\n */\nexport const Wire02RepresentationFieldsSchema = z\n .object({\n /**\n * FingerprintRef of the served content body.\n * Format: sha256:<64 lowercase hex>\n * hmac-sha256 is NOT permitted for representation hashes.\n */\n content_hash: z\n .string()\n .max(REPRESENTATION_LIMITS.maxContentHashLength)\n .refine(isValidContentHash, {\n message: 'content_hash must be a valid sha256 FingerprintRef (sha256:<64 lowercase hex>)',\n })\n .optional(),\n /**\n * MIME type of the served content (e.g., 'text/plain', 'application/json').\n * Conservative pattern validation: type/subtype with optional parameters.\n */\n content_type: z\n .string()\n .max(REPRESENTATION_LIMITS.maxContentTypeLength)\n .refine(isValidMimeType, {\n message: 'content_type must be a valid MIME type (type/subtype with optional parameters)',\n })\n .optional(),\n /**\n * Size of the served content in bytes.\n * Non-negative integer, bounded by Number.MAX_SAFE_INTEGER.\n */\n content_length: z.number().int().finite().nonnegative().max(Number.MAX_SAFE_INTEGER).optional(),\n })\n .strict();\n\n/** Inferred type for Wire 0.2 representation fields */\nexport type Wire02RepresentationFields = z.infer<typeof Wire02RepresentationFieldsSchema>;\n\n/**\n * Public export alias.\n * Internal name is Wire02RepresentationFieldsSchema to prevent wire-version\n * collisions; exported as RepresentationFieldsSchema for ergonomic use.\n */\nexport { Wire02RepresentationFieldsSchema as RepresentationFieldsSchema };\n","/**\n * Wire 0.2 Extension Group Limits\n *\n * Centralized per-field bounds for all Wire 0.2 extension group fields.\n * Prevents magic numbers and allows external reference.\n * Follows repo _LIMITS convention.\n *\n * Byte-budget constants are normative and live in @peac/kernel\n * (EXTENSION_BUDGET). Re-exported here for schema-layer convenience.\n */\n\n// Re-export kernel byte-budget constants for schema-layer consumers\nexport { EXTENSION_BUDGET } from '@peac/kernel';\n\n/**\n * Normative per-field bounds for Wire 0.2 extension group fields.\n */\nexport const EXTENSION_LIMITS = {\n // Extension key grammar\n maxExtensionKeyLength: 512,\n maxDnsLabelLength: 63,\n maxDnsDomainLength: 253,\n\n // Commerce\n maxPaymentRailLength: 128,\n maxCurrencyLength: 16,\n maxAmountMinorLength: 64,\n maxReferenceLength: 256,\n maxAssetLength: 256,\n maxCommerceEventLength: 64,\n\n // Access\n maxResourceLength: 2048,\n maxActionLength: 256,\n\n // Challenge\n maxProblemTypeLength: 2048,\n maxProblemTitleLength: 256,\n maxProblemDetailLength: 4096,\n maxProblemInstanceLength: 2048,\n\n // Identity\n maxProofRefLength: 256,\n\n // Correlation\n maxTraceIdLength: 32,\n maxSpanIdLength: 16,\n maxWorkflowIdLength: 256,\n maxParentJtiLength: 256,\n maxDependsOnLength: 64,\n\n // Consent\n maxConsentBasisLength: 128,\n maxConsentMethodLength: 128,\n maxDataCategoriesCount: 64,\n maxDataCategoryLength: 128,\n maxConsentScopeLength: 256,\n maxJurisdictionLength: 16,\n\n // Compliance\n maxFrameworkLength: 256,\n maxAuditRefLength: 256,\n maxAuditorLength: 256,\n maxComplianceScopeLength: 512,\n\n // Privacy\n maxDataClassificationLength: 128,\n maxProcessingBasisLength: 128,\n maxAnonymizationMethodLength: 128,\n maxDataSubjectCategoryLength: 128,\n maxTransferMechanismLength: 128,\n\n // Safety\n maxAssessmentMethodLength: 256,\n maxSafetyMeasuresCount: 32,\n maxSafetyMeasureLength: 256,\n maxIncidentRefLength: 256,\n maxModelRefLength: 256,\n maxSafetyCategoryLength: 128,\n\n // Provenance\n maxSourceTypeLength: 128,\n maxSourceRefLength: 256,\n maxVerificationMethodLength: 128,\n maxCustodyChainCount: 16,\n maxCustodianLength: 256,\n maxCustodyActionLength: 128,\n maxSlsaTrackLength: 64,\n maxSlsaVersionLength: 16,\n\n // Attribution\n maxCreatorRefLength: 256,\n maxObligationTypeLength: 128,\n maxAttributionTextLength: 1024,\n maxContentSignalSourceLength: 128,\n\n // Purpose\n maxExternalPurposesCount: 32,\n maxExternalPurposeLength: 128,\n maxPurposeBasisLength: 128,\n maxCompatiblePurposesCount: 32,\n\n // Shared field bounds\n maxHttpsUriLength: 2048,\n maxSha256DigestLength: 71, // \"sha256:\" (7) + 64 hex = 71 chars\n maxIso8601DurationLength: 64,\n maxIso8601DateLength: 10,\n maxSpdxExpressionLength: 128,\n} as const;\n","/**\n * Wire 0.2 Extension Key Grammar Validator\n *\n * Validates that extension keys conform to the Wire 0.2 reverse-DNS\n * extension key grammar: `<domain>/<segment>`.\n *\n * Extracted from the monolithic wire-02-extensions.ts for maintainability.\n */\n\nimport { EXTENSION_LIMITS } from './limits.js';\n\n/**\n * DNS label pattern: lowercase alphanumeric, may contain hyphens but not at\n * start or end. Single-char labels are valid (e.g., \"a\").\n */\nconst DNS_LABEL = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;\n\n/**\n * Segment pattern: lowercase alphanumeric start, may contain lowercase\n * alphanumeric, underscores, and hyphens.\n */\nconst SEGMENT_PATTERN = /^[a-z0-9][a-z0-9_-]*$/;\n\n/**\n * Validate that an extension key conforms to the Wire 0.2 extension key\n * grammar: `<domain>/<segment>`.\n *\n * Domain rules:\n * - At least one dot (distinguishes from single-label paths)\n * - Each label matches [a-z0-9]([a-z0-9-]*[a-z0-9])? (lowercase only)\n * - No uppercase letters anywhere in the domain\n *\n * Segment rules:\n * - Matches [a-z0-9][a-z0-9_-]* (lowercase only)\n * - Underscores are permitted (for extension names like credential_event)\n *\n * @param key - Extension key to validate\n * @returns true if valid extension key grammar; false otherwise\n */\nexport function isValidExtensionKey(key: string): boolean {\n if (key.length === 0 || key.length > EXTENSION_LIMITS.maxExtensionKeyLength) return false;\n\n const slashIdx = key.indexOf('/');\n if (slashIdx <= 0) return false;\n\n const domain = key.slice(0, slashIdx);\n const segment = key.slice(slashIdx + 1);\n\n if (!domain.includes('.')) return false;\n if (domain.length > EXTENSION_LIMITS.maxDnsDomainLength) return false;\n\n if (segment.length === 0) return false;\n if (!SEGMENT_PATTERN.test(segment)) return false;\n\n const labels = domain.split('.');\n for (const label of labels) {\n if (label.length === 0 || label.length > EXTENSION_LIMITS.maxDnsLabelLength) return false;\n if (!DNS_LABEL.test(label)) return false;\n }\n\n return true;\n}\n\n/**\n * Escape a single path segment per RFC 6901.\n * '~' -> '~0', '/' -> '~1'\n */\nexport function escapePointerSegment(s: string): string {\n return s.replace(/~/g, '~0').replace(/\\//g, '~1');\n}\n\n/**\n * Build a leaf-precise RFC 6901 JSON Pointer from a group key and Zod\n * issue path.\n *\n * @param groupKey - Extension group key (e.g., 'org.peacprotocol/commerce')\n * @param zodPath - Path array from the first Zod issue\n * @returns RFC 6901 pointer string\n */\nexport function zodPathToPointer(groupKey: string, zodPath: readonly PropertyKey[]): string {\n const escaped = escapePointerSegment(groupKey);\n const segments = zodPath.map((s) => escapePointerSegment(String(s)));\n return `/extensions/${escaped}` + (segments.length > 0 ? '/' + segments.join('/') : '');\n}\n","/**\n * Commerce Extension Group (org.peacprotocol/commerce)\n *\n * Records payment transaction evidence.\n * Shipped in v0.12.0-preview.1.\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\n\nexport const COMMERCE_EXTENSION_KEY = 'org.peacprotocol/commerce' as const;\n\n/** Base-10 integer string: optional leading minus, one or more digits */\nconst AMOUNT_MINOR_PATTERN = /^-?[0-9]+$/;\n\n/**\n * Shared amount_minor string schema. Single source of truth for both\n * CommerceExtensionSchema.shape.amount_minor and isValidAmountMinor().\n */\nexport const AmountMinorStringSchema = z\n .string()\n .min(1)\n .max(EXTENSION_LIMITS.maxAmountMinorLength)\n .regex(\n AMOUNT_MINOR_PATTERN,\n 'amount_minor must be a base-10 integer string (e.g., \"1000\", \"-50\")'\n );\n\n/**\n * Validate an amount_minor string against the commerce extension schema.\n *\n * Uses the same shared schema as CommerceExtensionSchema.shape.amount_minor.\n * Returns true only if the value passes validation. Does not coerce,\n * normalize, or silently accept invalid values.\n *\n * @param value - Candidate amount_minor string\n * @returns true if valid, false otherwise\n */\nexport function isValidAmountMinor(value: unknown): value is string {\n return AmountMinorStringSchema.safeParse(value).success;\n}\n\nexport const CommerceExtensionSchema = z\n .object({\n /** Payment rail identifier (e.g., 'stripe', 'x402', 'lightning') */\n payment_rail: z.string().min(1).max(EXTENSION_LIMITS.maxPaymentRailLength),\n /**\n * Amount in smallest currency unit as a string for arbitrary precision.\n * Base-10 integer: optional leading minus, one or more digits.\n * Decimals and empty strings are rejected.\n */\n amount_minor: AmountMinorStringSchema,\n /** ISO 4217 currency code or asset identifier */\n currency: z.string().min(1).max(EXTENSION_LIMITS.maxCurrencyLength),\n /** Caller-assigned payment reference */\n reference: z.string().max(EXTENSION_LIMITS.maxReferenceLength).optional(),\n /** Asset identifier for non-fiat (e.g., token address) */\n asset: z.string().max(EXTENSION_LIMITS.maxAssetLength).optional(),\n /** Environment discriminant */\n env: z.enum(['live', 'test']).optional(),\n /** Commerce lifecycle phase. Observational metadata only: does not encode settlement finality or protocol state transitions */\n event: z\n .enum(['authorization', 'capture', 'settlement', 'refund', 'void', 'chargeback'])\n .optional(),\n })\n .strict();\n\nexport type CommerceExtension = z.infer<typeof CommerceExtensionSchema>;\n","/**\n * Access Extension Group (org.peacprotocol/access)\n *\n * Records access control decision evidence.\n * Shipped in v0.12.0-preview.1.\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\n\nexport const ACCESS_EXTENSION_KEY = 'org.peacprotocol/access' as const;\n\nexport const AccessExtensionSchema = z\n .object({\n /** Resource being accessed (URI or identifier) */\n resource: z.string().min(1).max(EXTENSION_LIMITS.maxResourceLength),\n /** Action performed on the resource */\n action: z.string().min(1).max(EXTENSION_LIMITS.maxActionLength),\n /** Access decision */\n decision: z.enum(['allow', 'deny', 'review']),\n })\n .strict();\n\nexport type AccessExtension = z.infer<typeof AccessExtensionSchema>;\n","/**\n * Challenge Extension Group (org.peacprotocol/challenge)\n *\n * Records challenge issuance with RFC 9457 Problem Details.\n * Shipped in v0.12.0-preview.1.\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\n\nexport const CHALLENGE_EXTENSION_KEY = 'org.peacprotocol/challenge' as const;\n\n/**\n * Challenge type values (7 total, P0-6).\n * Includes purpose_disallowed (reviewer fix: 7 not 6).\n */\nexport const CHALLENGE_TYPES = [\n 'payment_required',\n 'identity_required',\n 'consent_required',\n 'attestation_required',\n 'rate_limited',\n 'purpose_disallowed',\n 'custom',\n] as const;\n\nexport const ChallengeTypeSchema = z.enum(CHALLENGE_TYPES);\nexport type ChallengeType = z.infer<typeof ChallengeTypeSchema>;\n\n/**\n * RFC 9457 Problem Details schema (P0-5).\n *\n * Uses .passthrough() for extension members per RFC 9457 Section 6.2.\n * Required fields: status (HTTP status code), type (problem type URI).\n * Optional fields: title, detail, instance.\n */\nexport const ProblemDetailsSchema = z\n .object({\n /** HTTP status code (100-599) */\n status: z.number().int().min(100).max(599),\n /** Problem type URI */\n type: z.string().min(1).max(EXTENSION_LIMITS.maxProblemTypeLength).url(),\n /** Short human-readable summary */\n title: z.string().max(EXTENSION_LIMITS.maxProblemTitleLength).optional(),\n /** Human-readable explanation specific to this occurrence */\n detail: z.string().max(EXTENSION_LIMITS.maxProblemDetailLength).optional(),\n /** URI reference identifying the specific occurrence */\n instance: z.string().max(EXTENSION_LIMITS.maxProblemInstanceLength).optional(),\n })\n .passthrough();\n\nexport const ChallengeExtensionSchema = z\n .object({\n /** Challenge type (7 values) */\n challenge_type: ChallengeTypeSchema,\n /** RFC 9457 Problem Details */\n problem: ProblemDetailsSchema,\n /** Resource that triggered the challenge */\n resource: z.string().max(EXTENSION_LIMITS.maxResourceLength).optional(),\n /** Action that triggered the challenge */\n action: z.string().max(EXTENSION_LIMITS.maxActionLength).optional(),\n /** Caller-defined requirements for resolving the challenge */\n requirements: z.record(z.string(), z.unknown()).optional(),\n })\n .strict();\n\nexport type ChallengeExtension = z.infer<typeof ChallengeExtensionSchema>;\n","/**\n * Identity Extension Group (org.peacprotocol/identity)\n *\n * Records identity verification or attestation evidence.\n * Shipped in v0.12.0-preview.1.\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\n\nexport const IDENTITY_EXTENSION_KEY = 'org.peacprotocol/identity' as const;\n\nexport const IdentityExtensionSchema = z\n .object({\n /** Proof reference (opaque string; no actor_binding: top-level actor is sole location) */\n proof_ref: z.string().max(EXTENSION_LIMITS.maxProofRefLength).optional(),\n })\n .strict();\n\nexport type IdentityExtension = z.infer<typeof IdentityExtensionSchema>;\n","/**\n * Correlation Extension Group (org.peacprotocol/correlation)\n *\n * Records workflow correlation and traceability metadata.\n * OpenTelemetry-compatible trace and span IDs.\n * Shipped in v0.12.0-preview.1.\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\n\nexport const CORRELATION_EXTENSION_KEY = 'org.peacprotocol/correlation' as const;\n\n/** OpenTelemetry trace ID: exactly 32 lowercase hex chars */\nconst TRACE_ID_PATTERN = /^[0-9a-f]{32}$/;\n\n/** OpenTelemetry span ID: exactly 16 lowercase hex chars */\nconst SPAN_ID_PATTERN = /^[0-9a-f]{16}$/;\n\nexport const CorrelationExtensionSchema = z\n .object({\n /** OpenTelemetry-compatible trace ID (32 lowercase hex chars) */\n trace_id: z\n .string()\n .length(EXTENSION_LIMITS.maxTraceIdLength)\n .regex(TRACE_ID_PATTERN, 'trace_id must be 32 lowercase hex characters')\n .optional(),\n /** OpenTelemetry-compatible span ID (16 lowercase hex chars) */\n span_id: z\n .string()\n .length(EXTENSION_LIMITS.maxSpanIdLength)\n .regex(SPAN_ID_PATTERN, 'span_id must be 16 lowercase hex characters')\n .optional(),\n /** Workflow identifier */\n workflow_id: z.string().min(1).max(EXTENSION_LIMITS.maxWorkflowIdLength).optional(),\n /** Parent receipt JTI for causal chains */\n parent_jti: z.string().min(1).max(EXTENSION_LIMITS.maxParentJtiLength).optional(),\n /** JTIs this receipt depends on */\n depends_on: z\n .array(z.string().min(1).max(EXTENSION_LIMITS.maxParentJtiLength))\n .max(EXTENSION_LIMITS.maxDependsOnLength)\n .optional(),\n })\n .strict();\n\nexport type CorrelationExtension = z.infer<typeof CorrelationExtensionSchema>;\n","/**\n * Wire 0.2 Shared Validator Schemas\n *\n * Protocol-grade Zod validators for common field patterns reused across\n * multiple extension groups. Consolidated to prevent drift, improve interop,\n * and keep Layer 1 clean.\n *\n * All validators are pure Zod schemas with zero I/O.\n *\n * @see HASH.pattern from @peac/kernel for SHA-256 digest grammar\n * @see PolicyBlockSchema.uri for HTTPS URI hint pattern origin\n */\n\nimport { z } from 'zod';\nimport { HASH } from '@peac/kernel';\n\n// ---------------------------------------------------------------------------\n// SHA-256 Digest (hash-first content references)\n// ---------------------------------------------------------------------------\n\n/**\n * Validates a SHA-256 digest string in the canonical PEAC format.\n *\n * Format: `sha256:<64 lowercase hex chars>`\n * Max length: 71 chars (\"sha256:\" = 7 chars + 64 hex chars = 71 total)\n *\n * Reuses `HASH.pattern` from `@peac/kernel` (same regex used in\n * `PolicyBlockSchema.digest` and `ReceiptRefSchema`).\n *\n * INTEROPERABILITY NOTE: This is a PEAC-internal self-describing digest\n * string grammar. It is NOT the same as:\n * - RFC 9530 `Content-Digest` / `Repr-Digest`, which use structured\n * HTTP fields with base64 encoding (e.g., `sha-256=:base64:`)\n * - RFC 9421 HTTP Message Signatures digest components\n * PEAC digest strings are used within JWS payloads and extension fields,\n * not as HTTP headers. When bridging to HTTP digest headers, adapters\n * (Layer 4+) must convert between formats.\n */\nexport const Sha256DigestSchema = z\n .string()\n .max(71)\n .regex(HASH.pattern, 'must be a valid SHA-256 digest (sha256:<64 lowercase hex>)');\n\n// ---------------------------------------------------------------------------\n// HTTPS URI Hint (locator hints only, SSRF prevention)\n// ---------------------------------------------------------------------------\n\n/**\n * Control character ranges that must not appear in URI hints.\n * Covers C0 controls (U+0000-U+001F) and DEL (U+007F).\n */\nconst CONTROL_CHAR_PATTERN = /[\\x00-\\x1f\\x7f]/;\n\n/**\n * Validates an HTTPS URI hint field.\n *\n * Security hardening beyond basic URL validation:\n * - MUST be https:// scheme (rejects http, ftp, data, javascript, file)\n * - MUST NOT contain embedded credentials (userinfo@)\n * - MUST NOT contain fragment identifiers (#)\n * - MUST NOT contain ASCII control characters (U+0000-U+001F, U+007F)\n * - Max 2048 chars (aligned with POLICY_BLOCK.uriMaxLength)\n *\n * These are locator hints only: callers MUST NOT auto-fetch.\n *\n * NORMATIVE: Localhost and private-network hosts (e.g., 10.x, 192.168.x,\n * localhost) are intentionally accepted at Layer 1 (schema). URI hints\n * are metadata, not fetch targets; restricting to public hosts would\n * break enterprise/internal deployments without improving security at\n * this layer. SSRF prevention is enforced by the non-fetch invariant\n *, not by host filtering in schema validation.\n *\n * Test suite covers: IDN/punycode, IPv6 literals, localhost-style\n * hosts, percent-encoded confusion, and parser ambiguity cases.\n */\nexport const HttpsUriHintSchema = z\n .string()\n .min(1)\n .max(2048)\n .refine(\n (value) => {\n // Reject control characters before URL parsing (prevents parser confusion)\n if (CONTROL_CHAR_PATTERN.test(value)) return false;\n\n // Reject fragments (not meaningful for locator hints)\n if (value.includes('#')) return false;\n\n try {\n const url = new URL(value);\n\n // MUST be https:// only\n if (url.protocol !== 'https:') return false;\n\n // MUST NOT contain embedded credentials\n if (url.username !== '' || url.password !== '') return false;\n\n // MUST have a non-empty hostname\n if (!url.hostname) return false;\n\n return true;\n } catch {\n return false;\n }\n },\n {\n message: 'must be a valid HTTPS URI (no credentials, no fragments, no control characters)',\n }\n );\n\n// ---------------------------------------------------------------------------\n// ISO 8601 Duration (parser-grade, strict)\n// ---------------------------------------------------------------------------\n\n/**\n * ISO 8601 duration component descriptor.\n */\ninterface DurationComponents {\n years: number;\n months: number;\n weeks: number;\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n}\n\n/**\n * Valid date-part designators in canonical order.\n * ISO 8601 requires Y before M before W before D.\n */\nconst DATE_DESIGNATOR_ORDER = ['Y', 'M', 'W', 'D'] as const;\n\n/**\n * Valid time-part designators in canonical order.\n * ISO 8601 requires H before M before S.\n */\nconst TIME_DESIGNATOR_ORDER = ['H', 'M', 'S'] as const;\n\n/**\n * Parse an ISO 8601 duration string into components.\n *\n * Enforces:\n * - No duplicate designators (P1Y2Y rejected)\n * - Canonical component ordering (P1D1Y rejected; must be P1Y1D)\n * - Weeks cannot be combined with other date components (ISO 8601)\n * - At least one component must be present (bare P rejected)\n * - At least one time component after T (bare PT rejected)\n * - Zero-value durations are accepted (P0D, PT0S are valid ISO 8601)\n *\n * Zero durations: P0D and PT0S are valid per ISO 8601. The spec says\n * \"a zero duration\" is representable. Consumers decide if a zero\n * duration is semantically meaningful for their use case.\n *\n * @param value - String to parse\n * @returns Parsed components, or null if invalid\n */\nexport function parseIso8601Duration(value: string): DurationComponents | null {\n if (typeof value !== 'string' || value.length === 0 || value.length > 64) {\n return null;\n }\n\n if (value.charAt(0) !== 'P') return null;\n\n let pos = 1;\n const len = value.length;\n\n // Bare \"P\" is invalid\n if (pos >= len) return null;\n\n const result: DurationComponents = {\n years: 0,\n months: 0,\n weeks: 0,\n days: 0,\n hours: 0,\n minutes: 0,\n seconds: 0,\n };\n\n let inTimePart = false;\n let hasAnyComponent = false;\n\n // Track seen designators to reject duplicates\n const seenDesignators = new Set<string>();\n\n // Track ordering: index into the relevant order array\n let dateOrderIdx = 0;\n let timeOrderIdx = 0;\n\n while (pos < len) {\n if (value.charAt(pos) === 'T') {\n if (inTimePart) return null; // Double T\n inTimePart = true;\n pos++;\n if (pos >= len) return null; // Bare \"PT\"\n continue;\n }\n\n // Parse digits\n const numStart = pos;\n while (pos < len && value.charAt(pos) >= '0' && value.charAt(pos) <= '9') {\n pos++;\n }\n if (pos === numStart) return null; // No digits before designator\n\n const digits = value.slice(numStart, pos);\n // Reject components that would lose precision as JS numbers.\n // Number.MAX_SAFE_INTEGER = 9007199254740991 (16 digits).\n // Duration components beyond this are structurally malformed for any\n // real-world use and would silently truncate.\n if (digits.length > 15) return null;\n const num = parseInt(digits, 10);\n if (!Number.isFinite(num) || num < 0) return null;\n\n if (pos >= len) return null; // No designator after number\n\n const designator = value.charAt(pos);\n pos++;\n\n // Reject duplicate designators\n const designatorKey = (inTimePart ? 'T' : '') + designator;\n if (seenDesignators.has(designatorKey)) return null;\n seenDesignators.add(designatorKey);\n\n if (inTimePart) {\n // Enforce canonical time ordering: H before M before S\n const timeIdx = TIME_DESIGNATOR_ORDER.indexOf(designator as 'H' | 'M' | 'S');\n if (timeIdx === -1) return null; // Invalid time designator\n if (timeIdx < timeOrderIdx) return null; // Out of order\n timeOrderIdx = timeIdx + 1;\n\n switch (designator) {\n case 'H':\n result.hours = num;\n break;\n case 'M':\n result.minutes = num;\n break;\n case 'S':\n result.seconds = num;\n break;\n }\n } else {\n // Enforce canonical date ordering: Y before M before W before D\n const dateIdx = DATE_DESIGNATOR_ORDER.indexOf(designator as 'Y' | 'M' | 'W' | 'D');\n if (dateIdx === -1) return null; // Invalid date designator\n if (dateIdx < dateOrderIdx) return null; // Out of order\n dateOrderIdx = dateIdx + 1;\n\n switch (designator) {\n case 'Y':\n result.years = num;\n break;\n case 'M':\n result.months = num;\n break;\n case 'W':\n result.weeks = num;\n break;\n case 'D':\n result.days = num;\n break;\n }\n }\n\n hasAnyComponent = true;\n }\n\n if (!hasAnyComponent) return null;\n\n // ISO 8601: weeks cannot be combined with other date components\n if (result.weeks > 0 && (result.years > 0 || result.months > 0 || result.days > 0)) {\n return null;\n }\n\n return result;\n}\n\n/**\n * Validates an ISO 8601 duration string.\n *\n * Parser-grade strict validation:\n * - Rejects bare P, bare PT\n * - Rejects duplicate designators (P1Y2Y)\n * - Enforces canonical component ordering (P1D1Y rejected)\n * - Rejects mixed weeks and other date components\n * - Accepts zero-value durations (P0D, PT0S are valid ISO 8601)\n * - Only non-negative integer components (no decimals, no negatives)\n *\n * Examples:\n * Valid: \"P30D\", \"P1Y\", \"P1Y6M\", \"PT1H30M\", \"P1W\", \"P0D\", \"PT0S\"\n * Invalid: \"P\", \"PT\", \"30D\", \"\", \"P1D1Y\", \"P1Y2Y\", \"P1WD3\", \"P-1D\"\n */\nexport const Iso8601DurationSchema = z\n .string()\n .min(2)\n .max(64)\n .refine((value) => parseIso8601Duration(value) !== null, {\n message: 'must be a valid ISO 8601 duration (e.g., P30D, P1Y6M, PT1H30M)',\n });\n\n// ---------------------------------------------------------------------------\n// ISO 8601 Date String (YYYY-MM-DD, structural only)\n// ---------------------------------------------------------------------------\n\n/**\n * Validates a structurally valid ISO 8601 date string (YYYY-MM-DD).\n *\n * Structural validation only: checks 4-digit year, 2-digit month 01-12,\n * 2-digit day 01-31. Does NOT validate calendar correctness (e.g.,\n * Feb 30 or Jun 31 would pass structural check). Calendar validation\n * is left to the application layer since this is an evidence record,\n * not a scheduling system.\n *\n * Named \"StructuralDate\" to avoid implying full calendar validation.\n */\nexport const Iso8601DateStringSchema = z\n .string()\n .length(10)\n .regex(/^\\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\\d|3[01])$/, {\n message: 'must be a structurally valid date string (YYYY-MM-DD)',\n });\n\n/**\n * @deprecated Use Iso8601DateStringSchema. Alias preserved for backward compat.\n */\nexport const Iso8601DateSchema = Iso8601DateStringSchema;\n\n// ---------------------------------------------------------------------------\n// ISO 8601 DateTime with Offset (Zod 4 top-level API)\n// ---------------------------------------------------------------------------\n\n/**\n * Validates an ISO 8601 datetime string with timezone offset.\n *\n * Uses Zod 4 top-level `z.iso.datetime({ offset: true })` (preferred\n * over the deprecated method-style `z.string().datetime()`).\n *\n * This is NOT strictly RFC 3339: it accepts minute-precision timestamps\n * (e.g., `2026-03-14T12:00+05:30` without seconds), which ISO 8601\n * allows but RFC 3339 does not. Use Rfc3339DateTimeSchema for strict\n * RFC 3339 compliance.\n *\n * Consistent with Wire 0.2 `occurred_at` field validation semantics.\n */\nexport const Iso8601OffsetDateTimeSchema = z.iso.datetime({ offset: true });\n\n// ---------------------------------------------------------------------------\n// RFC 3339 DateTime (strict: offset + seconds required, fractional optional)\n// ---------------------------------------------------------------------------\n\n/**\n * RFC 3339 seconds-presence pattern.\n * Matches the `T<HH>:<MM>:<SS>` portion, ensuring seconds are present.\n * Fractional seconds (.nnn) are optional per RFC 3339 Section 5.6.\n */\nconst RFC3339_SECONDS_PATTERN = /T\\d{2}:\\d{2}:\\d{2}/;\n\n/**\n * Validates a datetime string against a practical strict RFC 3339 profile.\n *\n * Enforces the key RFC 3339 Section 5.6 constraints:\n * - Timezone offset always present (Z or +/-HH:MM)\n * - Seconds always present (minute-only timestamps rejected)\n * - Fractional seconds optional (after the seconds component)\n * - No local timestamps\n *\n * This is a practical strict profile, not a proven ABNF implementation.\n * It uses `z.iso.datetime({ offset: true })` as the base (which handles\n * most RFC 3339 grammar) plus a seconds-presence refine. Edge cases\n * like leap seconds or two-digit year forms are not explicitly tested.\n *\n * @see https://www.rfc-editor.org/rfc/rfc3339#section-5.6\n */\nexport const Rfc3339DateTimeSchema = z.iso\n .datetime({ offset: true })\n .refine((value: string) => RFC3339_SECONDS_PATTERN.test(value), {\n message: 'RFC 3339 requires seconds precision (e.g., 2026-03-14T12:00:00Z)',\n });\n\n/**\n * @deprecated Use Iso8601OffsetDateTimeSchema or Rfc3339DateTimeSchema.\n * This alias points to Iso8601OffsetDateTimeSchema (which accepts\n * minute-precision and is therefore NOT strictly RFC 3339). Preserved\n * for backward compatibility only. Remove-not-before: v0.13.0.\n */\nexport const Rfc3339TimestampSchema = Iso8601OffsetDateTimeSchema;\n\n// ---------------------------------------------------------------------------\n// SPDX License Expression (documented structural subset)\n// ---------------------------------------------------------------------------\n\n/**\n * SPDX License Expression validator: documented structural subset.\n *\n * This is a structural subset validator for v0.12.2, NOT full SPDX 3.0.1\n * support. It validates expression grammar without checking license IDs\n * against the SPDX license list.\n *\n * Supported subset:\n * - Simple license IDs: MIT, Apache-2.0, GPL-3.0-only\n * - LicenseRef custom references: LicenseRef-custom\n * - Or-later suffix: GPL-2.0+\n * - Compound expressions: MIT AND Apache-2.0, MIT OR GPL-2.0-only\n * - Exception clauses: Apache-2.0 WITH Classpath-exception-2.0\n * - Parenthesized sub-expressions: (MIT OR Apache-2.0) AND GPL-3.0-only\n *\n * NOT supported (deferred to attribution extension PR, v0.12.2 PR 4):\n * - DocumentRef-*: prefixes (rare in practice; not seen in npm/PyPI/crates.io)\n *\n * @see https://spdx.github.io/spdx-spec/v3.0.1/annexes/spdx-license-expressions/\n */\nfunction isValidSpdxSubsetExpression(expr: string): boolean {\n if (typeof expr !== 'string' || expr.length === 0 || expr.length > 128) {\n return false;\n }\n\n // Tokenize: split on whitespace, preserving parentheses as separate tokens\n const tokens: string[] = [];\n let current = '';\n\n for (let i = 0; i < expr.length; i++) {\n const ch = expr.charAt(i);\n if (ch === '(' || ch === ')') {\n if (current.length > 0) {\n tokens.push(current);\n current = '';\n }\n tokens.push(ch);\n } else if (ch === ' ' || ch === '\\t') {\n if (current.length > 0) {\n tokens.push(current);\n current = '';\n }\n } else {\n current += ch;\n }\n }\n if (current.length > 0) {\n tokens.push(current);\n }\n\n if (tokens.length === 0) return false;\n\n // Recursive-descent parser\n let pos = 0;\n\n function peek(): string | undefined {\n return tokens[pos];\n }\n\n function advance(): string {\n return tokens[pos++];\n }\n\n // license-id: [A-Za-z0-9][A-Za-z0-9.-]* with optional + suffix\n // LicenseRef-: LicenseRef-[A-Za-z0-9.-]+\n function isLicenseId(token: string): boolean {\n const base = token.endsWith('+') ? token.slice(0, -1) : token;\n if (base.length === 0) return false;\n\n if (base.startsWith('LicenseRef-')) {\n const ref = base.slice(11);\n return ref.length > 0 && /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(ref);\n }\n\n return /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(base);\n }\n\n function isExceptionId(token: string): boolean {\n return /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(token);\n }\n\n // expr = term ((AND | OR) term)*\n function parseExpr(): boolean {\n if (!parseTerm()) return false;\n while (pos < tokens.length) {\n const op = peek();\n if (op === 'AND' || op === 'OR') {\n advance();\n if (!parseTerm()) return false;\n } else {\n break;\n }\n }\n return true;\n }\n\n // term = atom (WITH exception-id)?\n function parseTerm(): boolean {\n if (!parseAtom()) return false;\n if (peek() === 'WITH') {\n advance();\n const exception = peek();\n if (exception === undefined || !isExceptionId(exception)) return false;\n advance();\n }\n return true;\n }\n\n // atom = '(' expr ')' | license-id\n function parseAtom(): boolean {\n const token = peek();\n if (token === undefined) return false;\n\n if (token === '(') {\n advance();\n if (!parseExpr()) return false;\n if (peek() !== ')') return false;\n advance();\n return true;\n }\n\n if (token === ')' || token === 'AND' || token === 'OR' || token === 'WITH') {\n return false;\n }\n\n if (!isLicenseId(token)) return false;\n advance();\n return true;\n }\n\n const result = parseExpr();\n return result && pos === tokens.length;\n}\n\n/**\n * Validates an SPDX license expression (documented structural subset).\n *\n * Uses a recursive-descent parser for the supported grammar subset.\n * Does NOT validate against the SPDX license list (structure only).\n * Does NOT support DocumentRef-* prefixes (deferred).\n *\n * @see isValidSpdxSubsetExpression for the supported grammar\n */\nexport const SpdxExpressionSchema = z.string().min(1).max(128).refine(isValidSpdxSubsetExpression, {\n message:\n 'must be a valid SPDX license expression (e.g., MIT, Apache-2.0, MIT AND Apache-2.0). DocumentRef-* not yet supported.',\n});\n\n// ---------------------------------------------------------------------------\n// Exported internals for testing\n// ---------------------------------------------------------------------------\n\n/** @internal Exported for testing only */\nexport { parseIso8601Duration as _parseIso8601Duration };\n\n/** @internal Exported for testing only */\nexport { isValidSpdxSubsetExpression as _isValidSpdxExpression };\n","/**\n * Consent Extension Group (org.peacprotocol/consent)\n *\n * Records consent collection or withdrawal as an observation.\n * Jurisdiction-neutral. Aligned with ISO/IEC 29184:2020 concepts.\n *\n * Design:\n * - Open taxonomy for consent_basis, consent_method (jurisdiction-specific)\n * - Closed enum for consent_status (universal lifecycle states)\n * - URI fields are locator hints only; callers MUST NOT auto-fetch\n * - ISO 8601 durations for retention periods\n * - Observation-only semantics: records events, never enforces policy\n *\n * @see docs/specs/WIRE-0.2.md Section 12.10\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\nimport { HttpsUriHintSchema, Iso8601DurationSchema } from './shared-validators.js';\n\nexport const CONSENT_EXTENSION_KEY = 'org.peacprotocol/consent' as const;\n\n/**\n * Consent status: universal lifecycle states across GDPR Art 7,\n * CCPA Sec 1798.120, LGPD Art 8, ISO/IEC 29184.\n *\n * Closed enum: these 4 states cover all consent lifecycle transitions.\n */\nexport const CONSENT_STATUSES = ['granted', 'withdrawn', 'denied', 'expired'] as const;\nexport const ConsentStatusSchema = z.enum(CONSENT_STATUSES);\nexport type ConsentStatus = z.infer<typeof ConsentStatusSchema>;\n\nexport const ConsentExtensionSchema = z\n .object({\n /**\n * Legal basis identifier for consent.\n * Open string: jurisdictions define different bases\n * (e.g., explicit, implied, opt_out, legitimate_interest, contractual, legal_obligation).\n */\n consent_basis: z.string().min(1).max(EXTENSION_LIMITS.maxConsentBasisLength),\n\n /** Consent lifecycle state (closed vocabulary) */\n consent_status: ConsentStatusSchema,\n\n /**\n * Data categories covered by this consent.\n * Open vocabulary (e.g., personal, sensitive, biometric).\n */\n data_categories: z\n .array(z.string().min(1).max(EXTENSION_LIMITS.maxDataCategoryLength))\n .max(EXTENSION_LIMITS.maxDataCategoriesCount)\n .optional(),\n\n /** Data retention period as ISO 8601 duration. */\n retention_period: Iso8601DurationSchema.optional(),\n\n /**\n * How consent was collected.\n * Open vocabulary (e.g., click_through, double_opt_in, verbal, written).\n */\n consent_method: z.string().min(1).max(EXTENSION_LIMITS.maxConsentMethodLength).optional(),\n\n /**\n * HTTPS URI hint for consent withdrawal.\n * Locator hint only: callers MUST NOT auto-fetch.\n * Rejects non-HTTPS, embedded credentials, fragments, control chars.\n */\n withdrawal_uri: HttpsUriHintSchema.optional(),\n\n /** Free-text scope description */\n scope: z.string().min(1).max(EXTENSION_LIMITS.maxConsentScopeLength).optional(),\n\n /**\n * Jurisdiction code: ISO 3166-1 alpha-2 or composite.\n * Examples: EU, US-CA, BR, GB, DE, JP, IN.\n */\n jurisdiction: z.string().min(1).max(EXTENSION_LIMITS.maxJurisdictionLength).optional(),\n })\n .strict();\n\nexport type ConsentExtension = z.infer<typeof ConsentExtensionSchema>;\n","/**\n * Privacy Extension Group (org.peacprotocol/privacy)\n *\n * Records data classification and handling observations.\n * Aligned with ISO/IEC 27701 concepts.\n *\n * Design:\n * - Open taxonomy for data_classification, processing_basis, methods\n * - Closed enums for retention_mode, recipient_scope (universal categories)\n * - retention_period (ISO 8601 duration) and retention_mode are separate fields\n * to keep duration grammar and non-duration semantics distinct\n * - Observation-only semantics: records events, never enforces policy\n *\n * @see docs/specs/WIRE-0.2.md Section 12.11\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\nimport { Iso8601DurationSchema } from './shared-validators.js';\n\nexport const PRIVACY_EXTENSION_KEY = 'org.peacprotocol/privacy' as const;\n\n/**\n * Retention mode: non-duration retention semantics.\n * Separate from retention_period to keep duration grammar distinct.\n *\n * Closed enum: 3 values cover all non-duration retention patterns.\n */\nexport const RETENTION_MODES = ['time_bound', 'indefinite', 'session_only'] as const;\nexport const RetentionModeSchema = z.enum(RETENTION_MODES);\nexport type RetentionMode = z.infer<typeof RetentionModeSchema>;\n\n/**\n * Recipient scope: aligned with GDPR Art 13-14 disclosure categories.\n *\n * Closed enum: 4 values cover standard data recipient classifications.\n */\nexport const RECIPIENT_SCOPES = ['internal', 'processor', 'third_party', 'public'] as const;\nexport const RecipientScopeSchema = z.enum(RECIPIENT_SCOPES);\nexport type RecipientScope = z.infer<typeof RecipientScopeSchema>;\n\nexport const PrivacyExtensionSchema = z\n .object({\n /**\n * Data classification level.\n * Open taxonomy (e.g., public, internal, confidential, restricted, pii, sensitive_pii).\n */\n data_classification: z.string().min(1).max(EXTENSION_LIMITS.maxDataClassificationLength),\n\n /**\n * Legal basis for data processing.\n * Open vocabulary (e.g., consent, legitimate_interest, contract, legal_obligation).\n */\n processing_basis: z.string().min(1).max(EXTENSION_LIMITS.maxProcessingBasisLength).optional(),\n\n /**\n * Data retention period as ISO 8601 duration.\n * For non-duration retention semantics, use retention_mode instead.\n */\n retention_period: Iso8601DurationSchema.optional(),\n\n /**\n * Retention mode for non-duration semantics.\n * Closed enum: time_bound, indefinite, session_only.\n * When time_bound, retention_period SHOULD also be present.\n */\n retention_mode: RetentionModeSchema.optional(),\n\n /**\n * Data recipient classification.\n * Closed enum aligned with GDPR Art 13-14 disclosure categories.\n */\n recipient_scope: RecipientScopeSchema.optional(),\n\n /**\n * Anonymization or pseudonymization method applied.\n * Open vocabulary (e.g., k_anonymity, differential_privacy, pseudonymization,\n * tokenization, aggregation).\n */\n anonymization_method: z\n .string()\n .min(1)\n .max(EXTENSION_LIMITS.maxAnonymizationMethodLength)\n .optional(),\n\n /**\n * Data subject category.\n * Open vocabulary (e.g., customer, employee, minor, patient, student).\n */\n data_subject_category: z\n .string()\n .min(1)\n .max(EXTENSION_LIMITS.maxDataSubjectCategoryLength)\n .optional(),\n\n /**\n * Cross-border data transfer mechanism.\n * Open vocabulary (e.g., adequacy_decision, scc, bcr, derogation, consent).\n */\n transfer_mechanism: z\n .string()\n .min(1)\n .max(EXTENSION_LIMITS.maxTransferMechanismLength)\n .optional(),\n })\n .strict();\n\nexport type PrivacyExtension = z.infer<typeof PrivacyExtensionSchema>;\n","/**\n * Safety Extension Group (org.peacprotocol/safety)\n *\n * Records safety assessment evidence. Jurisdiction-neutral design.\n * Usage profiles decide when regulatory-specific fields become required.\n *\n * Design:\n * - review_status required (universal assessment lifecycle)\n * - risk_level optional at schema layer; usage profiles may require it\n * - Open taxonomy for assessment_method, safety_measures, category\n * - Observation-only semantics: records events, never enforces policy\n *\n * @see docs/specs/WIRE-0.2.md Section 12.12\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\n\nexport const SAFETY_EXTENSION_KEY = 'org.peacprotocol/safety' as const;\n\n/**\n * Review status: universal safety assessment lifecycle.\n *\n * Closed enum: 4 states cover the assessment lifecycle across\n * EU AI Act, NIST AI RMF, ISO 23894, and general safety review.\n */\nexport const REVIEW_STATUSES = ['reviewed', 'pending', 'flagged', 'not_applicable'] as const;\nexport const ReviewStatusSchema = z.enum(REVIEW_STATUSES);\nexport type ReviewStatus = z.infer<typeof ReviewStatusSchema>;\n\n/**\n * Risk level: converges across EU AI Act Art 6, NIST AI RMF, ISO 23894.\n *\n * Closed enum: 4 risk tiers. Optional at schema level to maintain\n * jurisdiction neutrality; usage profiles may require this field.\n */\nexport const RISK_LEVELS = ['unacceptable', 'high', 'limited', 'minimal'] as const;\nexport const RiskLevelSchema = z.enum(RISK_LEVELS);\nexport type RiskLevel = z.infer<typeof RiskLevelSchema>;\n\nexport const SafetyExtensionSchema = z\n .object({\n /** Safety review status (closed vocabulary, universal lifecycle) */\n review_status: ReviewStatusSchema,\n\n /**\n * Risk classification level.\n * Optional at schema level; usage profiles may require it.\n * Converges across EU AI Act Art 6, NIST AI RMF, ISO 23894.\n */\n risk_level: RiskLevelSchema.optional(),\n\n /**\n * Assessment method used.\n * Open vocabulary (e.g., automated_scan, human_review, red_team,\n * penetration_test, static_analysis, model_evaluation).\n */\n assessment_method: z.string().min(1).max(EXTENSION_LIMITS.maxAssessmentMethodLength).optional(),\n\n /**\n * Safety measures applied.\n * Open vocabulary. Array bounded by maxSafetyMeasuresCount.\n */\n safety_measures: z\n .array(z.string().min(1).max(EXTENSION_LIMITS.maxSafetyMeasureLength))\n .max(EXTENSION_LIMITS.maxSafetyMeasuresCount)\n .optional(),\n\n /** Incident report reference. Opaque identifier (e.g., ticket ID or digest). */\n incident_ref: z.string().min(1).max(EXTENSION_LIMITS.maxIncidentRefLength).optional(),\n\n /** AI model reference. Opaque identifier (e.g., model version string). */\n model_ref: z.string().min(1).max(EXTENSION_LIMITS.maxModelRefLength).optional(),\n\n /**\n * Safety category.\n * Open vocabulary (e.g., content_safety, bias, hallucination,\n * toxicity, fairness, robustness, privacy_risk).\n */\n category: z.string().min(1).max(EXTENSION_LIMITS.maxSafetyCategoryLength).optional(),\n })\n .strict();\n\nexport type SafetyExtension = z.infer<typeof SafetyExtensionSchema>;\n","/**\n * Compliance Extension Group (org.peacprotocol/compliance)\n *\n * Records regulatory compliance check evidence as an observation.\n * Framework-neutral. Does not assert or certify compliance; records\n * that a check occurred, what framework was evaluated, and what the\n * observed outcome was.\n *\n * Design:\n * - Open taxonomy for framework, auditor, scope (domain-specific)\n * - Closed enum for compliance_status (universal audit conclusion categories)\n * - ISO 8601 durations for validity periods\n * - Observation-only semantics: records events, never enforces policy\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\nimport {\n Iso8601DateStringSchema,\n Iso8601DurationSchema,\n Sha256DigestSchema,\n} from './shared-validators.js';\n\nexport const COMPLIANCE_EXTENSION_KEY = 'org.peacprotocol/compliance' as const;\n\n/**\n * Compliance status: maps to ISO 19011 audit conclusion categories.\n *\n * Closed enum: 5 values cover the universal compliance assessment\n * lifecycle across regulatory frameworks.\n */\nexport const COMPLIANCE_STATUSES = [\n 'compliant',\n 'non_compliant',\n 'partial',\n 'under_review',\n 'exempt',\n] as const;\nexport const ComplianceStatusSchema = z.enum(COMPLIANCE_STATUSES);\nexport type ComplianceStatus = z.infer<typeof ComplianceStatusSchema>;\n\nexport const ComplianceExtensionSchema = z\n .object({\n /**\n * Framework identifier evaluated.\n * Open string: preferred grammar is lowercase slugs with hyphens\n * (e.g., eu-ai-act, soc2-type2, iso-27001, nist-ai-rmf, gdpr, hipaa).\n */\n framework: z.string().min(1).max(EXTENSION_LIMITS.maxFrameworkLength),\n\n /** Observed compliance status (closed vocabulary) */\n compliance_status: ComplianceStatusSchema,\n\n /** Opaque reference to audit report or evidence (e.g., report ID, ticket number). */\n audit_ref: z.string().min(1).max(EXTENSION_LIMITS.maxAuditRefLength).optional(),\n\n /** Auditor identifier (organization name or DID). */\n auditor: z.string().min(1).max(EXTENSION_LIMITS.maxAuditorLength).optional(),\n\n /** Date the compliance check was performed (YYYY-MM-DD). */\n audit_date: Iso8601DateStringSchema.optional(),\n\n /** Scope of the compliance check. */\n scope: z.string().min(1).max(EXTENSION_LIMITS.maxComplianceScopeLength).optional(),\n\n /** How long this finding remains valid as an ISO 8601 duration. */\n validity_period: Iso8601DurationSchema.optional(),\n\n /** SHA-256 digest of supporting evidence document. */\n evidence_ref: Sha256DigestSchema.optional(),\n })\n .strict();\n\nexport type ComplianceExtension = z.infer<typeof ComplianceExtensionSchema>;\n","/**\n * Provenance Extension Group (org.peacprotocol/provenance)\n *\n * Records origin tracking and chain of custody as observations.\n *\n * Design:\n * - source_type required, open vocabulary for derivation categories\n * - custody_chain: ordered array of strict nested entries\n * - slsa: structured object recording SLSA-aligned metadata\n * (track-based model; does not certify SLSA compliance)\n * - URI fields are locator hints only; callers MUST NOT auto-fetch\n * - Observation-only semantics: records events, never enforces policy\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\nimport { HttpsUriHintSchema, Rfc3339DateTimeSchema } from './shared-validators.js';\n\nexport const PROVENANCE_EXTENSION_KEY = 'org.peacprotocol/provenance' as const;\n\n// ---------------------------------------------------------------------------\n// Nested schemas\n// ---------------------------------------------------------------------------\n\n/**\n * A single entry in the custody chain.\n *\n * Records one transfer-of-custody event: who held it, what action\n * occurred, and when. Ordered within the custody_chain array.\n */\nexport const CustodyEntrySchema = z\n .object({\n /** Custodian identifier (organization name, DID, or opaque ID). */\n custodian: z.string().min(1).max(EXTENSION_LIMITS.maxCustodianLength),\n\n /** Action performed (e.g., received, transformed, verified, released). */\n action: z.string().min(1).max(EXTENSION_LIMITS.maxCustodyActionLength),\n\n /** When the custody event occurred (RFC 3339 with seconds). */\n timestamp: Rfc3339DateTimeSchema,\n })\n .strict();\n\nexport type CustodyEntry = z.infer<typeof CustodyEntrySchema>;\n\n/**\n * Structured SLSA-aligned provenance metadata.\n *\n * Uses a track-based model rather than a flat scalar.\n * Records metadata; does not certify compliance.\n */\nexport const SlsaLevelSchema = z\n .object({\n /** SLSA track identifier (e.g., build, source). */\n track: z.string().min(1).max(EXTENSION_LIMITS.maxSlsaTrackLength),\n\n /** SLSA level within the track (0-4). */\n level: z.number().int().min(0).max(4),\n\n /** SLSA spec version this metadata references (e.g., 1.0, 1.2). */\n version: z.string().min(1).max(EXTENSION_LIMITS.maxSlsaVersionLength),\n })\n .strict();\n\nexport type SlsaLevel = z.infer<typeof SlsaLevelSchema>;\n\n// ---------------------------------------------------------------------------\n// Main schema\n// ---------------------------------------------------------------------------\n\nexport const ProvenanceExtensionSchema = z\n .object({\n /**\n * Type of source or derivation.\n * Open vocabulary (e.g., original, derived, curated, synthetic, aggregated, transformed).\n */\n source_type: z.string().min(1).max(EXTENSION_LIMITS.maxSourceTypeLength),\n\n /** Opaque source reference identifier (e.g., commit hash, artifact ID). */\n source_ref: z.string().min(1).max(EXTENSION_LIMITS.maxSourceRefLength).optional(),\n\n /**\n * HTTPS URI hint for the source artifact.\n * Locator hint only: callers MUST NOT auto-fetch.\n */\n source_uri: HttpsUriHintSchema.optional(),\n\n /**\n * HTTPS URI hint for build provenance metadata.\n * Locator hint only: callers MUST NOT auto-fetch.\n */\n build_provenance_uri: HttpsUriHintSchema.optional(),\n\n /**\n * How provenance was verified.\n * Open vocabulary (e.g., signature_check, hash_chain,\n * manual_attestation, transparency_log).\n */\n verification_method: z\n .string()\n .min(1)\n .max(EXTENSION_LIMITS.maxVerificationMethodLength)\n .optional(),\n\n /**\n * Ordered custody chain entries.\n * Each entry records a custodian, action, and timestamp.\n */\n custody_chain: z\n .array(CustodyEntrySchema)\n .max(EXTENSION_LIMITS.maxCustodyChainCount)\n .optional(),\n\n /**\n * Structured SLSA-aligned provenance metadata.\n * Records track, level, and spec version.\n */\n slsa: SlsaLevelSchema.optional(),\n })\n .strict();\n\nexport type ProvenanceExtension = z.infer<typeof ProvenanceExtensionSchema>;\n","/**\n * Attribution Extension Group (org.peacprotocol/attribution)\n *\n * Records credit, obligations, and content signal observations.\n *\n * Design:\n * - Identifier and reference-based fields; not identity attestation\n * - Closed enum for content_signal_source (known observation sources)\n * - SPDX license expressions via parser-grade shared validator\n * - Observation-only semantics: records events, never enforces policy\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\nimport { Sha256DigestSchema, SpdxExpressionSchema } from './shared-validators.js';\n\nexport const ATTRIBUTION_EXTENSION_KEY = 'org.peacprotocol/attribution' as const;\n\n/**\n * Content signal observation source.\n *\n * Closed enum: maps to the known observation sources in the\n * content signals precedence chain.\n */\nexport const CONTENT_SIGNAL_SOURCES = [\n 'tdmrep_json',\n 'content_signal_header',\n 'content_usage_header',\n 'robots_txt',\n 'custom',\n] as const;\nexport const ContentSignalSourceSchema = z.enum(CONTENT_SIGNAL_SOURCES);\nexport type ContentSignalSource = z.infer<typeof ContentSignalSourceSchema>;\n\nexport const AttributionExtensionSchema = z\n .object({\n /**\n * Creator identifier (DID, URI, or opaque ID).\n * Not an identity attestation; records observed attribution metadata.\n */\n creator_ref: z.string().min(1).max(EXTENSION_LIMITS.maxCreatorRefLength),\n\n /** SPDX license expression (parser-grade structural subset validator). */\n license_spdx: SpdxExpressionSchema.optional(),\n\n /**\n * Obligation type.\n * Open vocabulary (e.g., attribution_required, share_alike, non_commercial).\n */\n obligation_type: z.string().min(1).max(EXTENSION_LIMITS.maxObligationTypeLength).optional(),\n\n /** Required attribution text. */\n attribution_text: z.string().min(1).max(EXTENSION_LIMITS.maxAttributionTextLength).optional(),\n\n /** Content signal observation source (closed vocabulary). */\n content_signal_source: ContentSignalSourceSchema.optional(),\n\n /** SHA-256 digest of the attributed content. */\n content_digest: Sha256DigestSchema.optional(),\n })\n .strict();\n\nexport type AttributionExtension = z.infer<typeof AttributionExtensionSchema>;\n","/**\n * Purpose Extension Group (org.peacprotocol/purpose)\n *\n * Records external/legal/business purpose declarations as observations.\n * Explicitly separated from PEAC operational purpose tokens\n * (CanonicalPurpose in purpose.ts).\n *\n * Design:\n * - external_purposes: token-based array (machine-safe, bounded, unique)\n * - peac_purpose_mapping: optional bridge to PEAC operational tokens\n * via PURPOSE_TOKEN_REGEX\n * - No prose-heavy fields at schema layer\n * - Observation-only semantics: records events, never enforces policy\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_LIMITS } from './limits.js';\nimport { PURPOSE_TOKEN_REGEX, MAX_PURPOSE_TOKEN_LENGTH } from '../purpose.js';\n\nexport const PURPOSE_EXTENSION_KEY = 'org.peacprotocol/purpose' as const;\n\n/**\n * Machine-safe token schema for purpose label arrays.\n *\n * Reuses PURPOSE_TOKEN_REGEX from purpose.ts for the lexical grammar\n * (lowercase alphanumeric, underscores, hyphens, optional vendor prefix).\n * Semantically independent from PEAC operational CanonicalPurpose tokens.\n */\nconst MachineSafePurposeTokenSchema = z\n .string()\n .min(1)\n .max(EXTENSION_LIMITS.maxExternalPurposeLength)\n .regex(PURPOSE_TOKEN_REGEX, 'must be a machine-safe lowercase token');\n\n/**\n * Check that all items in a string array are unique.\n */\nfunction hasUniqueItems(items: string[]): boolean {\n return new Set(items).size === items.length;\n}\n\nexport const PurposeExtensionSchema = z\n .object({\n /**\n * External/legal/business purpose labels.\n * Machine-safe tokens: lowercase alphanumeric with underscores, hyphens,\n * and optional vendor prefix (e.g., ai_training, analytics, marketing).\n * Not PEAC operational tokens; use peac_purpose_mapping for bridging.\n * Items must be unique.\n */\n external_purposes: z\n .array(MachineSafePurposeTokenSchema)\n .min(1)\n .max(EXTENSION_LIMITS.maxExternalPurposesCount)\n .refine(hasUniqueItems, { message: 'external_purposes must contain unique items' }),\n\n /**\n * Legal or policy basis for the declared purposes.\n * Open vocabulary (e.g., consent, legitimate_interest, contract).\n */\n purpose_basis: z.string().min(1).max(EXTENSION_LIMITS.maxPurposeBasisLength).optional(),\n\n /** Whether purpose limitation applies. */\n purpose_limitation: z.boolean().optional(),\n\n /** Whether data minimization was applied. */\n data_minimization: z.boolean().optional(),\n\n /**\n * Compatible purposes for secondary use.\n * Same machine-safe token grammar as external_purposes.\n * Items must be unique.\n */\n compatible_purposes: z\n .array(MachineSafePurposeTokenSchema)\n .max(EXTENSION_LIMITS.maxCompatiblePurposesCount)\n .refine(hasUniqueItems, { message: 'compatible_purposes must contain unique items' })\n .optional(),\n\n /**\n * Explicit mapping to a PEAC operational CanonicalPurpose token.\n * Validated against PURPOSE_TOKEN_REGEX from purpose.ts.\n * Bridges external purpose vocabulary to operational tokens.\n */\n peac_purpose_mapping: z\n .string()\n .min(1)\n .max(MAX_PURPOSE_TOKEN_LENGTH)\n .regex(PURPOSE_TOKEN_REGEX, 'must be a valid PEAC purpose token')\n .optional(),\n })\n .strict();\n\nexport type PurposeExtension = z.infer<typeof PurposeExtensionSchema>;\n","/**\n * Wire 0.2 Extension Schema Map\n *\n * Maps known extension group keys to their Zod schemas.\n * Used by validateKnownExtensions() for group-level validation\n * and by type-to-extension enforcement.\n *\n * This file is the single mutation point for group registration.\n */\n\nimport type { z } from 'zod';\n\nimport { COMMERCE_EXTENSION_KEY, CommerceExtensionSchema } from './commerce.js';\nimport { ACCESS_EXTENSION_KEY, AccessExtensionSchema } from './access.js';\nimport { CHALLENGE_EXTENSION_KEY, ChallengeExtensionSchema } from './challenge.js';\nimport { IDENTITY_EXTENSION_KEY, IdentityExtensionSchema } from './identity.js';\nimport { CORRELATION_EXTENSION_KEY, CorrelationExtensionSchema } from './correlation.js';\nimport { CONSENT_EXTENSION_KEY, ConsentExtensionSchema } from './consent.js';\nimport { PRIVACY_EXTENSION_KEY, PrivacyExtensionSchema } from './privacy.js';\nimport { SAFETY_EXTENSION_KEY, SafetyExtensionSchema } from './safety.js';\nimport { COMPLIANCE_EXTENSION_KEY, ComplianceExtensionSchema } from './compliance.js';\nimport { PROVENANCE_EXTENSION_KEY, ProvenanceExtensionSchema } from './provenance.js';\nimport { ATTRIBUTION_EXTENSION_KEY, AttributionExtensionSchema } from './attribution.js';\nimport { PURPOSE_EXTENSION_KEY, PurposeExtensionSchema } from './purpose-extension.js';\n\n/** Map from known extension key to its Zod schema */\nexport const EXTENSION_SCHEMA_MAP = new Map<string, z.ZodTypeAny>();\nEXTENSION_SCHEMA_MAP.set(COMMERCE_EXTENSION_KEY, CommerceExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(ACCESS_EXTENSION_KEY, AccessExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(CHALLENGE_EXTENSION_KEY, ChallengeExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(IDENTITY_EXTENSION_KEY, IdentityExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(CORRELATION_EXTENSION_KEY, CorrelationExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(CONSENT_EXTENSION_KEY, ConsentExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(PRIVACY_EXTENSION_KEY, PrivacyExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(SAFETY_EXTENSION_KEY, SafetyExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(COMPLIANCE_EXTENSION_KEY, ComplianceExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(PROVENANCE_EXTENSION_KEY, ProvenanceExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(ATTRIBUTION_EXTENSION_KEY, AttributionExtensionSchema);\nEXTENSION_SCHEMA_MAP.set(PURPOSE_EXTENSION_KEY, PurposeExtensionSchema);\n","/**\n * Wire 0.2 Extension Validation (envelope-level superRefine helper)\n *\n * Validates the extensions record inside Wire02ClaimsSchema.superRefine():\n * 1. Extension key grammar validation\n * 2. Recursive plain-JSON-value guard (rejects non-JSON-safe values)\n * 3. Known extension group schema validation\n * 4. Byte-budget enforcement\n *\n * NORMATIVE: Extension group values MUST be plain JSON values all the\n * way down (objects, arrays, strings, finite numbers, booleans, null).\n * Arbitrary JavaScript objects (functions, Symbols, Dates, BigInt,\n * objects with toJSON(), circular references, non-finite numbers, etc.)\n * are not a supported input class and are rejected at the validation\n * boundary via E_EXTENSION_NON_JSON_VALUE. This ensures cross-language\n * portability and reproducible byte-budget measurement.\n *\n * MEASUREMENT BASIS: Byte budgets are measured as the UTF-8 byte length\n * of ECMAScript JSON.stringify() output on plain JSON data. This is\n * explicitly ECMAScript-defined, not language-neutral canonical JSON.\n * Equivalent objects with different member order can yield different\n * byte counts; if cross-language reproducibility is needed in the\n * future, a canonical JSON profile (e.g., JCS / RFC 8785) can be\n * adopted via a future DD without changing the budget constants.\n * See EXTENSION_BUDGET in @peac/kernel for the full specification.\n *\n * Schema does NOT emit warnings (unknown_extension_preserved belongs\n * in @peac/protocol.verifyLocal(), Layer 3).\n *\n * Layer 1 (@peac/schema): pure Zod validation, zero I/O.\n */\n\nimport { z } from 'zod';\nimport { EXTENSION_BUDGET, ERROR_CODES as KERNEL_ERROR_CODES } from '@peac/kernel';\nimport { ERROR_CODES } from '../errors.js';\nimport { isValidExtensionKey } from './grammar.js';\nimport { EXTENSION_SCHEMA_MAP } from './schema-map.js';\n\n// ---------------------------------------------------------------------------\n// UTF-8 byte measurement (browser-safe, no Buffer dependency)\n// ---------------------------------------------------------------------------\n\n/** Shared TextEncoder instance (Layer 1 safe: no I/O, no fetch) */\nconst textEncoder = new TextEncoder();\n\n/**\n * Measure UTF-8 byte length of a JSON-serialized value.\n *\n * Returns Infinity if serialization fails (circular references, BigInt,\n * etc.). Callers treat Infinity as over-budget, which produces a clear\n * E_EXTENSION_SIZE_EXCEEDED error.\n */\nfunction jsonUtf8ByteLength(value: unknown): number {\n try {\n return textEncoder.encode(JSON.stringify(value)).byteLength;\n } catch {\n return Infinity;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Recursive plain-JSON-value guard\n// ---------------------------------------------------------------------------\n\n/**\n * Maximum recursion depth for the plain-JSON guard. Prevents stack\n * overflow on pathologically deep but structurally valid JSON trees.\n * 64 levels deep is far beyond any reasonable extension group shape.\n */\nconst MAX_JSON_GUARD_DEPTH = 64;\n\n/**\n * Recursively check whether a value is a plain JSON value.\n *\n * A plain JSON value is one of:\n * - null\n * - boolean\n * - finite number (NaN, Infinity, -Infinity rejected)\n * - string\n * - plain array where every element is a plain JSON value\n * - plain object (prototype === Object.prototype or null, no toJSON)\n * where every own enumerable value is a plain JSON value\n *\n * Rejects:\n * - Functions, Symbols, BigInt, undefined\n * - Non-finite numbers (NaN, Infinity, -Infinity)\n * - Date, RegExp, Map, Set, TypedArray, Error, Promise\n * - Objects with toJSON() methods (non-reproducible serialization)\n * - Any object with a non-plain prototype\n * - Circular references (detected via depth limit + seen set)\n *\n * @param value - Value to check\n * @param depth - Current recursion depth (bounded by MAX_JSON_GUARD_DEPTH)\n * @param seen - WeakSet for circular reference detection\n * @returns true if the value is a plain JSON value all the way down\n */\nfunction isPlainJsonValueRecursive(value: unknown, depth: number, seen: WeakSet<object>): boolean {\n // Depth guard: reject pathologically deep structures\n if (depth > MAX_JSON_GUARD_DEPTH) return false;\n\n // Primitives\n if (value === null) return true;\n const t = typeof value;\n if (t === 'string' || t === 'boolean') return true;\n if (t === 'number') return Number.isFinite(value as number);\n if (t === 'function' || t === 'symbol' || t === 'bigint' || t === 'undefined') return false;\n\n // Must be an object type from here\n if (t !== 'object') return false;\n const obj = value as object;\n\n // Reference cycle / shared-reference detection.\n // Intentionally rejects shared-but-acyclic subobjects (same JS reference\n // appearing in two places). JSON has no concept of object identity;\n // extensions must be JSON trees, not arbitrary JS object graphs. If the\n // same object appears twice, JSON.stringify would serialize it twice\n // (inflating byte count), and the data model is ambiguous. Rejecting\n // shared references ensures the extension tree matches a true JSON tree.\n if (seen.has(obj)) return false;\n seen.add(obj);\n\n // Array: recursively check every element\n if (Array.isArray(obj)) {\n for (let i = 0; i < obj.length; i++) {\n if (!isPlainJsonValueRecursive(obj[i], depth + 1, seen)) return false;\n }\n return true;\n }\n\n // Must be a plain object (no exotic prototype, no toJSON)\n const proto = Object.getPrototypeOf(obj);\n if (proto !== Object.prototype && proto !== null) return false;\n if (typeof (obj as Record<string, unknown>).toJSON === 'function') return false;\n\n // Recursively check every own enumerable value\n const keys = Object.keys(obj);\n for (const key of keys) {\n if (!isPlainJsonValueRecursive((obj as Record<string, unknown>)[key], depth + 1, seen)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Check whether a value is a plain JSON value all the way down.\n *\n * This is the public entry point for the recursive guard. It initializes\n * the depth counter and circular-reference detection set.\n *\n * @param value - Value to check\n * @returns true if the entire value tree is plain JSON\n */\nfunction isPlainJsonValue(value: unknown): boolean {\n return isPlainJsonValueRecursive(value, 0, new WeakSet());\n}\n\n// ---------------------------------------------------------------------------\n// Envelope-level extension validation\n// ---------------------------------------------------------------------------\n\n/**\n * Validate extensions record in Wire02ClaimsSchema.superRefine().\n *\n * Steps:\n * 1. Validate extension key grammar\n * 2. Recursive guard: reject non-plain-JSON values (E_EXTENSION_NON_JSON_VALUE)\n * 3. Validate known extension groups against their Zod schemas\n * 4. Unconditional byte-budget enforcement\n *\n * @param extensions - The extensions record from Wire 0.2 claims\n * @param ctx - Zod refinement context\n */\nexport function validateKnownExtensions(\n extensions: Record<string, unknown> | undefined,\n ctx: z.RefinementCtx\n): void {\n if (extensions === undefined) return;\n\n const keys = Object.keys(extensions);\n\n for (const key of keys) {\n // Step 1: Validate extension key grammar\n if (!isValidExtensionKey(key)) {\n ctx.addIssue({\n code: 'custom',\n message: ERROR_CODES.E_INVALID_EXTENSION_KEY,\n path: ['extensions', key],\n });\n continue;\n }\n\n // Step 2: Recursive plain-JSON guard\n if (!isPlainJsonValue(extensions[key])) {\n ctx.addIssue({\n code: 'custom',\n message: KERNEL_ERROR_CODES.E_EXTENSION_NON_JSON_VALUE,\n path: ['extensions', key],\n });\n continue;\n }\n\n // Step 3: Validate known extension groups against their schemas\n const schema = EXTENSION_SCHEMA_MAP.get(key);\n if (schema !== undefined) {\n const result = schema.safeParse(extensions[key]);\n if (!result.success) {\n const firstIssue = result.error.issues[0];\n const issuePath: PropertyKey[] = firstIssue?.path ?? [];\n ctx.addIssue({\n code: 'custom',\n message: firstIssue?.message ?? 'Invalid extension value',\n path: ['extensions', key, ...issuePath],\n });\n }\n }\n }\n\n // Step 4: Byte-budget enforcement (unconditional)\n const totalBytes = jsonUtf8ByteLength(extensions);\n if (totalBytes > EXTENSION_BUDGET.maxTotalBytes) {\n ctx.addIssue({\n code: 'custom',\n message: KERNEL_ERROR_CODES.E_EXTENSION_SIZE_EXCEEDED,\n path: ['extensions'],\n });\n return;\n }\n\n for (const key of keys) {\n const groupBytes = jsonUtf8ByteLength(extensions[key]);\n if (groupBytes > EXTENSION_BUDGET.maxGroupBytes) {\n ctx.addIssue({\n code: 'custom',\n message: KERNEL_ERROR_CODES.E_EXTENSION_SIZE_EXCEEDED,\n path: ['extensions', key],\n });\n }\n }\n}\n\n// Exported for testing only\nexport { isPlainJsonValue as _isPlainJsonValue };\n","/**\n * Wire 0.2 Zod schemas and types (v0.12.0-preview.1)\n *\n * This file contains:\n * - Wire02ClaimsSchema: the canonical Zod schema for Wire 0.2 envelopes\n * - Wire02Claims: inferred TypeScript type (z.infer<typeof Wire02ClaimsSchema>)\n * - Supporting schemas: EvidencePillarSchema, PillarsSchema, Wire02KindSchema,\n * ReceiptTypeSchema, CanonicalIssSchema, PolicyBlockSchema\n * - isCanonicalIss(): exported canonical-iss validator\n * - isValidReceiptType(): exported type-grammar validator\n * - checkOccurredAtSkew(): cross-field skew check helper\n *\n * Wire02Claims does NOT live in @peac/kernel (layer violation);\n * it lives here because it references schema-layer types (Correction 4).\n */\n\nimport { z } from 'zod';\nimport {\n ISS_CANONICAL,\n TYPE_GRAMMAR,\n POLICY_BLOCK,\n OCCURRED_AT_TOLERANCE_SECONDS,\n HASH,\n} from '@peac/kernel';\nimport type { EvidencePillar, VerificationWarning } from '@peac/kernel';\nimport { ActorBindingSchema } from './actor-binding.js';\nimport { Wire02RepresentationFieldsSchema } from './wire-02-representation.js';\nimport { validateKnownExtensions } from './wire-02-extensions.js';\n\n// ---------------------------------------------------------------------------\n// Private helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Check that an array is sorted in ascending order with no duplicates.\n * Used to validate the pillars array.\n */\nfunction isSortedAndUnique(arr: readonly string[]): boolean {\n for (let i = 1; i < arr.length; i++) {\n if (arr[i] <= arr[i - 1]) return false;\n }\n return true;\n}\n\n// ---------------------------------------------------------------------------\n// isCanonicalIss (exported helper)\n// ---------------------------------------------------------------------------\n\n/**\n * Validate that an issuer (iss) claim is in canonical form.\n *\n * Accepted schemes:\n * - `https://`: ASCII origin (lowercase scheme+host, no explicit default port\n * (:443 rejected), origin-only, no path/query/fragment/userinfo).\n * Raw Unicode hosts are rejected; punycode (xn--...) is accepted.\n * - `did:`: DID Core identifier (`did:<method>:<id>`) where method is\n * `[a-z0-9]+` and the method-specific-id contains no `#`, `?`, or `/`.\n *\n * All other schemes produce E_ISS_NOT_CANONICAL.\n *\n * @param iss - Issuer claim value to validate\n * @returns true if canonical form; false otherwise\n */\nexport function isCanonicalIss(iss: string): boolean {\n if (typeof iss !== 'string' || iss.length === 0 || iss.length > ISS_CANONICAL.maxLength) {\n return false;\n }\n\n // did: branch: check before URL parsing (did: is a valid URL scheme in some parsers)\n if (iss.startsWith('did:')) {\n // did:<method>:<method-specific-id>\n // Method: lowercase letters and digits only ([a-z0-9]+)\n // Method-specific-id: non-empty, no literal '/', '?', or '#'\n return /^did:[a-z0-9]+:[^#?/]+$/.test(iss);\n }\n\n // https:// branch: try URL constructor for comprehensive validation\n try {\n const url = new URL(iss);\n\n // Must be https: scheme only\n if (url.protocol !== 'https:') return false;\n\n // Non-empty host required\n if (!url.hostname) return false;\n\n // No userinfo (credentials in origins are a security risk)\n if (url.username !== '' || url.password !== '') return false;\n\n // Reconstruct canonical origin (URL spec normalizes hostname to lowercase\n // and removes the default port 443 from url.host).\n // Exact match rejects: uppercase host, trailing slash, default port (:443),\n // path, query, fragment, userinfo, raw Unicode hostname.\n const origin = `${url.protocol}//${url.host}`;\n return iss === origin;\n } catch {\n return false;\n }\n}\n\n// ---------------------------------------------------------------------------\n// isValidReceiptType (exported helper)\n// ---------------------------------------------------------------------------\n\n/** Absolute URI pattern: scheme followed by '://' (RFC 3986 generic-URI) */\nconst ABS_URI_PATTERN = /^[a-z][a-z0-9+.-]*:\\/\\//;\n\n/**\n * Validate that a type claim conforms to the Wire 0.2 type grammar.\n *\n * Accepted forms:\n * - Reverse-DNS notation: `<domain>/<segment>` where `<domain>` has at\n * least one dot (e.g., `org.peacprotocol/commerce`, `com.example/flow`)\n * - Absolute URI: starts with `scheme://` (e.g., `https://example.com/type`)\n *\n * @param value - Type claim value to validate\n * @returns true if valid type grammar; false otherwise\n */\nexport function isValidReceiptType(value: string): boolean {\n if (value.length === 0 || value.length > TYPE_GRAMMAR.maxLength) return false;\n\n // Absolute URI form\n if (ABS_URI_PATTERN.test(value)) return true;\n\n // Reverse-DNS form: <domain>/<segment>\n const slashIdx = value.indexOf('/');\n if (slashIdx <= 0) return false; // no slash, or slash at position 0\n\n const domain = value.slice(0, slashIdx);\n const segment = value.slice(slashIdx + 1);\n\n // Domain must have at least one dot (distinguishes from single-label paths)\n if (!domain.includes('.')) return false;\n\n // Segment must be non-empty\n if (segment.length === 0) return false;\n\n // Domain: letters, digits, dots, hyphens; must start with alphanumeric\n if (!/^[a-zA-Z0-9][a-zA-Z0-9.-]*$/.test(domain)) return false;\n\n // Segment: letters, digits, hyphens, underscores, dots.\n // Additional slashes are NOT permitted in the reverse-DNS form; use an\n // absolute URI (handled by ABS_URI_PATTERN above) for multi-segment paths.\n if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(segment)) return false;\n\n return true;\n}\n\n// ---------------------------------------------------------------------------\n// EvidencePillar schema (closed 10-value taxonomy)\n// ---------------------------------------------------------------------------\n\n/** All 10 registered pillar values in ascending lexicographic order */\nconst EVIDENCE_PILLARS: readonly EvidencePillar[] = [\n 'access',\n 'attribution',\n 'commerce',\n 'compliance',\n 'consent',\n 'identity',\n 'privacy',\n 'provenance',\n 'purpose',\n 'safety',\n];\n\nexport const EvidencePillarSchema = z.enum(\n EVIDENCE_PILLARS as [EvidencePillar, ...EvidencePillar[]]\n);\n\n// ---------------------------------------------------------------------------\n// PillarsSchema (non-empty array, sorted + unique)\n// ---------------------------------------------------------------------------\n\nexport const PillarsSchema = z\n .array(EvidencePillarSchema)\n .min(1)\n .superRefine((arr, ctx) => {\n if (!isSortedAndUnique(arr)) {\n ctx.addIssue({\n code: 'custom',\n message: 'E_PILLARS_NOT_SORTED',\n });\n }\n });\n\n// ---------------------------------------------------------------------------\n// Wire02KindSchema\n// ---------------------------------------------------------------------------\n\nexport const Wire02KindSchema = z.enum(['evidence', 'challenge']);\n\n// ---------------------------------------------------------------------------\n// ReceiptTypeSchema\n// ---------------------------------------------------------------------------\n\nexport const ReceiptTypeSchema = z.string().max(TYPE_GRAMMAR.maxLength).refine(isValidReceiptType, {\n message: 'type must be reverse-DNS notation (e.g., org.example/flow) or an absolute URI',\n});\n\n// ---------------------------------------------------------------------------\n// CanonicalIssSchema\n// ---------------------------------------------------------------------------\n\nexport const CanonicalIssSchema = z.string().max(ISS_CANONICAL.maxLength).refine(isCanonicalIss, {\n message: 'E_ISS_NOT_CANONICAL',\n});\n\n// ---------------------------------------------------------------------------\n// PolicyBlockSchema\n// ---------------------------------------------------------------------------\n\nexport const PolicyBlockSchema = z.object({\n /** JCS+SHA-256 digest: 'sha256:<64 lowercase hex>' */\n digest: z.string().regex(HASH.pattern, 'digest must be sha256:<64 lowercase hex>'),\n /**\n * HTTPS locator hint for the policy document.\n * MUST be an https:// URL (max 2048 chars).\n * MUST NOT trigger auto-fetch; callers use this as a hint only.\n */\n uri: z\n .string()\n .max(POLICY_BLOCK.uriMaxLength)\n .url()\n .refine((u) => u.startsWith('https://'), 'policy.uri must be an https:// URL')\n .optional(),\n /** Caller-assigned version label (max 256 chars) */\n version: z.string().max(POLICY_BLOCK.versionMaxLength).optional(),\n});\n\n// RepresentationFieldsSchema: see wire-02-representation.ts (PR 15)\n\n// ---------------------------------------------------------------------------\n// Wire02ClaimsSchema\n// ---------------------------------------------------------------------------\n\nexport const Wire02ClaimsSchema = z\n .object({\n /** Wire format version discriminant; always '0.2' for Wire 0.2 */\n peac_version: z.literal('0.2'),\n /** Structural kind: 'evidence' or 'challenge' */\n kind: Wire02KindSchema,\n /** Open semantic type (reverse-DNS or absolute URI) */\n type: ReceiptTypeSchema,\n /** Canonical issuer (https:// ASCII origin or did: identifier) */\n iss: CanonicalIssSchema,\n /** Issued-at time (Unix seconds). REQUIRED. */\n iat: z.number().int(),\n /** Unique receipt identifier; 1 to 256 chars */\n jti: z.string().min(1).max(256),\n /** Subject identifier; max 2048 chars */\n sub: z.string().max(2048).optional(),\n /** Evidence pillars (closed 10-value taxonomy); sorted ascending, unique */\n pillars: PillarsSchema.optional(),\n /** Top-level actor binding (sole location for ActorBinding in Wire 0.2) */\n actor: ActorBindingSchema.optional(),\n /** Policy binding block */\n policy: PolicyBlockSchema.optional(),\n /** Representation fields: FingerprintRef validation, sha256-only, strict */\n representation: Wire02RepresentationFieldsSchema.optional(),\n /** ISO 8601 / RFC 3339 timestamp when the interaction occurred; evidence kind only */\n occurred_at: z.string().datetime({ offset: true }).optional(),\n /** Declared purpose string; max 256 chars */\n purpose_declared: z.string().max(256).optional(),\n /** Extension groups (open; known group keys validated by group schema) */\n extensions: z.record(z.string(), z.unknown()).optional(),\n })\n .superRefine((data, ctx) => {\n // occurred_at is prohibited on challenge-kind receipts\n if (data.kind === 'challenge' && data.occurred_at !== undefined) {\n ctx.addIssue({\n code: 'custom',\n message: 'E_OCCURRED_AT_ON_CHALLENGE',\n });\n }\n // Validate known extension groups + reject malformed key grammar\n validateKnownExtensions(data.extensions, ctx);\n })\n .strict();\n\n/** Inferred type for Wire 0.2 receipt claims */\nexport type Wire02Claims = z.infer<typeof Wire02ClaimsSchema>;\n\n// ---------------------------------------------------------------------------\n// checkOccurredAtSkew (Correction 5)\n// ---------------------------------------------------------------------------\n\n/**\n * Check the occurred_at field for temporal consistency.\n *\n * Rules (evidence kind only; caller must not call for challenge kind):\n * - If occurred_at > now + tolerance: hard error (E_OCCURRED_AT_FUTURE)\n * - If occurred_at > iat (within tolerance): warning (occurred_at_skew)\n * - If occurred_at <= iat: valid, no warning\n * - If occurred_at is undefined: no check performed\n *\n * @param occurredAt - Value of the occurred_at claim, or undefined\n * @param iat - iat claim value (Unix seconds)\n * @param now - Current time (Unix seconds)\n * @param tolerance - Allowed future skew in seconds (default: OCCURRED_AT_TOLERANCE_SECONDS)\n * @returns 'future_error' for hard error, VerificationWarning for skew warning, null for valid\n */\nexport function checkOccurredAtSkew(\n occurredAt: string | undefined,\n iat: number,\n now: number,\n tolerance: number = OCCURRED_AT_TOLERANCE_SECONDS\n): VerificationWarning | 'future_error' | null {\n if (occurredAt === undefined) return null;\n\n const ts = Date.parse(occurredAt) / 1000;\n if (isNaN(ts)) return null; // unparseable; parse error surfaces from schema validation\n\n if (ts > now + tolerance) return 'future_error';\n\n if (ts > iat) {\n return {\n code: 'occurred_at_skew',\n message: 'occurred_at is after iat',\n pointer: '/occurred_at',\n };\n }\n\n return null;\n}\n","/**\n * Unified Receipt Parser\n *\n * Single entry point for classifying and validating receipt claims.\n * Supports Wire 0.1 (commerce and attestation) and Wire 0.2 receipts.\n *\n * Wire 0.1 classification uses key presence ('amt' in obj), NOT truthy values.\n * If any of amt|cur|payment are present, the receipt is classified as commerce.\n * If commerce validation fails, it returns a commerce error -- never falls\n * through to attestation.\n *\n * Wire 0.2 detection uses the peac_version field (value '0.2').\n */\n\nimport { ZodError } from 'zod';\nimport type { VerificationWarning } from '@peac/kernel';\nimport { ReceiptClaimsSchema, type ReceiptClaimsType } from './validators.js';\nimport {\n AttestationReceiptClaimsSchema,\n type AttestationReceiptClaims,\n} from './attestation-receipt.js';\nimport { Wire02ClaimsSchema, type Wire02Claims } from './wire-02-envelope.js';\n\n/**\n * Receipt variant discriminator for Wire 0.1\n */\nexport type ReceiptVariant = 'commerce' | 'attestation' | 'wire-02';\n\n/**\n * Parse error with canonical error code\n */\nexport interface PEACParseError {\n /** Canonical error code from specs/kernel/errors.json */\n code: string;\n /** Human-readable message */\n message: string;\n /** Zod issues (if schema validation failed) */\n issues?: ZodError['issues'];\n}\n\n/**\n * Successful parse result (v0.12.0-preview.1: adds wireVersion and warnings)\n */\nexport interface ParseSuccess {\n ok: true;\n variant: ReceiptVariant;\n /** Wire version of the parsed receipt */\n wireVersion: '0.1' | '0.2';\n /** Verification warnings collected during parsing (Wire 0.1: always []) */\n warnings: VerificationWarning[];\n claims: ReceiptClaimsType | AttestationReceiptClaims | Wire02Claims;\n}\n\n/**\n * Failed parse result\n */\nexport interface ParseFailure {\n ok: false;\n error: PEACParseError;\n}\n\n/**\n * Parse result type\n */\nexport type ParseReceiptResult = ParseSuccess | ParseFailure;\n\n/**\n * Options for parseReceiptClaims\n */\nexport interface ParseReceiptOptions {\n /** Wire version hint; if provided, skips auto-detection */\n wireVersion?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Wire version detection\n// ---------------------------------------------------------------------------\n\n/**\n * Detect the wire version of a receipt payload.\n *\n * Wire 0.2 receipts contain a `peac_version: '0.2'` field.\n * Wire 0.1 receipts have no `peac_version` field.\n *\n * @param obj - Raw claims object\n * @returns '0.2' if Wire 0.2, '0.1' if Wire 0.1, null if indeterminate\n */\nexport function detectWireVersion(obj: unknown): '0.1' | '0.2' | null {\n if (obj === null || obj === undefined || typeof obj !== 'object' || Array.isArray(obj)) {\n return null;\n }\n const record = obj as Record<string, unknown>;\n if (record.peac_version === '0.2') return '0.2';\n if ('peac_version' in record) return null; // peac_version present but not '0.2'\n return '0.1';\n}\n\n// ---------------------------------------------------------------------------\n// Wire 0.1 helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Classify a Wire 0.1 claims object as commerce or attestation.\n *\n * Uses key presence (not truthiness). If ANY of amt, cur, payment\n * are present as keys, the receipt is classified as commerce.\n */\nfunction classifyWire01Receipt(obj: Record<string, unknown>): 'commerce' | 'attestation' {\n if ('amt' in obj || 'cur' in obj || 'payment' in obj) {\n return 'commerce';\n }\n return 'attestation';\n}\n\n// ---------------------------------------------------------------------------\n// Main parser\n// ---------------------------------------------------------------------------\n\n/**\n * Parse and validate receipt claims.\n *\n * Unified entry point for Wire 0.1 (commerce + attestation) and Wire 0.2\n * receipt validation. Wire version is auto-detected from the `peac_version`\n * field unless `opts.wireVersion` overrides it.\n *\n * Wire 0.1 classification is strict: if any commerce key (amt, cur, payment)\n * is present, the receipt MUST validate as commerce. There is no fallback to\n * attestation for Wire 0.1.\n *\n * @param input - Raw claims object (typically decoded from JWS payload)\n * @param opts - Optional parse options\n * @returns Parse result with variant discrimination, wireVersion, warnings, and validated claims\n */\nexport function parseReceiptClaims(input: unknown, opts?: ParseReceiptOptions): ParseReceiptResult {\n // Guard: input must be a non-null object\n if (input === null || input === undefined || typeof input !== 'object' || Array.isArray(input)) {\n return {\n ok: false,\n error: {\n code: 'E_PARSE_INVALID_INPUT',\n message: 'Input must be a non-null object',\n },\n };\n }\n\n const obj = input as Record<string, unknown>;\n\n // Determine wire version\n const wireVersion =\n opts?.wireVersion === '0.2' || opts?.wireVersion === '0.1'\n ? opts.wireVersion\n : detectWireVersion(obj);\n\n if (wireVersion === null) {\n return {\n ok: false,\n error: {\n code: 'E_UNSUPPORTED_WIRE_VERSION',\n message: `Unsupported or unrecognized peac_version: ${JSON.stringify(obj['peac_version'])}`,\n },\n };\n }\n\n // ---------------------------------------------------------------------------\n // Wire 0.2 path\n // ---------------------------------------------------------------------------\n if (wireVersion === '0.2') {\n const result = Wire02ClaimsSchema.safeParse(obj);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: 'E_INVALID_FORMAT',\n message: `Wire 0.2 receipt validation failed: ${result.error.issues.map((i) => i.message).join('; ')}`,\n issues: result.error.issues,\n },\n };\n }\n return {\n ok: true,\n variant: 'wire-02',\n wireVersion: '0.2',\n warnings: [],\n claims: result.data,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Wire 0.1 path (existing logic unchanged)\n // ---------------------------------------------------------------------------\n const variant = classifyWire01Receipt(obj);\n\n if (variant === 'commerce') {\n const result = ReceiptClaimsSchema.safeParse(obj);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: 'E_PARSE_COMMERCE_INVALID',\n message: `Commerce receipt validation failed: ${result.error.issues.map((i) => i.message).join('; ')}`,\n issues: result.error.issues,\n },\n };\n }\n return {\n ok: true,\n variant: 'commerce',\n wireVersion: '0.1',\n warnings: [],\n claims: result.data,\n };\n }\n\n // Attestation path\n const result = AttestationReceiptClaimsSchema.safeParse(obj);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: 'E_PARSE_ATTESTATION_INVALID',\n message: `Attestation receipt validation failed: ${result.error.issues.map((i) => i.message).join('; ')}`,\n issues: result.error.issues,\n },\n };\n }\n return {\n ok: true,\n variant: 'attestation',\n wireVersion: '0.1',\n warnings: [],\n claims: result.data,\n };\n}\n"]}
|