repository is now a presentation-ready development prototype
This commit is contained in:
@@ -52,13 +52,25 @@ function filesRecursively(directory) {
|
||||
});
|
||||
}
|
||||
|
||||
function viewSource(html, route) {
|
||||
const marker = `<section class="view" id="view-${route}"`;
|
||||
const start = html.indexOf(marker);
|
||||
if (start < 0) return "";
|
||||
const remaining = html.slice(start + marker.length);
|
||||
const nextView = remaining.indexOf('<section class="view" id="view-');
|
||||
const mainEnd = remaining.indexOf("</main>");
|
||||
const candidates = [nextView, mainEnd].filter((index) => index >= 0);
|
||||
const end = candidates.length ? Math.min(...candidates) : remaining.length;
|
||||
return html.slice(start, start + marker.length + end);
|
||||
}
|
||||
|
||||
test("static shell exposes four semantic navigable views", () => {
|
||||
const html = readFileSync(path.join(DASHBOARD_ROOT, "index.html"), "utf8");
|
||||
assert.match(html, /<header\b/);
|
||||
assert.match(html, /<nav\b[^>]*aria-label="Dashboard views"/);
|
||||
assert.match(html, /<main\b/);
|
||||
assert.match(html, /<footer\b/);
|
||||
for (const route of ["overview", "reliability", "estimator", "methods"]) {
|
||||
for (const route of ["overview", "cohorts", "model", "methods"]) {
|
||||
assert.match(html, new RegExp(`data-route="${route}"`));
|
||||
assert.match(html, new RegExp(`data-view="${route}"`));
|
||||
}
|
||||
@@ -67,20 +79,45 @@ test("static shell exposes four semantic navigable views", () => {
|
||||
assert.doesNotMatch(html, /<strong>Locked test<\/strong>|<small>Final evaluation<\/small>/);
|
||||
});
|
||||
|
||||
test("estimator remains disabled and contains no identifying input", () => {
|
||||
test("narrow layouts constrain body content while preserving local nav scrolling", () => {
|
||||
const css = readFileSync(path.join(DASHBOARD_ROOT, "styles.css"), "utf8");
|
||||
assert.match(css, /html\s*{[^}]*max-width:\s*100%;[^}]*overflow-x:\s*clip;/s);
|
||||
assert.match(css, /body\s*{[^}]*max-width:\s*100%;[^}]*overflow-x:\s*clip;/s);
|
||||
assert.match(css, /\.primary-nav__inner\s*{[^}]*overflow-x:\s*auto;/s);
|
||||
const mobile = css.match(/@media \(max-width: 660px\)\s*{[\s\S]*?(?=@media|$)/)?.[0];
|
||||
assert.ok(mobile, "mobile breakpoint is present");
|
||||
assert.match(mobile, /\.page-shell\s*{[^}]*width:\s*auto;[^}]*max-width:\s*calc\(100% - 2rem\);/s);
|
||||
assert.match(mobile, /\.preview-banner\s*{[^}]*justify-content:\s*flex-start;/s);
|
||||
assert.match(mobile, /overflow-wrap:\s*anywhere;/);
|
||||
});
|
||||
|
||||
test("model view declares the final model, benchmark role, and publication boundary", () => {
|
||||
const html = readFileSync(path.join(DASHBOARD_ROOT, "index.html"), "utf8");
|
||||
const estimator = html.match(/<section class="view" id="view-estimator"[\s\S]*?<\/section>/)?.[0];
|
||||
assert.ok(estimator, "estimator section is present");
|
||||
assert.match(estimator, /<fieldset disabled>/);
|
||||
const controlAttributes = [...estimator.matchAll(/<(?:input|select|textarea)\b([^>]*)>/g)].map(
|
||||
(match) => match[1],
|
||||
);
|
||||
for (const attributes of controlAttributes) {
|
||||
assert.doesNotMatch(
|
||||
attributes,
|
||||
/(?:name|id)\s*=\s*["'][^"']*(?:vin|plate|address|station|free.?text|zip)[^"']*["']/i,
|
||||
);
|
||||
const modelView = viewSource(html, "model");
|
||||
assert.ok(modelView, "model section is present");
|
||||
assert.match(modelView, /Calibrated logistic regression/);
|
||||
assert.match(modelView, /Final prototype/);
|
||||
assert.match(modelView, /Calibrated boosted tree/);
|
||||
assert.match(modelView, /Benchmark only/);
|
||||
assert.match(modelView, /partition used to fit Platt calibration/i);
|
||||
assert.match(modelView, /not independent final-performance estimates/i);
|
||||
assert.match(modelView, /No vehicle-level prediction service/);
|
||||
assert.doesNotMatch(modelView, /<(?:input|select|textarea|form)\b/i);
|
||||
assert.doesNotMatch(modelView, /prediction_lookup|planned tool|future approved output/i);
|
||||
});
|
||||
|
||||
test("every result-facing view visibly labels the sample and non-population scope", () => {
|
||||
const html = readFileSync(path.join(DASHBOARD_ROOT, "index.html"), "utf8");
|
||||
assert.match(html, /Private 10,000-vehicle development sample/);
|
||||
for (const route of ["overview", "cohorts", "model", "methods"]) {
|
||||
const view = viewSource(html, route);
|
||||
assert.ok(view, `${route} view is present`);
|
||||
assert.match(view, /scope-strip/);
|
||||
assert.match(view, /sample/i);
|
||||
assert.match(view, /not[^.]{0,80}population|population estimate/i);
|
||||
}
|
||||
assert.match(html, /not a county outcome ranking/i);
|
||||
assert.match(html, /not a reliability ranking or population comparison/i);
|
||||
});
|
||||
|
||||
test("all required generated assets satisfy the browser contract", () => {
|
||||
@@ -91,6 +128,12 @@ test("all required generated assets satisfy the browser contract", () => {
|
||||
assert.equal(validated.manifest.definitions.locked_test_metrics_published, false);
|
||||
assert.match(validated.manifest.release_id, /^[0-9a-f]{64}$/);
|
||||
assert.ok(validated.manifest.model_versions.length > 0);
|
||||
assert.ok(validated.diagnostics.rows.some(
|
||||
(row) => row.model === "logistic_platt" && row.partition === "calibrate",
|
||||
));
|
||||
assert.ok(validated.diagnostics.rows.some(
|
||||
(row) => row.model === "hist_gradient_boosting_platt" && row.partition === "calibrate",
|
||||
));
|
||||
assert.deepEqual(
|
||||
validated.filters.partitions,
|
||||
["train", "tune", "calibrate"],
|
||||
@@ -151,10 +194,37 @@ test("contract fails closed for missing, inconsistent, or sensitive data", () =>
|
||||
inconsistent.ageRisk.population_estimate_allowed = true;
|
||||
assert.throws(() => validateAssetSet(inconsistent), DataContractError);
|
||||
|
||||
const populationClaim = assetSet();
|
||||
populationClaim.manifest.population_estimate_allowed = true;
|
||||
assert.throws(() => validateAssetSet(populationClaim), DataContractError);
|
||||
|
||||
const broadenedTarget = assetSet();
|
||||
broadenedTarget.manifest.definitions.target = "any inspection outcome";
|
||||
assert.throws(() => validateAssetSet(broadenedTarget), DataContractError);
|
||||
|
||||
const sensitive = assetSet();
|
||||
sensitive.scorecards.rows[0].vehicle_token = "not-public";
|
||||
assert.throws(() => validateAssetSet(sensitive), DataContractError);
|
||||
|
||||
for (const deniedField of [
|
||||
"vin",
|
||||
"plate",
|
||||
"zip",
|
||||
"station",
|
||||
"technician_id",
|
||||
"inspector_id",
|
||||
"row_prediction",
|
||||
"probability",
|
||||
"raw_json",
|
||||
"credential",
|
||||
"password",
|
||||
"secret",
|
||||
]) {
|
||||
const denied = assetSet();
|
||||
denied.overview.rows[0][deniedField] = "not-public";
|
||||
assert.throws(() => validateAssetSet(denied), DataContractError, deniedField);
|
||||
}
|
||||
|
||||
const extraRowField = assetSet();
|
||||
extraRowField.overview.rows[0].note = "unapproved";
|
||||
assert.throws(() => validateAssetSet(extraRowField), DataContractError);
|
||||
@@ -167,6 +237,20 @@ test("contract fails closed for missing, inconsistent, or sensitive data", () =>
|
||||
extraPartition.filters.partitions.push("locked_test");
|
||||
assert.throws(() => validateAssetSet(extraPartition), DataContractError);
|
||||
|
||||
const missingFinalDiagnostic = assetSet();
|
||||
missingFinalDiagnostic.diagnostics.rows = missingFinalDiagnostic.diagnostics.rows.filter(
|
||||
(row) => !(row.model === "logistic_platt" && row.partition === "calibrate"),
|
||||
);
|
||||
assert.throws(() => validateAssetSet(missingFinalDiagnostic), DataContractError);
|
||||
|
||||
const duplicatedBenchmarkDiagnostic = assetSet();
|
||||
duplicatedBenchmarkDiagnostic.diagnostics.rows.push({
|
||||
...duplicatedBenchmarkDiagnostic.diagnostics.rows.find(
|
||||
(row) => row.model === "hist_gradient_boosting_platt" && row.partition === "calibrate",
|
||||
),
|
||||
});
|
||||
assert.throws(() => validateAssetSet(duplicatedBenchmarkDiagnostic), DataContractError);
|
||||
|
||||
const unsortedVersions = assetSet();
|
||||
unsortedVersions.manifest.model_versions = ["z_v1", "a_v1"];
|
||||
assert.throws(() => validateAssetSet(unsortedVersions), DataContractError);
|
||||
@@ -194,3 +278,15 @@ test("dashboard source has no external runtime dependency or credential marker",
|
||||
assert.doesNotMatch(source, /<script[^>]+src=["']https?:|@import\s+url\(["']?https?:/i);
|
||||
}
|
||||
});
|
||||
|
||||
test("public data directory contains only the approved suppressed aggregate bundle", () => {
|
||||
const expected = Object.values(REQUIRED_ASSETS).sort();
|
||||
const observed = readdirSync(PUBLIC_DATA).sort();
|
||||
assert.deepEqual(observed, expected);
|
||||
|
||||
const serialized = observed
|
||||
.map((filename) => readFileSync(path.join(PUBLIC_DATA, filename), "utf8"))
|
||||
.join("\n");
|
||||
assert.doesNotMatch(serialized, /\b[A-HJ-NPR-Z0-9]{17}\b/);
|
||||
assert.doesNotMatch(serialized, /(?:postgres(?:ql)?:\/\/|PGPASSWORD|BEGIN [A-Z ]*PRIVATE KEY)/i);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user