import type BetterSqlite3 from "better-sqlite3"; import { ModelConfigurationService, modelIds, type ModelConfigCandidate } from "./model-configuration.js"; const safeRefPattern = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,159}$/; const requiredRatios = ["3:4", "1:1", "4:3", "9:16"]; const requiredAdapterErrors = [ "upstream_timeout", "upstream_failed", "safety_rejected", "gateway_balance_insufficient", "gateway_contract_invalid", "reference_invalid", "unknown_retryable", "unknown_non_retryable", ]; const forbiddenKeyFragments = ["credential", "password", "prompt_text", "raw", "secret", "token"]; export interface ModelContractEvidenceInput { evidence_hash: string; evidence_ref: string; matrix: unknown; model_id: string; verified_at: string; verifier_ref: string; } function hasForbiddenEvidenceKey(value: unknown, depth = 0): boolean { if (depth > 8 || !value || typeof value !== "object") return false; if (Array.isArray(value)) return value.some((entry) => hasForbiddenEvidenceKey(entry, depth + 1)); return Object.entries(value).some(([key, entry]) => ( forbiddenKeyFragments.some((fragment) => key.toLowerCase().includes(fragment)) || hasForbiddenEvidenceKey(entry, depth + 1) )); } function validateEvidence(input: ModelContractEvidenceInput) { if (!modelIds.includes(input.model_id as typeof modelIds[number])) throw new Error("contract_evidence_model_invalid"); if (!safeRefPattern.test(input.evidence_hash) || !safeRefPattern.test(input.evidence_ref) || !safeRefPattern.test(input.verifier_ref)) { throw new Error("contract_evidence_reference_invalid"); } const verifiedAt = Date.parse(input.verified_at); if (!Number.isFinite(verifiedAt) || new Date(verifiedAt).toISOString() !== input.verified_at) throw new Error("contract_evidence_time_invalid"); if (hasForbiddenEvidenceKey(input.matrix)) throw new Error("contract_evidence_sensitive_field"); if (!input.matrix || typeof input.matrix !== "object") throw new Error("contract_evidence_matrix_incomplete"); const matrix = input.matrix as Record; const passedSingleOutput = (value: unknown) => Boolean(value && typeof value === "object" && "status" in value && value.status === "passed" && "outputs" in value && value.outputs === 1); const ratios = Array.isArray(matrix.ratios) ? matrix.ratios as Array> : []; const ratioNames = ratios.filter(passedSingleOutput).map((entry) => entry.ratio).toSorted(); const executionModes = Array.isArray(matrix.execution_modes) ? matrix.execution_modes : []; const errorMapping = Array.isArray(matrix.error_mapping) ? matrix.error_mapping : []; const executionComplete = executionModes.includes("sync") || (executionModes.includes("async") && executionModes.includes("poll")); if (matrix.model_id !== input.model_id || !passedSingleOutput(matrix.pure_text) || !passedSingleOutput(matrix.reference_image) || JSON.stringify(ratioNames) !== JSON.stringify([...requiredRatios].toSorted()) || !executionComplete || !requiredAdapterErrors.every((category) => errorMapping.includes(category))) { throw new Error("contract_evidence_matrix_incomplete"); } return verifiedAt; } function editableCandidates(models: ReturnType["models"]): ModelConfigCandidate[] { return models.map(({ config_version: _configVersion, runtime_availability: _runtime, ...candidate }) => structuredClone(candidate)); } export class ModelContractEvidenceService { readonly database: BetterSqlite3.Database; private readonly clock: () => number; private readonly models: ModelConfigurationService; constructor(input: { clock?: () => number; database: BetterSqlite3.Database; models: ModelConfigurationService }) { this.clock = input.clock ?? Date.now; this.database = input.database; this.models = input.models; this.migrate(); } recordVerified(input: { actorId: string; evidence: ModelContractEvidenceInput; expectedConfigSetVersion: number; idempotencyKey: string; }) { const verifiedAt = validateEvidence(input.evidence); return this.database.transaction(() => { const current = this.models.read(); if (current.config_set_version !== input.expectedConfigSetVersion) throw new Error("contract_evidence_config_set_conflict"); const existingHash = this.database.prepare("SELECT model_id FROM model_contract_evidence WHERE evidence_hash = ?").get(input.evidence.evidence_hash) as { model_id: string } | undefined; if (existingHash && existingHash.model_id !== input.evidence.model_id) throw new Error("contract_evidence_shared_between_models"); const candidates = editableCandidates(current.models); const target = candidates.find((model) => model.model_id === input.evidence.model_id)!; target.contract_validation_status = "verified"; target.contract_evidence_ref = input.evidence.evidence_ref; const configuration = this.models.replace({ actorId: input.actorId, expectedConfigSetVersion: input.expectedConfigSetVersion, idempotencyKey: input.idempotencyKey, models: candidates, }); const model = configuration.models.find((candidate) => candidate.model_id === input.evidence.model_id)!; this.database.prepare(` INSERT OR IGNORE INTO model_contract_evidence ( model_id, config_version, evidence_hash, evidence_ref, verifier_ref, verified_at, evidence_json, created_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) `).run( input.evidence.model_id, model.config_version, input.evidence.evidence_hash, input.evidence.evidence_ref, input.evidence.verifier_ref, verifiedAt, JSON.stringify(input.evidence.matrix), this.clock(), ); return { configuration, evidence: structuredClone(input.evidence), model }; }).immediate(); } read(modelId: string, configVersion: number) { return this.database.prepare(` SELECT model_id, config_version, evidence_hash, evidence_ref, verifier_ref, verified_at, evidence_json FROM model_contract_evidence WHERE model_id = ? AND config_version = ? `).get(modelId, configVersion) as { config_version: number; evidence_hash: string; evidence_json: string; evidence_ref: string; model_id: string; verified_at: number; verifier_ref: string; } | undefined; } private migrate() { this.database.exec(` CREATE TABLE IF NOT EXISTS model_contract_evidence ( model_id TEXT NOT NULL, config_version INTEGER NOT NULL, evidence_hash TEXT NOT NULL UNIQUE, evidence_ref TEXT NOT NULL, verifier_ref TEXT NOT NULL, verified_at INTEGER NOT NULL, evidence_json TEXT NOT NULL CHECK (json_valid(evidence_json)), created_at INTEGER NOT NULL, PRIMARY KEY (model_id, config_version), FOREIGN KEY (model_id, config_version) REFERENCES model_config_versions(model_id, config_version) ); CREATE TRIGGER IF NOT EXISTS model_contract_evidence_no_update BEFORE UPDATE ON model_contract_evidence BEGIN SELECT RAISE(ABORT, 'model_contract_evidence_immutable'); END; CREATE TRIGGER IF NOT EXISTS model_contract_evidence_no_delete BEFORE DELETE ON model_contract_evidence BEGIN SELECT RAISE(ABORT, 'model_contract_evidence_immutable'); END; `); } }