const SCHEMA_VERSION = "dashboard_data_v1"; const APPROVED_PARTITIONS = Object.freeze(["train", "tune", "calibrate"]); const APPROVED_TARGET = "first-attempt next-episode binary non-pass rate"; const REQUIRED_CALIBRATION_MODELS = Object.freeze([ "hist_gradient_boosting_platt", "logistic_platt", ]); const ENVELOPE_KEYS = Object.freeze([ "development_preview", "population_estimate_allowed", "schema_version", ]); const SHA256_INITIAL_STATE = Object.freeze([ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, ]); const SHA256_ROUND_CONSTANTS = Object.freeze([ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, ]); export const REQUIRED_ASSETS = Object.freeze({ manifest: "data_manifest.json", overview: "overview_period_county.json", ageRisk: "age_risk_curve.json", scorecards: "cohort_scorecard.json", diagnostics: "model_diagnostics.json", coverage: "coverage_quality.json", filters: "filter_catalog.json", shaManifest: "sha256_manifest.json", }); const SENSITIVE_KEY_PARTS = new Set([ "address", "certificate", "credential", "email", "inspector", "internal", "ip", "owner", "password", "pid", "plate", "prediction", "probability", "raw", "secret", "session", "station", "technician", "token", "user", "vin", "zip", ]); const ASSET_VALIDATORS = { overview: (value) => validateRows(value, validateOverviewRow, "overview_period_county"), ageRisk: (value) => validateRows(value, validateAgeRiskRow, "age_risk_curve"), scorecards: (value) => validateRows(value, validateScorecardRow, "cohort_scorecard"), diagnostics: (value) => validateRows(value, validateDiagnosticRow, "model_diagnostics"), coverage: (value) => validateRows(value, validateCoverageRow, "coverage_quality"), filters: validateFilterCatalog, shaManifest: validateShaManifest, }; export class DataContractError extends Error { constructor(message) { super(message); this.name = "DataContractError"; } } function isPlainObject(value) { if (value === null || typeof value !== "object" || Array.isArray(value)) return false; const prototype = Object.getPrototypeOf(value); return prototype === Object.prototype || prototype === null; } function requirePlainObject(value, label) { if (!isPlainObject(value)) { throw new DataContractError(`${label} must be a JSON object.`); } } function requireExactKeys(value, expectedKeys, label) { const observed = Object.keys(value).sort(); const expected = [...expectedKeys].sort(); if (JSON.stringify(observed) !== JSON.stringify(expected)) { throw new DataContractError(`${label} does not match the approved field schema.`); } } function requireExactStringSet(value, expectedValues, label) { validateStringArray(value, label); const observed = [...value].sort(); const expected = [...expectedValues].sort(); if (JSON.stringify(observed) !== JSON.stringify(expected)) { throw new DataContractError(`${label} does not match the approved values.`); } } function requireBoolean(value, label) { if (typeof value !== "boolean") { throw new DataContractError(`${label} must be true or false.`); } } function requireString(value, label) { if (typeof value !== "string" || value.trim() === "") { throw new DataContractError(`${label} must be a non-empty string.`); } } function requireSafeModelVersion(value, label) { requireString(value, label); if (!/^[A-Za-z0-9._-]{1,64}$/.test(value)) { throw new DataContractError(`${label} is not an approved model version.`); } } function requireNumber(value, label, { min = -Infinity, max = Infinity } = {}) { if (typeof value !== "number" || !Number.isFinite(value) || value < min || value > max) { throw new DataContractError(`${label} must be a finite number in the approved range.`); } } function requireInteger(value, label, { min = -Infinity, max = Infinity } = {}) { requireNumber(value, label, { min, max }); if (!Number.isInteger(value)) { throw new DataContractError(`${label} must be an integer.`); } } function validateEnvelope(value, label) { requirePlainObject(value, label); if (value.schema_version !== SCHEMA_VERSION) { throw new DataContractError(`${label} uses an unsupported schema version.`); } requireBoolean(value.development_preview, `${label}.development_preview`); requireBoolean( value.population_estimate_allowed, `${label}.population_estimate_allowed`, ); rejectSensitiveKeys(value, label); } function validateRows(value, rowValidator, label) { validateEnvelope(value, label); requireExactKeys(value, [...ENVELOPE_KEYS, "rows"], label); if (!Array.isArray(value.rows)) { throw new DataContractError(`${label}.rows must be an array.`); } value.rows.forEach((row, index) => { requirePlainObject(row, `${label}.rows[${index}]`); rowValidator(row, `${label}.rows[${index}]`); }); return value; } function validateOverviewRow(row, label) { requireExactKeys( row, ["year", "quarter", "public_county", "support_rounded", "nonpass_rate"], label, ); requireInteger(row.year, `${label}.year`, { min: 2010, max: 2100 }); requireInteger(row.quarter, `${label}.quarter`, { min: 1, max: 4 }); requireString(row.public_county, `${label}.public_county`); requireInteger(row.support_rounded, `${label}.support_rounded`, { min: 0 }); requireNumber(row.nonpass_rate, `${label}.nonpass_rate`, { min: 0, max: 1 }); } function validateAgeRiskRow(row, label) { requireExactKeys(row, ["age_band", "support_rounded", "nonpass_rate"], label); requireString(row.age_band, `${label}.age_band`); requireInteger(row.support_rounded, `${label}.support_rounded`, { min: 0 }); requireNumber(row.nonpass_rate, `${label}.nonpass_rate`, { min: 0, max: 1 }); } function validateScorecardRow(row, label) { requireExactKeys( row, ["prior_make", "prior_model", "support_rounded", "nonpass_rate"], label, ); requireString(row.prior_make, `${label}.prior_make`); requireString(row.prior_model, `${label}.prior_model`); requireInteger(row.support_rounded, `${label}.support_rounded`, { min: 0 }); requireNumber(row.nonpass_rate, `${label}.nonpass_rate`, { min: 0, max: 1 }); } function validateDiagnosticRow(row, label) { requireExactKeys( row, [ "model", "partition", "average_precision", "brier", "log_loss", "roc_auc", "top_10_capture", ], label, ); requireString(row.model, `${label}.model`); requireString(row.partition, `${label}.partition`); if (!APPROVED_PARTITIONS.includes(row.partition)) { throw new DataContractError(`${label}.partition is not approved for this public schema.`); } for (const metric of [ "average_precision", "brier", "log_loss", "roc_auc", "top_10_capture", ]) { requireNumber(row[metric], `${label}.${metric}`, { min: 0 }); } if (row.average_precision > 1 || row.brier > 1 || row.roc_auc > 1 || row.top_10_capture > 1) { throw new DataContractError(`${label} contains a probability metric above 1.`); } } function validateCoverageRow(row, label) { requireExactKeys( row, [ "year", "source_era", "support_rounded", "labeled_rate", "overall_result_share", "utah_obd_proxy_share", ], label, ); requireInteger(row.year, `${label}.year`, { min: 2010, max: 2100 }); requireString(row.source_era, `${label}.source_era`); requireInteger(row.support_rounded, `${label}.support_rounded`, { min: 0 }); for (const metric of ["labeled_rate", "overall_result_share", "utah_obd_proxy_share"]) { requireNumber(row[metric], `${label}.${metric}`, { min: 0, max: 1 }); } } function validateStringArray(value, label) { if (!Array.isArray(value)) throw new DataContractError(`${label} must be an array.`); value.forEach((item, index) => requireString(item, `${label}[${index}]`)); } function validateFilterCatalog(value) { const label = "filter_catalog"; validateEnvelope(value, label); requireExactKeys( value, [ ...ENVELOPE_KEYS, "public_counties", "age_bands", "prior_make_models", "periods", "models", "partitions", ], label, ); validateStringArray(value.public_counties, `${label}.public_counties`); validateStringArray(value.age_bands, `${label}.age_bands`); validateStringArray(value.models, `${label}.models`); requireExactStringSet(value.partitions, APPROVED_PARTITIONS, `${label}.partitions`); if (!Array.isArray(value.prior_make_models)) { throw new DataContractError(`${label}.prior_make_models must be an array.`); } value.prior_make_models.forEach((row, index) => { requirePlainObject(row, `${label}.prior_make_models[${index}]`); requireExactKeys( row, ["prior_make", "prior_model"], `${label}.prior_make_models[${index}]`, ); requireString(row.prior_make, `${label}.prior_make_models[${index}].prior_make`); requireString(row.prior_model, `${label}.prior_make_models[${index}].prior_model`); }); if (!Array.isArray(value.periods)) { throw new DataContractError(`${label}.periods must be an array.`); } value.periods.forEach((period, index) => { requirePlainObject(period, `${label}.periods[${index}]`); requireExactKeys(period, ["year", "quarters"], `${label}.periods[${index}]`); requireInteger(period.year, `${label}.periods[${index}].year`, { min: 2010, max: 2100, }); if (!Array.isArray(period.quarters) || period.quarters.length === 0) { throw new DataContractError(`${label}.periods[${index}].quarters must be non-empty.`); } period.quarters.forEach((quarter, quarterIndex) => requireInteger(quarter, `${label}.periods[${index}].quarters[${quarterIndex}]`, { min: 1, max: 4, }), ); }); return value; } function validateShaManifest(value) { const label = "sha256_manifest"; validateEnvelope(value, label); requireExactKeys(value, [...ENVELOPE_KEYS, "files"], label); if (!Array.isArray(value.files)) { throw new DataContractError(`${label}.files must be an array.`); } const expectedNames = Object.entries(REQUIRED_ASSETS) .filter(([name]) => name !== "shaManifest") .map(([, filename]) => filename) .sort(); const observedNames = []; for (const [index, file] of value.files.entries()) { requirePlainObject(file, `${label}.files[${index}]`); requireExactKeys(file, ["name", "sha256"], `${label}.files[${index}]`); requireString(file.name, `${label}.files[${index}].name`); requireString(file.sha256, `${label}.files[${index}].sha256`); if (!/^[0-9a-f]{64}$/.test(file.sha256)) { throw new DataContractError(`${label}.files[${index}].sha256 is invalid.`); } observedNames.push(file.name); } observedNames.sort(); if (JSON.stringify(observedNames) !== JSON.stringify(expectedNames)) { throw new DataContractError(`${label} does not cover the exact approved asset set.`); } return value; } function rejectSensitiveKeys(value, label, seen = new WeakSet()) { if (value === null || typeof value !== "object") return; if (seen.has(value)) return; seen.add(value); if (Array.isArray(value)) { value.forEach((item, index) => rejectSensitiveKeys(item, `${label}[${index}]`, seen)); return; } for (const [key, child] of Object.entries(value)) { const normalizedParts = key.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean); if (normalizedParts.some((part) => SENSITIVE_KEY_PARTS.has(part))) { throw new DataContractError(`${label} contains a field outside the public data contract.`); } rejectSensitiveKeys(child, `${label}.${key}`, seen); } } export function validateAssetSet(rawAssets) { requirePlainObject(rawAssets, "asset set"); requireExactKeys(rawAssets, Object.keys(REQUIRED_ASSETS), "asset set"); const manifest = rawAssets.manifest; validateEnvelope(manifest, "data_manifest"); if (!manifest.development_preview || manifest.population_estimate_allowed) { throw new DataContractError( "The dashboard accepts development-sample, non-population assets only.", ); } requireExactKeys( manifest, [ ...ENVELOPE_KEYS, "assets", "data_scope", "definitions", "model_versions", "release_id", ], "data_manifest", ); if (Object.hasOwn(manifest, "rows")) { throw new DataContractError("data_manifest must not contain row data."); } requirePlainObject(manifest.data_scope, "data_manifest.data_scope"); requirePlainObject(manifest.definitions, "data_manifest.definitions"); requireString(manifest.release_id, "data_manifest.release_id"); if (!/^[0-9a-f]{64}$/.test(manifest.release_id)) { throw new DataContractError("data_manifest.release_id is invalid."); } if (!Array.isArray(manifest.model_versions) || manifest.model_versions.length === 0) { throw new DataContractError("data_manifest.model_versions must be a non-empty array."); } manifest.model_versions.forEach((version, index) => requireSafeModelVersion(version, `data_manifest.model_versions[${index}]`), ); if ( JSON.stringify(manifest.model_versions) !== JSON.stringify([...new Set(manifest.model_versions)].sort()) ) { throw new DataContractError("data_manifest.model_versions must be sorted and unique."); } requireExactKeys( manifest.data_scope, ["first_year", "last_year", "model_names", "partitions"], "data_manifest.data_scope", ); requireInteger(manifest.data_scope.first_year, "data_manifest.data_scope.first_year", { min: 2010, max: 2100, }); requireInteger(manifest.data_scope.last_year, "data_manifest.data_scope.last_year", { min: manifest.data_scope.first_year, max: 2100, }); validateStringArray(manifest.data_scope.model_names, "data_manifest.data_scope.model_names"); requireExactStringSet( manifest.data_scope.partitions, APPROVED_PARTITIONS, "data_manifest.data_scope.partitions", ); requireExactKeys( manifest.definitions, [ "episode_gap_days", "locked_test_metrics_published", "support_rounding", "suppression_min_nonpass", "suppression_min_pass", "suppression_min_support", "suppression_min_distinct_vehicles", "suppression_min_distinct_pass_vehicles", "suppression_min_distinct_nonpass_vehicles", "target", ], "data_manifest.definitions", ); requireInteger(manifest.definitions.episode_gap_days, "data_manifest.definitions.episode_gap_days", { min: 1, }); requireBoolean( manifest.definitions.locked_test_metrics_published, "data_manifest.definitions.locked_test_metrics_published", ); if (manifest.definitions.locked_test_metrics_published !== false) { throw new DataContractError("Locked-test metrics are not approved for this public preview."); } for (const key of [ "support_rounding", "suppression_min_nonpass", "suppression_min_pass", "suppression_min_support", "suppression_min_distinct_vehicles", "suppression_min_distinct_pass_vehicles", "suppression_min_distinct_nonpass_vehicles", ]) { requireInteger(manifest.definitions[key], `data_manifest.definitions.${key}`, { min: 1 }); } requireString(manifest.definitions.target, "data_manifest.definitions.target"); if (manifest.definitions.target !== APPROVED_TARGET) { throw new DataContractError("data_manifest.definitions.target is outside the approved scope."); } if (!Array.isArray(manifest.assets)) { throw new DataContractError("data_manifest.assets must be an array."); } validateStringArray(manifest.assets, "data_manifest.assets"); const expectedManifestAssets = Object.entries(REQUIRED_ASSETS) .filter(([name]) => !["manifest", "shaManifest"].includes(name)) .map(([, filename]) => filename) .sort(); const declaredAssets = [...manifest.assets].sort(); if (JSON.stringify(declaredAssets) !== JSON.stringify(expectedManifestAssets)) { throw new DataContractError("data_manifest.assets does not match the approved asset set."); } const validated = { manifest }; for (const [name, validator] of Object.entries(ASSET_VALIDATORS)) { if (!Object.hasOwn(rawAssets, name)) { throw new DataContractError(`A required approved aggregate is missing: ${name}.`); } validated[name] = validator(rawAssets[name]); if ( validated[name].development_preview !== manifest.development_preview || validated[name].population_estimate_allowed !== manifest.population_estimate_allowed ) { throw new DataContractError(`${name} publication flags disagree with data_manifest.`); } } requireExactStringSet( validated.filters.models, manifest.data_scope.model_names, "filter_catalog.models", ); for (const [index, row] of validated.diagnostics.rows.entries()) { if (!validated.filters.models.includes(row.model)) { throw new DataContractError(`model_diagnostics.rows[${index}].model is not cataloged.`); } } for (const model of REQUIRED_CALIBRATION_MODELS) { const matches = validated.diagnostics.rows.filter( (row) => row.model === model && row.partition === "calibrate", ); if (matches.length !== 1) { throw new DataContractError( `model_diagnostics must contain exactly one approved calibration row for ${model}.`, ); } } const minimumSupport = manifest.definitions.suppression_min_support; const supportRounding = manifest.definitions.support_rounding; for (const name of ["overview", "ageRisk", "scorecards", "coverage"]) { for (const [index, row] of validated[name].rows.entries()) { if ( row.support_rounded < minimumSupport || row.support_rounded % supportRounding !== 0 ) { throw new DataContractError( `${name}.rows[${index}].support_rounded violates the publication thresholds.`, ); } } } return Object.freeze(validated); } async function fetchBytes(path, fetchImplementation) { let response; try { response = await fetchImplementation(path, { cache: "no-store", credentials: "same-origin", }); } catch { throw new DataContractError("Approved dashboard assets could not be reached."); } if (!response.ok) { throw new DataContractError("One or more approved dashboard assets are unavailable."); } try { return await response.arrayBuffer(); } catch { throw new DataContractError("An approved dashboard asset could not be read safely."); } } function parseJsonBytes(bytes, label) { if (typeof TextDecoder !== "function") { throw new DataContractError("This browser cannot decode dashboard assets safely."); } try { return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes)); } catch { throw new DataContractError(`${label} is not valid UTF-8 JSON.`); } } function rotateRight(value, shift) { return ((value >>> shift) | (value << (32 - shift))) >>> 0; } function sha256HexFallback(bytes) { const input = new Uint8Array(bytes); const bitLength = input.byteLength * 8; if (!Number.isSafeInteger(bitLength)) { throw new DataContractError("Dashboard asset integrity verification failed."); } const paddedLength = Math.ceil((input.byteLength + 9) / 64) * 64; const padded = new Uint8Array(paddedLength); padded.set(input); padded[input.byteLength] = 0x80; const paddedView = new DataView(padded.buffer); paddedView.setUint32(paddedLength - 8, Math.floor(bitLength / 0x100000000), false); paddedView.setUint32(paddedLength - 4, bitLength >>> 0, false); const state = [...SHA256_INITIAL_STATE]; const words = new Uint32Array(64); for (let offset = 0; offset < paddedLength; offset += 64) { for (let index = 0; index < 16; index += 1) { words[index] = paddedView.getUint32(offset + index * 4, false); } for (let index = 16; index < 64; index += 1) { const sigma0 = rotateRight(words[index - 15], 7) ^ rotateRight(words[index - 15], 18) ^ (words[index - 15] >>> 3); const sigma1 = rotateRight(words[index - 2], 17) ^ rotateRight(words[index - 2], 19) ^ (words[index - 2] >>> 10); words[index] = (words[index - 16] + sigma0 + words[index - 7] + sigma1) >>> 0; } let [a, b, c, d, e, f, g, h] = state; for (let index = 0; index < 64; index += 1) { const sum1 = rotateRight(e, 6) ^ rotateRight(e, 11) ^ rotateRight(e, 25); const choose = (e & f) ^ (~e & g); const temporary1 = (h + sum1 + choose + SHA256_ROUND_CONSTANTS[index] + words[index]) >>> 0; const sum0 = rotateRight(a, 2) ^ rotateRight(a, 13) ^ rotateRight(a, 22); const majority = (a & b) ^ (a & c) ^ (b & c); const temporary2 = (sum0 + majority) >>> 0; h = g; g = f; f = e; e = (d + temporary1) >>> 0; d = c; c = b; b = a; a = (temporary1 + temporary2) >>> 0; } state[0] = (state[0] + a) >>> 0; state[1] = (state[1] + b) >>> 0; state[2] = (state[2] + c) >>> 0; state[3] = (state[3] + d) >>> 0; state[4] = (state[4] + e) >>> 0; state[5] = (state[5] + f) >>> 0; state[6] = (state[6] + g) >>> 0; state[7] = (state[7] + h) >>> 0; } return state.map((word) => word.toString(16).padStart(8, "0")).join(""); } async function sha256Hex(bytes, cryptoImplementation) { if (!cryptoImplementation?.subtle || typeof cryptoImplementation.subtle.digest !== "function") { return sha256HexFallback(bytes); } let digest; try { digest = await cryptoImplementation.subtle.digest("SHA-256", bytes); } catch { throw new DataContractError("Dashboard asset integrity verification failed."); } return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join(""); } export async function loadDashboardData({ basePath = "./public/data/", fetchImplementation = globalThis.fetch, cryptoImplementation = globalThis.crypto, } = {}) { if (typeof fetchImplementation !== "function") { throw new DataContractError("This browser cannot load dashboard assets safely."); } const baseUrl = new URL(basePath, globalThis.location?.href ?? "http://local/"); const shaBytes = await fetchBytes( new URL(REQUIRED_ASSETS.shaManifest, baseUrl), fetchImplementation, ); const shaManifest = validateShaManifest( parseJsonBytes(shaBytes, "The checksum manifest"), ); const expectedDigests = new Map( shaManifest.files.map((entry) => [entry.name, entry.sha256]), ); const assetEntries = Object.entries(REQUIRED_ASSETS).filter( ([name]) => name !== "shaManifest", ); const rawEntries = await Promise.all( assetEntries.map(async ([name, filename]) => [ name, filename, await fetchBytes(new URL(filename, baseUrl), fetchImplementation), ]), ); await Promise.all( rawEntries.map(async ([, filename, bytes]) => { const observed = await sha256Hex(bytes, cryptoImplementation); if (observed !== expectedDigests.get(filename)) { throw new DataContractError(`Integrity verification failed for ${filename}.`); } }), ); const parsedEntries = rawEntries.map(([name, filename, bytes]) => [ name, parseJsonBytes(bytes, filename), ]); parsedEntries.push(["shaManifest", shaManifest]); return validateAssetSet(Object.fromEntries(parsedEntries)); } export { SCHEMA_VERSION };