From db5c0c863556ad949b7d9b2d824d255a70dd8a96 Mon Sep 17 00:00:00 2001 From: Andrew Peris Date: Fri, 11 Sep 2026 08:06:39 -0400 Subject: [PATCH 1/3] Implement metadata-only execution provenance observers --- CONSTITUTION_CONFORMANCE.md | 18 +++ docs/README.md | 3 + docs/adr/0007-execution-observers.md | 15 ++ docs/execution-provenance.md | 49 +++++++ examples/execution-provenance.mjs | 15 ++ .../generate-provenance-schema-validator.mjs | 11 ++ src/prompt-sdk/execute.js | 22 ++- .../generated/provenance-v1-schema.js | 2 + src/prompt-sdk/index.js | 1 + src/prompt-sdk/provenance.js | 102 ++++++++++++++ tests/prompt-sdk/provenance.test.js | 129 ++++++++++++++++++ 11 files changed, 366 insertions(+), 1 deletion(-) create mode 100644 docs/adr/0007-execution-observers.md create mode 100644 docs/execution-provenance.md create mode 100644 examples/execution-provenance.mjs create mode 100644 scripts/generate-provenance-schema-validator.mjs create mode 100644 src/prompt-sdk/generated/provenance-v1-schema.js create mode 100644 src/prompt-sdk/provenance.js create mode 100644 tests/prompt-sdk/provenance.test.js diff --git a/CONSTITUTION_CONFORMANCE.md b/CONSTITUTION_CONFORMANCE.md index 289616e..81e9443 100644 --- a/CONSTITUTION_CONFORMANCE.md +++ b/CONSTITUTION_CONFORMANCE.md @@ -1,5 +1,23 @@ # Constitution conformance record +## Issue #69 assessment — 2026-09-11 + +This assessment extends and supersedes the prior issue #68 scope below for the +current candidate. Constitution v1.0.0 at +`a9cc8a503aa30e17820edc62ac95f7cbe10e0564` remains the authority. +Accountable owner: @andrewperis; status: Conforming candidate pending owner merge. +Base revision: `07abeef7bd02ae63c5bc1505a0d02a20f680a0bc`. + +Scope: Execution provenance builder/validator, compiled pinned schema, optional executor observer, bounded local observer, docs, ADR 0007 and synthetic example. +Evidence: npm test: 74 passing tests. Codex valid/invalid provenance fixtures and deterministic validator generation checked. +No new constitutional exceptions. Public fixtures are synthetic. Body content, +authorization and diagnostic strings are omitted; non-public content identities +are suppressed. Sinks cannot change the provider result or trigger retries. +Caller-owned opaque identifiers, production sink retention/access controls and +immutable contract publication (#72) remain outside this candidate. +The existing lockfile has a high-severity fast-uri advisory reported by npm audit; dependency remediation remains separate, with no dependency changes in this diff. +Next review: before release or any security-boundary/dependency change. + ## Constitutional alignment - Constitution: [Definitely Secure Studio Constitution v1.0.0](https://github.com/DefinitelySecureStudio/studio/tree/constitution/v1.0.0) diff --git a/docs/README.md b/docs/README.md index f22caa1..7bcd517 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,8 @@ # Platform documentation +- [Execution provenance](execution-provenance.md) covers metadata policy and pluggable observers. +- [Observer decision](adr/0007-execution-observers.md) records the failure-isolated boundary. + This directory contains architecture decisions, public interfaces, operational guides, and deployment documentation for the production platform. diff --git a/docs/adr/0007-execution-observers.md b/docs/adr/0007-execution-observers.md new file mode 100644 index 0000000..9fbfef7 --- /dev/null +++ b/docs/adr/0007-execution-observers.md @@ -0,0 +1,15 @@ +# ADR 0007: Execution provenance observers + +Candidate for owner merge, 2026-09-11. Owner: @andrewperis. +Issue: https://github.com/DefinitelySecureStudio/studio/issues/69 + +Project accepted execution results into the Codex Execution Provenance v1 +allowlist and deliver once to an optional vendor-neutral observer. Capture +effective parameters at negotiation, before adapter invocation. Use immutable +snapshots and bounded sink waiting so observability cannot obscure results. +Expose a pure builder for later validation/structured-output revisions. + +Default storage is a bounded memory buffer. Body capture is excluded even when +execution policy allows it. Classification gates hashes/context identity, and +diagnostics become counts. This preserves traceability while keeping free-form +provider and prompt data out of sinks. Custom sinks own their storage policy. diff --git a/docs/execution-provenance.md b/docs/execution-provenance.md new file mode 100644 index 0000000..e2da419 --- /dev/null +++ b/docs/execution-provenance.md @@ -0,0 +1,49 @@ +# Execution provenance and observers + +Issue #69 adds a metadata record suitable for linking execution/correlation ids +to later build manifests. Enable it with `executePrompt(request, { adapter, +observer: new LocalExecutionObserver() })`. No observer means no record storage. + +Observers implement `async observe(record)`. The executor passes one frozen +record after any accepted execution finishes, including preflight failure, +cancellation and timeout. Observer rejection, mutation attempts and deadline +expiry add `OBSERVATION_DELIVERY_FAILED` to the result. Provider status is +preserved and no execution is retried. The default observer deadline is 1000 ms; +`observerTimeoutMs` accepts 1–60000 ms. Timeout bounds waiting, but cannot cancel +external work a custom sink already started. Sinks must manage their own I/O. + +`LocalExecutionObserver({ capacity: 100 })` keeps the newest records in memory. +`snapshot()` returns copies; `clear()` erases the local buffer. It performs no +console/file/network output. Production sinks own retention and access control. + +`createExecutionProvenance(request, result, options)` supports post-execution +construction and later structured-output evidence. Options are +`effectiveParameters`, `validation`, `structuredOutput`, and +`contentIdentities` (`public-only`, default, or `omit`). Effective parameters are +captured automatically by the executor after negotiation. Manual callers must +provide the resolved values or the record states `not-resolved`. + +Pass prompt validation/lint evidence as `provenance: { validation: report }` to +the executor. Only outcome/counts survive; absent evidence is `not-run`. +After structured processing, construct another record with `structuredOutput` +and send it to the same observer. Processing status/id are retained only after +matching execution id, expectation and raw byte identity. Keep both record +revisions if an audit requires history; their canonical digests differ. + +Records omit messages, input/output bodies, parsed values, URIs, authorization +details, provider request ids, idempotency keys, stop strings, extension objects, +and diagnostic/error/warning text. Numeric portable parameters and stop count +remain. Render/output hashes and context package/source versions are retained +only for public content; context identities are suppressed when the overall +rendered prompt is non-public. `omit` suppresses all content identities. +Body-capture permission never broadens this metadata projection. + +Prompt, execution, correlation and provider/model ids must be approved opaque +identifiers. A secret disguised as an identifier cannot be detected by a schema. +Records are operational evidence, not an automatic public release artifact. + +The closed Codex schema is pinned by the reproducible generator: +`node scripts/generate-provenance-schema-validator.mjs /path/to/execution-provenance.schema.json`. +The envelope identity covers Studio canonical JSON of `record`. Consumers use +`validateExecutionProvenance` to check schema and digest. Immutable contract +publication under issue #72 remains required before a production release. diff --git a/examples/execution-provenance.mjs b/examples/execution-provenance.mjs new file mode 100644 index 0000000..5f86953 --- /dev/null +++ b/examples/execution-provenance.mjs @@ -0,0 +1,15 @@ +import { readFile } from 'node:fs/promises'; +import { renderPrompt, createExecutionRequest, executePrompt, MockTextAdapter, LocalExecutionObserver } from '../src/prompt-sdk/index.js'; + +const definition = JSON.parse(await readFile(new URL('../tests/fixtures/prompt-definition.json', import.meta.url))); +const request = createExecutionRequest(renderPrompt(definition, { inputValues: { item: 'blue cube', attributes: {} } }), { + execution_id: 'exec_provenance_example', correlation_id: 'build_example', idempotency_key: 'idem_example', + target: { adapter_id: 'studio.mock.text', provider_id: 'studio-mock', model_id: 'mock-text-v1' }, + capabilities: { required: ['text-generation'], optional: [] }, parameters: {}, + expected_output: { kind: 'text', media_type: 'text/plain', validation: 'none' }, + delegation: { caller_id: 'example', human_owner: 'andrewperis', purpose: 'Synthetic provenance example.', authority_reference: 'https://github.com/DefinitelySecureStudio/studio/issues/69' }, + observability: { retention: 'metadata-only', capture_prompt: false, capture_output: false } +}); +const observer = new LocalExecutionObserver(); +await executePrompt(request, { adapter: new MockTextAdapter(), observer, clock: () => 0 }); +console.log(JSON.stringify(observer.snapshot()[0], null, 2)); diff --git a/scripts/generate-provenance-schema-validator.mjs b/scripts/generate-provenance-schema-validator.mjs new file mode 100644 index 0000000..4b91052 --- /dev/null +++ b/scripts/generate-provenance-schema-validator.mjs @@ -0,0 +1,11 @@ +import { readFile, writeFile } from 'node:fs/promises'; +import { createHash } from 'node:crypto'; +import Ajv from 'ajv/dist/2020.js'; +import standaloneCode from 'ajv/dist/standalone/index.js'; +const bytes = await readFile(process.argv[2]); +const commit = '901543a367664e9f1b6822304a74e37471104ee1'; +const hash = '0d3c4ab43dab1f05042613751e5238525f56aed8021b1b4f4d16e0797c5619cb'; +if (bytes.length !== 9617 || createHash('sha256').update(bytes).digest('hex') !== hash) throw new Error('Provenance schema identity mismatch'); +const ajv = new Ajv({ allErrors: true, strict: true, code: { source: true, esm: true } }); +const code = standaloneCode(ajv, ajv.compile(JSON.parse(bytes))); +await writeFile(new URL('../src/prompt-sdk/generated/provenance-v1-schema.js', import.meta.url), `// Generated from DefinitelySecureStudio/codex@${commit}; SHA256 ${hash}\n${code}`); diff --git a/src/prompt-sdk/execute.js b/src/prompt-sdk/execute.js index e9074df..5a8bb8c 100644 --- a/src/prompt-sdk/execute.js +++ b/src/prompt-sdk/execute.js @@ -1,6 +1,7 @@ import { createHash } from "node:crypto"; import { AdapterExecutionError, ExecutionValidationError } from "./execution-errors.js"; import { validateExecutionCompatibility, validateExecutionDocument, validateExecutionResult } from "./validate-execution.js"; +import { createExecutionProvenance, deliverExecutionProvenance } from './provenance.js'; function identity(descriptor, request) { return descriptor ? { @@ -52,7 +53,7 @@ function normalizeThrown(error) { return { category: "internal", code: "ADAPTER_UNEXPECTED_ERROR", message: "The adapter failed without a normalized error.", retryable: false, stage: "adapter" }; } -export async function executePrompt(request, { adapter, signal, clock = Date.now } = {}) { +async function executePromptCore(request, { adapter, signal, clock = Date.now } = {}, observation = {}) { if (!adapter || typeof adapter.describe !== "function" || typeof adapter.execute !== "function") throw new TypeError("adapter must implement describe() and execute()."); const requestValidation = validateExecutionDocument(request); if (!requestValidation.valid) throw new ExecutionValidationError("Execution request does not satisfy the provider-neutral contract.", requestValidation); @@ -66,6 +67,7 @@ export async function executePrompt(request, { adapter, signal, clock = Date.now const compatibility = validateExecutionCompatibility(request, descriptor); const preflightWarnings = compatibility.diagnostics.filter(({ severity }) => severity === "warning").map(warning); if (!compatibility.valid) return failure(request, descriptor, started, clock(), compatibilityError(), preflightWarnings); + observation.effectiveParameters = structuredClone(compatibility.effectiveParameters); if (signal?.aborted) return failure(request, descriptor, started, clock(), { category: "cancelled", code: "EXECUTION_CANCELLED", message: "Execution was cancelled before provider invocation.", retryable: false, stage: "preflight" }, preflightWarnings); const controller = new AbortController(); @@ -116,3 +118,21 @@ export async function executePrompt(request, { adapter, signal, clock = Date.now signal?.removeEventListener("abort", abort); } } + +export async function executePrompt(request, options = {}) { + const { observer, observerTimeoutMs = 1000, provenance = {} } = options; + if (observer === undefined) return executePromptCore(request, options); + if (typeof observer?.observe !== 'function' || !Number.isSafeInteger(observerTimeoutMs) || observerTimeoutMs < 1 || observerTimeoutMs > 60000) throw new TypeError('Invalid observer or observer timeout'); + const requestValidation = validateExecutionDocument(request); + if (!requestValidation.valid) throw new ExecutionValidationError('Execution request does not satisfy the provider-neutral contract.', requestValidation); + const snapshot = structuredClone(request); + const observation = {}; + const result = await executePromptCore(structuredClone(snapshot), options, observation); + let delivered = false; + try { + const document = createExecutionProvenance(snapshot, result, { ...provenance, effectiveParameters: observation.effectiveParameters }); + delivered = await deliverExecutionProvenance(observer, document, observerTimeoutMs); + } catch { /* Observer failures must not obscure the provider outcome. */ } + if (!delivered) return { ...result, warnings: [...result.warnings, { code: 'OBSERVATION_DELIVERY_FAILED', message: 'Execution provenance could not be delivered.' }] }; + return result; +} diff --git a/src/prompt-sdk/generated/provenance-v1-schema.js b/src/prompt-sdk/generated/provenance-v1-schema.js new file mode 100644 index 0000000..e2fbc62 --- /dev/null +++ b/src/prompt-sdk/generated/provenance-v1-schema.js @@ -0,0 +1,2 @@ +// Generated from DefinitelySecureStudio/codex@901543a367664e9f1b6822304a74e37471104ee1; SHA256 0d3c4ab43dab1f05042613751e5238525f56aed8021b1b4f4d16e0797c5619cb +"use strict";export const validate = validate20;export default validate20;const schema31 = {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"urn:definitely-secure:contract:execution-provenance:1.0.0:record","type":"object","additionalProperties":false,"required":["spec_version","kind","record","identity"],"properties":{"spec_version":{"const":"1.0.0"},"kind":{"const":"execution-provenance"},"record":{"type":"object","additionalProperties":false,"required":["execution_id","prompt","contexts","redacted_context_count","target","identity","parameters","parameters_status","stop_sequence_count","timing","status","finish_reason","validation","structured_output","policy"],"properties":{"execution_id":{"type":"string"},"correlation_id":{"type":"string"},"prompt":{"type":"object","additionalProperties":false,"required":["id","version","spec_version"],"properties":{"id":{"type":"string"},"version":{"type":"string"},"spec_version":{"type":"string"}}},"rendered":{"type":"object","additionalProperties":false,"required":["byte_size","sha256"],"properties":{"byte_size":{"type":"integer","minimum":0},"sha256":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}}},"contexts":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["slot","classification"],"properties":{"slot":{"type":"string"},"classification":{"type":"string"},"package":{"type":"object","additionalProperties":false,"required":["id","version","instance_id","manifest_sha256"],"properties":{"id":{"type":"string"},"version":{"type":"string"},"instance_id":{"type":"string"},"manifest_sha256":{"type":"string"}}},"sources":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["source_id","version","kind","classification"],"properties":{"source_id":{"type":"string"},"version":{"type":"string"},"kind":{"type":"string"},"classification":{"type":"string"}}}}}}},"redacted_context_count":{"type":"integer","minimum":0},"target":{"type":"object","additionalProperties":false,"required":["adapter_id","provider_id","model_id"],"properties":{"adapter_id":{"type":"string"},"provider_id":{"type":"string"},"model_id":{"type":"string"}}},"identity":{"type":"object","additionalProperties":false,"required":["adapter_id","adapter_version","provider_id","model_id"],"properties":{"adapter_id":{"type":"string"},"adapter_version":{"type":"string"},"provider_id":{"type":"string"},"model_id":{"type":"string"},"model_revision":{"type":"string"}}},"parameters":{"type":"object","additionalProperties":false,"required":[],"properties":{"max_output_tokens":{"type":"number"},"temperature":{"type":"number"},"top_p":{"type":"number"},"seed":{"type":"number"}}},"parameters_status":{"enum":["resolved","not-resolved"]},"stop_sequence_count":{"type":"integer","minimum":0},"timing":{"type":"object","additionalProperties":false,"required":["started_at","completed_at","duration_ms"],"properties":{"started_at":{"type":"string"},"completed_at":{"type":"string"},"duration_ms":{"type":"integer","minimum":0}}},"status":{"enum":["succeeded","failed","cancelled","timed-out"]},"finish_reason":{"enum":["stop","length","content-filter","cancelled","error","unknown"]},"usage":{"type":"object","additionalProperties":false,"required":["provider_reported"],"properties":{"provider_reported":{"type":"boolean"},"input_tokens":{"type":"integer","minimum":0},"output_tokens":{"type":"integer","minimum":0},"total_tokens":{"type":"integer","minimum":0}}},"output":{"type":"object","additionalProperties":false,"required":["byte_size","sha256"],"properties":{"byte_size":{"type":"integer","minimum":0},"sha256":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}}},"validation":{"type":"object","additionalProperties":false,"required":["status","errors","warnings"],"properties":{"status":{"enum":["not-run","passed","failed"]},"errors":{"type":"integer","minimum":0},"warnings":{"type":"integer","minimum":0}}},"structured_output":{"type":"object","additionalProperties":false,"required":["status"],"properties":{"status":{"enum":["not-run","validated","failed"]},"processing_id":{"type":"string"}}},"policy":{"type":"object","additionalProperties":false,"required":["content_identities","bodies"],"properties":{"content_identities":{"enum":["public-only","omit"]},"bodies":{"const":"omitted"}}}}},"identity":{"type":"object","additionalProperties":false,"required":["byte_size","sha256"],"properties":{"byte_size":{"type":"integer","minimum":0},"sha256":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}}}}};const func1 = Object.prototype.hasOwnProperty;const pattern4 = new RegExp("^sha256:[0-9a-f]{64}$", "u");function validate20(data, {instancePath="", parentData, parentDataProperty, rootData=data, dynamicAnchors={}}={}){/*# sourceURL="urn:definitely-secure:contract:execution-provenance:1.0.0:record" */;let vErrors = null;let errors = 0;const evaluated0 = validate20.evaluated;if(evaluated0.dynamicProps){evaluated0.props = undefined;}if(evaluated0.dynamicItems){evaluated0.items = undefined;}if(data && typeof data == "object" && !Array.isArray(data)){if(data.spec_version === undefined){const err0 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "spec_version"},message:"must have required property '"+"spec_version"+"'"};if(vErrors === null){vErrors = [err0];}else {vErrors.push(err0);}errors++;}if(data.kind === undefined){const err1 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "kind"},message:"must have required property '"+"kind"+"'"};if(vErrors === null){vErrors = [err1];}else {vErrors.push(err1);}errors++;}if(data.record === undefined){const err2 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "record"},message:"must have required property '"+"record"+"'"};if(vErrors === null){vErrors = [err2];}else {vErrors.push(err2);}errors++;}if(data.identity === undefined){const err3 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "identity"},message:"must have required property '"+"identity"+"'"};if(vErrors === null){vErrors = [err3];}else {vErrors.push(err3);}errors++;}for(const key0 in data){if(!((((key0 === "spec_version") || (key0 === "kind")) || (key0 === "record")) || (key0 === "identity"))){const err4 = {instancePath,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key0},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err4];}else {vErrors.push(err4);}errors++;}}if(data.spec_version !== undefined){if("1.0.0" !== data.spec_version){const err5 = {instancePath:instancePath+"/spec_version",schemaPath:"#/properties/spec_version/const",keyword:"const",params:{allowedValue: "1.0.0"},message:"must be equal to constant"};if(vErrors === null){vErrors = [err5];}else {vErrors.push(err5);}errors++;}}if(data.kind !== undefined){if("execution-provenance" !== data.kind){const err6 = {instancePath:instancePath+"/kind",schemaPath:"#/properties/kind/const",keyword:"const",params:{allowedValue: "execution-provenance"},message:"must be equal to constant"};if(vErrors === null){vErrors = [err6];}else {vErrors.push(err6);}errors++;}}if(data.record !== undefined){let data2 = data.record;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){if(data2.execution_id === undefined){const err7 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "execution_id"},message:"must have required property '"+"execution_id"+"'"};if(vErrors === null){vErrors = [err7];}else {vErrors.push(err7);}errors++;}if(data2.prompt === undefined){const err8 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "prompt"},message:"must have required property '"+"prompt"+"'"};if(vErrors === null){vErrors = [err8];}else {vErrors.push(err8);}errors++;}if(data2.contexts === undefined){const err9 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "contexts"},message:"must have required property '"+"contexts"+"'"};if(vErrors === null){vErrors = [err9];}else {vErrors.push(err9);}errors++;}if(data2.redacted_context_count === undefined){const err10 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "redacted_context_count"},message:"must have required property '"+"redacted_context_count"+"'"};if(vErrors === null){vErrors = [err10];}else {vErrors.push(err10);}errors++;}if(data2.target === undefined){const err11 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "target"},message:"must have required property '"+"target"+"'"};if(vErrors === null){vErrors = [err11];}else {vErrors.push(err11);}errors++;}if(data2.identity === undefined){const err12 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "identity"},message:"must have required property '"+"identity"+"'"};if(vErrors === null){vErrors = [err12];}else {vErrors.push(err12);}errors++;}if(data2.parameters === undefined){const err13 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "parameters"},message:"must have required property '"+"parameters"+"'"};if(vErrors === null){vErrors = [err13];}else {vErrors.push(err13);}errors++;}if(data2.parameters_status === undefined){const err14 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "parameters_status"},message:"must have required property '"+"parameters_status"+"'"};if(vErrors === null){vErrors = [err14];}else {vErrors.push(err14);}errors++;}if(data2.stop_sequence_count === undefined){const err15 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "stop_sequence_count"},message:"must have required property '"+"stop_sequence_count"+"'"};if(vErrors === null){vErrors = [err15];}else {vErrors.push(err15);}errors++;}if(data2.timing === undefined){const err16 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "timing"},message:"must have required property '"+"timing"+"'"};if(vErrors === null){vErrors = [err16];}else {vErrors.push(err16);}errors++;}if(data2.status === undefined){const err17 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "status"},message:"must have required property '"+"status"+"'"};if(vErrors === null){vErrors = [err17];}else {vErrors.push(err17);}errors++;}if(data2.finish_reason === undefined){const err18 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "finish_reason"},message:"must have required property '"+"finish_reason"+"'"};if(vErrors === null){vErrors = [err18];}else {vErrors.push(err18);}errors++;}if(data2.validation === undefined){const err19 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "validation"},message:"must have required property '"+"validation"+"'"};if(vErrors === null){vErrors = [err19];}else {vErrors.push(err19);}errors++;}if(data2.structured_output === undefined){const err20 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "structured_output"},message:"must have required property '"+"structured_output"+"'"};if(vErrors === null){vErrors = [err20];}else {vErrors.push(err20);}errors++;}if(data2.policy === undefined){const err21 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "policy"},message:"must have required property '"+"policy"+"'"};if(vErrors === null){vErrors = [err21];}else {vErrors.push(err21);}errors++;}for(const key1 in data2){if(!(func1.call(schema31.properties.record.properties, key1))){const err22 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key1},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err22];}else {vErrors.push(err22);}errors++;}}if(data2.execution_id !== undefined){if(typeof data2.execution_id !== "string"){const err23 = {instancePath:instancePath+"/record/execution_id",schemaPath:"#/properties/record/properties/execution_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err23];}else {vErrors.push(err23);}errors++;}}if(data2.correlation_id !== undefined){if(typeof data2.correlation_id !== "string"){const err24 = {instancePath:instancePath+"/record/correlation_id",schemaPath:"#/properties/record/properties/correlation_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err24];}else {vErrors.push(err24);}errors++;}}if(data2.prompt !== undefined){let data5 = data2.prompt;if(data5 && typeof data5 == "object" && !Array.isArray(data5)){if(data5.id === undefined){const err25 = {instancePath:instancePath+"/record/prompt",schemaPath:"#/properties/record/properties/prompt/required",keyword:"required",params:{missingProperty: "id"},message:"must have required property '"+"id"+"'"};if(vErrors === null){vErrors = [err25];}else {vErrors.push(err25);}errors++;}if(data5.version === undefined){const err26 = {instancePath:instancePath+"/record/prompt",schemaPath:"#/properties/record/properties/prompt/required",keyword:"required",params:{missingProperty: "version"},message:"must have required property '"+"version"+"'"};if(vErrors === null){vErrors = [err26];}else {vErrors.push(err26);}errors++;}if(data5.spec_version === undefined){const err27 = {instancePath:instancePath+"/record/prompt",schemaPath:"#/properties/record/properties/prompt/required",keyword:"required",params:{missingProperty: "spec_version"},message:"must have required property '"+"spec_version"+"'"};if(vErrors === null){vErrors = [err27];}else {vErrors.push(err27);}errors++;}for(const key2 in data5){if(!(((key2 === "id") || (key2 === "version")) || (key2 === "spec_version"))){const err28 = {instancePath:instancePath+"/record/prompt",schemaPath:"#/properties/record/properties/prompt/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key2},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err28];}else {vErrors.push(err28);}errors++;}}if(data5.id !== undefined){if(typeof data5.id !== "string"){const err29 = {instancePath:instancePath+"/record/prompt/id",schemaPath:"#/properties/record/properties/prompt/properties/id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err29];}else {vErrors.push(err29);}errors++;}}if(data5.version !== undefined){if(typeof data5.version !== "string"){const err30 = {instancePath:instancePath+"/record/prompt/version",schemaPath:"#/properties/record/properties/prompt/properties/version/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err30];}else {vErrors.push(err30);}errors++;}}if(data5.spec_version !== undefined){if(typeof data5.spec_version !== "string"){const err31 = {instancePath:instancePath+"/record/prompt/spec_version",schemaPath:"#/properties/record/properties/prompt/properties/spec_version/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err31];}else {vErrors.push(err31);}errors++;}}}else {const err32 = {instancePath:instancePath+"/record/prompt",schemaPath:"#/properties/record/properties/prompt/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err32];}else {vErrors.push(err32);}errors++;}}if(data2.rendered !== undefined){let data9 = data2.rendered;if(data9 && typeof data9 == "object" && !Array.isArray(data9)){if(data9.byte_size === undefined){const err33 = {instancePath:instancePath+"/record/rendered",schemaPath:"#/properties/record/properties/rendered/required",keyword:"required",params:{missingProperty: "byte_size"},message:"must have required property '"+"byte_size"+"'"};if(vErrors === null){vErrors = [err33];}else {vErrors.push(err33);}errors++;}if(data9.sha256 === undefined){const err34 = {instancePath:instancePath+"/record/rendered",schemaPath:"#/properties/record/properties/rendered/required",keyword:"required",params:{missingProperty: "sha256"},message:"must have required property '"+"sha256"+"'"};if(vErrors === null){vErrors = [err34];}else {vErrors.push(err34);}errors++;}for(const key3 in data9){if(!((key3 === "byte_size") || (key3 === "sha256"))){const err35 = {instancePath:instancePath+"/record/rendered",schemaPath:"#/properties/record/properties/rendered/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key3},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err35];}else {vErrors.push(err35);}errors++;}}if(data9.byte_size !== undefined){let data10 = data9.byte_size;if(!(((typeof data10 == "number") && (!(data10 % 1) && !isNaN(data10))) && (isFinite(data10)))){const err36 = {instancePath:instancePath+"/record/rendered/byte_size",schemaPath:"#/properties/record/properties/rendered/properties/byte_size/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err36];}else {vErrors.push(err36);}errors++;}if((typeof data10 == "number") && (isFinite(data10))){if(data10 < 0 || isNaN(data10)){const err37 = {instancePath:instancePath+"/record/rendered/byte_size",schemaPath:"#/properties/record/properties/rendered/properties/byte_size/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err37];}else {vErrors.push(err37);}errors++;}}}if(data9.sha256 !== undefined){let data11 = data9.sha256;if(typeof data11 === "string"){if(!pattern4.test(data11)){const err38 = {instancePath:instancePath+"/record/rendered/sha256",schemaPath:"#/properties/record/properties/rendered/properties/sha256/pattern",keyword:"pattern",params:{pattern: "^sha256:[0-9a-f]{64}$"},message:"must match pattern \""+"^sha256:[0-9a-f]{64}$"+"\""};if(vErrors === null){vErrors = [err38];}else {vErrors.push(err38);}errors++;}}else {const err39 = {instancePath:instancePath+"/record/rendered/sha256",schemaPath:"#/properties/record/properties/rendered/properties/sha256/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err39];}else {vErrors.push(err39);}errors++;}}}else {const err40 = {instancePath:instancePath+"/record/rendered",schemaPath:"#/properties/record/properties/rendered/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err40];}else {vErrors.push(err40);}errors++;}}if(data2.contexts !== undefined){let data12 = data2.contexts;if(Array.isArray(data12)){const len0 = data12.length;for(let i0=0; i0=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err70];}else {vErrors.push(err70);}errors++;}}}if(data2.target !== undefined){let data28 = data2.target;if(data28 && typeof data28 == "object" && !Array.isArray(data28)){if(data28.adapter_id === undefined){const err71 = {instancePath:instancePath+"/record/target",schemaPath:"#/properties/record/properties/target/required",keyword:"required",params:{missingProperty: "adapter_id"},message:"must have required property '"+"adapter_id"+"'"};if(vErrors === null){vErrors = [err71];}else {vErrors.push(err71);}errors++;}if(data28.provider_id === undefined){const err72 = {instancePath:instancePath+"/record/target",schemaPath:"#/properties/record/properties/target/required",keyword:"required",params:{missingProperty: "provider_id"},message:"must have required property '"+"provider_id"+"'"};if(vErrors === null){vErrors = [err72];}else {vErrors.push(err72);}errors++;}if(data28.model_id === undefined){const err73 = {instancePath:instancePath+"/record/target",schemaPath:"#/properties/record/properties/target/required",keyword:"required",params:{missingProperty: "model_id"},message:"must have required property '"+"model_id"+"'"};if(vErrors === null){vErrors = [err73];}else {vErrors.push(err73);}errors++;}for(const key7 in data28){if(!(((key7 === "adapter_id") || (key7 === "provider_id")) || (key7 === "model_id"))){const err74 = {instancePath:instancePath+"/record/target",schemaPath:"#/properties/record/properties/target/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key7},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err74];}else {vErrors.push(err74);}errors++;}}if(data28.adapter_id !== undefined){if(typeof data28.adapter_id !== "string"){const err75 = {instancePath:instancePath+"/record/target/adapter_id",schemaPath:"#/properties/record/properties/target/properties/adapter_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err75];}else {vErrors.push(err75);}errors++;}}if(data28.provider_id !== undefined){if(typeof data28.provider_id !== "string"){const err76 = {instancePath:instancePath+"/record/target/provider_id",schemaPath:"#/properties/record/properties/target/properties/provider_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err76];}else {vErrors.push(err76);}errors++;}}if(data28.model_id !== undefined){if(typeof data28.model_id !== "string"){const err77 = {instancePath:instancePath+"/record/target/model_id",schemaPath:"#/properties/record/properties/target/properties/model_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err77];}else {vErrors.push(err77);}errors++;}}}else {const err78 = {instancePath:instancePath+"/record/target",schemaPath:"#/properties/record/properties/target/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err78];}else {vErrors.push(err78);}errors++;}}if(data2.identity !== undefined){let data32 = data2.identity;if(data32 && typeof data32 == "object" && !Array.isArray(data32)){if(data32.adapter_id === undefined){const err79 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/required",keyword:"required",params:{missingProperty: "adapter_id"},message:"must have required property '"+"adapter_id"+"'"};if(vErrors === null){vErrors = [err79];}else {vErrors.push(err79);}errors++;}if(data32.adapter_version === undefined){const err80 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/required",keyword:"required",params:{missingProperty: "adapter_version"},message:"must have required property '"+"adapter_version"+"'"};if(vErrors === null){vErrors = [err80];}else {vErrors.push(err80);}errors++;}if(data32.provider_id === undefined){const err81 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/required",keyword:"required",params:{missingProperty: "provider_id"},message:"must have required property '"+"provider_id"+"'"};if(vErrors === null){vErrors = [err81];}else {vErrors.push(err81);}errors++;}if(data32.model_id === undefined){const err82 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/required",keyword:"required",params:{missingProperty: "model_id"},message:"must have required property '"+"model_id"+"'"};if(vErrors === null){vErrors = [err82];}else {vErrors.push(err82);}errors++;}for(const key8 in data32){if(!(((((key8 === "adapter_id") || (key8 === "adapter_version")) || (key8 === "provider_id")) || (key8 === "model_id")) || (key8 === "model_revision"))){const err83 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key8},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err83];}else {vErrors.push(err83);}errors++;}}if(data32.adapter_id !== undefined){if(typeof data32.adapter_id !== "string"){const err84 = {instancePath:instancePath+"/record/identity/adapter_id",schemaPath:"#/properties/record/properties/identity/properties/adapter_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err84];}else {vErrors.push(err84);}errors++;}}if(data32.adapter_version !== undefined){if(typeof data32.adapter_version !== "string"){const err85 = {instancePath:instancePath+"/record/identity/adapter_version",schemaPath:"#/properties/record/properties/identity/properties/adapter_version/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err85];}else {vErrors.push(err85);}errors++;}}if(data32.provider_id !== undefined){if(typeof data32.provider_id !== "string"){const err86 = {instancePath:instancePath+"/record/identity/provider_id",schemaPath:"#/properties/record/properties/identity/properties/provider_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err86];}else {vErrors.push(err86);}errors++;}}if(data32.model_id !== undefined){if(typeof data32.model_id !== "string"){const err87 = {instancePath:instancePath+"/record/identity/model_id",schemaPath:"#/properties/record/properties/identity/properties/model_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err87];}else {vErrors.push(err87);}errors++;}}if(data32.model_revision !== undefined){if(typeof data32.model_revision !== "string"){const err88 = {instancePath:instancePath+"/record/identity/model_revision",schemaPath:"#/properties/record/properties/identity/properties/model_revision/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err88];}else {vErrors.push(err88);}errors++;}}}else {const err89 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err89];}else {vErrors.push(err89);}errors++;}}if(data2.parameters !== undefined){let data38 = data2.parameters;if(data38 && typeof data38 == "object" && !Array.isArray(data38)){for(const key9 in data38){if(!((((key9 === "max_output_tokens") || (key9 === "temperature")) || (key9 === "top_p")) || (key9 === "seed"))){const err90 = {instancePath:instancePath+"/record/parameters",schemaPath:"#/properties/record/properties/parameters/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key9},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err90];}else {vErrors.push(err90);}errors++;}}if(data38.max_output_tokens !== undefined){let data39 = data38.max_output_tokens;if(!((typeof data39 == "number") && (isFinite(data39)))){const err91 = {instancePath:instancePath+"/record/parameters/max_output_tokens",schemaPath:"#/properties/record/properties/parameters/properties/max_output_tokens/type",keyword:"type",params:{type: "number"},message:"must be number"};if(vErrors === null){vErrors = [err91];}else {vErrors.push(err91);}errors++;}}if(data38.temperature !== undefined){let data40 = data38.temperature;if(!((typeof data40 == "number") && (isFinite(data40)))){const err92 = {instancePath:instancePath+"/record/parameters/temperature",schemaPath:"#/properties/record/properties/parameters/properties/temperature/type",keyword:"type",params:{type: "number"},message:"must be number"};if(vErrors === null){vErrors = [err92];}else {vErrors.push(err92);}errors++;}}if(data38.top_p !== undefined){let data41 = data38.top_p;if(!((typeof data41 == "number") && (isFinite(data41)))){const err93 = {instancePath:instancePath+"/record/parameters/top_p",schemaPath:"#/properties/record/properties/parameters/properties/top_p/type",keyword:"type",params:{type: "number"},message:"must be number"};if(vErrors === null){vErrors = [err93];}else {vErrors.push(err93);}errors++;}}if(data38.seed !== undefined){let data42 = data38.seed;if(!((typeof data42 == "number") && (isFinite(data42)))){const err94 = {instancePath:instancePath+"/record/parameters/seed",schemaPath:"#/properties/record/properties/parameters/properties/seed/type",keyword:"type",params:{type: "number"},message:"must be number"};if(vErrors === null){vErrors = [err94];}else {vErrors.push(err94);}errors++;}}}else {const err95 = {instancePath:instancePath+"/record/parameters",schemaPath:"#/properties/record/properties/parameters/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err95];}else {vErrors.push(err95);}errors++;}}if(data2.parameters_status !== undefined){let data43 = data2.parameters_status;if(!((data43 === "resolved") || (data43 === "not-resolved"))){const err96 = {instancePath:instancePath+"/record/parameters_status",schemaPath:"#/properties/record/properties/parameters_status/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.parameters_status.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err96];}else {vErrors.push(err96);}errors++;}}if(data2.stop_sequence_count !== undefined){let data44 = data2.stop_sequence_count;if(!(((typeof data44 == "number") && (!(data44 % 1) && !isNaN(data44))) && (isFinite(data44)))){const err97 = {instancePath:instancePath+"/record/stop_sequence_count",schemaPath:"#/properties/record/properties/stop_sequence_count/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err97];}else {vErrors.push(err97);}errors++;}if((typeof data44 == "number") && (isFinite(data44))){if(data44 < 0 || isNaN(data44)){const err98 = {instancePath:instancePath+"/record/stop_sequence_count",schemaPath:"#/properties/record/properties/stop_sequence_count/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err98];}else {vErrors.push(err98);}errors++;}}}if(data2.timing !== undefined){let data45 = data2.timing;if(data45 && typeof data45 == "object" && !Array.isArray(data45)){if(data45.started_at === undefined){const err99 = {instancePath:instancePath+"/record/timing",schemaPath:"#/properties/record/properties/timing/required",keyword:"required",params:{missingProperty: "started_at"},message:"must have required property '"+"started_at"+"'"};if(vErrors === null){vErrors = [err99];}else {vErrors.push(err99);}errors++;}if(data45.completed_at === undefined){const err100 = {instancePath:instancePath+"/record/timing",schemaPath:"#/properties/record/properties/timing/required",keyword:"required",params:{missingProperty: "completed_at"},message:"must have required property '"+"completed_at"+"'"};if(vErrors === null){vErrors = [err100];}else {vErrors.push(err100);}errors++;}if(data45.duration_ms === undefined){const err101 = {instancePath:instancePath+"/record/timing",schemaPath:"#/properties/record/properties/timing/required",keyword:"required",params:{missingProperty: "duration_ms"},message:"must have required property '"+"duration_ms"+"'"};if(vErrors === null){vErrors = [err101];}else {vErrors.push(err101);}errors++;}for(const key10 in data45){if(!(((key10 === "started_at") || (key10 === "completed_at")) || (key10 === "duration_ms"))){const err102 = {instancePath:instancePath+"/record/timing",schemaPath:"#/properties/record/properties/timing/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key10},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err102];}else {vErrors.push(err102);}errors++;}}if(data45.started_at !== undefined){if(typeof data45.started_at !== "string"){const err103 = {instancePath:instancePath+"/record/timing/started_at",schemaPath:"#/properties/record/properties/timing/properties/started_at/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err103];}else {vErrors.push(err103);}errors++;}}if(data45.completed_at !== undefined){if(typeof data45.completed_at !== "string"){const err104 = {instancePath:instancePath+"/record/timing/completed_at",schemaPath:"#/properties/record/properties/timing/properties/completed_at/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err104];}else {vErrors.push(err104);}errors++;}}if(data45.duration_ms !== undefined){let data48 = data45.duration_ms;if(!(((typeof data48 == "number") && (!(data48 % 1) && !isNaN(data48))) && (isFinite(data48)))){const err105 = {instancePath:instancePath+"/record/timing/duration_ms",schemaPath:"#/properties/record/properties/timing/properties/duration_ms/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err105];}else {vErrors.push(err105);}errors++;}if((typeof data48 == "number") && (isFinite(data48))){if(data48 < 0 || isNaN(data48)){const err106 = {instancePath:instancePath+"/record/timing/duration_ms",schemaPath:"#/properties/record/properties/timing/properties/duration_ms/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err106];}else {vErrors.push(err106);}errors++;}}}}else {const err107 = {instancePath:instancePath+"/record/timing",schemaPath:"#/properties/record/properties/timing/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err107];}else {vErrors.push(err107);}errors++;}}if(data2.status !== undefined){let data49 = data2.status;if(!((((data49 === "succeeded") || (data49 === "failed")) || (data49 === "cancelled")) || (data49 === "timed-out"))){const err108 = {instancePath:instancePath+"/record/status",schemaPath:"#/properties/record/properties/status/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.status.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err108];}else {vErrors.push(err108);}errors++;}}if(data2.finish_reason !== undefined){let data50 = data2.finish_reason;if(!((((((data50 === "stop") || (data50 === "length")) || (data50 === "content-filter")) || (data50 === "cancelled")) || (data50 === "error")) || (data50 === "unknown"))){const err109 = {instancePath:instancePath+"/record/finish_reason",schemaPath:"#/properties/record/properties/finish_reason/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.finish_reason.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err109];}else {vErrors.push(err109);}errors++;}}if(data2.usage !== undefined){let data51 = data2.usage;if(data51 && typeof data51 == "object" && !Array.isArray(data51)){if(data51.provider_reported === undefined){const err110 = {instancePath:instancePath+"/record/usage",schemaPath:"#/properties/record/properties/usage/required",keyword:"required",params:{missingProperty: "provider_reported"},message:"must have required property '"+"provider_reported"+"'"};if(vErrors === null){vErrors = [err110];}else {vErrors.push(err110);}errors++;}for(const key11 in data51){if(!((((key11 === "provider_reported") || (key11 === "input_tokens")) || (key11 === "output_tokens")) || (key11 === "total_tokens"))){const err111 = {instancePath:instancePath+"/record/usage",schemaPath:"#/properties/record/properties/usage/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key11},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err111];}else {vErrors.push(err111);}errors++;}}if(data51.provider_reported !== undefined){if(typeof data51.provider_reported !== "boolean"){const err112 = {instancePath:instancePath+"/record/usage/provider_reported",schemaPath:"#/properties/record/properties/usage/properties/provider_reported/type",keyword:"type",params:{type: "boolean"},message:"must be boolean"};if(vErrors === null){vErrors = [err112];}else {vErrors.push(err112);}errors++;}}if(data51.input_tokens !== undefined){let data53 = data51.input_tokens;if(!(((typeof data53 == "number") && (!(data53 % 1) && !isNaN(data53))) && (isFinite(data53)))){const err113 = {instancePath:instancePath+"/record/usage/input_tokens",schemaPath:"#/properties/record/properties/usage/properties/input_tokens/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err113];}else {vErrors.push(err113);}errors++;}if((typeof data53 == "number") && (isFinite(data53))){if(data53 < 0 || isNaN(data53)){const err114 = {instancePath:instancePath+"/record/usage/input_tokens",schemaPath:"#/properties/record/properties/usage/properties/input_tokens/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err114];}else {vErrors.push(err114);}errors++;}}}if(data51.output_tokens !== undefined){let data54 = data51.output_tokens;if(!(((typeof data54 == "number") && (!(data54 % 1) && !isNaN(data54))) && (isFinite(data54)))){const err115 = {instancePath:instancePath+"/record/usage/output_tokens",schemaPath:"#/properties/record/properties/usage/properties/output_tokens/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err115];}else {vErrors.push(err115);}errors++;}if((typeof data54 == "number") && (isFinite(data54))){if(data54 < 0 || isNaN(data54)){const err116 = {instancePath:instancePath+"/record/usage/output_tokens",schemaPath:"#/properties/record/properties/usage/properties/output_tokens/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err116];}else {vErrors.push(err116);}errors++;}}}if(data51.total_tokens !== undefined){let data55 = data51.total_tokens;if(!(((typeof data55 == "number") && (!(data55 % 1) && !isNaN(data55))) && (isFinite(data55)))){const err117 = {instancePath:instancePath+"/record/usage/total_tokens",schemaPath:"#/properties/record/properties/usage/properties/total_tokens/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err117];}else {vErrors.push(err117);}errors++;}if((typeof data55 == "number") && (isFinite(data55))){if(data55 < 0 || isNaN(data55)){const err118 = {instancePath:instancePath+"/record/usage/total_tokens",schemaPath:"#/properties/record/properties/usage/properties/total_tokens/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err118];}else {vErrors.push(err118);}errors++;}}}}else {const err119 = {instancePath:instancePath+"/record/usage",schemaPath:"#/properties/record/properties/usage/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err119];}else {vErrors.push(err119);}errors++;}}if(data2.output !== undefined){let data56 = data2.output;if(data56 && typeof data56 == "object" && !Array.isArray(data56)){if(data56.byte_size === undefined){const err120 = {instancePath:instancePath+"/record/output",schemaPath:"#/properties/record/properties/output/required",keyword:"required",params:{missingProperty: "byte_size"},message:"must have required property '"+"byte_size"+"'"};if(vErrors === null){vErrors = [err120];}else {vErrors.push(err120);}errors++;}if(data56.sha256 === undefined){const err121 = {instancePath:instancePath+"/record/output",schemaPath:"#/properties/record/properties/output/required",keyword:"required",params:{missingProperty: "sha256"},message:"must have required property '"+"sha256"+"'"};if(vErrors === null){vErrors = [err121];}else {vErrors.push(err121);}errors++;}for(const key12 in data56){if(!((key12 === "byte_size") || (key12 === "sha256"))){const err122 = {instancePath:instancePath+"/record/output",schemaPath:"#/properties/record/properties/output/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key12},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err122];}else {vErrors.push(err122);}errors++;}}if(data56.byte_size !== undefined){let data57 = data56.byte_size;if(!(((typeof data57 == "number") && (!(data57 % 1) && !isNaN(data57))) && (isFinite(data57)))){const err123 = {instancePath:instancePath+"/record/output/byte_size",schemaPath:"#/properties/record/properties/output/properties/byte_size/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err123];}else {vErrors.push(err123);}errors++;}if((typeof data57 == "number") && (isFinite(data57))){if(data57 < 0 || isNaN(data57)){const err124 = {instancePath:instancePath+"/record/output/byte_size",schemaPath:"#/properties/record/properties/output/properties/byte_size/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err124];}else {vErrors.push(err124);}errors++;}}}if(data56.sha256 !== undefined){let data58 = data56.sha256;if(typeof data58 === "string"){if(!pattern4.test(data58)){const err125 = {instancePath:instancePath+"/record/output/sha256",schemaPath:"#/properties/record/properties/output/properties/sha256/pattern",keyword:"pattern",params:{pattern: "^sha256:[0-9a-f]{64}$"},message:"must match pattern \""+"^sha256:[0-9a-f]{64}$"+"\""};if(vErrors === null){vErrors = [err125];}else {vErrors.push(err125);}errors++;}}else {const err126 = {instancePath:instancePath+"/record/output/sha256",schemaPath:"#/properties/record/properties/output/properties/sha256/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err126];}else {vErrors.push(err126);}errors++;}}}else {const err127 = {instancePath:instancePath+"/record/output",schemaPath:"#/properties/record/properties/output/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err127];}else {vErrors.push(err127);}errors++;}}if(data2.validation !== undefined){let data59 = data2.validation;if(data59 && typeof data59 == "object" && !Array.isArray(data59)){if(data59.status === undefined){const err128 = {instancePath:instancePath+"/record/validation",schemaPath:"#/properties/record/properties/validation/required",keyword:"required",params:{missingProperty: "status"},message:"must have required property '"+"status"+"'"};if(vErrors === null){vErrors = [err128];}else {vErrors.push(err128);}errors++;}if(data59.errors === undefined){const err129 = {instancePath:instancePath+"/record/validation",schemaPath:"#/properties/record/properties/validation/required",keyword:"required",params:{missingProperty: "errors"},message:"must have required property '"+"errors"+"'"};if(vErrors === null){vErrors = [err129];}else {vErrors.push(err129);}errors++;}if(data59.warnings === undefined){const err130 = {instancePath:instancePath+"/record/validation",schemaPath:"#/properties/record/properties/validation/required",keyword:"required",params:{missingProperty: "warnings"},message:"must have required property '"+"warnings"+"'"};if(vErrors === null){vErrors = [err130];}else {vErrors.push(err130);}errors++;}for(const key13 in data59){if(!(((key13 === "status") || (key13 === "errors")) || (key13 === "warnings"))){const err131 = {instancePath:instancePath+"/record/validation",schemaPath:"#/properties/record/properties/validation/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key13},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err131];}else {vErrors.push(err131);}errors++;}}if(data59.status !== undefined){let data60 = data59.status;if(!(((data60 === "not-run") || (data60 === "passed")) || (data60 === "failed"))){const err132 = {instancePath:instancePath+"/record/validation/status",schemaPath:"#/properties/record/properties/validation/properties/status/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.validation.properties.status.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err132];}else {vErrors.push(err132);}errors++;}}if(data59.errors !== undefined){let data61 = data59.errors;if(!(((typeof data61 == "number") && (!(data61 % 1) && !isNaN(data61))) && (isFinite(data61)))){const err133 = {instancePath:instancePath+"/record/validation/errors",schemaPath:"#/properties/record/properties/validation/properties/errors/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err133];}else {vErrors.push(err133);}errors++;}if((typeof data61 == "number") && (isFinite(data61))){if(data61 < 0 || isNaN(data61)){const err134 = {instancePath:instancePath+"/record/validation/errors",schemaPath:"#/properties/record/properties/validation/properties/errors/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err134];}else {vErrors.push(err134);}errors++;}}}if(data59.warnings !== undefined){let data62 = data59.warnings;if(!(((typeof data62 == "number") && (!(data62 % 1) && !isNaN(data62))) && (isFinite(data62)))){const err135 = {instancePath:instancePath+"/record/validation/warnings",schemaPath:"#/properties/record/properties/validation/properties/warnings/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err135];}else {vErrors.push(err135);}errors++;}if((typeof data62 == "number") && (isFinite(data62))){if(data62 < 0 || isNaN(data62)){const err136 = {instancePath:instancePath+"/record/validation/warnings",schemaPath:"#/properties/record/properties/validation/properties/warnings/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err136];}else {vErrors.push(err136);}errors++;}}}}else {const err137 = {instancePath:instancePath+"/record/validation",schemaPath:"#/properties/record/properties/validation/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err137];}else {vErrors.push(err137);}errors++;}}if(data2.structured_output !== undefined){let data63 = data2.structured_output;if(data63 && typeof data63 == "object" && !Array.isArray(data63)){if(data63.status === undefined){const err138 = {instancePath:instancePath+"/record/structured_output",schemaPath:"#/properties/record/properties/structured_output/required",keyword:"required",params:{missingProperty: "status"},message:"must have required property '"+"status"+"'"};if(vErrors === null){vErrors = [err138];}else {vErrors.push(err138);}errors++;}for(const key14 in data63){if(!((key14 === "status") || (key14 === "processing_id"))){const err139 = {instancePath:instancePath+"/record/structured_output",schemaPath:"#/properties/record/properties/structured_output/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key14},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err139];}else {vErrors.push(err139);}errors++;}}if(data63.status !== undefined){let data64 = data63.status;if(!(((data64 === "not-run") || (data64 === "validated")) || (data64 === "failed"))){const err140 = {instancePath:instancePath+"/record/structured_output/status",schemaPath:"#/properties/record/properties/structured_output/properties/status/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.structured_output.properties.status.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err140];}else {vErrors.push(err140);}errors++;}}if(data63.processing_id !== undefined){if(typeof data63.processing_id !== "string"){const err141 = {instancePath:instancePath+"/record/structured_output/processing_id",schemaPath:"#/properties/record/properties/structured_output/properties/processing_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err141];}else {vErrors.push(err141);}errors++;}}}else {const err142 = {instancePath:instancePath+"/record/structured_output",schemaPath:"#/properties/record/properties/structured_output/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err142];}else {vErrors.push(err142);}errors++;}}if(data2.policy !== undefined){let data66 = data2.policy;if(data66 && typeof data66 == "object" && !Array.isArray(data66)){if(data66.content_identities === undefined){const err143 = {instancePath:instancePath+"/record/policy",schemaPath:"#/properties/record/properties/policy/required",keyword:"required",params:{missingProperty: "content_identities"},message:"must have required property '"+"content_identities"+"'"};if(vErrors === null){vErrors = [err143];}else {vErrors.push(err143);}errors++;}if(data66.bodies === undefined){const err144 = {instancePath:instancePath+"/record/policy",schemaPath:"#/properties/record/properties/policy/required",keyword:"required",params:{missingProperty: "bodies"},message:"must have required property '"+"bodies"+"'"};if(vErrors === null){vErrors = [err144];}else {vErrors.push(err144);}errors++;}for(const key15 in data66){if(!((key15 === "content_identities") || (key15 === "bodies"))){const err145 = {instancePath:instancePath+"/record/policy",schemaPath:"#/properties/record/properties/policy/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key15},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err145];}else {vErrors.push(err145);}errors++;}}if(data66.content_identities !== undefined){let data67 = data66.content_identities;if(!((data67 === "public-only") || (data67 === "omit"))){const err146 = {instancePath:instancePath+"/record/policy/content_identities",schemaPath:"#/properties/record/properties/policy/properties/content_identities/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.policy.properties.content_identities.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err146];}else {vErrors.push(err146);}errors++;}}if(data66.bodies !== undefined){if("omitted" !== data66.bodies){const err147 = {instancePath:instancePath+"/record/policy/bodies",schemaPath:"#/properties/record/properties/policy/properties/bodies/const",keyword:"const",params:{allowedValue: "omitted"},message:"must be equal to constant"};if(vErrors === null){vErrors = [err147];}else {vErrors.push(err147);}errors++;}}}else {const err148 = {instancePath:instancePath+"/record/policy",schemaPath:"#/properties/record/properties/policy/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err148];}else {vErrors.push(err148);}errors++;}}}else {const err149 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err149];}else {vErrors.push(err149);}errors++;}}if(data.identity !== undefined){let data69 = data.identity;if(data69 && typeof data69 == "object" && !Array.isArray(data69)){if(data69.byte_size === undefined){const err150 = {instancePath:instancePath+"/identity",schemaPath:"#/properties/identity/required",keyword:"required",params:{missingProperty: "byte_size"},message:"must have required property '"+"byte_size"+"'"};if(vErrors === null){vErrors = [err150];}else {vErrors.push(err150);}errors++;}if(data69.sha256 === undefined){const err151 = {instancePath:instancePath+"/identity",schemaPath:"#/properties/identity/required",keyword:"required",params:{missingProperty: "sha256"},message:"must have required property '"+"sha256"+"'"};if(vErrors === null){vErrors = [err151];}else {vErrors.push(err151);}errors++;}for(const key16 in data69){if(!((key16 === "byte_size") || (key16 === "sha256"))){const err152 = {instancePath:instancePath+"/identity",schemaPath:"#/properties/identity/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key16},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err152];}else {vErrors.push(err152);}errors++;}}if(data69.byte_size !== undefined){let data70 = data69.byte_size;if(!(((typeof data70 == "number") && (!(data70 % 1) && !isNaN(data70))) && (isFinite(data70)))){const err153 = {instancePath:instancePath+"/identity/byte_size",schemaPath:"#/properties/identity/properties/byte_size/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err153];}else {vErrors.push(err153);}errors++;}if((typeof data70 == "number") && (isFinite(data70))){if(data70 < 0 || isNaN(data70)){const err154 = {instancePath:instancePath+"/identity/byte_size",schemaPath:"#/properties/identity/properties/byte_size/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err154];}else {vErrors.push(err154);}errors++;}}}if(data69.sha256 !== undefined){let data71 = data69.sha256;if(typeof data71 === "string"){if(!pattern4.test(data71)){const err155 = {instancePath:instancePath+"/identity/sha256",schemaPath:"#/properties/identity/properties/sha256/pattern",keyword:"pattern",params:{pattern: "^sha256:[0-9a-f]{64}$"},message:"must match pattern \""+"^sha256:[0-9a-f]{64}$"+"\""};if(vErrors === null){vErrors = [err155];}else {vErrors.push(err155);}errors++;}}else {const err156 = {instancePath:instancePath+"/identity/sha256",schemaPath:"#/properties/identity/properties/sha256/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err156];}else {vErrors.push(err156);}errors++;}}}else {const err157 = {instancePath:instancePath+"/identity",schemaPath:"#/properties/identity/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err157];}else {vErrors.push(err157);}errors++;}}}else {const err158 = {instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err158];}else {vErrors.push(err158);}errors++;}validate20.errors = vErrors;return errors === 0;}validate20.evaluated = {"props":true,"dynamicProps":false,"dynamicItems":false}; \ No newline at end of file diff --git a/src/prompt-sdk/index.js b/src/prompt-sdk/index.js index 7dbae60..b80c1fd 100644 --- a/src/prompt-sdk/index.js +++ b/src/prompt-sdk/index.js @@ -1,4 +1,5 @@ export { canonicalJson } from "./canonical-json.js"; +export { createExecutionProvenance, validateExecutionProvenance, LocalExecutionObserver, deliverExecutionProvenance } from './provenance.js'; export { CONTEXT_PACKAGE_CONTRACT, CONTRACT, EXECUTION_CONTRACT, PROMPT_DEFINITION_CONTRACT, STRUCTURED_OUTPUT_CONTRACT } from "./diagnostics.js"; export { AdapterExecutionError, ExecutionValidationError } from "./execution-errors.js"; export { ContextPackageError } from "./context-errors.js"; diff --git a/src/prompt-sdk/provenance.js b/src/prompt-sdk/provenance.js new file mode 100644 index 0000000..5e158c8 --- /dev/null +++ b/src/prompt-sdk/provenance.js @@ -0,0 +1,102 @@ +import { createHash } from 'node:crypto'; +import { canonicalJson } from './canonical-json.js'; +import validateSchema from './generated/provenance-v1-schema.js'; +import { validateExecutionDocument } from './validate-execution.js'; +import { validateStructuredOutputDocument } from './structured-output.js'; + +const pick = (value, keys) => Object.fromEntries(keys.filter(key => value?.[key] !== undefined).map(key => [key, structuredClone(value[key])])); +function identity(value) { + const text = canonicalJson(value); + return { byte_size: Buffer.byteLength(text), sha256: `sha256:${createHash('sha256').update(text).digest('hex')}` }; +} +function freeze(value) { + if (value && typeof value === 'object') { Object.values(value).forEach(freeze); Object.freeze(value); } + return value; +} +function summary(validation) { + if (validation === undefined) return { status: 'not-run', errors: 0, warnings: 0 }; + if (typeof validation?.valid !== 'boolean' || !Array.isArray(validation.diagnostics)) throw new Error('Invalid validation evidence'); + const errors = validation.diagnostics.filter(x => x.severity === 'error').length; + const warnings = validation.diagnostics.filter(x => x.severity === 'warning').length; + if (validation.valid !== (errors === 0)) throw new Error('Inconsistent validation evidence'); + return { status: validation.valid ? 'passed' : 'failed', errors, warnings }; +} +export function validateExecutionProvenance(document) { + try { + canonicalJson(document); + if (!validateSchema(document)) return false; + return canonicalJson(identity(document.record)) === canonicalJson(document.identity); + } catch { return false; } +} + +export function createExecutionProvenance(request, result, { effectiveParameters, validation, structuredOutput, contentIdentities = 'public-only' } = {}) { + if (!validateExecutionDocument(request).valid || request.kind !== 'execution-request' || !validateExecutionDocument(result).valid || result.kind !== 'execution-result') throw new Error('Invalid execution provenance inputs'); + if (request.execution_id !== result.execution_id || request.correlation_id !== result.correlation_id) throw new Error('Execution provenance correlation mismatch'); + if (!['public-only', 'omit'].includes(contentIdentities)) throw new Error('Invalid provenance identity policy'); + let structured = { status: 'not-run' }; + if (structuredOutput !== undefined) { + if (!validateStructuredOutputDocument(structuredOutput).valid || structuredOutput.execution_id !== result.execution_id || canonicalJson(structuredOutput.expectation) !== canonicalJson(request.expected_output) || !result.output || structuredOutput.raw.sha256 !== result.output.sha256 || structuredOutput.raw.byte_size !== result.output.byte_size) throw new Error('Structured output provenance mismatch'); + structured = { status: structuredOutput.status, processing_id: structuredOutput.processing_id }; + } + const publicIdentities = contentIdentities === 'public-only'; + const contexts = []; + for (const context of request.rendered_prompt.contexts) { + if (!publicIdentities || request.rendered_prompt.classification !== 'public' || context.classification !== 'public') continue; + const safe = pick(context, ['slot', 'classification']); + if (context.package) { + safe.package = pick(context.package.package, ['id', 'version', 'instance_id', 'manifest_sha256']); + safe.sources = context.package.sources.map(source => pick(source, ['source_id', 'version', 'kind', 'classification'])); + } + contexts.push(safe); + } + const parameters = effectiveParameters ?? request.parameters; + const record = { + ...pick(request, ['execution_id', 'correlation_id']), + prompt: pick(request.rendered_prompt.definition, ['id', 'version', 'spec_version']), + contexts, redacted_context_count: request.rendered_prompt.contexts.length - contexts.length, + target: pick(request.target, ['adapter_id', 'provider_id', 'model_id']), + identity: pick(result.identity, ['adapter_id', 'adapter_version', 'provider_id', 'model_id', 'model_revision']), + parameters: pick(parameters, ['max_output_tokens', 'temperature', 'top_p', 'seed']), + parameters_status: effectiveParameters === undefined ? 'not-resolved' : 'resolved', + stop_sequence_count: parameters.stop_sequences?.length ?? 0, + timing: pick(result.timing, ['started_at', 'completed_at', 'duration_ms']), + status: result.status, finish_reason: result.finish_reason, + validation: summary(validation), structured_output: structured, + policy: { content_identities: contentIdentities, bodies: 'omitted' } + }; + if (result.usage) record.usage = pick(result.usage, ['provider_reported', 'input_tokens', 'output_tokens', 'total_tokens']); + if (publicIdentities && request.rendered_prompt.classification === 'public') record.rendered = pick(request.rendered_prompt, ['byte_size', 'sha256']); + if (publicIdentities && result.output?.classification === 'public') record.output = pick(result.output, ['byte_size', 'sha256']); + const document = { spec_version: '1.0.0', kind: 'execution-provenance', record, identity: identity(record) }; + if (!validateExecutionProvenance(document)) throw new Error('Invalid execution provenance record'); + return freeze(document); +} + +export class LocalExecutionObserver { + #records = []; + #capacity; + constructor({ capacity = 100 } = {}) { + if (!Number.isSafeInteger(capacity) || capacity < 1) throw new TypeError('Observer capacity must be positive'); + this.#capacity = capacity; + } + async observe(record) { + if (!validateExecutionProvenance(record)) throw new Error('Invalid observer record'); + this.#records.push(structuredClone(record)); + if (this.#records.length > this.#capacity) this.#records.shift(); + } + snapshot() { return structuredClone(this.#records); } + clear() { this.#records = []; } +} + +export async function deliverExecutionProvenance(observer, document, timeoutMs = 1000) { + if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 60000) return false; + let timer; + try { + await Promise.race([ + Promise.resolve().then(() => observer.observe(document)), + new Promise((_, reject) => { timer = setTimeout(() => reject(new Error('Observer timeout')), timeoutMs); }) + ]); + return true; + } catch { return false; } + finally { clearTimeout(timer); } +} diff --git a/tests/prompt-sdk/provenance.test.js b/tests/prompt-sdk/provenance.test.js new file mode 100644 index 0000000..ca99e87 --- /dev/null +++ b/tests/prompt-sdk/provenance.test.js @@ -0,0 +1,129 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { readFile } from 'node:fs/promises'; +import { createHash } from 'node:crypto'; +import { canonicalJson, createMockContextPackage, createMockContextAuthorization, renderPromptWithContextPackage } from '../../src/prompt-sdk/index.js'; +import { createExecutionRequest, renderPrompt, executePrompt, MockTextAdapter, LocalExecutionObserver, createExecutionProvenance, validateExecutionProvenance, processStructuredOutput } from '../../src/prompt-sdk/index.js'; +const definition = JSON.parse(await readFile(new URL('../fixtures/prompt-definition.json', import.meta.url))); +test('public context package/source versions survive; non-public packages are counted only', async () => { + for (const classification of ['public', 'internal']) { + const prompt = structuredClone(definition); + prompt.template.messages[0].parts[0].text = 'Describe the item using supplied context.'; + prompt.context_slots.push({ name: 'context_facts', description: 'Facts', required: true, accepted_classifications: [classification], accepted_media_types: ['application/json'], max_bytes: 100 }); + prompt.template.messages[1].parts.push({ type: 'context', slot: 'context_facts', format: 'json' }); + const packageDocument = createMockContextPackage(); + packageDocument.manifest.classification = classification; + packageDocument.manifest.sources.forEach(source => { source.classification = classification; }); + packageDocument.manifest.sections.forEach(section => { section.classification = classification; }); + prompt.context_slots[0].accepted_classifications = [classification]; + const bytes = canonicalJson(packageDocument.manifest); + packageDocument.manifest_identity = { canonicalization: 'studio-json-v1', byte_size: Buffer.byteLength(bytes), sha256: 'sha256:' + createHash('sha256').update(bytes).digest('hex') }; + const rendered = renderPromptWithContextPackage(prompt, { inputValues: { item: 'synthetic', attributes: {} }, packageDocument, authorization: createMockContextAuthorization({ promptId: prompt.id, promptVersion: prompt.version }), at: '2026-08-20T12:00:00Z' }); + const input = createExecutionRequest(rendered, request()); + const observer = new LocalExecutionObserver(); + await executePrompt(input, { adapter: new MockTextAdapter(), observer }); + const record = observer.snapshot()[0].record; + assert.equal(record.contexts.length, classification === 'public' ? 2 : 0); + assert.equal(record.redacted_context_count, classification === 'public' ? 0 : 2); + if (classification === 'public') { + assert.equal(record.contexts[0].package.version, '1.0.0'); + assert.equal(record.contexts[0].sources[0].version, '1.0.0'); + } + assert.doesNotMatch(JSON.stringify(record), /evidence_reference|authority_reference|Synthetic approved note/); + } +}); +function request(overrides = {}, classification = 'public') { + const prompt = structuredClone(definition); + prompt.inputs[0].classification = classification; + return createExecutionRequest(renderPrompt(prompt, { inputValues: { item: 'SECRET_INPUT', attributes: {} } }), { + execution_id: 'exec_observer', correlation_id: 'build_observer', idempotency_key: 'SECRET_KEY', + target: { adapter_id: 'studio.mock.text', provider_id: 'studio-mock', model_id: 'mock-text-v1' }, + capabilities: { required: ['text-generation'], optional: [] }, parameters: { stop_sequences: ['SECRET_STOP'] }, + expected_output: { kind: 'text', media_type: 'text/plain', validation: 'none' }, + delegation: { caller_id: 'test', human_owner: 'owner', purpose: 'SECRET_PURPOSE', authority_reference: 'https://example.invalid/SECRET_AUTH' }, + observability: { retention: 'metadata-only', capture_prompt: false, capture_output: false }, ...overrides + }); +} +test('observer captures effective defaults, versions, timing and usage without strings or bodies', async () => { + const input = request(); + const observer = new LocalExecutionObserver(); + const adapter = new MockTextAdapter({ content: 'SECRET_OUTPUT', provider_request_id: 'SECRET_PROVIDER', warnings: [{ code: 'PROVIDER_WARNING', message: 'SECRET_WARNING', details: { secret: 'SECRET_DETAILS' } }] }); + const result = await executePrompt(input, { adapter, observer, clock: () => 0, provenance: { validation: { valid: true, diagnostics: [{ severity: 'warning', message: 'SECRET_LINT', path: '/SECRET_PATH' }] } } }); + assert.equal(result.status, 'succeeded'); + const [envelope] = observer.snapshot(); + assert.ok(validateExecutionProvenance(envelope)); + const record = envelope.record; + assert.equal(record.prompt.version, definition.version); + assert.equal(record.prompt.spec_version, '1.0.0'); + assert.equal(record.correlation_id, 'build_observer'); + assert.equal(record.parameters.max_output_tokens, 256); + assert.equal(record.parameters_status, 'resolved'); + assert.equal(record.stop_sequence_count, 1); + assert.equal(record.usage.total_tokens, 22); + assert.equal(record.validation.warnings, 1); + assert.doesNotMatch(JSON.stringify(envelope), /SECRET_/); + assert.deepEqual(createExecutionProvenance(input, result), createExecutionProvenance(input, result)); + envelope.record.status = 'failed'; + assert.equal(validateExecutionProvenance(envelope), false); + assert.equal(observer.snapshot()[0].record.status, 'succeeded'); +}); +test('non-public and omit policies suppress content hashes', async () => { + const input = request({}, 'restricted'); + const observer = new LocalExecutionObserver(); + const result = await executePrompt(input, { adapter: new MockTextAdapter(), observer }); + const record = observer.snapshot()[0].record; + assert.equal(record.rendered, undefined); + assert.equal(record.output, undefined); + const publicInput = request(); + const publicResult = await executePrompt(publicInput, { adapter: new MockTextAdapter() }); + assert.equal(createExecutionProvenance(publicInput, publicResult, { contentIdentities: 'omit' }).record.rendered, undefined); + assert.equal(createExecutionProvenance(input, result).record.validation.status, 'not-run'); +}); +test('observer records preflight, cancellation, timeout, and provider failures once', async () => { + const cancelled = new AbortController(); cancelled.abort(); + const scenarios = [ + [request({ capabilities: { required: ['text-generation', 'unsupported'], optional: [] } }), {}, 'failed'], + [request(), { signal: cancelled.signal }, 'cancelled'], + [request({ timeout_ms: 1 }), { adapter: new MockTextAdapter({ delay_ms: 30 }) }, 'timed-out'], + [request(), { adapter: new MockTextAdapter({ error: { category: 'internal', code: 'FAIL', message: 'SECRET_FAILURE', stage: 'adapter' } }) }, 'failed'] + ]; + for (const [input, options, status] of scenarios) { + const observer = new LocalExecutionObserver(); + const result = await executePrompt(input, { adapter: new MockTextAdapter(), ...options, observer }); + assert.equal(result.status, status); + assert.equal(observer.snapshot().length, 1); + assert.equal(observer.snapshot()[0].record.status, status); + assert.doesNotMatch(JSON.stringify(observer.snapshot()), /SECRET_/); + } +}); +test('sink rejection, mutation and timeout do not obscure success or retry provider', async () => { + for (const observer of [{ observe() { throw new Error('SECRET_SINK'); } }, { observe() { return new Promise(() => {}); } }, { observe(record) { record.record.status = 'failed'; } }]) { + const adapter = new MockTextAdapter(); + const result = await executePrompt(request(), { adapter, observer, observerTimeoutMs: 5 }); + assert.equal(result.status, 'succeeded'); + assert.equal(adapter.calls.length, 1); + assert.ok(result.warnings.some(x => x.code === 'OBSERVATION_DELIVERY_FAILED')); + assert.doesNotMatch(JSON.stringify(result.warnings), /SECRET_SINK/); + } +}); +test('local observer is bounded, isolated, and clearable', async () => { + const observer = new LocalExecutionObserver({ capacity: 1 }); + await executePrompt(request(), { adapter: new MockTextAdapter(), observer }); + await executePrompt(request({ execution_id: 'exec_second' }), { adapter: new MockTextAdapter(), observer }); + assert.equal(observer.snapshot().length, 1); + assert.equal(observer.snapshot()[0].record.execution_id, 'exec_second'); + observer.clear(); assert.deepEqual(observer.snapshot(), []); +}); +test('structured-output success/failure revisions retain only matched outcome evidence', async () => { + for (const content of ['{"secret":"SECRET_PARSED"}', '{bad']) { + const input = request({ capabilities: { required: ['text-generation', 'structured-output'], optional: [] }, expected_output: { kind: 'json', media_type: 'application/json', validation: 'json-syntax' } }); + const result = await executePrompt(input, { adapter: new MockTextAdapter({ content }) }); + let structuredOutput; + try { structuredOutput = processStructuredOutput(input, result, { processing_id: 'processing_test', rawRetention: 'identity-only', providerConstraintMode: 'adapter-emulated' }); } + catch (error) { structuredOutput = error.failure; } + const envelope = createExecutionProvenance(input, result, { structuredOutput }); + assert.equal(envelope.record.structured_output.status, content === '{bad' ? 'failed' : 'validated'); + assert.doesNotMatch(JSON.stringify(envelope), /SECRET_/); + assert.throws(() => createExecutionProvenance(input, result, { structuredOutput: { ...structuredOutput, execution_id: 'other' } }), /mismatch/); + } +}); From 4fea82187f59b5b17c059d3d0a40bdd7aa230a66 Mon Sep 17 00:00:00 2001 From: Andrew Peris Date: Fri, 11 Sep 2026 08:19:59 -0400 Subject: [PATCH 2/3] Reject mismatched execution provenance inputs --- CONSTITUTION_CONFORMANCE.md | 5 +++- docs/execution-provenance.md | 9 +++++- src/prompt-sdk/provenance.js | 8 +++++ tests/prompt-sdk/provenance.test.js | 46 ++++++++++++++++++++++++++++- 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/CONSTITUTION_CONFORMANCE.md b/CONSTITUTION_CONFORMANCE.md index 81e9443..8e5b078 100644 --- a/CONSTITUTION_CONFORMANCE.md +++ b/CONSTITUTION_CONFORMANCE.md @@ -9,7 +9,10 @@ Accountable owner: @andrewperis; status: Conforming candidate pending owner merg Base revision: `07abeef7bd02ae63c5bc1505a0d02a20f680a0bc`. Scope: Execution provenance builder/validator, compiled pinned schema, optional executor observer, bounded local observer, docs, ADR 0007 and synthetic example. -Evidence: npm test: 74 passing tests. Codex valid/invalid provenance fixtures and deterministic validator generation checked. +Evidence: npm test: 77 passing tests. Codex valid/invalid provenance fixtures and deterministic validator generation checked. +PR #12 review hardening adds request/result target, classification and output +contract checks, including all classification downgrade pairs and fail-closed +observer behavior for a target-mismatch preflight result. No new constitutional exceptions. Public fixtures are synthetic. Body content, authorization and diagnostic strings are omitted; non-public content identities are suppressed. Sinks cannot change the provider result or trigger retries. diff --git a/docs/execution-provenance.md b/docs/execution-provenance.md index e2da419..3324aac 100644 --- a/docs/execution-provenance.md +++ b/docs/execution-provenance.md @@ -5,7 +5,7 @@ to later build manifests. Enable it with `executePrompt(request, { adapter, observer: new LocalExecutionObserver() })`. No observer means no record storage. Observers implement `async observe(record)`. The executor passes one frozen -record after any accepted execution finishes, including preflight failure, +record after an accepted execution with matching request/result identity finishes, including preflight failure, cancellation and timeout. Observer rejection, mutation attempts and deadline expiry add `OBSERVATION_DELIVERY_FAILED` to the result. Provider status is preserved and no execution is retried. The default observer deadline is 1000 ms; @@ -23,6 +23,13 @@ construction and later structured-output evidence. Options are captured automatically by the executor after negotiation. Manual callers must provide the resolved values or the record states `not-resolved`. +Manual construction rejects mismatched execution/correlation ids, target +adapter/provider/model ids, output kind/media type, and any output classification +below the rendered prompt. A matching id alone is not proof of origin; callers +still own the authenticity of the supplied evidence. Target-mismatch preflight +failures retain their original execution error, but cannot produce a matching +provenance record: the executor adds its static delivery warning instead. + Pass prompt validation/lint evidence as `provenance: { validation: report }` to the executor. Only outcome/counts survive; absent evidence is `not-run`. After structured processing, construct another record with `structuredOutput` diff --git a/src/prompt-sdk/provenance.js b/src/prompt-sdk/provenance.js index 5e158c8..dfd2b9a 100644 --- a/src/prompt-sdk/provenance.js +++ b/src/prompt-sdk/provenance.js @@ -32,6 +32,14 @@ export function validateExecutionProvenance(document) { export function createExecutionProvenance(request, result, { effectiveParameters, validation, structuredOutput, contentIdentities = 'public-only' } = {}) { if (!validateExecutionDocument(request).valid || request.kind !== 'execution-request' || !validateExecutionDocument(result).valid || result.kind !== 'execution-result') throw new Error('Invalid execution provenance inputs'); if (request.execution_id !== result.execution_id || request.correlation_id !== result.correlation_id) throw new Error('Execution provenance correlation mismatch'); + for (const field of ['adapter_id', 'provider_id', 'model_id']) { + if (request.target[field] !== result.identity[field]) throw new Error('Execution provenance target mismatch'); + } + if (result.output) { + const classifications = ['public', 'internal', 'confidential', 'restricted']; + if (classifications.indexOf(result.output.classification) < classifications.indexOf(request.rendered_prompt.classification)) throw new Error('Execution provenance classification downgrade'); + if (result.output.kind !== request.expected_output.kind || result.output.media_type !== request.expected_output.media_type) throw new Error('Execution provenance output contract mismatch'); + } if (!['public-only', 'omit'].includes(contentIdentities)) throw new Error('Invalid provenance identity policy'); let structured = { status: 'not-run' }; if (structuredOutput !== undefined) { diff --git a/tests/prompt-sdk/provenance.test.js b/tests/prompt-sdk/provenance.test.js index ca99e87..1e4f512 100644 --- a/tests/prompt-sdk/provenance.test.js +++ b/tests/prompt-sdk/provenance.test.js @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import test from 'node:test'; import { readFile } from 'node:fs/promises'; import { createHash } from 'node:crypto'; -import { canonicalJson, createMockContextPackage, createMockContextAuthorization, renderPromptWithContextPackage } from '../../src/prompt-sdk/index.js'; +import { canonicalJson, createMockContextPackage, createMockContextAuthorization, renderPromptWithContextPackage, validateExecutionDocument } from '../../src/prompt-sdk/index.js'; import { createExecutionRequest, renderPrompt, executePrompt, MockTextAdapter, LocalExecutionObserver, createExecutionProvenance, validateExecutionProvenance, processStructuredOutput } from '../../src/prompt-sdk/index.js'; const definition = JSON.parse(await readFile(new URL('../fixtures/prompt-definition.json', import.meta.url))); test('public context package/source versions survive; non-public packages are counted only', async () => { @@ -79,6 +79,50 @@ test('non-public and omit policies suppress content hashes', async () => { assert.equal(createExecutionProvenance(publicInput, publicResult, { contentIdentities: 'omit' }).record.rendered, undefined); assert.equal(createExecutionProvenance(input, result).record.validation.status, 'not-run'); }); +test('manual provenance rejects unrelated target identities despite matching correlation ids', async () => { + const input = request(); + const result = await executePrompt(input, { adapter: new MockTextAdapter() }); + for (const field of ['adapter_id', 'provider_id', 'model_id']) { + const unrelated = structuredClone(result); + unrelated.identity[field] = 'studio.unrelated.target'; + assert.equal(validateExecutionDocument(unrelated).valid, true); + assert.throws(() => createExecutionProvenance(input, unrelated), /target mismatch/); + } +}); +test('manual provenance rejects classification downgrades and mismatched output contracts', async () => { + const classifications = ['public', 'internal', 'confidential', 'restricted']; + for (const classification of classifications) { + const input = request({}, classification); + const result = await executePrompt(input, { adapter: new MockTextAdapter() }); + for (const outputClassification of classifications) { + const candidate = structuredClone(result); + candidate.output.classification = outputClassification; + assert.equal(validateExecutionDocument(candidate).valid, true); + if (classifications.indexOf(outputClassification) < classifications.indexOf(classification)) { + assert.throws(() => createExecutionProvenance(input, candidate), /classification downgrade/); + } else { + const record = createExecutionProvenance(input, candidate).record; + assert.equal(record.output !== undefined, outputClassification === 'public'); + } + } + const candidate = structuredClone(result); + Object.assign(candidate.output, { kind: 'json', media_type: 'application/json' }); + assert.equal(validateExecutionDocument(candidate).valid, true); + assert.throws(() => createExecutionProvenance(input, candidate), /output contract mismatch/); + } +}); +test('target-mismatch preflight preserves failure and warns instead of recording unrelated identity', async () => { + const input = request({ target: { adapter_id: 'studio.other.adapter', provider_id: 'studio-mock', model_id: 'mock-text-v1' } }); + const adapter = new MockTextAdapter(); + const observer = new LocalExecutionObserver(); + const result = await executePrompt(input, { adapter, observer }); + assert.equal(result.status, 'failed'); + assert.equal(result.error.code, 'EXECUTION_PREFLIGHT_REJECTED'); + assert.equal(adapter.calls.length, 0); + assert.deepEqual(observer.snapshot(), []); + assert.ok(result.warnings.some(warning => warning.code === 'OBSERVATION_DELIVERY_FAILED')); + assert.throws(() => createExecutionProvenance(input, result), /target mismatch/); +}); test('observer records preflight, cancellation, timeout, and provider failures once', async () => { const cancelled = new AbortController(); cancelled.abort(); const scenarios = [ From 5289044663e79a843dbf1157b947a763391051b0 Mon Sep 17 00:00:00 2001 From: Andrew Peris Date: Fri, 11 Sep 2026 08:38:28 -0400 Subject: [PATCH 3/3] Consume hardened provenance schema from Codex review --- CONSTITUTION_CONFORMANCE.md | 5 ++++- .../generate-provenance-schema-validator.mjs | 12 +++++----- .../generated/provenance-v1-schema.js | 6 +++-- tests/prompt-sdk/provenance.test.js | 22 +++++++++++++++++++ 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/CONSTITUTION_CONFORMANCE.md b/CONSTITUTION_CONFORMANCE.md index 8e5b078..10b2020 100644 --- a/CONSTITUTION_CONFORMANCE.md +++ b/CONSTITUTION_CONFORMANCE.md @@ -9,7 +9,10 @@ Accountable owner: @andrewperis; status: Conforming candidate pending owner merg Base revision: `07abeef7bd02ae63c5bc1505a0d02a20f680a0bc`. Scope: Execution provenance builder/validator, compiled pinned schema, optional executor observer, bounded local observer, docs, ADR 0007 and synthetic example. -Evidence: npm test: 77 passing tests. Codex valid/invalid provenance fixtures and deterministic validator generation checked. +Evidence: npm test: 78 passing tests. Codex valid/invalid provenance fixtures and deterministic validator generation checked. +Codex PR #9 review constraints are consumed from commit +`416f0493d5b7932b818387ea23030f6d0f89c395`; compiled validation enables RFC 3339 +format assertions and rejects contradictory records even with recomputed digests. PR #12 review hardening adds request/result target, classification and output contract checks, including all classification downgrade pairs and fail-closed observer behavior for a target-mismatch preflight result. diff --git a/scripts/generate-provenance-schema-validator.mjs b/scripts/generate-provenance-schema-validator.mjs index 4b91052..2c5ba4b 100644 --- a/scripts/generate-provenance-schema-validator.mjs +++ b/scripts/generate-provenance-schema-validator.mjs @@ -1,11 +1,13 @@ import { readFile, writeFile } from 'node:fs/promises'; import { createHash } from 'node:crypto'; import Ajv from 'ajv/dist/2020.js'; +import addFormats from 'ajv-formats'; import standaloneCode from 'ajv/dist/standalone/index.js'; const bytes = await readFile(process.argv[2]); -const commit = '901543a367664e9f1b6822304a74e37471104ee1'; -const hash = '0d3c4ab43dab1f05042613751e5238525f56aed8021b1b4f4d16e0797c5619cb'; -if (bytes.length !== 9617 || createHash('sha256').update(bytes).digest('hex') !== hash) throw new Error('Provenance schema identity mismatch'); -const ajv = new Ajv({ allErrors: true, strict: true, code: { source: true, esm: true } }); +const commit = '416f0493d5b7932b818387ea23030f6d0f89c395'; +const hash = 'd1f897fdd40c8a513f2f3dc9c44728ec124e53a57977a1b11b04e00953020118'; +if (bytes.length !== 13143 || createHash('sha256').update(bytes).digest('hex') !== hash) throw new Error('Provenance schema identity mismatch'); +const ajv = new Ajv({ allErrors: true, strict: true, strictRequired: false, code: { source: true, esm: true } }); +addFormats(ajv); const code = standaloneCode(ajv, ajv.compile(JSON.parse(bytes))); -await writeFile(new URL('../src/prompt-sdk/generated/provenance-v1-schema.js', import.meta.url), `// Generated from DefinitelySecureStudio/codex@${commit}; SHA256 ${hash}\n${code}`); +await writeFile(new URL('../src/prompt-sdk/generated/provenance-v1-schema.js', import.meta.url), `// Generated from DefinitelySecureStudio/codex@${commit}; SHA256 ${hash}\nimport { createRequire } from 'node:module';\nconst require = createRequire(import.meta.url);\n${code}`); diff --git a/src/prompt-sdk/generated/provenance-v1-schema.js b/src/prompt-sdk/generated/provenance-v1-schema.js index e2fbc62..76963da 100644 --- a/src/prompt-sdk/generated/provenance-v1-schema.js +++ b/src/prompt-sdk/generated/provenance-v1-schema.js @@ -1,2 +1,4 @@ -// Generated from DefinitelySecureStudio/codex@901543a367664e9f1b6822304a74e37471104ee1; SHA256 0d3c4ab43dab1f05042613751e5238525f56aed8021b1b4f4d16e0797c5619cb -"use strict";export const validate = validate20;export default validate20;const schema31 = {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"urn:definitely-secure:contract:execution-provenance:1.0.0:record","type":"object","additionalProperties":false,"required":["spec_version","kind","record","identity"],"properties":{"spec_version":{"const":"1.0.0"},"kind":{"const":"execution-provenance"},"record":{"type":"object","additionalProperties":false,"required":["execution_id","prompt","contexts","redacted_context_count","target","identity","parameters","parameters_status","stop_sequence_count","timing","status","finish_reason","validation","structured_output","policy"],"properties":{"execution_id":{"type":"string"},"correlation_id":{"type":"string"},"prompt":{"type":"object","additionalProperties":false,"required":["id","version","spec_version"],"properties":{"id":{"type":"string"},"version":{"type":"string"},"spec_version":{"type":"string"}}},"rendered":{"type":"object","additionalProperties":false,"required":["byte_size","sha256"],"properties":{"byte_size":{"type":"integer","minimum":0},"sha256":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}}},"contexts":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["slot","classification"],"properties":{"slot":{"type":"string"},"classification":{"type":"string"},"package":{"type":"object","additionalProperties":false,"required":["id","version","instance_id","manifest_sha256"],"properties":{"id":{"type":"string"},"version":{"type":"string"},"instance_id":{"type":"string"},"manifest_sha256":{"type":"string"}}},"sources":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["source_id","version","kind","classification"],"properties":{"source_id":{"type":"string"},"version":{"type":"string"},"kind":{"type":"string"},"classification":{"type":"string"}}}}}}},"redacted_context_count":{"type":"integer","minimum":0},"target":{"type":"object","additionalProperties":false,"required":["adapter_id","provider_id","model_id"],"properties":{"adapter_id":{"type":"string"},"provider_id":{"type":"string"},"model_id":{"type":"string"}}},"identity":{"type":"object","additionalProperties":false,"required":["adapter_id","adapter_version","provider_id","model_id"],"properties":{"adapter_id":{"type":"string"},"adapter_version":{"type":"string"},"provider_id":{"type":"string"},"model_id":{"type":"string"},"model_revision":{"type":"string"}}},"parameters":{"type":"object","additionalProperties":false,"required":[],"properties":{"max_output_tokens":{"type":"number"},"temperature":{"type":"number"},"top_p":{"type":"number"},"seed":{"type":"number"}}},"parameters_status":{"enum":["resolved","not-resolved"]},"stop_sequence_count":{"type":"integer","minimum":0},"timing":{"type":"object","additionalProperties":false,"required":["started_at","completed_at","duration_ms"],"properties":{"started_at":{"type":"string"},"completed_at":{"type":"string"},"duration_ms":{"type":"integer","minimum":0}}},"status":{"enum":["succeeded","failed","cancelled","timed-out"]},"finish_reason":{"enum":["stop","length","content-filter","cancelled","error","unknown"]},"usage":{"type":"object","additionalProperties":false,"required":["provider_reported"],"properties":{"provider_reported":{"type":"boolean"},"input_tokens":{"type":"integer","minimum":0},"output_tokens":{"type":"integer","minimum":0},"total_tokens":{"type":"integer","minimum":0}}},"output":{"type":"object","additionalProperties":false,"required":["byte_size","sha256"],"properties":{"byte_size":{"type":"integer","minimum":0},"sha256":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}}},"validation":{"type":"object","additionalProperties":false,"required":["status","errors","warnings"],"properties":{"status":{"enum":["not-run","passed","failed"]},"errors":{"type":"integer","minimum":0},"warnings":{"type":"integer","minimum":0}}},"structured_output":{"type":"object","additionalProperties":false,"required":["status"],"properties":{"status":{"enum":["not-run","validated","failed"]},"processing_id":{"type":"string"}}},"policy":{"type":"object","additionalProperties":false,"required":["content_identities","bodies"],"properties":{"content_identities":{"enum":["public-only","omit"]},"bodies":{"const":"omitted"}}}}},"identity":{"type":"object","additionalProperties":false,"required":["byte_size","sha256"],"properties":{"byte_size":{"type":"integer","minimum":0},"sha256":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}}}}};const func1 = Object.prototype.hasOwnProperty;const pattern4 = new RegExp("^sha256:[0-9a-f]{64}$", "u");function validate20(data, {instancePath="", parentData, parentDataProperty, rootData=data, dynamicAnchors={}}={}){/*# sourceURL="urn:definitely-secure:contract:execution-provenance:1.0.0:record" */;let vErrors = null;let errors = 0;const evaluated0 = validate20.evaluated;if(evaluated0.dynamicProps){evaluated0.props = undefined;}if(evaluated0.dynamicItems){evaluated0.items = undefined;}if(data && typeof data == "object" && !Array.isArray(data)){if(data.spec_version === undefined){const err0 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "spec_version"},message:"must have required property '"+"spec_version"+"'"};if(vErrors === null){vErrors = [err0];}else {vErrors.push(err0);}errors++;}if(data.kind === undefined){const err1 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "kind"},message:"must have required property '"+"kind"+"'"};if(vErrors === null){vErrors = [err1];}else {vErrors.push(err1);}errors++;}if(data.record === undefined){const err2 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "record"},message:"must have required property '"+"record"+"'"};if(vErrors === null){vErrors = [err2];}else {vErrors.push(err2);}errors++;}if(data.identity === undefined){const err3 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "identity"},message:"must have required property '"+"identity"+"'"};if(vErrors === null){vErrors = [err3];}else {vErrors.push(err3);}errors++;}for(const key0 in data){if(!((((key0 === "spec_version") || (key0 === "kind")) || (key0 === "record")) || (key0 === "identity"))){const err4 = {instancePath,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key0},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err4];}else {vErrors.push(err4);}errors++;}}if(data.spec_version !== undefined){if("1.0.0" !== data.spec_version){const err5 = {instancePath:instancePath+"/spec_version",schemaPath:"#/properties/spec_version/const",keyword:"const",params:{allowedValue: "1.0.0"},message:"must be equal to constant"};if(vErrors === null){vErrors = [err5];}else {vErrors.push(err5);}errors++;}}if(data.kind !== undefined){if("execution-provenance" !== data.kind){const err6 = {instancePath:instancePath+"/kind",schemaPath:"#/properties/kind/const",keyword:"const",params:{allowedValue: "execution-provenance"},message:"must be equal to constant"};if(vErrors === null){vErrors = [err6];}else {vErrors.push(err6);}errors++;}}if(data.record !== undefined){let data2 = data.record;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){if(data2.execution_id === undefined){const err7 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "execution_id"},message:"must have required property '"+"execution_id"+"'"};if(vErrors === null){vErrors = [err7];}else {vErrors.push(err7);}errors++;}if(data2.prompt === undefined){const err8 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "prompt"},message:"must have required property '"+"prompt"+"'"};if(vErrors === null){vErrors = [err8];}else {vErrors.push(err8);}errors++;}if(data2.contexts === undefined){const err9 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "contexts"},message:"must have required property '"+"contexts"+"'"};if(vErrors === null){vErrors = [err9];}else {vErrors.push(err9);}errors++;}if(data2.redacted_context_count === undefined){const err10 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "redacted_context_count"},message:"must have required property '"+"redacted_context_count"+"'"};if(vErrors === null){vErrors = [err10];}else {vErrors.push(err10);}errors++;}if(data2.target === undefined){const err11 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "target"},message:"must have required property '"+"target"+"'"};if(vErrors === null){vErrors = [err11];}else {vErrors.push(err11);}errors++;}if(data2.identity === undefined){const err12 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "identity"},message:"must have required property '"+"identity"+"'"};if(vErrors === null){vErrors = [err12];}else {vErrors.push(err12);}errors++;}if(data2.parameters === undefined){const err13 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "parameters"},message:"must have required property '"+"parameters"+"'"};if(vErrors === null){vErrors = [err13];}else {vErrors.push(err13);}errors++;}if(data2.parameters_status === undefined){const err14 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "parameters_status"},message:"must have required property '"+"parameters_status"+"'"};if(vErrors === null){vErrors = [err14];}else {vErrors.push(err14);}errors++;}if(data2.stop_sequence_count === undefined){const err15 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "stop_sequence_count"},message:"must have required property '"+"stop_sequence_count"+"'"};if(vErrors === null){vErrors = [err15];}else {vErrors.push(err15);}errors++;}if(data2.timing === undefined){const err16 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "timing"},message:"must have required property '"+"timing"+"'"};if(vErrors === null){vErrors = [err16];}else {vErrors.push(err16);}errors++;}if(data2.status === undefined){const err17 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "status"},message:"must have required property '"+"status"+"'"};if(vErrors === null){vErrors = [err17];}else {vErrors.push(err17);}errors++;}if(data2.finish_reason === undefined){const err18 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "finish_reason"},message:"must have required property '"+"finish_reason"+"'"};if(vErrors === null){vErrors = [err18];}else {vErrors.push(err18);}errors++;}if(data2.validation === undefined){const err19 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "validation"},message:"must have required property '"+"validation"+"'"};if(vErrors === null){vErrors = [err19];}else {vErrors.push(err19);}errors++;}if(data2.structured_output === undefined){const err20 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "structured_output"},message:"must have required property '"+"structured_output"+"'"};if(vErrors === null){vErrors = [err20];}else {vErrors.push(err20);}errors++;}if(data2.policy === undefined){const err21 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "policy"},message:"must have required property '"+"policy"+"'"};if(vErrors === null){vErrors = [err21];}else {vErrors.push(err21);}errors++;}for(const key1 in data2){if(!(func1.call(schema31.properties.record.properties, key1))){const err22 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key1},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err22];}else {vErrors.push(err22);}errors++;}}if(data2.execution_id !== undefined){if(typeof data2.execution_id !== "string"){const err23 = {instancePath:instancePath+"/record/execution_id",schemaPath:"#/properties/record/properties/execution_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err23];}else {vErrors.push(err23);}errors++;}}if(data2.correlation_id !== undefined){if(typeof data2.correlation_id !== "string"){const err24 = {instancePath:instancePath+"/record/correlation_id",schemaPath:"#/properties/record/properties/correlation_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err24];}else {vErrors.push(err24);}errors++;}}if(data2.prompt !== undefined){let data5 = data2.prompt;if(data5 && typeof data5 == "object" && !Array.isArray(data5)){if(data5.id === undefined){const err25 = {instancePath:instancePath+"/record/prompt",schemaPath:"#/properties/record/properties/prompt/required",keyword:"required",params:{missingProperty: "id"},message:"must have required property '"+"id"+"'"};if(vErrors === null){vErrors = [err25];}else {vErrors.push(err25);}errors++;}if(data5.version === undefined){const err26 = {instancePath:instancePath+"/record/prompt",schemaPath:"#/properties/record/properties/prompt/required",keyword:"required",params:{missingProperty: "version"},message:"must have required property '"+"version"+"'"};if(vErrors === null){vErrors = [err26];}else {vErrors.push(err26);}errors++;}if(data5.spec_version === undefined){const err27 = {instancePath:instancePath+"/record/prompt",schemaPath:"#/properties/record/properties/prompt/required",keyword:"required",params:{missingProperty: "spec_version"},message:"must have required property '"+"spec_version"+"'"};if(vErrors === null){vErrors = [err27];}else {vErrors.push(err27);}errors++;}for(const key2 in data5){if(!(((key2 === "id") || (key2 === "version")) || (key2 === "spec_version"))){const err28 = {instancePath:instancePath+"/record/prompt",schemaPath:"#/properties/record/properties/prompt/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key2},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err28];}else {vErrors.push(err28);}errors++;}}if(data5.id !== undefined){if(typeof data5.id !== "string"){const err29 = {instancePath:instancePath+"/record/prompt/id",schemaPath:"#/properties/record/properties/prompt/properties/id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err29];}else {vErrors.push(err29);}errors++;}}if(data5.version !== undefined){if(typeof data5.version !== "string"){const err30 = {instancePath:instancePath+"/record/prompt/version",schemaPath:"#/properties/record/properties/prompt/properties/version/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err30];}else {vErrors.push(err30);}errors++;}}if(data5.spec_version !== undefined){if(typeof data5.spec_version !== "string"){const err31 = {instancePath:instancePath+"/record/prompt/spec_version",schemaPath:"#/properties/record/properties/prompt/properties/spec_version/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err31];}else {vErrors.push(err31);}errors++;}}}else {const err32 = {instancePath:instancePath+"/record/prompt",schemaPath:"#/properties/record/properties/prompt/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err32];}else {vErrors.push(err32);}errors++;}}if(data2.rendered !== undefined){let data9 = data2.rendered;if(data9 && typeof data9 == "object" && !Array.isArray(data9)){if(data9.byte_size === undefined){const err33 = {instancePath:instancePath+"/record/rendered",schemaPath:"#/properties/record/properties/rendered/required",keyword:"required",params:{missingProperty: "byte_size"},message:"must have required property '"+"byte_size"+"'"};if(vErrors === null){vErrors = [err33];}else {vErrors.push(err33);}errors++;}if(data9.sha256 === undefined){const err34 = {instancePath:instancePath+"/record/rendered",schemaPath:"#/properties/record/properties/rendered/required",keyword:"required",params:{missingProperty: "sha256"},message:"must have required property '"+"sha256"+"'"};if(vErrors === null){vErrors = [err34];}else {vErrors.push(err34);}errors++;}for(const key3 in data9){if(!((key3 === "byte_size") || (key3 === "sha256"))){const err35 = {instancePath:instancePath+"/record/rendered",schemaPath:"#/properties/record/properties/rendered/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key3},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err35];}else {vErrors.push(err35);}errors++;}}if(data9.byte_size !== undefined){let data10 = data9.byte_size;if(!(((typeof data10 == "number") && (!(data10 % 1) && !isNaN(data10))) && (isFinite(data10)))){const err36 = {instancePath:instancePath+"/record/rendered/byte_size",schemaPath:"#/properties/record/properties/rendered/properties/byte_size/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err36];}else {vErrors.push(err36);}errors++;}if((typeof data10 == "number") && (isFinite(data10))){if(data10 < 0 || isNaN(data10)){const err37 = {instancePath:instancePath+"/record/rendered/byte_size",schemaPath:"#/properties/record/properties/rendered/properties/byte_size/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err37];}else {vErrors.push(err37);}errors++;}}}if(data9.sha256 !== undefined){let data11 = data9.sha256;if(typeof data11 === "string"){if(!pattern4.test(data11)){const err38 = {instancePath:instancePath+"/record/rendered/sha256",schemaPath:"#/properties/record/properties/rendered/properties/sha256/pattern",keyword:"pattern",params:{pattern: "^sha256:[0-9a-f]{64}$"},message:"must match pattern \""+"^sha256:[0-9a-f]{64}$"+"\""};if(vErrors === null){vErrors = [err38];}else {vErrors.push(err38);}errors++;}}else {const err39 = {instancePath:instancePath+"/record/rendered/sha256",schemaPath:"#/properties/record/properties/rendered/properties/sha256/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err39];}else {vErrors.push(err39);}errors++;}}}else {const err40 = {instancePath:instancePath+"/record/rendered",schemaPath:"#/properties/record/properties/rendered/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err40];}else {vErrors.push(err40);}errors++;}}if(data2.contexts !== undefined){let data12 = data2.contexts;if(Array.isArray(data12)){const len0 = data12.length;for(let i0=0; i0=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err70];}else {vErrors.push(err70);}errors++;}}}if(data2.target !== undefined){let data28 = data2.target;if(data28 && typeof data28 == "object" && !Array.isArray(data28)){if(data28.adapter_id === undefined){const err71 = {instancePath:instancePath+"/record/target",schemaPath:"#/properties/record/properties/target/required",keyword:"required",params:{missingProperty: "adapter_id"},message:"must have required property '"+"adapter_id"+"'"};if(vErrors === null){vErrors = [err71];}else {vErrors.push(err71);}errors++;}if(data28.provider_id === undefined){const err72 = {instancePath:instancePath+"/record/target",schemaPath:"#/properties/record/properties/target/required",keyword:"required",params:{missingProperty: "provider_id"},message:"must have required property '"+"provider_id"+"'"};if(vErrors === null){vErrors = [err72];}else {vErrors.push(err72);}errors++;}if(data28.model_id === undefined){const err73 = {instancePath:instancePath+"/record/target",schemaPath:"#/properties/record/properties/target/required",keyword:"required",params:{missingProperty: "model_id"},message:"must have required property '"+"model_id"+"'"};if(vErrors === null){vErrors = [err73];}else {vErrors.push(err73);}errors++;}for(const key7 in data28){if(!(((key7 === "adapter_id") || (key7 === "provider_id")) || (key7 === "model_id"))){const err74 = {instancePath:instancePath+"/record/target",schemaPath:"#/properties/record/properties/target/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key7},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err74];}else {vErrors.push(err74);}errors++;}}if(data28.adapter_id !== undefined){if(typeof data28.adapter_id !== "string"){const err75 = {instancePath:instancePath+"/record/target/adapter_id",schemaPath:"#/properties/record/properties/target/properties/adapter_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err75];}else {vErrors.push(err75);}errors++;}}if(data28.provider_id !== undefined){if(typeof data28.provider_id !== "string"){const err76 = {instancePath:instancePath+"/record/target/provider_id",schemaPath:"#/properties/record/properties/target/properties/provider_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err76];}else {vErrors.push(err76);}errors++;}}if(data28.model_id !== undefined){if(typeof data28.model_id !== "string"){const err77 = {instancePath:instancePath+"/record/target/model_id",schemaPath:"#/properties/record/properties/target/properties/model_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err77];}else {vErrors.push(err77);}errors++;}}}else {const err78 = {instancePath:instancePath+"/record/target",schemaPath:"#/properties/record/properties/target/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err78];}else {vErrors.push(err78);}errors++;}}if(data2.identity !== undefined){let data32 = data2.identity;if(data32 && typeof data32 == "object" && !Array.isArray(data32)){if(data32.adapter_id === undefined){const err79 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/required",keyword:"required",params:{missingProperty: "adapter_id"},message:"must have required property '"+"adapter_id"+"'"};if(vErrors === null){vErrors = [err79];}else {vErrors.push(err79);}errors++;}if(data32.adapter_version === undefined){const err80 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/required",keyword:"required",params:{missingProperty: "adapter_version"},message:"must have required property '"+"adapter_version"+"'"};if(vErrors === null){vErrors = [err80];}else {vErrors.push(err80);}errors++;}if(data32.provider_id === undefined){const err81 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/required",keyword:"required",params:{missingProperty: "provider_id"},message:"must have required property '"+"provider_id"+"'"};if(vErrors === null){vErrors = [err81];}else {vErrors.push(err81);}errors++;}if(data32.model_id === undefined){const err82 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/required",keyword:"required",params:{missingProperty: "model_id"},message:"must have required property '"+"model_id"+"'"};if(vErrors === null){vErrors = [err82];}else {vErrors.push(err82);}errors++;}for(const key8 in data32){if(!(((((key8 === "adapter_id") || (key8 === "adapter_version")) || (key8 === "provider_id")) || (key8 === "model_id")) || (key8 === "model_revision"))){const err83 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key8},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err83];}else {vErrors.push(err83);}errors++;}}if(data32.adapter_id !== undefined){if(typeof data32.adapter_id !== "string"){const err84 = {instancePath:instancePath+"/record/identity/adapter_id",schemaPath:"#/properties/record/properties/identity/properties/adapter_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err84];}else {vErrors.push(err84);}errors++;}}if(data32.adapter_version !== undefined){if(typeof data32.adapter_version !== "string"){const err85 = {instancePath:instancePath+"/record/identity/adapter_version",schemaPath:"#/properties/record/properties/identity/properties/adapter_version/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err85];}else {vErrors.push(err85);}errors++;}}if(data32.provider_id !== undefined){if(typeof data32.provider_id !== "string"){const err86 = {instancePath:instancePath+"/record/identity/provider_id",schemaPath:"#/properties/record/properties/identity/properties/provider_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err86];}else {vErrors.push(err86);}errors++;}}if(data32.model_id !== undefined){if(typeof data32.model_id !== "string"){const err87 = {instancePath:instancePath+"/record/identity/model_id",schemaPath:"#/properties/record/properties/identity/properties/model_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err87];}else {vErrors.push(err87);}errors++;}}if(data32.model_revision !== undefined){if(typeof data32.model_revision !== "string"){const err88 = {instancePath:instancePath+"/record/identity/model_revision",schemaPath:"#/properties/record/properties/identity/properties/model_revision/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err88];}else {vErrors.push(err88);}errors++;}}}else {const err89 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err89];}else {vErrors.push(err89);}errors++;}}if(data2.parameters !== undefined){let data38 = data2.parameters;if(data38 && typeof data38 == "object" && !Array.isArray(data38)){for(const key9 in data38){if(!((((key9 === "max_output_tokens") || (key9 === "temperature")) || (key9 === "top_p")) || (key9 === "seed"))){const err90 = {instancePath:instancePath+"/record/parameters",schemaPath:"#/properties/record/properties/parameters/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key9},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err90];}else {vErrors.push(err90);}errors++;}}if(data38.max_output_tokens !== undefined){let data39 = data38.max_output_tokens;if(!((typeof data39 == "number") && (isFinite(data39)))){const err91 = {instancePath:instancePath+"/record/parameters/max_output_tokens",schemaPath:"#/properties/record/properties/parameters/properties/max_output_tokens/type",keyword:"type",params:{type: "number"},message:"must be number"};if(vErrors === null){vErrors = [err91];}else {vErrors.push(err91);}errors++;}}if(data38.temperature !== undefined){let data40 = data38.temperature;if(!((typeof data40 == "number") && (isFinite(data40)))){const err92 = {instancePath:instancePath+"/record/parameters/temperature",schemaPath:"#/properties/record/properties/parameters/properties/temperature/type",keyword:"type",params:{type: "number"},message:"must be number"};if(vErrors === null){vErrors = [err92];}else {vErrors.push(err92);}errors++;}}if(data38.top_p !== undefined){let data41 = data38.top_p;if(!((typeof data41 == "number") && (isFinite(data41)))){const err93 = {instancePath:instancePath+"/record/parameters/top_p",schemaPath:"#/properties/record/properties/parameters/properties/top_p/type",keyword:"type",params:{type: "number"},message:"must be number"};if(vErrors === null){vErrors = [err93];}else {vErrors.push(err93);}errors++;}}if(data38.seed !== undefined){let data42 = data38.seed;if(!((typeof data42 == "number") && (isFinite(data42)))){const err94 = {instancePath:instancePath+"/record/parameters/seed",schemaPath:"#/properties/record/properties/parameters/properties/seed/type",keyword:"type",params:{type: "number"},message:"must be number"};if(vErrors === null){vErrors = [err94];}else {vErrors.push(err94);}errors++;}}}else {const err95 = {instancePath:instancePath+"/record/parameters",schemaPath:"#/properties/record/properties/parameters/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err95];}else {vErrors.push(err95);}errors++;}}if(data2.parameters_status !== undefined){let data43 = data2.parameters_status;if(!((data43 === "resolved") || (data43 === "not-resolved"))){const err96 = {instancePath:instancePath+"/record/parameters_status",schemaPath:"#/properties/record/properties/parameters_status/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.parameters_status.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err96];}else {vErrors.push(err96);}errors++;}}if(data2.stop_sequence_count !== undefined){let data44 = data2.stop_sequence_count;if(!(((typeof data44 == "number") && (!(data44 % 1) && !isNaN(data44))) && (isFinite(data44)))){const err97 = {instancePath:instancePath+"/record/stop_sequence_count",schemaPath:"#/properties/record/properties/stop_sequence_count/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err97];}else {vErrors.push(err97);}errors++;}if((typeof data44 == "number") && (isFinite(data44))){if(data44 < 0 || isNaN(data44)){const err98 = {instancePath:instancePath+"/record/stop_sequence_count",schemaPath:"#/properties/record/properties/stop_sequence_count/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err98];}else {vErrors.push(err98);}errors++;}}}if(data2.timing !== undefined){let data45 = data2.timing;if(data45 && typeof data45 == "object" && !Array.isArray(data45)){if(data45.started_at === undefined){const err99 = {instancePath:instancePath+"/record/timing",schemaPath:"#/properties/record/properties/timing/required",keyword:"required",params:{missingProperty: "started_at"},message:"must have required property '"+"started_at"+"'"};if(vErrors === null){vErrors = [err99];}else {vErrors.push(err99);}errors++;}if(data45.completed_at === undefined){const err100 = {instancePath:instancePath+"/record/timing",schemaPath:"#/properties/record/properties/timing/required",keyword:"required",params:{missingProperty: "completed_at"},message:"must have required property '"+"completed_at"+"'"};if(vErrors === null){vErrors = [err100];}else {vErrors.push(err100);}errors++;}if(data45.duration_ms === undefined){const err101 = {instancePath:instancePath+"/record/timing",schemaPath:"#/properties/record/properties/timing/required",keyword:"required",params:{missingProperty: "duration_ms"},message:"must have required property '"+"duration_ms"+"'"};if(vErrors === null){vErrors = [err101];}else {vErrors.push(err101);}errors++;}for(const key10 in data45){if(!(((key10 === "started_at") || (key10 === "completed_at")) || (key10 === "duration_ms"))){const err102 = {instancePath:instancePath+"/record/timing",schemaPath:"#/properties/record/properties/timing/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key10},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err102];}else {vErrors.push(err102);}errors++;}}if(data45.started_at !== undefined){if(typeof data45.started_at !== "string"){const err103 = {instancePath:instancePath+"/record/timing/started_at",schemaPath:"#/properties/record/properties/timing/properties/started_at/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err103];}else {vErrors.push(err103);}errors++;}}if(data45.completed_at !== undefined){if(typeof data45.completed_at !== "string"){const err104 = {instancePath:instancePath+"/record/timing/completed_at",schemaPath:"#/properties/record/properties/timing/properties/completed_at/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err104];}else {vErrors.push(err104);}errors++;}}if(data45.duration_ms !== undefined){let data48 = data45.duration_ms;if(!(((typeof data48 == "number") && (!(data48 % 1) && !isNaN(data48))) && (isFinite(data48)))){const err105 = {instancePath:instancePath+"/record/timing/duration_ms",schemaPath:"#/properties/record/properties/timing/properties/duration_ms/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err105];}else {vErrors.push(err105);}errors++;}if((typeof data48 == "number") && (isFinite(data48))){if(data48 < 0 || isNaN(data48)){const err106 = {instancePath:instancePath+"/record/timing/duration_ms",schemaPath:"#/properties/record/properties/timing/properties/duration_ms/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err106];}else {vErrors.push(err106);}errors++;}}}}else {const err107 = {instancePath:instancePath+"/record/timing",schemaPath:"#/properties/record/properties/timing/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err107];}else {vErrors.push(err107);}errors++;}}if(data2.status !== undefined){let data49 = data2.status;if(!((((data49 === "succeeded") || (data49 === "failed")) || (data49 === "cancelled")) || (data49 === "timed-out"))){const err108 = {instancePath:instancePath+"/record/status",schemaPath:"#/properties/record/properties/status/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.status.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err108];}else {vErrors.push(err108);}errors++;}}if(data2.finish_reason !== undefined){let data50 = data2.finish_reason;if(!((((((data50 === "stop") || (data50 === "length")) || (data50 === "content-filter")) || (data50 === "cancelled")) || (data50 === "error")) || (data50 === "unknown"))){const err109 = {instancePath:instancePath+"/record/finish_reason",schemaPath:"#/properties/record/properties/finish_reason/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.finish_reason.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err109];}else {vErrors.push(err109);}errors++;}}if(data2.usage !== undefined){let data51 = data2.usage;if(data51 && typeof data51 == "object" && !Array.isArray(data51)){if(data51.provider_reported === undefined){const err110 = {instancePath:instancePath+"/record/usage",schemaPath:"#/properties/record/properties/usage/required",keyword:"required",params:{missingProperty: "provider_reported"},message:"must have required property '"+"provider_reported"+"'"};if(vErrors === null){vErrors = [err110];}else {vErrors.push(err110);}errors++;}for(const key11 in data51){if(!((((key11 === "provider_reported") || (key11 === "input_tokens")) || (key11 === "output_tokens")) || (key11 === "total_tokens"))){const err111 = {instancePath:instancePath+"/record/usage",schemaPath:"#/properties/record/properties/usage/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key11},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err111];}else {vErrors.push(err111);}errors++;}}if(data51.provider_reported !== undefined){if(typeof data51.provider_reported !== "boolean"){const err112 = {instancePath:instancePath+"/record/usage/provider_reported",schemaPath:"#/properties/record/properties/usage/properties/provider_reported/type",keyword:"type",params:{type: "boolean"},message:"must be boolean"};if(vErrors === null){vErrors = [err112];}else {vErrors.push(err112);}errors++;}}if(data51.input_tokens !== undefined){let data53 = data51.input_tokens;if(!(((typeof data53 == "number") && (!(data53 % 1) && !isNaN(data53))) && (isFinite(data53)))){const err113 = {instancePath:instancePath+"/record/usage/input_tokens",schemaPath:"#/properties/record/properties/usage/properties/input_tokens/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err113];}else {vErrors.push(err113);}errors++;}if((typeof data53 == "number") && (isFinite(data53))){if(data53 < 0 || isNaN(data53)){const err114 = {instancePath:instancePath+"/record/usage/input_tokens",schemaPath:"#/properties/record/properties/usage/properties/input_tokens/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err114];}else {vErrors.push(err114);}errors++;}}}if(data51.output_tokens !== undefined){let data54 = data51.output_tokens;if(!(((typeof data54 == "number") && (!(data54 % 1) && !isNaN(data54))) && (isFinite(data54)))){const err115 = {instancePath:instancePath+"/record/usage/output_tokens",schemaPath:"#/properties/record/properties/usage/properties/output_tokens/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err115];}else {vErrors.push(err115);}errors++;}if((typeof data54 == "number") && (isFinite(data54))){if(data54 < 0 || isNaN(data54)){const err116 = {instancePath:instancePath+"/record/usage/output_tokens",schemaPath:"#/properties/record/properties/usage/properties/output_tokens/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err116];}else {vErrors.push(err116);}errors++;}}}if(data51.total_tokens !== undefined){let data55 = data51.total_tokens;if(!(((typeof data55 == "number") && (!(data55 % 1) && !isNaN(data55))) && (isFinite(data55)))){const err117 = {instancePath:instancePath+"/record/usage/total_tokens",schemaPath:"#/properties/record/properties/usage/properties/total_tokens/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err117];}else {vErrors.push(err117);}errors++;}if((typeof data55 == "number") && (isFinite(data55))){if(data55 < 0 || isNaN(data55)){const err118 = {instancePath:instancePath+"/record/usage/total_tokens",schemaPath:"#/properties/record/properties/usage/properties/total_tokens/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err118];}else {vErrors.push(err118);}errors++;}}}}else {const err119 = {instancePath:instancePath+"/record/usage",schemaPath:"#/properties/record/properties/usage/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err119];}else {vErrors.push(err119);}errors++;}}if(data2.output !== undefined){let data56 = data2.output;if(data56 && typeof data56 == "object" && !Array.isArray(data56)){if(data56.byte_size === undefined){const err120 = {instancePath:instancePath+"/record/output",schemaPath:"#/properties/record/properties/output/required",keyword:"required",params:{missingProperty: "byte_size"},message:"must have required property '"+"byte_size"+"'"};if(vErrors === null){vErrors = [err120];}else {vErrors.push(err120);}errors++;}if(data56.sha256 === undefined){const err121 = {instancePath:instancePath+"/record/output",schemaPath:"#/properties/record/properties/output/required",keyword:"required",params:{missingProperty: "sha256"},message:"must have required property '"+"sha256"+"'"};if(vErrors === null){vErrors = [err121];}else {vErrors.push(err121);}errors++;}for(const key12 in data56){if(!((key12 === "byte_size") || (key12 === "sha256"))){const err122 = {instancePath:instancePath+"/record/output",schemaPath:"#/properties/record/properties/output/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key12},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err122];}else {vErrors.push(err122);}errors++;}}if(data56.byte_size !== undefined){let data57 = data56.byte_size;if(!(((typeof data57 == "number") && (!(data57 % 1) && !isNaN(data57))) && (isFinite(data57)))){const err123 = {instancePath:instancePath+"/record/output/byte_size",schemaPath:"#/properties/record/properties/output/properties/byte_size/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err123];}else {vErrors.push(err123);}errors++;}if((typeof data57 == "number") && (isFinite(data57))){if(data57 < 0 || isNaN(data57)){const err124 = {instancePath:instancePath+"/record/output/byte_size",schemaPath:"#/properties/record/properties/output/properties/byte_size/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err124];}else {vErrors.push(err124);}errors++;}}}if(data56.sha256 !== undefined){let data58 = data56.sha256;if(typeof data58 === "string"){if(!pattern4.test(data58)){const err125 = {instancePath:instancePath+"/record/output/sha256",schemaPath:"#/properties/record/properties/output/properties/sha256/pattern",keyword:"pattern",params:{pattern: "^sha256:[0-9a-f]{64}$"},message:"must match pattern \""+"^sha256:[0-9a-f]{64}$"+"\""};if(vErrors === null){vErrors = [err125];}else {vErrors.push(err125);}errors++;}}else {const err126 = {instancePath:instancePath+"/record/output/sha256",schemaPath:"#/properties/record/properties/output/properties/sha256/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err126];}else {vErrors.push(err126);}errors++;}}}else {const err127 = {instancePath:instancePath+"/record/output",schemaPath:"#/properties/record/properties/output/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err127];}else {vErrors.push(err127);}errors++;}}if(data2.validation !== undefined){let data59 = data2.validation;if(data59 && typeof data59 == "object" && !Array.isArray(data59)){if(data59.status === undefined){const err128 = {instancePath:instancePath+"/record/validation",schemaPath:"#/properties/record/properties/validation/required",keyword:"required",params:{missingProperty: "status"},message:"must have required property '"+"status"+"'"};if(vErrors === null){vErrors = [err128];}else {vErrors.push(err128);}errors++;}if(data59.errors === undefined){const err129 = {instancePath:instancePath+"/record/validation",schemaPath:"#/properties/record/properties/validation/required",keyword:"required",params:{missingProperty: "errors"},message:"must have required property '"+"errors"+"'"};if(vErrors === null){vErrors = [err129];}else {vErrors.push(err129);}errors++;}if(data59.warnings === undefined){const err130 = {instancePath:instancePath+"/record/validation",schemaPath:"#/properties/record/properties/validation/required",keyword:"required",params:{missingProperty: "warnings"},message:"must have required property '"+"warnings"+"'"};if(vErrors === null){vErrors = [err130];}else {vErrors.push(err130);}errors++;}for(const key13 in data59){if(!(((key13 === "status") || (key13 === "errors")) || (key13 === "warnings"))){const err131 = {instancePath:instancePath+"/record/validation",schemaPath:"#/properties/record/properties/validation/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key13},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err131];}else {vErrors.push(err131);}errors++;}}if(data59.status !== undefined){let data60 = data59.status;if(!(((data60 === "not-run") || (data60 === "passed")) || (data60 === "failed"))){const err132 = {instancePath:instancePath+"/record/validation/status",schemaPath:"#/properties/record/properties/validation/properties/status/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.validation.properties.status.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err132];}else {vErrors.push(err132);}errors++;}}if(data59.errors !== undefined){let data61 = data59.errors;if(!(((typeof data61 == "number") && (!(data61 % 1) && !isNaN(data61))) && (isFinite(data61)))){const err133 = {instancePath:instancePath+"/record/validation/errors",schemaPath:"#/properties/record/properties/validation/properties/errors/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err133];}else {vErrors.push(err133);}errors++;}if((typeof data61 == "number") && (isFinite(data61))){if(data61 < 0 || isNaN(data61)){const err134 = {instancePath:instancePath+"/record/validation/errors",schemaPath:"#/properties/record/properties/validation/properties/errors/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err134];}else {vErrors.push(err134);}errors++;}}}if(data59.warnings !== undefined){let data62 = data59.warnings;if(!(((typeof data62 == "number") && (!(data62 % 1) && !isNaN(data62))) && (isFinite(data62)))){const err135 = {instancePath:instancePath+"/record/validation/warnings",schemaPath:"#/properties/record/properties/validation/properties/warnings/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err135];}else {vErrors.push(err135);}errors++;}if((typeof data62 == "number") && (isFinite(data62))){if(data62 < 0 || isNaN(data62)){const err136 = {instancePath:instancePath+"/record/validation/warnings",schemaPath:"#/properties/record/properties/validation/properties/warnings/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err136];}else {vErrors.push(err136);}errors++;}}}}else {const err137 = {instancePath:instancePath+"/record/validation",schemaPath:"#/properties/record/properties/validation/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err137];}else {vErrors.push(err137);}errors++;}}if(data2.structured_output !== undefined){let data63 = data2.structured_output;if(data63 && typeof data63 == "object" && !Array.isArray(data63)){if(data63.status === undefined){const err138 = {instancePath:instancePath+"/record/structured_output",schemaPath:"#/properties/record/properties/structured_output/required",keyword:"required",params:{missingProperty: "status"},message:"must have required property '"+"status"+"'"};if(vErrors === null){vErrors = [err138];}else {vErrors.push(err138);}errors++;}for(const key14 in data63){if(!((key14 === "status") || (key14 === "processing_id"))){const err139 = {instancePath:instancePath+"/record/structured_output",schemaPath:"#/properties/record/properties/structured_output/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key14},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err139];}else {vErrors.push(err139);}errors++;}}if(data63.status !== undefined){let data64 = data63.status;if(!(((data64 === "not-run") || (data64 === "validated")) || (data64 === "failed"))){const err140 = {instancePath:instancePath+"/record/structured_output/status",schemaPath:"#/properties/record/properties/structured_output/properties/status/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.structured_output.properties.status.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err140];}else {vErrors.push(err140);}errors++;}}if(data63.processing_id !== undefined){if(typeof data63.processing_id !== "string"){const err141 = {instancePath:instancePath+"/record/structured_output/processing_id",schemaPath:"#/properties/record/properties/structured_output/properties/processing_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err141];}else {vErrors.push(err141);}errors++;}}}else {const err142 = {instancePath:instancePath+"/record/structured_output",schemaPath:"#/properties/record/properties/structured_output/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err142];}else {vErrors.push(err142);}errors++;}}if(data2.policy !== undefined){let data66 = data2.policy;if(data66 && typeof data66 == "object" && !Array.isArray(data66)){if(data66.content_identities === undefined){const err143 = {instancePath:instancePath+"/record/policy",schemaPath:"#/properties/record/properties/policy/required",keyword:"required",params:{missingProperty: "content_identities"},message:"must have required property '"+"content_identities"+"'"};if(vErrors === null){vErrors = [err143];}else {vErrors.push(err143);}errors++;}if(data66.bodies === undefined){const err144 = {instancePath:instancePath+"/record/policy",schemaPath:"#/properties/record/properties/policy/required",keyword:"required",params:{missingProperty: "bodies"},message:"must have required property '"+"bodies"+"'"};if(vErrors === null){vErrors = [err144];}else {vErrors.push(err144);}errors++;}for(const key15 in data66){if(!((key15 === "content_identities") || (key15 === "bodies"))){const err145 = {instancePath:instancePath+"/record/policy",schemaPath:"#/properties/record/properties/policy/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key15},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err145];}else {vErrors.push(err145);}errors++;}}if(data66.content_identities !== undefined){let data67 = data66.content_identities;if(!((data67 === "public-only") || (data67 === "omit"))){const err146 = {instancePath:instancePath+"/record/policy/content_identities",schemaPath:"#/properties/record/properties/policy/properties/content_identities/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.policy.properties.content_identities.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err146];}else {vErrors.push(err146);}errors++;}}if(data66.bodies !== undefined){if("omitted" !== data66.bodies){const err147 = {instancePath:instancePath+"/record/policy/bodies",schemaPath:"#/properties/record/properties/policy/properties/bodies/const",keyword:"const",params:{allowedValue: "omitted"},message:"must be equal to constant"};if(vErrors === null){vErrors = [err147];}else {vErrors.push(err147);}errors++;}}}else {const err148 = {instancePath:instancePath+"/record/policy",schemaPath:"#/properties/record/properties/policy/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err148];}else {vErrors.push(err148);}errors++;}}}else {const err149 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err149];}else {vErrors.push(err149);}errors++;}}if(data.identity !== undefined){let data69 = data.identity;if(data69 && typeof data69 == "object" && !Array.isArray(data69)){if(data69.byte_size === undefined){const err150 = {instancePath:instancePath+"/identity",schemaPath:"#/properties/identity/required",keyword:"required",params:{missingProperty: "byte_size"},message:"must have required property '"+"byte_size"+"'"};if(vErrors === null){vErrors = [err150];}else {vErrors.push(err150);}errors++;}if(data69.sha256 === undefined){const err151 = {instancePath:instancePath+"/identity",schemaPath:"#/properties/identity/required",keyword:"required",params:{missingProperty: "sha256"},message:"must have required property '"+"sha256"+"'"};if(vErrors === null){vErrors = [err151];}else {vErrors.push(err151);}errors++;}for(const key16 in data69){if(!((key16 === "byte_size") || (key16 === "sha256"))){const err152 = {instancePath:instancePath+"/identity",schemaPath:"#/properties/identity/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key16},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err152];}else {vErrors.push(err152);}errors++;}}if(data69.byte_size !== undefined){let data70 = data69.byte_size;if(!(((typeof data70 == "number") && (!(data70 % 1) && !isNaN(data70))) && (isFinite(data70)))){const err153 = {instancePath:instancePath+"/identity/byte_size",schemaPath:"#/properties/identity/properties/byte_size/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err153];}else {vErrors.push(err153);}errors++;}if((typeof data70 == "number") && (isFinite(data70))){if(data70 < 0 || isNaN(data70)){const err154 = {instancePath:instancePath+"/identity/byte_size",schemaPath:"#/properties/identity/properties/byte_size/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err154];}else {vErrors.push(err154);}errors++;}}}if(data69.sha256 !== undefined){let data71 = data69.sha256;if(typeof data71 === "string"){if(!pattern4.test(data71)){const err155 = {instancePath:instancePath+"/identity/sha256",schemaPath:"#/properties/identity/properties/sha256/pattern",keyword:"pattern",params:{pattern: "^sha256:[0-9a-f]{64}$"},message:"must match pattern \""+"^sha256:[0-9a-f]{64}$"+"\""};if(vErrors === null){vErrors = [err155];}else {vErrors.push(err155);}errors++;}}else {const err156 = {instancePath:instancePath+"/identity/sha256",schemaPath:"#/properties/identity/properties/sha256/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err156];}else {vErrors.push(err156);}errors++;}}}else {const err157 = {instancePath:instancePath+"/identity",schemaPath:"#/properties/identity/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err157];}else {vErrors.push(err157);}errors++;}}}else {const err158 = {instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err158];}else {vErrors.push(err158);}errors++;}validate20.errors = vErrors;return errors === 0;}validate20.evaluated = {"props":true,"dynamicProps":false,"dynamicItems":false}; \ No newline at end of file +// Generated from DefinitelySecureStudio/codex@416f0493d5b7932b818387ea23030f6d0f89c395; SHA256 d1f897fdd40c8a513f2f3dc9c44728ec124e53a57977a1b11b04e00953020118 +import { createRequire } from 'node:module'; +const require = createRequire(import.meta.url); +"use strict";export const validate = validate20;export default validate20;const schema31 = {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"urn:definitely-secure:contract:execution-provenance:1.0.0:record","type":"object","additionalProperties":false,"required":["spec_version","kind","record","identity"],"properties":{"spec_version":{"const":"1.0.0"},"kind":{"const":"execution-provenance"},"record":{"type":"object","additionalProperties":false,"required":["execution_id","prompt","contexts","redacted_context_count","target","identity","parameters","parameters_status","stop_sequence_count","timing","status","finish_reason","validation","structured_output","policy"],"properties":{"execution_id":{"type":"string"},"correlation_id":{"type":"string"},"prompt":{"type":"object","additionalProperties":false,"required":["id","version","spec_version"],"properties":{"id":{"type":"string"},"version":{"type":"string"},"spec_version":{"type":"string"}}},"rendered":{"type":"object","additionalProperties":false,"required":["byte_size","sha256"],"properties":{"byte_size":{"type":"integer","minimum":0},"sha256":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}}},"contexts":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["slot","classification"],"properties":{"slot":{"type":"string"},"classification":{"const":"public"},"package":{"type":"object","additionalProperties":false,"required":["id","version","instance_id","manifest_sha256"],"properties":{"id":{"type":"string"},"version":{"type":"string"},"instance_id":{"type":"string"},"manifest_sha256":{"type":"string"}}},"sources":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["source_id","version","kind","classification"],"properties":{"source_id":{"type":"string"},"version":{"type":"string"},"kind":{"type":"string"},"classification":{"const":"public"}}}}}}},"redacted_context_count":{"type":"integer","minimum":0},"target":{"type":"object","additionalProperties":false,"required":["adapter_id","provider_id","model_id"],"properties":{"adapter_id":{"type":"string"},"provider_id":{"type":"string"},"model_id":{"type":"string"}}},"identity":{"type":"object","additionalProperties":false,"required":["adapter_id","adapter_version","provider_id","model_id"],"properties":{"adapter_id":{"type":"string"},"adapter_version":{"type":"string"},"provider_id":{"type":"string"},"model_id":{"type":"string"},"model_revision":{"type":"string"}}},"parameters":{"type":"object","additionalProperties":false,"required":[],"properties":{"max_output_tokens":{"type":"integer","minimum":1},"temperature":{"type":"number","minimum":0,"maximum":2},"top_p":{"type":"number","exclusiveMinimum":0,"maximum":1},"seed":{"type":"integer","minimum":0,"maximum":9007199254740991}}},"parameters_status":{"enum":["resolved","not-resolved"]},"stop_sequence_count":{"type":"integer","minimum":0},"timing":{"type":"object","additionalProperties":false,"required":["started_at","completed_at","duration_ms"],"properties":{"started_at":{"type":"string","format":"date-time"},"completed_at":{"type":"string","format":"date-time"},"duration_ms":{"type":"integer","minimum":0}}},"status":{"enum":["succeeded","failed","cancelled","timed-out"]},"finish_reason":{"enum":["stop","length","content-filter","cancelled","error","unknown"]},"usage":{"type":"object","additionalProperties":false,"required":["provider_reported"],"properties":{"provider_reported":{"type":"boolean"},"input_tokens":{"type":"integer","minimum":0},"output_tokens":{"type":"integer","minimum":0},"total_tokens":{"type":"integer","minimum":0}}},"output":{"type":"object","additionalProperties":false,"required":["byte_size","sha256"],"properties":{"byte_size":{"type":"integer","minimum":0},"sha256":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}}},"validation":{"type":"object","additionalProperties":false,"required":["status","errors","warnings"],"properties":{"status":{"enum":["not-run","passed","failed"]},"errors":{"type":"integer","minimum":0},"warnings":{"type":"integer","minimum":0}}},"structured_output":{"type":"object","additionalProperties":false,"required":["status"],"properties":{"status":{"enum":["not-run","validated","failed"]},"processing_id":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$"}},"allOf":[{"if":{"properties":{"status":{"const":"not-run"}},"required":["status"]},"then":{"not":{"required":["processing_id"]}},"else":{"required":["processing_id"]}}]},"policy":{"type":"object","additionalProperties":false,"required":["content_identities","bodies"],"properties":{"content_identities":{"enum":["public-only","omit"]},"bodies":{"const":"omitted"}}}},"allOf":[{"if":{"properties":{"policy":{"type":"object","properties":{"content_identities":{"const":"omit"}},"required":["content_identities"]}},"required":["policy"]},"then":{"properties":{"contexts":{"type":"array","maxItems":0},"rendered":false,"output":false}}},{"if":{"properties":{"status":{"const":"succeeded"}},"required":["status"]},"then":{"properties":{"finish_reason":{"enum":["stop","length","content-filter","unknown"]}}}},{"if":{"properties":{"status":{"const":"failed"}},"required":["status"]},"then":{"properties":{"finish_reason":{"enum":["error"]}}}},{"if":{"properties":{"status":{"const":"cancelled"}},"required":["status"]},"then":{"properties":{"finish_reason":{"enum":["cancelled"]}}}},{"if":{"properties":{"status":{"const":"timed-out"}},"required":["status"]},"then":{"properties":{"finish_reason":{"enum":["error"]}}}}]},"identity":{"type":"object","additionalProperties":false,"required":["byte_size","sha256"],"properties":{"byte_size":{"type":"integer","minimum":0},"sha256":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}}}}};const func1 = Object.prototype.hasOwnProperty;const pattern4 = new RegExp("^sha256:[0-9a-f]{64}$", "u");const pattern6 = new RegExp("^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$", "u");const formats0 = require("ajv-formats/dist/formats").fullFormats["date-time"];function validate20(data, {instancePath="", parentData, parentDataProperty, rootData=data, dynamicAnchors={}}={}){/*# sourceURL="urn:definitely-secure:contract:execution-provenance:1.0.0:record" */;let vErrors = null;let errors = 0;const evaluated0 = validate20.evaluated;if(evaluated0.dynamicProps){evaluated0.props = undefined;}if(evaluated0.dynamicItems){evaluated0.items = undefined;}if(data && typeof data == "object" && !Array.isArray(data)){if(data.spec_version === undefined){const err0 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "spec_version"},message:"must have required property '"+"spec_version"+"'"};if(vErrors === null){vErrors = [err0];}else {vErrors.push(err0);}errors++;}if(data.kind === undefined){const err1 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "kind"},message:"must have required property '"+"kind"+"'"};if(vErrors === null){vErrors = [err1];}else {vErrors.push(err1);}errors++;}if(data.record === undefined){const err2 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "record"},message:"must have required property '"+"record"+"'"};if(vErrors === null){vErrors = [err2];}else {vErrors.push(err2);}errors++;}if(data.identity === undefined){const err3 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "identity"},message:"must have required property '"+"identity"+"'"};if(vErrors === null){vErrors = [err3];}else {vErrors.push(err3);}errors++;}for(const key0 in data){if(!((((key0 === "spec_version") || (key0 === "kind")) || (key0 === "record")) || (key0 === "identity"))){const err4 = {instancePath,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key0},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err4];}else {vErrors.push(err4);}errors++;}}if(data.spec_version !== undefined){if("1.0.0" !== data.spec_version){const err5 = {instancePath:instancePath+"/spec_version",schemaPath:"#/properties/spec_version/const",keyword:"const",params:{allowedValue: "1.0.0"},message:"must be equal to constant"};if(vErrors === null){vErrors = [err5];}else {vErrors.push(err5);}errors++;}}if(data.kind !== undefined){if("execution-provenance" !== data.kind){const err6 = {instancePath:instancePath+"/kind",schemaPath:"#/properties/kind/const",keyword:"const",params:{allowedValue: "execution-provenance"},message:"must be equal to constant"};if(vErrors === null){vErrors = [err6];}else {vErrors.push(err6);}errors++;}}if(data.record !== undefined){let data2 = data.record;const _errs7 = errors;let valid2 = true;const _errs8 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){let missing0;if((data2.policy === undefined) && (missing0 = "policy")){const err7 = {};if(vErrors === null){vErrors = [err7];}else {vErrors.push(err7);}errors++;}else {if(data2.policy !== undefined){let data3 = data2.policy;const _errs9 = errors;if(errors === _errs9){if(data3 && typeof data3 == "object" && !Array.isArray(data3)){let missing1;if((data3.content_identities === undefined) && (missing1 = "content_identities")){const err8 = {};if(vErrors === null){vErrors = [err8];}else {vErrors.push(err8);}errors++;}else {if(data3.content_identities !== undefined){if("omit" !== data3.content_identities){const err9 = {};if(vErrors === null){vErrors = [err9];}else {vErrors.push(err9);}errors++;}}}}else {const err10 = {};if(vErrors === null){vErrors = [err10];}else {vErrors.push(err10);}errors++;}}}}}var _valid0 = _errs8 === errors;errors = _errs7;if(vErrors !== null){if(_errs7){vErrors.length = _errs7;}else {vErrors = null;}}if(_valid0){const _errs12 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){if(data2.contexts !== undefined){let data5 = data2.contexts;if(Array.isArray(data5)){if(data5.length > 0){const err11 = {instancePath:instancePath+"/record/contexts",schemaPath:"#/properties/record/allOf/0/then/properties/contexts/maxItems",keyword:"maxItems",params:{limit: 0},message:"must NOT have more than 0 items"};if(vErrors === null){vErrors = [err11];}else {vErrors.push(err11);}errors++;}}else {const err12 = {instancePath:instancePath+"/record/contexts",schemaPath:"#/properties/record/allOf/0/then/properties/contexts/type",keyword:"type",params:{type: "array"},message:"must be array"};if(vErrors === null){vErrors = [err12];}else {vErrors.push(err12);}errors++;}}if(data2.rendered !== undefined){const err13 = {instancePath:instancePath+"/record/rendered",schemaPath:"#/properties/record/allOf/0/then/properties/rendered/false schema",keyword:"false schema",params:{},message:"boolean schema is false"};if(vErrors === null){vErrors = [err13];}else {vErrors.push(err13);}errors++;}if(data2.output !== undefined){const err14 = {instancePath:instancePath+"/record/output",schemaPath:"#/properties/record/allOf/0/then/properties/output/false schema",keyword:"false schema",params:{},message:"boolean schema is false"};if(vErrors === null){vErrors = [err14];}else {vErrors.push(err14);}errors++;}}var _valid0 = _errs12 === errors;valid2 = _valid0;if(valid2){var props0 = {};props0.contexts = true;props0.rendered = true;props0.output = true;props0.policy = true;}}if(!valid2){const err15 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/allOf/0/if",keyword:"if",params:{failingKeyword: "then"},message:"must match \"then\" schema"};if(vErrors === null){vErrors = [err15];}else {vErrors.push(err15);}errors++;}const _errs16 = errors;let valid6 = true;const _errs17 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){let missing2;if((data2.status === undefined) && (missing2 = "status")){const err16 = {};if(vErrors === null){vErrors = [err16];}else {vErrors.push(err16);}errors++;}else {if(data2.status !== undefined){if("succeeded" !== data2.status){const err17 = {};if(vErrors === null){vErrors = [err17];}else {vErrors.push(err17);}errors++;}}}}var _valid1 = _errs17 === errors;errors = _errs16;if(vErrors !== null){if(_errs16){vErrors.length = _errs16;}else {vErrors = null;}}if(_valid1){const _errs19 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){if(data2.finish_reason !== undefined){let data9 = data2.finish_reason;if(!((((data9 === "stop") || (data9 === "length")) || (data9 === "content-filter")) || (data9 === "unknown"))){const err18 = {instancePath:instancePath+"/record/finish_reason",schemaPath:"#/properties/record/allOf/1/then/properties/finish_reason/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.allOf[1].then.properties.finish_reason.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err18];}else {vErrors.push(err18);}errors++;}}}var _valid1 = _errs19 === errors;valid6 = _valid1;if(valid6){var props1 = {};props1.finish_reason = true;props1.status = true;}}if(!valid6){const err19 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/allOf/1/if",keyword:"if",params:{failingKeyword: "then"},message:"must match \"then\" schema"};if(vErrors === null){vErrors = [err19];}else {vErrors.push(err19);}errors++;}if(props0 !== true && props1 !== undefined){if(props1 === true){props0 = true;}else {props0 = props0 || {};Object.assign(props0, props1);}}const _errs22 = errors;let valid9 = true;const _errs23 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){let missing3;if((data2.status === undefined) && (missing3 = "status")){const err20 = {};if(vErrors === null){vErrors = [err20];}else {vErrors.push(err20);}errors++;}else {if(data2.status !== undefined){if("failed" !== data2.status){const err21 = {};if(vErrors === null){vErrors = [err21];}else {vErrors.push(err21);}errors++;}}}}var _valid2 = _errs23 === errors;errors = _errs22;if(vErrors !== null){if(_errs22){vErrors.length = _errs22;}else {vErrors = null;}}if(_valid2){const _errs25 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){if(data2.finish_reason !== undefined){if(!(data2.finish_reason === "error")){const err22 = {instancePath:instancePath+"/record/finish_reason",schemaPath:"#/properties/record/allOf/2/then/properties/finish_reason/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.allOf[2].then.properties.finish_reason.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err22];}else {vErrors.push(err22);}errors++;}}}var _valid2 = _errs25 === errors;valid9 = _valid2;if(valid9){var props2 = {};props2.finish_reason = true;props2.status = true;}}if(!valid9){const err23 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/allOf/2/if",keyword:"if",params:{failingKeyword: "then"},message:"must match \"then\" schema"};if(vErrors === null){vErrors = [err23];}else {vErrors.push(err23);}errors++;}if(props0 !== true && props2 !== undefined){if(props2 === true){props0 = true;}else {props0 = props0 || {};Object.assign(props0, props2);}}const _errs28 = errors;let valid12 = true;const _errs29 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){let missing4;if((data2.status === undefined) && (missing4 = "status")){const err24 = {};if(vErrors === null){vErrors = [err24];}else {vErrors.push(err24);}errors++;}else {if(data2.status !== undefined){if("cancelled" !== data2.status){const err25 = {};if(vErrors === null){vErrors = [err25];}else {vErrors.push(err25);}errors++;}}}}var _valid3 = _errs29 === errors;errors = _errs28;if(vErrors !== null){if(_errs28){vErrors.length = _errs28;}else {vErrors = null;}}if(_valid3){const _errs31 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){if(data2.finish_reason !== undefined){if(!(data2.finish_reason === "cancelled")){const err26 = {instancePath:instancePath+"/record/finish_reason",schemaPath:"#/properties/record/allOf/3/then/properties/finish_reason/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.allOf[3].then.properties.finish_reason.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err26];}else {vErrors.push(err26);}errors++;}}}var _valid3 = _errs31 === errors;valid12 = _valid3;if(valid12){var props3 = {};props3.finish_reason = true;props3.status = true;}}if(!valid12){const err27 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/allOf/3/if",keyword:"if",params:{failingKeyword: "then"},message:"must match \"then\" schema"};if(vErrors === null){vErrors = [err27];}else {vErrors.push(err27);}errors++;}if(props0 !== true && props3 !== undefined){if(props3 === true){props0 = true;}else {props0 = props0 || {};Object.assign(props0, props3);}}const _errs34 = errors;let valid15 = true;const _errs35 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){let missing5;if((data2.status === undefined) && (missing5 = "status")){const err28 = {};if(vErrors === null){vErrors = [err28];}else {vErrors.push(err28);}errors++;}else {if(data2.status !== undefined){if("timed-out" !== data2.status){const err29 = {};if(vErrors === null){vErrors = [err29];}else {vErrors.push(err29);}errors++;}}}}var _valid4 = _errs35 === errors;errors = _errs34;if(vErrors !== null){if(_errs34){vErrors.length = _errs34;}else {vErrors = null;}}if(_valid4){const _errs37 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){if(data2.finish_reason !== undefined){if(!(data2.finish_reason === "error")){const err30 = {instancePath:instancePath+"/record/finish_reason",schemaPath:"#/properties/record/allOf/4/then/properties/finish_reason/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.allOf[4].then.properties.finish_reason.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err30];}else {vErrors.push(err30);}errors++;}}}var _valid4 = _errs37 === errors;valid15 = _valid4;if(valid15){var props4 = {};props4.finish_reason = true;props4.status = true;}}if(!valid15){const err31 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/allOf/4/if",keyword:"if",params:{failingKeyword: "then"},message:"must match \"then\" schema"};if(vErrors === null){vErrors = [err31];}else {vErrors.push(err31);}errors++;}if(props0 !== true && props4 !== undefined){if(props4 === true){props0 = true;}else {props0 = props0 || {};Object.assign(props0, props4);}}if(data2 && typeof data2 == "object" && !Array.isArray(data2)){if(data2.execution_id === undefined){const err32 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "execution_id"},message:"must have required property '"+"execution_id"+"'"};if(vErrors === null){vErrors = [err32];}else {vErrors.push(err32);}errors++;}if(data2.prompt === undefined){const err33 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "prompt"},message:"must have required property '"+"prompt"+"'"};if(vErrors === null){vErrors = [err33];}else {vErrors.push(err33);}errors++;}if(data2.contexts === undefined){const err34 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "contexts"},message:"must have required property '"+"contexts"+"'"};if(vErrors === null){vErrors = [err34];}else {vErrors.push(err34);}errors++;}if(data2.redacted_context_count === undefined){const err35 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "redacted_context_count"},message:"must have required property '"+"redacted_context_count"+"'"};if(vErrors === null){vErrors = [err35];}else {vErrors.push(err35);}errors++;}if(data2.target === undefined){const err36 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "target"},message:"must have required property '"+"target"+"'"};if(vErrors === null){vErrors = [err36];}else {vErrors.push(err36);}errors++;}if(data2.identity === undefined){const err37 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "identity"},message:"must have required property '"+"identity"+"'"};if(vErrors === null){vErrors = [err37];}else {vErrors.push(err37);}errors++;}if(data2.parameters === undefined){const err38 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "parameters"},message:"must have required property '"+"parameters"+"'"};if(vErrors === null){vErrors = [err38];}else {vErrors.push(err38);}errors++;}if(data2.parameters_status === undefined){const err39 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "parameters_status"},message:"must have required property '"+"parameters_status"+"'"};if(vErrors === null){vErrors = [err39];}else {vErrors.push(err39);}errors++;}if(data2.stop_sequence_count === undefined){const err40 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "stop_sequence_count"},message:"must have required property '"+"stop_sequence_count"+"'"};if(vErrors === null){vErrors = [err40];}else {vErrors.push(err40);}errors++;}if(data2.timing === undefined){const err41 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "timing"},message:"must have required property '"+"timing"+"'"};if(vErrors === null){vErrors = [err41];}else {vErrors.push(err41);}errors++;}if(data2.status === undefined){const err42 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "status"},message:"must have required property '"+"status"+"'"};if(vErrors === null){vErrors = [err42];}else {vErrors.push(err42);}errors++;}if(data2.finish_reason === undefined){const err43 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "finish_reason"},message:"must have required property '"+"finish_reason"+"'"};if(vErrors === null){vErrors = [err43];}else {vErrors.push(err43);}errors++;}if(data2.validation === undefined){const err44 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "validation"},message:"must have required property '"+"validation"+"'"};if(vErrors === null){vErrors = [err44];}else {vErrors.push(err44);}errors++;}if(data2.structured_output === undefined){const err45 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "structured_output"},message:"must have required property '"+"structured_output"+"'"};if(vErrors === null){vErrors = [err45];}else {vErrors.push(err45);}errors++;}if(data2.policy === undefined){const err46 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/required",keyword:"required",params:{missingProperty: "policy"},message:"must have required property '"+"policy"+"'"};if(vErrors === null){vErrors = [err46];}else {vErrors.push(err46);}errors++;}for(const key1 in data2){if(!(func1.call(schema31.properties.record.properties, key1))){const err47 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key1},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err47];}else {vErrors.push(err47);}errors++;}}if(data2.execution_id !== undefined){if(typeof data2.execution_id !== "string"){const err48 = {instancePath:instancePath+"/record/execution_id",schemaPath:"#/properties/record/properties/execution_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err48];}else {vErrors.push(err48);}errors++;}}if(data2.correlation_id !== undefined){if(typeof data2.correlation_id !== "string"){const err49 = {instancePath:instancePath+"/record/correlation_id",schemaPath:"#/properties/record/properties/correlation_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err49];}else {vErrors.push(err49);}errors++;}}if(data2.prompt !== undefined){let data18 = data2.prompt;if(data18 && typeof data18 == "object" && !Array.isArray(data18)){if(data18.id === undefined){const err50 = {instancePath:instancePath+"/record/prompt",schemaPath:"#/properties/record/properties/prompt/required",keyword:"required",params:{missingProperty: "id"},message:"must have required property '"+"id"+"'"};if(vErrors === null){vErrors = [err50];}else {vErrors.push(err50);}errors++;}if(data18.version === undefined){const err51 = {instancePath:instancePath+"/record/prompt",schemaPath:"#/properties/record/properties/prompt/required",keyword:"required",params:{missingProperty: "version"},message:"must have required property '"+"version"+"'"};if(vErrors === null){vErrors = [err51];}else {vErrors.push(err51);}errors++;}if(data18.spec_version === undefined){const err52 = {instancePath:instancePath+"/record/prompt",schemaPath:"#/properties/record/properties/prompt/required",keyword:"required",params:{missingProperty: "spec_version"},message:"must have required property '"+"spec_version"+"'"};if(vErrors === null){vErrors = [err52];}else {vErrors.push(err52);}errors++;}for(const key2 in data18){if(!(((key2 === "id") || (key2 === "version")) || (key2 === "spec_version"))){const err53 = {instancePath:instancePath+"/record/prompt",schemaPath:"#/properties/record/properties/prompt/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key2},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err53];}else {vErrors.push(err53);}errors++;}}if(data18.id !== undefined){if(typeof data18.id !== "string"){const err54 = {instancePath:instancePath+"/record/prompt/id",schemaPath:"#/properties/record/properties/prompt/properties/id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err54];}else {vErrors.push(err54);}errors++;}}if(data18.version !== undefined){if(typeof data18.version !== "string"){const err55 = {instancePath:instancePath+"/record/prompt/version",schemaPath:"#/properties/record/properties/prompt/properties/version/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err55];}else {vErrors.push(err55);}errors++;}}if(data18.spec_version !== undefined){if(typeof data18.spec_version !== "string"){const err56 = {instancePath:instancePath+"/record/prompt/spec_version",schemaPath:"#/properties/record/properties/prompt/properties/spec_version/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err56];}else {vErrors.push(err56);}errors++;}}}else {const err57 = {instancePath:instancePath+"/record/prompt",schemaPath:"#/properties/record/properties/prompt/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err57];}else {vErrors.push(err57);}errors++;}}if(data2.rendered !== undefined){let data22 = data2.rendered;if(data22 && typeof data22 == "object" && !Array.isArray(data22)){if(data22.byte_size === undefined){const err58 = {instancePath:instancePath+"/record/rendered",schemaPath:"#/properties/record/properties/rendered/required",keyword:"required",params:{missingProperty: "byte_size"},message:"must have required property '"+"byte_size"+"'"};if(vErrors === null){vErrors = [err58];}else {vErrors.push(err58);}errors++;}if(data22.sha256 === undefined){const err59 = {instancePath:instancePath+"/record/rendered",schemaPath:"#/properties/record/properties/rendered/required",keyword:"required",params:{missingProperty: "sha256"},message:"must have required property '"+"sha256"+"'"};if(vErrors === null){vErrors = [err59];}else {vErrors.push(err59);}errors++;}for(const key3 in data22){if(!((key3 === "byte_size") || (key3 === "sha256"))){const err60 = {instancePath:instancePath+"/record/rendered",schemaPath:"#/properties/record/properties/rendered/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key3},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err60];}else {vErrors.push(err60);}errors++;}}if(data22.byte_size !== undefined){let data23 = data22.byte_size;if(!(((typeof data23 == "number") && (!(data23 % 1) && !isNaN(data23))) && (isFinite(data23)))){const err61 = {instancePath:instancePath+"/record/rendered/byte_size",schemaPath:"#/properties/record/properties/rendered/properties/byte_size/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err61];}else {vErrors.push(err61);}errors++;}if((typeof data23 == "number") && (isFinite(data23))){if(data23 < 0 || isNaN(data23)){const err62 = {instancePath:instancePath+"/record/rendered/byte_size",schemaPath:"#/properties/record/properties/rendered/properties/byte_size/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err62];}else {vErrors.push(err62);}errors++;}}}if(data22.sha256 !== undefined){let data24 = data22.sha256;if(typeof data24 === "string"){if(!pattern4.test(data24)){const err63 = {instancePath:instancePath+"/record/rendered/sha256",schemaPath:"#/properties/record/properties/rendered/properties/sha256/pattern",keyword:"pattern",params:{pattern: "^sha256:[0-9a-f]{64}$"},message:"must match pattern \""+"^sha256:[0-9a-f]{64}$"+"\""};if(vErrors === null){vErrors = [err63];}else {vErrors.push(err63);}errors++;}}else {const err64 = {instancePath:instancePath+"/record/rendered/sha256",schemaPath:"#/properties/record/properties/rendered/properties/sha256/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err64];}else {vErrors.push(err64);}errors++;}}}else {const err65 = {instancePath:instancePath+"/record/rendered",schemaPath:"#/properties/record/properties/rendered/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err65];}else {vErrors.push(err65);}errors++;}}if(data2.contexts !== undefined){let data25 = data2.contexts;if(Array.isArray(data25)){const len0 = data25.length;for(let i0=0; i0=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err95];}else {vErrors.push(err95);}errors++;}}}if(data2.target !== undefined){let data41 = data2.target;if(data41 && typeof data41 == "object" && !Array.isArray(data41)){if(data41.adapter_id === undefined){const err96 = {instancePath:instancePath+"/record/target",schemaPath:"#/properties/record/properties/target/required",keyword:"required",params:{missingProperty: "adapter_id"},message:"must have required property '"+"adapter_id"+"'"};if(vErrors === null){vErrors = [err96];}else {vErrors.push(err96);}errors++;}if(data41.provider_id === undefined){const err97 = {instancePath:instancePath+"/record/target",schemaPath:"#/properties/record/properties/target/required",keyword:"required",params:{missingProperty: "provider_id"},message:"must have required property '"+"provider_id"+"'"};if(vErrors === null){vErrors = [err97];}else {vErrors.push(err97);}errors++;}if(data41.model_id === undefined){const err98 = {instancePath:instancePath+"/record/target",schemaPath:"#/properties/record/properties/target/required",keyword:"required",params:{missingProperty: "model_id"},message:"must have required property '"+"model_id"+"'"};if(vErrors === null){vErrors = [err98];}else {vErrors.push(err98);}errors++;}for(const key7 in data41){if(!(((key7 === "adapter_id") || (key7 === "provider_id")) || (key7 === "model_id"))){const err99 = {instancePath:instancePath+"/record/target",schemaPath:"#/properties/record/properties/target/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key7},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err99];}else {vErrors.push(err99);}errors++;}}if(data41.adapter_id !== undefined){if(typeof data41.adapter_id !== "string"){const err100 = {instancePath:instancePath+"/record/target/adapter_id",schemaPath:"#/properties/record/properties/target/properties/adapter_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err100];}else {vErrors.push(err100);}errors++;}}if(data41.provider_id !== undefined){if(typeof data41.provider_id !== "string"){const err101 = {instancePath:instancePath+"/record/target/provider_id",schemaPath:"#/properties/record/properties/target/properties/provider_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err101];}else {vErrors.push(err101);}errors++;}}if(data41.model_id !== undefined){if(typeof data41.model_id !== "string"){const err102 = {instancePath:instancePath+"/record/target/model_id",schemaPath:"#/properties/record/properties/target/properties/model_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err102];}else {vErrors.push(err102);}errors++;}}}else {const err103 = {instancePath:instancePath+"/record/target",schemaPath:"#/properties/record/properties/target/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err103];}else {vErrors.push(err103);}errors++;}}if(data2.identity !== undefined){let data45 = data2.identity;if(data45 && typeof data45 == "object" && !Array.isArray(data45)){if(data45.adapter_id === undefined){const err104 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/required",keyword:"required",params:{missingProperty: "adapter_id"},message:"must have required property '"+"adapter_id"+"'"};if(vErrors === null){vErrors = [err104];}else {vErrors.push(err104);}errors++;}if(data45.adapter_version === undefined){const err105 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/required",keyword:"required",params:{missingProperty: "adapter_version"},message:"must have required property '"+"adapter_version"+"'"};if(vErrors === null){vErrors = [err105];}else {vErrors.push(err105);}errors++;}if(data45.provider_id === undefined){const err106 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/required",keyword:"required",params:{missingProperty: "provider_id"},message:"must have required property '"+"provider_id"+"'"};if(vErrors === null){vErrors = [err106];}else {vErrors.push(err106);}errors++;}if(data45.model_id === undefined){const err107 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/required",keyword:"required",params:{missingProperty: "model_id"},message:"must have required property '"+"model_id"+"'"};if(vErrors === null){vErrors = [err107];}else {vErrors.push(err107);}errors++;}for(const key8 in data45){if(!(((((key8 === "adapter_id") || (key8 === "adapter_version")) || (key8 === "provider_id")) || (key8 === "model_id")) || (key8 === "model_revision"))){const err108 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key8},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err108];}else {vErrors.push(err108);}errors++;}}if(data45.adapter_id !== undefined){if(typeof data45.adapter_id !== "string"){const err109 = {instancePath:instancePath+"/record/identity/adapter_id",schemaPath:"#/properties/record/properties/identity/properties/adapter_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err109];}else {vErrors.push(err109);}errors++;}}if(data45.adapter_version !== undefined){if(typeof data45.adapter_version !== "string"){const err110 = {instancePath:instancePath+"/record/identity/adapter_version",schemaPath:"#/properties/record/properties/identity/properties/adapter_version/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err110];}else {vErrors.push(err110);}errors++;}}if(data45.provider_id !== undefined){if(typeof data45.provider_id !== "string"){const err111 = {instancePath:instancePath+"/record/identity/provider_id",schemaPath:"#/properties/record/properties/identity/properties/provider_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err111];}else {vErrors.push(err111);}errors++;}}if(data45.model_id !== undefined){if(typeof data45.model_id !== "string"){const err112 = {instancePath:instancePath+"/record/identity/model_id",schemaPath:"#/properties/record/properties/identity/properties/model_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err112];}else {vErrors.push(err112);}errors++;}}if(data45.model_revision !== undefined){if(typeof data45.model_revision !== "string"){const err113 = {instancePath:instancePath+"/record/identity/model_revision",schemaPath:"#/properties/record/properties/identity/properties/model_revision/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err113];}else {vErrors.push(err113);}errors++;}}}else {const err114 = {instancePath:instancePath+"/record/identity",schemaPath:"#/properties/record/properties/identity/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err114];}else {vErrors.push(err114);}errors++;}}if(data2.parameters !== undefined){let data51 = data2.parameters;if(data51 && typeof data51 == "object" && !Array.isArray(data51)){for(const key9 in data51){if(!((((key9 === "max_output_tokens") || (key9 === "temperature")) || (key9 === "top_p")) || (key9 === "seed"))){const err115 = {instancePath:instancePath+"/record/parameters",schemaPath:"#/properties/record/properties/parameters/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key9},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err115];}else {vErrors.push(err115);}errors++;}}if(data51.max_output_tokens !== undefined){let data52 = data51.max_output_tokens;if(!(((typeof data52 == "number") && (!(data52 % 1) && !isNaN(data52))) && (isFinite(data52)))){const err116 = {instancePath:instancePath+"/record/parameters/max_output_tokens",schemaPath:"#/properties/record/properties/parameters/properties/max_output_tokens/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err116];}else {vErrors.push(err116);}errors++;}if((typeof data52 == "number") && (isFinite(data52))){if(data52 < 1 || isNaN(data52)){const err117 = {instancePath:instancePath+"/record/parameters/max_output_tokens",schemaPath:"#/properties/record/properties/parameters/properties/max_output_tokens/minimum",keyword:"minimum",params:{comparison: ">=", limit: 1},message:"must be >= 1"};if(vErrors === null){vErrors = [err117];}else {vErrors.push(err117);}errors++;}}}if(data51.temperature !== undefined){let data53 = data51.temperature;if((typeof data53 == "number") && (isFinite(data53))){if(data53 > 2 || isNaN(data53)){const err118 = {instancePath:instancePath+"/record/parameters/temperature",schemaPath:"#/properties/record/properties/parameters/properties/temperature/maximum",keyword:"maximum",params:{comparison: "<=", limit: 2},message:"must be <= 2"};if(vErrors === null){vErrors = [err118];}else {vErrors.push(err118);}errors++;}if(data53 < 0 || isNaN(data53)){const err119 = {instancePath:instancePath+"/record/parameters/temperature",schemaPath:"#/properties/record/properties/parameters/properties/temperature/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err119];}else {vErrors.push(err119);}errors++;}}else {const err120 = {instancePath:instancePath+"/record/parameters/temperature",schemaPath:"#/properties/record/properties/parameters/properties/temperature/type",keyword:"type",params:{type: "number"},message:"must be number"};if(vErrors === null){vErrors = [err120];}else {vErrors.push(err120);}errors++;}}if(data51.top_p !== undefined){let data54 = data51.top_p;if((typeof data54 == "number") && (isFinite(data54))){if(data54 > 1 || isNaN(data54)){const err121 = {instancePath:instancePath+"/record/parameters/top_p",schemaPath:"#/properties/record/properties/parameters/properties/top_p/maximum",keyword:"maximum",params:{comparison: "<=", limit: 1},message:"must be <= 1"};if(vErrors === null){vErrors = [err121];}else {vErrors.push(err121);}errors++;}if(data54 <= 0 || isNaN(data54)){const err122 = {instancePath:instancePath+"/record/parameters/top_p",schemaPath:"#/properties/record/properties/parameters/properties/top_p/exclusiveMinimum",keyword:"exclusiveMinimum",params:{comparison: ">", limit: 0},message:"must be > 0"};if(vErrors === null){vErrors = [err122];}else {vErrors.push(err122);}errors++;}}else {const err123 = {instancePath:instancePath+"/record/parameters/top_p",schemaPath:"#/properties/record/properties/parameters/properties/top_p/type",keyword:"type",params:{type: "number"},message:"must be number"};if(vErrors === null){vErrors = [err123];}else {vErrors.push(err123);}errors++;}}if(data51.seed !== undefined){let data55 = data51.seed;if(!(((typeof data55 == "number") && (!(data55 % 1) && !isNaN(data55))) && (isFinite(data55)))){const err124 = {instancePath:instancePath+"/record/parameters/seed",schemaPath:"#/properties/record/properties/parameters/properties/seed/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err124];}else {vErrors.push(err124);}errors++;}if((typeof data55 == "number") && (isFinite(data55))){if(data55 > 9007199254740991 || isNaN(data55)){const err125 = {instancePath:instancePath+"/record/parameters/seed",schemaPath:"#/properties/record/properties/parameters/properties/seed/maximum",keyword:"maximum",params:{comparison: "<=", limit: 9007199254740991},message:"must be <= 9007199254740991"};if(vErrors === null){vErrors = [err125];}else {vErrors.push(err125);}errors++;}if(data55 < 0 || isNaN(data55)){const err126 = {instancePath:instancePath+"/record/parameters/seed",schemaPath:"#/properties/record/properties/parameters/properties/seed/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err126];}else {vErrors.push(err126);}errors++;}}}}else {const err127 = {instancePath:instancePath+"/record/parameters",schemaPath:"#/properties/record/properties/parameters/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err127];}else {vErrors.push(err127);}errors++;}}if(data2.parameters_status !== undefined){let data56 = data2.parameters_status;if(!((data56 === "resolved") || (data56 === "not-resolved"))){const err128 = {instancePath:instancePath+"/record/parameters_status",schemaPath:"#/properties/record/properties/parameters_status/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.parameters_status.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err128];}else {vErrors.push(err128);}errors++;}}if(data2.stop_sequence_count !== undefined){let data57 = data2.stop_sequence_count;if(!(((typeof data57 == "number") && (!(data57 % 1) && !isNaN(data57))) && (isFinite(data57)))){const err129 = {instancePath:instancePath+"/record/stop_sequence_count",schemaPath:"#/properties/record/properties/stop_sequence_count/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err129];}else {vErrors.push(err129);}errors++;}if((typeof data57 == "number") && (isFinite(data57))){if(data57 < 0 || isNaN(data57)){const err130 = {instancePath:instancePath+"/record/stop_sequence_count",schemaPath:"#/properties/record/properties/stop_sequence_count/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err130];}else {vErrors.push(err130);}errors++;}}}if(data2.timing !== undefined){let data58 = data2.timing;if(data58 && typeof data58 == "object" && !Array.isArray(data58)){if(data58.started_at === undefined){const err131 = {instancePath:instancePath+"/record/timing",schemaPath:"#/properties/record/properties/timing/required",keyword:"required",params:{missingProperty: "started_at"},message:"must have required property '"+"started_at"+"'"};if(vErrors === null){vErrors = [err131];}else {vErrors.push(err131);}errors++;}if(data58.completed_at === undefined){const err132 = {instancePath:instancePath+"/record/timing",schemaPath:"#/properties/record/properties/timing/required",keyword:"required",params:{missingProperty: "completed_at"},message:"must have required property '"+"completed_at"+"'"};if(vErrors === null){vErrors = [err132];}else {vErrors.push(err132);}errors++;}if(data58.duration_ms === undefined){const err133 = {instancePath:instancePath+"/record/timing",schemaPath:"#/properties/record/properties/timing/required",keyword:"required",params:{missingProperty: "duration_ms"},message:"must have required property '"+"duration_ms"+"'"};if(vErrors === null){vErrors = [err133];}else {vErrors.push(err133);}errors++;}for(const key10 in data58){if(!(((key10 === "started_at") || (key10 === "completed_at")) || (key10 === "duration_ms"))){const err134 = {instancePath:instancePath+"/record/timing",schemaPath:"#/properties/record/properties/timing/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key10},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err134];}else {vErrors.push(err134);}errors++;}}if(data58.started_at !== undefined){let data59 = data58.started_at;if(typeof data59 === "string"){if(!(formats0.validate(data59))){const err135 = {instancePath:instancePath+"/record/timing/started_at",schemaPath:"#/properties/record/properties/timing/properties/started_at/format",keyword:"format",params:{format: "date-time"},message:"must match format \""+"date-time"+"\""};if(vErrors === null){vErrors = [err135];}else {vErrors.push(err135);}errors++;}}else {const err136 = {instancePath:instancePath+"/record/timing/started_at",schemaPath:"#/properties/record/properties/timing/properties/started_at/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err136];}else {vErrors.push(err136);}errors++;}}if(data58.completed_at !== undefined){let data60 = data58.completed_at;if(typeof data60 === "string"){if(!(formats0.validate(data60))){const err137 = {instancePath:instancePath+"/record/timing/completed_at",schemaPath:"#/properties/record/properties/timing/properties/completed_at/format",keyword:"format",params:{format: "date-time"},message:"must match format \""+"date-time"+"\""};if(vErrors === null){vErrors = [err137];}else {vErrors.push(err137);}errors++;}}else {const err138 = {instancePath:instancePath+"/record/timing/completed_at",schemaPath:"#/properties/record/properties/timing/properties/completed_at/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err138];}else {vErrors.push(err138);}errors++;}}if(data58.duration_ms !== undefined){let data61 = data58.duration_ms;if(!(((typeof data61 == "number") && (!(data61 % 1) && !isNaN(data61))) && (isFinite(data61)))){const err139 = {instancePath:instancePath+"/record/timing/duration_ms",schemaPath:"#/properties/record/properties/timing/properties/duration_ms/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err139];}else {vErrors.push(err139);}errors++;}if((typeof data61 == "number") && (isFinite(data61))){if(data61 < 0 || isNaN(data61)){const err140 = {instancePath:instancePath+"/record/timing/duration_ms",schemaPath:"#/properties/record/properties/timing/properties/duration_ms/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err140];}else {vErrors.push(err140);}errors++;}}}}else {const err141 = {instancePath:instancePath+"/record/timing",schemaPath:"#/properties/record/properties/timing/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err141];}else {vErrors.push(err141);}errors++;}}if(data2.status !== undefined){let data62 = data2.status;if(!((((data62 === "succeeded") || (data62 === "failed")) || (data62 === "cancelled")) || (data62 === "timed-out"))){const err142 = {instancePath:instancePath+"/record/status",schemaPath:"#/properties/record/properties/status/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.status.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err142];}else {vErrors.push(err142);}errors++;}}if(data2.finish_reason !== undefined){let data63 = data2.finish_reason;if(!((((((data63 === "stop") || (data63 === "length")) || (data63 === "content-filter")) || (data63 === "cancelled")) || (data63 === "error")) || (data63 === "unknown"))){const err143 = {instancePath:instancePath+"/record/finish_reason",schemaPath:"#/properties/record/properties/finish_reason/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.finish_reason.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err143];}else {vErrors.push(err143);}errors++;}}if(data2.usage !== undefined){let data64 = data2.usage;if(data64 && typeof data64 == "object" && !Array.isArray(data64)){if(data64.provider_reported === undefined){const err144 = {instancePath:instancePath+"/record/usage",schemaPath:"#/properties/record/properties/usage/required",keyword:"required",params:{missingProperty: "provider_reported"},message:"must have required property '"+"provider_reported"+"'"};if(vErrors === null){vErrors = [err144];}else {vErrors.push(err144);}errors++;}for(const key11 in data64){if(!((((key11 === "provider_reported") || (key11 === "input_tokens")) || (key11 === "output_tokens")) || (key11 === "total_tokens"))){const err145 = {instancePath:instancePath+"/record/usage",schemaPath:"#/properties/record/properties/usage/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key11},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err145];}else {vErrors.push(err145);}errors++;}}if(data64.provider_reported !== undefined){if(typeof data64.provider_reported !== "boolean"){const err146 = {instancePath:instancePath+"/record/usage/provider_reported",schemaPath:"#/properties/record/properties/usage/properties/provider_reported/type",keyword:"type",params:{type: "boolean"},message:"must be boolean"};if(vErrors === null){vErrors = [err146];}else {vErrors.push(err146);}errors++;}}if(data64.input_tokens !== undefined){let data66 = data64.input_tokens;if(!(((typeof data66 == "number") && (!(data66 % 1) && !isNaN(data66))) && (isFinite(data66)))){const err147 = {instancePath:instancePath+"/record/usage/input_tokens",schemaPath:"#/properties/record/properties/usage/properties/input_tokens/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err147];}else {vErrors.push(err147);}errors++;}if((typeof data66 == "number") && (isFinite(data66))){if(data66 < 0 || isNaN(data66)){const err148 = {instancePath:instancePath+"/record/usage/input_tokens",schemaPath:"#/properties/record/properties/usage/properties/input_tokens/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err148];}else {vErrors.push(err148);}errors++;}}}if(data64.output_tokens !== undefined){let data67 = data64.output_tokens;if(!(((typeof data67 == "number") && (!(data67 % 1) && !isNaN(data67))) && (isFinite(data67)))){const err149 = {instancePath:instancePath+"/record/usage/output_tokens",schemaPath:"#/properties/record/properties/usage/properties/output_tokens/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err149];}else {vErrors.push(err149);}errors++;}if((typeof data67 == "number") && (isFinite(data67))){if(data67 < 0 || isNaN(data67)){const err150 = {instancePath:instancePath+"/record/usage/output_tokens",schemaPath:"#/properties/record/properties/usage/properties/output_tokens/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err150];}else {vErrors.push(err150);}errors++;}}}if(data64.total_tokens !== undefined){let data68 = data64.total_tokens;if(!(((typeof data68 == "number") && (!(data68 % 1) && !isNaN(data68))) && (isFinite(data68)))){const err151 = {instancePath:instancePath+"/record/usage/total_tokens",schemaPath:"#/properties/record/properties/usage/properties/total_tokens/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err151];}else {vErrors.push(err151);}errors++;}if((typeof data68 == "number") && (isFinite(data68))){if(data68 < 0 || isNaN(data68)){const err152 = {instancePath:instancePath+"/record/usage/total_tokens",schemaPath:"#/properties/record/properties/usage/properties/total_tokens/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err152];}else {vErrors.push(err152);}errors++;}}}}else {const err153 = {instancePath:instancePath+"/record/usage",schemaPath:"#/properties/record/properties/usage/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err153];}else {vErrors.push(err153);}errors++;}}if(data2.output !== undefined){let data69 = data2.output;if(data69 && typeof data69 == "object" && !Array.isArray(data69)){if(data69.byte_size === undefined){const err154 = {instancePath:instancePath+"/record/output",schemaPath:"#/properties/record/properties/output/required",keyword:"required",params:{missingProperty: "byte_size"},message:"must have required property '"+"byte_size"+"'"};if(vErrors === null){vErrors = [err154];}else {vErrors.push(err154);}errors++;}if(data69.sha256 === undefined){const err155 = {instancePath:instancePath+"/record/output",schemaPath:"#/properties/record/properties/output/required",keyword:"required",params:{missingProperty: "sha256"},message:"must have required property '"+"sha256"+"'"};if(vErrors === null){vErrors = [err155];}else {vErrors.push(err155);}errors++;}for(const key12 in data69){if(!((key12 === "byte_size") || (key12 === "sha256"))){const err156 = {instancePath:instancePath+"/record/output",schemaPath:"#/properties/record/properties/output/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key12},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err156];}else {vErrors.push(err156);}errors++;}}if(data69.byte_size !== undefined){let data70 = data69.byte_size;if(!(((typeof data70 == "number") && (!(data70 % 1) && !isNaN(data70))) && (isFinite(data70)))){const err157 = {instancePath:instancePath+"/record/output/byte_size",schemaPath:"#/properties/record/properties/output/properties/byte_size/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err157];}else {vErrors.push(err157);}errors++;}if((typeof data70 == "number") && (isFinite(data70))){if(data70 < 0 || isNaN(data70)){const err158 = {instancePath:instancePath+"/record/output/byte_size",schemaPath:"#/properties/record/properties/output/properties/byte_size/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err158];}else {vErrors.push(err158);}errors++;}}}if(data69.sha256 !== undefined){let data71 = data69.sha256;if(typeof data71 === "string"){if(!pattern4.test(data71)){const err159 = {instancePath:instancePath+"/record/output/sha256",schemaPath:"#/properties/record/properties/output/properties/sha256/pattern",keyword:"pattern",params:{pattern: "^sha256:[0-9a-f]{64}$"},message:"must match pattern \""+"^sha256:[0-9a-f]{64}$"+"\""};if(vErrors === null){vErrors = [err159];}else {vErrors.push(err159);}errors++;}}else {const err160 = {instancePath:instancePath+"/record/output/sha256",schemaPath:"#/properties/record/properties/output/properties/sha256/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err160];}else {vErrors.push(err160);}errors++;}}}else {const err161 = {instancePath:instancePath+"/record/output",schemaPath:"#/properties/record/properties/output/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err161];}else {vErrors.push(err161);}errors++;}}if(data2.validation !== undefined){let data72 = data2.validation;if(data72 && typeof data72 == "object" && !Array.isArray(data72)){if(data72.status === undefined){const err162 = {instancePath:instancePath+"/record/validation",schemaPath:"#/properties/record/properties/validation/required",keyword:"required",params:{missingProperty: "status"},message:"must have required property '"+"status"+"'"};if(vErrors === null){vErrors = [err162];}else {vErrors.push(err162);}errors++;}if(data72.errors === undefined){const err163 = {instancePath:instancePath+"/record/validation",schemaPath:"#/properties/record/properties/validation/required",keyword:"required",params:{missingProperty: "errors"},message:"must have required property '"+"errors"+"'"};if(vErrors === null){vErrors = [err163];}else {vErrors.push(err163);}errors++;}if(data72.warnings === undefined){const err164 = {instancePath:instancePath+"/record/validation",schemaPath:"#/properties/record/properties/validation/required",keyword:"required",params:{missingProperty: "warnings"},message:"must have required property '"+"warnings"+"'"};if(vErrors === null){vErrors = [err164];}else {vErrors.push(err164);}errors++;}for(const key13 in data72){if(!(((key13 === "status") || (key13 === "errors")) || (key13 === "warnings"))){const err165 = {instancePath:instancePath+"/record/validation",schemaPath:"#/properties/record/properties/validation/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key13},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err165];}else {vErrors.push(err165);}errors++;}}if(data72.status !== undefined){let data73 = data72.status;if(!(((data73 === "not-run") || (data73 === "passed")) || (data73 === "failed"))){const err166 = {instancePath:instancePath+"/record/validation/status",schemaPath:"#/properties/record/properties/validation/properties/status/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.validation.properties.status.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err166];}else {vErrors.push(err166);}errors++;}}if(data72.errors !== undefined){let data74 = data72.errors;if(!(((typeof data74 == "number") && (!(data74 % 1) && !isNaN(data74))) && (isFinite(data74)))){const err167 = {instancePath:instancePath+"/record/validation/errors",schemaPath:"#/properties/record/properties/validation/properties/errors/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err167];}else {vErrors.push(err167);}errors++;}if((typeof data74 == "number") && (isFinite(data74))){if(data74 < 0 || isNaN(data74)){const err168 = {instancePath:instancePath+"/record/validation/errors",schemaPath:"#/properties/record/properties/validation/properties/errors/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err168];}else {vErrors.push(err168);}errors++;}}}if(data72.warnings !== undefined){let data75 = data72.warnings;if(!(((typeof data75 == "number") && (!(data75 % 1) && !isNaN(data75))) && (isFinite(data75)))){const err169 = {instancePath:instancePath+"/record/validation/warnings",schemaPath:"#/properties/record/properties/validation/properties/warnings/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err169];}else {vErrors.push(err169);}errors++;}if((typeof data75 == "number") && (isFinite(data75))){if(data75 < 0 || isNaN(data75)){const err170 = {instancePath:instancePath+"/record/validation/warnings",schemaPath:"#/properties/record/properties/validation/properties/warnings/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err170];}else {vErrors.push(err170);}errors++;}}}}else {const err171 = {instancePath:instancePath+"/record/validation",schemaPath:"#/properties/record/properties/validation/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err171];}else {vErrors.push(err171);}errors++;}}if(data2.structured_output !== undefined){let data76 = data2.structured_output;const _errs169 = errors;let valid36 = true;const _errs170 = errors;if(data76 && typeof data76 == "object" && !Array.isArray(data76)){let missing6;if((data76.status === undefined) && (missing6 = "status")){const err172 = {};if(vErrors === null){vErrors = [err172];}else {vErrors.push(err172);}errors++;}else {if(data76.status !== undefined){if("not-run" !== data76.status){const err173 = {};if(vErrors === null){vErrors = [err173];}else {vErrors.push(err173);}errors++;}}}}var _valid5 = _errs170 === errors;errors = _errs169;if(vErrors !== null){if(_errs169){vErrors.length = _errs169;}else {vErrors = null;}}let ifClause0;if(_valid5){const _errs172 = errors;const _errs173 = errors;const _errs174 = errors;if(data76 && typeof data76 == "object" && !Array.isArray(data76)){let missing7;if((data76.processing_id === undefined) && (missing7 = "processing_id")){const err174 = {};if(vErrors === null){vErrors = [err174];}else {vErrors.push(err174);}errors++;}}var valid38 = _errs174 === errors;if(valid38){const err175 = {instancePath:instancePath+"/record/structured_output",schemaPath:"#/properties/record/properties/structured_output/allOf/0/then/not",keyword:"not",params:{},message:"must NOT be valid"};if(vErrors === null){vErrors = [err175];}else {vErrors.push(err175);}errors++;}else {errors = _errs173;if(vErrors !== null){if(_errs173){vErrors.length = _errs173;}else {vErrors = null;}}}var _valid5 = _errs172 === errors;valid36 = _valid5;ifClause0 = "then";}else {const _errs175 = errors;if(data76 && typeof data76 == "object" && !Array.isArray(data76)){if(data76.processing_id === undefined){const err176 = {instancePath:instancePath+"/record/structured_output",schemaPath:"#/properties/record/properties/structured_output/allOf/0/else/required",keyword:"required",params:{missingProperty: "processing_id"},message:"must have required property '"+"processing_id"+"'"};if(vErrors === null){vErrors = [err176];}else {vErrors.push(err176);}errors++;}}var _valid5 = _errs175 === errors;valid36 = _valid5;ifClause0 = "else";}if(!valid36){const err177 = {instancePath:instancePath+"/record/structured_output",schemaPath:"#/properties/record/properties/structured_output/allOf/0/if",keyword:"if",params:{failingKeyword: ifClause0},message:"must match \""+ifClause0+"\" schema"};if(vErrors === null){vErrors = [err177];}else {vErrors.push(err177);}errors++;}if(data76 && typeof data76 == "object" && !Array.isArray(data76)){if(data76.status === undefined){const err178 = {instancePath:instancePath+"/record/structured_output",schemaPath:"#/properties/record/properties/structured_output/required",keyword:"required",params:{missingProperty: "status"},message:"must have required property '"+"status"+"'"};if(vErrors === null){vErrors = [err178];}else {vErrors.push(err178);}errors++;}for(const key14 in data76){if(!((key14 === "status") || (key14 === "processing_id"))){const err179 = {instancePath:instancePath+"/record/structured_output",schemaPath:"#/properties/record/properties/structured_output/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key14},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err179];}else {vErrors.push(err179);}errors++;}}if(data76.status !== undefined){let data78 = data76.status;if(!(((data78 === "not-run") || (data78 === "validated")) || (data78 === "failed"))){const err180 = {instancePath:instancePath+"/record/structured_output/status",schemaPath:"#/properties/record/properties/structured_output/properties/status/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.structured_output.properties.status.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err180];}else {vErrors.push(err180);}errors++;}}if(data76.processing_id !== undefined){let data79 = data76.processing_id;if(typeof data79 === "string"){if(!pattern6.test(data79)){const err181 = {instancePath:instancePath+"/record/structured_output/processing_id",schemaPath:"#/properties/record/properties/structured_output/properties/processing_id/pattern",keyword:"pattern",params:{pattern: "^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$"},message:"must match pattern \""+"^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$"+"\""};if(vErrors === null){vErrors = [err181];}else {vErrors.push(err181);}errors++;}}else {const err182 = {instancePath:instancePath+"/record/structured_output/processing_id",schemaPath:"#/properties/record/properties/structured_output/properties/processing_id/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err182];}else {vErrors.push(err182);}errors++;}}}else {const err183 = {instancePath:instancePath+"/record/structured_output",schemaPath:"#/properties/record/properties/structured_output/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err183];}else {vErrors.push(err183);}errors++;}}if(data2.policy !== undefined){let data80 = data2.policy;if(data80 && typeof data80 == "object" && !Array.isArray(data80)){if(data80.content_identities === undefined){const err184 = {instancePath:instancePath+"/record/policy",schemaPath:"#/properties/record/properties/policy/required",keyword:"required",params:{missingProperty: "content_identities"},message:"must have required property '"+"content_identities"+"'"};if(vErrors === null){vErrors = [err184];}else {vErrors.push(err184);}errors++;}if(data80.bodies === undefined){const err185 = {instancePath:instancePath+"/record/policy",schemaPath:"#/properties/record/properties/policy/required",keyword:"required",params:{missingProperty: "bodies"},message:"must have required property '"+"bodies"+"'"};if(vErrors === null){vErrors = [err185];}else {vErrors.push(err185);}errors++;}for(const key15 in data80){if(!((key15 === "content_identities") || (key15 === "bodies"))){const err186 = {instancePath:instancePath+"/record/policy",schemaPath:"#/properties/record/properties/policy/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key15},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err186];}else {vErrors.push(err186);}errors++;}}if(data80.content_identities !== undefined){let data81 = data80.content_identities;if(!((data81 === "public-only") || (data81 === "omit"))){const err187 = {instancePath:instancePath+"/record/policy/content_identities",schemaPath:"#/properties/record/properties/policy/properties/content_identities/enum",keyword:"enum",params:{allowedValues: schema31.properties.record.properties.policy.properties.content_identities.enum},message:"must be equal to one of the allowed values"};if(vErrors === null){vErrors = [err187];}else {vErrors.push(err187);}errors++;}}if(data80.bodies !== undefined){if("omitted" !== data80.bodies){const err188 = {instancePath:instancePath+"/record/policy/bodies",schemaPath:"#/properties/record/properties/policy/properties/bodies/const",keyword:"const",params:{allowedValue: "omitted"},message:"must be equal to constant"};if(vErrors === null){vErrors = [err188];}else {vErrors.push(err188);}errors++;}}}else {const err189 = {instancePath:instancePath+"/record/policy",schemaPath:"#/properties/record/properties/policy/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err189];}else {vErrors.push(err189);}errors++;}}}else {const err190 = {instancePath:instancePath+"/record",schemaPath:"#/properties/record/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err190];}else {vErrors.push(err190);}errors++;}}if(data.identity !== undefined){let data83 = data.identity;if(data83 && typeof data83 == "object" && !Array.isArray(data83)){if(data83.byte_size === undefined){const err191 = {instancePath:instancePath+"/identity",schemaPath:"#/properties/identity/required",keyword:"required",params:{missingProperty: "byte_size"},message:"must have required property '"+"byte_size"+"'"};if(vErrors === null){vErrors = [err191];}else {vErrors.push(err191);}errors++;}if(data83.sha256 === undefined){const err192 = {instancePath:instancePath+"/identity",schemaPath:"#/properties/identity/required",keyword:"required",params:{missingProperty: "sha256"},message:"must have required property '"+"sha256"+"'"};if(vErrors === null){vErrors = [err192];}else {vErrors.push(err192);}errors++;}for(const key16 in data83){if(!((key16 === "byte_size") || (key16 === "sha256"))){const err193 = {instancePath:instancePath+"/identity",schemaPath:"#/properties/identity/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key16},message:"must NOT have additional properties"};if(vErrors === null){vErrors = [err193];}else {vErrors.push(err193);}errors++;}}if(data83.byte_size !== undefined){let data84 = data83.byte_size;if(!(((typeof data84 == "number") && (!(data84 % 1) && !isNaN(data84))) && (isFinite(data84)))){const err194 = {instancePath:instancePath+"/identity/byte_size",schemaPath:"#/properties/identity/properties/byte_size/type",keyword:"type",params:{type: "integer"},message:"must be integer"};if(vErrors === null){vErrors = [err194];}else {vErrors.push(err194);}errors++;}if((typeof data84 == "number") && (isFinite(data84))){if(data84 < 0 || isNaN(data84)){const err195 = {instancePath:instancePath+"/identity/byte_size",schemaPath:"#/properties/identity/properties/byte_size/minimum",keyword:"minimum",params:{comparison: ">=", limit: 0},message:"must be >= 0"};if(vErrors === null){vErrors = [err195];}else {vErrors.push(err195);}errors++;}}}if(data83.sha256 !== undefined){let data85 = data83.sha256;if(typeof data85 === "string"){if(!pattern4.test(data85)){const err196 = {instancePath:instancePath+"/identity/sha256",schemaPath:"#/properties/identity/properties/sha256/pattern",keyword:"pattern",params:{pattern: "^sha256:[0-9a-f]{64}$"},message:"must match pattern \""+"^sha256:[0-9a-f]{64}$"+"\""};if(vErrors === null){vErrors = [err196];}else {vErrors.push(err196);}errors++;}}else {const err197 = {instancePath:instancePath+"/identity/sha256",schemaPath:"#/properties/identity/properties/sha256/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err197];}else {vErrors.push(err197);}errors++;}}}else {const err198 = {instancePath:instancePath+"/identity",schemaPath:"#/properties/identity/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err198];}else {vErrors.push(err198);}errors++;}}}else {const err199 = {instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err199];}else {vErrors.push(err199);}errors++;}validate20.errors = vErrors;return errors === 0;}validate20.evaluated = {"props":true,"dynamicProps":false,"dynamicItems":false}; \ No newline at end of file diff --git a/tests/prompt-sdk/provenance.test.js b/tests/prompt-sdk/provenance.test.js index 1e4f512..b751188 100644 --- a/tests/prompt-sdk/provenance.test.js +++ b/tests/prompt-sdk/provenance.test.js @@ -89,6 +89,28 @@ test('manual provenance rejects unrelated target identities despite matching cor assert.throws(() => createExecutionProvenance(input, unrelated), /target mismatch/); } }); +test('compiled provenance schema rejects policy and execution contradictions with valid digests', async () => { + const input = request(); + const result = await executePrompt(input, { adapter: new MockTextAdapter() }); + const valid = createExecutionProvenance(input, result); + for (const mutate of [ + record => { record.policy.content_identities = 'omit'; }, + record => { record.contexts = [{ slot: 'private', classification: 'restricted' }]; }, + record => { record.parameters.max_output_tokens = -1.5; }, + record => { record.finish_reason = 'error'; }, + record => { record.structured_output = { status: 'validated' }; }, + record => { record.structured_output.processing_id = 'spurious'; }, + record => { record.timing.started_at = 'later'; }, + record => { record.timing.completed_at = '2026-02-30T00:00:00Z'; } + ]) { + const candidate = structuredClone(valid); + mutate(candidate.record); + const bytes = canonicalJson(candidate.record); + candidate.identity = { byte_size: Buffer.byteLength(bytes), sha256: 'sha256:' + createHash('sha256').update(bytes).digest('hex') }; + assert.equal(validateExecutionProvenance(candidate), false); + await assert.rejects(new LocalExecutionObserver().observe(candidate), /Invalid observer record/); + } +}); test('manual provenance rejects classification downgrades and mismatched output contracts', async () => { const classifications = ['public', 'internal', 'confidential', 'restricted']; for (const classification of classifications) {