feat(lab): publish M4.8T quality evidence

This commit is contained in:
DCCONSTRUCTIONS
2026-08-25 23:44:27 +03:00
parent 9a956c318a
commit 3ff3b9b587
20 changed files with 1419 additions and 4 deletions
@@ -43,11 +43,13 @@ import {
} from "./m48ObjectCentricQuality";
import { fetchM48SmallStaticRegression } from "./m48SmallStaticRegression";
import { fetchM48SFixedClassDetectorResult } from "./m48sFixedClassDetector";
import { fetchM48TRiskQualityResult } from "./m48tRiskQuality";
export type AdvancedLaboratoryWorkId =
| "m48-object-centric-quality"
| "m48-small-static-passage-regression"
| "m48s-fixed-class-detector"
| "m48t-risk-quality-temporal"
| "m47-reference-graph-shadow"
| "m4-replay-threat"
| "l3-pointpillars-visual-audit"
@@ -93,6 +95,7 @@ const WORK_IDS: readonly AdvancedLaboratoryWorkId[] = [
"m48-object-centric-quality",
"m48-small-static-passage-regression",
"m48s-fixed-class-detector",
"m48t-risk-quality-temporal",
"m47-reference-graph-shadow",
"m4-replay-threat",
"l3-pointpillars-visual-audit",
@@ -133,6 +136,7 @@ const RESULT_PREFIX: Readonly<Record<AdvancedLaboratoryWorkId, string>> = {
"m48-object-centric-quality": "m48-object-quality-(?:pack|result)",
"m48-small-static-passage-regression": "m48-small-static-passage-regression",
"m48s-fixed-class-detector": "m48s-fixed-class-detector-lab",
"m48t-risk-quality-temporal": "m48t-risk-quality-temporal-lab",
"m47-reference-graph-shadow": "m47-reference-graph-lab",
"m4-replay-threat": "m4-threat-replay",
"l3-pointpillars-visual-audit": "l3-pointpillars-visual-audit",
@@ -181,6 +185,7 @@ export function emptyAdvancedLaboratoryResults(): AdvancedLaboratoryResults {
m48: null,
m48SmallStatic: null,
m48s: null,
m48t: null,
m4Threat: null,
l3: null,
l31: null,
@@ -308,6 +313,7 @@ export function advancedLaboratoryResultAvailable(
return workId === "m48-object-centric-quality" ? results.m48 !== null
: workId === "m48-small-static-passage-regression" ? results.m48SmallStatic !== null
: workId === "m48s-fixed-class-detector" ? results.m48s !== null
: workId === "m48t-risk-quality-temporal" ? results.m48t !== null
: workId === "m47-reference-graph-shadow" ? results.m47Graph !== null
: workId === "m4-replay-threat" ? results.m4Threat !== null
: workId === "l3-pointpillars-visual-audit" ? results.l3 !== null
@@ -366,6 +372,9 @@ export async function fetchAdvancedLaboratoryResult(
} else if (workId === "m48s-fixed-class-detector") {
if (!resultId) throw new AdvancedLaboratoryContractError("M4.8S LAB identity не выбрана.");
results.m48s = await fetchM48SFixedClassDetectorResult(resultId, { fetcher, signal });
} else if (workId === "m48t-risk-quality-temporal") {
if (!resultId) throw new AdvancedLaboratoryContractError("M4.8T LAB identity не выбрана.");
results.m48t = await fetchM48TRiskQualityResult(resultId, { fetcher, signal });
} else if (workId === "m47-reference-graph-shadow") {
if (!resultId) {
throw new AdvancedLaboratoryContractError("M4.7 LAB identity не выбрана.");
@@ -37,12 +37,14 @@ import type { M47ReferenceGraphLabResult } from "./m47ReferenceGraph";
import type { M48AdvancedResult } from "./m48ObjectCentricQuality";
import type { M48SmallStaticRegressionResult } from "./m48SmallStaticRegression";
import type { M48SFixedClassDetectorResult } from "./m48sFixedClassDetector";
import type { M48TRiskQualityResult } from "./m48tRiskQuality";
export interface AdvancedLaboratoryResults {
m47Graph: M47ReferenceGraphLabResult | null;
m48: M48AdvancedResult | null;
m48SmallStatic: M48SmallStaticRegressionResult | null;
m48s: M48SFixedClassDetectorResult | null;
m48t: M48TRiskQualityResult | null;
m4Threat: M4ThreatReplayResult | null;
l3: L3PointPillarsVisualAuditResult | null;
l31: L31PointPillarsRavnovesResult | null;
@@ -967,7 +967,7 @@ export async function fetchAdvancedLaboratoryResults({
const e39 = settledCatalogValue(settled[7]);
const e40 = settledCatalogValue(settled[8]);
return {
m47Graph: null, m48: null, m48SmallStatic: null, m48s: null, m4Threat: null,
m47Graph: null, m48: null, m48SmallStatic: null, m48s: null, m48t: null, m4Threat: null,
l3: null, l31: null,
l32: null,
l33: null,
@@ -0,0 +1,326 @@
export interface M48TLaboratoryMethod {
completeness: "complete";
executionClass: "hybrid";
pipelineId: string;
components: readonly {
kind: "source" | "model" | "algorithm" | "runtime" | "tool";
name: string;
version: string;
role: string;
identitySha256: string;
}[];
}
export interface M48TReviewCase {
caseId: string;
imageId: number;
imageUrl: string;
byteLength: number;
sha256: string;
}
export interface M48TRiskQualityResult {
resultId: string;
createdAtUtc: string;
source: {
quality: {
datasetId: "coco-2017-val";
riskImages: number;
truthInstances: number;
independentHumanAnnotations: true;
ravnovesGroundTruth: false;
};
temporal: {
sourceId: "RAVNOVES00";
frames: number;
publications: number;
independentSemanticTruthAvailable: false;
};
};
candidate: {
providerId: string;
modelId: "rf_detr_large:1";
minimumScore: 0.25;
};
execution: {
durationSeconds: number;
effectiveImagesPerSecond: number;
imageP95Ms: number;
inferenceP95Ms: number;
timingIsAdmissionEvidence: false;
};
quality: {
microPrecision: number;
microRecall: number;
mediumLargeRecall: number;
emptyRiskImageFraction: number;
families: Readonly<Record<"person" | "animal" | "light-road-user" | "vehicle", number>>;
};
counts: {
truth: number;
predictions: number;
truePositive: number;
falsePositive: number;
falseNegative: number;
};
failures: Readonly<Record<string, number>>;
temporal: {
rawClassSwitches: number;
stableClassSwitches: number;
rawFamilySwitches: number;
stableFamilySwitches: number;
suppressedClassSwitches: number;
suppressedFamilySwitches: number;
selectedPublications: number;
semanticObservations: number;
peakActiveComponents: number;
maximumActiveComponents: number;
};
acceptance: {
qualityPassed: false;
failedQualityGates: readonly [
"minimum-micro-precision",
"minimum-family-recall:vehicle",
];
temporalInvariantPassed: true;
};
review: {
truthColor: "green";
predictionColor: "yellow";
cases: readonly M48TReviewCase[];
};
method: M48TLaboratoryMethod;
limitations: readonly string[];
}
type LaboratoryFetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
export class M48TContractError extends Error {}
function object(value: unknown, label: string): Record<string, unknown> {
if (!value || typeof value !== "object" || Array.isArray(value)) {
throw new M48TContractError(`${label}: ожидался объект.`);
}
return value as Record<string, unknown>;
}
function array(value: unknown, label: string): readonly unknown[] {
if (!Array.isArray(value)) throw new M48TContractError(`${label}: ожидался массив.`);
return value;
}
function text(value: unknown, label: string): string {
if (typeof value !== "string" || !value.trim()) {
throw new M48TContractError(`${label}: ожидалась строка.`);
}
return value;
}
function number(value: unknown, label: string): number {
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
throw new M48TContractError(`${label}: ожидалось неотрицательное число.`);
}
return value;
}
function integer(value: unknown, label: string): number {
const parsed = number(value, label);
if (!Number.isSafeInteger(parsed)) {
throw new M48TContractError(`${label}: ожидалось целое число.`);
}
return parsed;
}
function exact<T extends string | number | boolean>(
value: unknown,
expected: T,
label: string,
): T {
if (value !== expected) throw new M48TContractError(`${label}: нарушен контракт.`);
return expected;
}
function sha(value: unknown, label: string): string {
const parsed = text(value, label);
if (!/^[a-f0-9]{64}$/.test(parsed)) {
throw new M48TContractError(`${label}: нарушена SHA-256 идентичность.`);
}
return parsed;
}
function method(value: unknown): M48TLaboratoryMethod {
const raw = object(value, "M4.8T method");
exact(raw.schema_version, "missioncore.laboratory-method/v1", "M4.8T method schema");
exact(raw.completeness, "complete", "M4.8T method completeness");
exact(raw.execution_class, "hybrid", "M4.8T method execution");
const allowedKinds = new Set(["source", "model", "algorithm", "runtime", "tool"]);
return {
completeness: "complete",
executionClass: "hybrid",
pipelineId: text(raw.pipeline_id, "M4.8T pipeline"),
components: array(raw.components, "M4.8T components").map((value) => {
const component = object(value, "M4.8T component");
const kind = text(component.kind, "M4.8T component kind");
if (!allowedKinds.has(kind)) throw new M48TContractError("M4.8T component kind: неизвестное значение.");
return {
kind: kind as "source" | "model" | "algorithm" | "runtime" | "tool",
name: text(component.name, "M4.8T component name"),
version: text(component.version, "M4.8T component version"),
role: text(component.role, "M4.8T component role"),
identitySha256: sha(component.identity_sha256, "M4.8T component identity"),
};
}),
};
}
function parseResult(value: unknown, expectedResultId: string): M48TRiskQualityResult {
const raw = object(value, "M4.8T result");
exact(raw.schema_version, "missioncore.m48t-risk-quality-temporal-view/v1", "M4.8T schema");
exact(raw.result_id, expectedResultId, "M4.8T identity");
exact(raw.status, "complete-quality-gate-failed-temporal-invariant-passed", "M4.8T status");
exact(raw.access, "read-only", "M4.8T access");
exact(raw.ground_truth, false, "M4.8T ground truth");
const source = object(raw.source, "M4.8T source");
const qualitySource = object(source.quality, "M4.8T quality source");
const temporalSource = object(source.temporal, "M4.8T temporal source");
const configuration = object(raw.configuration, "M4.8T configuration");
const candidate = object(configuration.candidate, "M4.8T candidate");
const execution = object(raw.execution, "M4.8T execution");
const imageTiming = object(execution.image_timing_ms, "M4.8T image timing");
const inferenceTiming = object(execution.triton_inference_ms, "M4.8T inference timing");
const metrics = object(raw.metrics, "M4.8T metrics");
const quality = object(metrics.quality, "M4.8T quality metrics");
const families = object(quality.families, "M4.8T family metrics");
const familyRecall = (name: "person" | "animal" | "light-road-user" | "vehicle") =>
number(object(families[name], `M4.8T ${name}`).family_recall, `M4.8T ${name} recall`);
const counts = object(metrics.counts, "M4.8T counts");
const failures = object(metrics.failure_buckets, "M4.8T failures");
const temporal = object(metrics.temporal, "M4.8T temporal metrics");
const snapshot = object(temporal.snapshot, "M4.8T temporal snapshot");
const acceptance = object(raw.acceptance, "M4.8T acceptance");
const qualityGate = object(acceptance.quality, "M4.8T quality gate");
const temporalGate = object(acceptance.temporal_invariant, "M4.8T temporal gate");
const failed = array(qualityGate.failed, "M4.8T failed gates").map((item) => text(item, "M4.8T failed gate"));
if (failed.length !== 2 || failed[0] !== "minimum-micro-precision" || failed[1] !== "minimum-family-recall:vehicle") {
throw new M48TContractError("M4.8T failed gates: изменён зафиксированный результат.");
}
exact(qualityGate.passed, false, "M4.8T quality gate");
exact(temporalGate.passed, true, "M4.8T temporal invariant");
exact(temporalGate.semantic_quality_accepted, false, "M4.8T temporal semantic acceptance");
const review = object(raw.review, "M4.8T review");
const legend = object(review.legend, "M4.8T review legend");
exact(legend.ground_truth, "green", "M4.8T truth legend");
exact(legend.rf_detr_prediction, "yellow", "M4.8T prediction legend");
const cases = array(review.cases, "M4.8T review cases").map((value) => {
const item = object(value, "M4.8T review case");
const caseId = text(item.case_id, "M4.8T case id");
if (!/^[0-9]{12}$/.test(caseId)) throw new M48TContractError("M4.8T case identity нарушена.");
exact(item.media_type, "image/jpeg", "M4.8T case media");
return {
caseId,
imageId: integer(item.image_id, "M4.8T image id"),
imageUrl: text(item.image_url, "M4.8T image URL"),
byteLength: integer(item.byte_length, "M4.8T image bytes"),
sha256: sha(item.sha256, "M4.8T image SHA"),
};
});
if (cases.length !== 16 || new Set(cases.map(({ caseId }) => caseId)).size !== 16) {
throw new M48TContractError("M4.8T review catalog: нарушен размер.");
}
const parsedFailures: Record<string, number> = {};
for (const [key, count] of Object.entries(failures)) parsedFailures[key] = integer(count, `M4.8T failure ${key}`);
const temporalConfiguration = object(configuration.temporal, "M4.8T temporal configuration");
return {
resultId: expectedResultId,
createdAtUtc: text(raw.created_at_utc, "M4.8T created at"),
source: {
quality: {
datasetId: exact(qualitySource.dataset_id, "coco-2017-val", "M4.8T dataset"),
riskImages: integer(qualitySource.risk_images, "M4.8T risk images"),
truthInstances: integer(qualitySource.truth_instances, "M4.8T truth instances"),
independentHumanAnnotations: exact(qualitySource.independent_human_annotations, true, "M4.8T independent truth"),
ravnovesGroundTruth: exact(qualitySource.ravnoves_ground_truth, false, "M4.8T RAVNOVES truth"),
},
temporal: {
sourceId: exact(temporalSource.source_id, "RAVNOVES00", "M4.8T temporal source"),
frames: integer(temporalSource.frames, "M4.8T temporal frames"),
publications: integer(temporalSource.publications, "M4.8T temporal publications"),
independentSemanticTruthAvailable: exact(temporalSource.independent_semantic_truth_available, false, "M4.8T temporal truth"),
},
},
candidate: {
providerId: text(candidate.provider_id, "M4.8T provider"),
modelId: exact(candidate.model_id, "rf_detr_large:1", "M4.8T model"),
minimumScore: exact(candidate.minimum_score, 0.25, "M4.8T threshold"),
},
execution: {
durationSeconds: number(execution.duration_seconds, "M4.8T duration"),
effectiveImagesPerSecond: number(execution.effective_images_per_second, "M4.8T throughput"),
imageP95Ms: number(imageTiming.p95, "M4.8T image p95"),
inferenceP95Ms: number(inferenceTiming.p95, "M4.8T inference p95"),
timingIsAdmissionEvidence: exact(execution.timing_is_admission_evidence, false, "M4.8T timing authority"),
},
quality: {
microPrecision: number(quality.micro_precision, "M4.8T precision"),
microRecall: number(quality.micro_recall, "M4.8T recall"),
mediumLargeRecall: number(quality.medium_large_recall, "M4.8T medium-large recall"),
emptyRiskImageFraction: number(quality.empty_prediction_risk_image_fraction, "M4.8T empty fraction"),
families: {
person: familyRecall("person"),
animal: familyRecall("animal"),
"light-road-user": familyRecall("light-road-user"),
vehicle: familyRecall("vehicle"),
},
},
counts: {
truth: integer(qualitySource.truth_instances, "M4.8T truth count"),
predictions: integer(counts.predictions, "M4.8T predictions"),
truePositive: integer(counts.true_positive, "M4.8T TP"),
falsePositive: integer(counts.false_positive, "M4.8T FP"),
falseNegative: integer(counts.false_negative, "M4.8T FN"),
},
failures: parsedFailures,
temporal: {
rawClassSwitches: integer(temporal.raw_class_switches, "M4.8T raw class switches"),
stableClassSwitches: integer(temporal.stable_class_switches, "M4.8T stable class switches"),
rawFamilySwitches: integer(temporal.raw_family_switches, "M4.8T raw family switches"),
stableFamilySwitches: integer(temporal.stable_family_switches, "M4.8T stable family switches"),
suppressedClassSwitches: integer(temporal.suppressed_or_deferred_class_switches, "M4.8T suppressed class switches"),
suppressedFamilySwitches: integer(temporal.suppressed_or_deferred_family_switches, "M4.8T suppressed family switches"),
selectedPublications: integer(temporal.selected_publications, "M4.8T selected publications"),
semanticObservations: integer(temporal.semantic_current_observations, "M4.8T semantic observations"),
peakActiveComponents: integer(snapshot.peak_active_components, "M4.8T active peak"),
maximumActiveComponents: integer(temporalConfiguration.maximum_active_components, "M4.8T active bound"),
},
acceptance: {
qualityPassed: false,
failedQualityGates: ["minimum-micro-precision", "minimum-family-recall:vehicle"],
temporalInvariantPassed: true,
},
review: { truthColor: "green", predictionColor: "yellow", cases },
method: method(raw.method),
limitations: array(raw.limitations, "M4.8T limitations").map((item) => text(item, "M4.8T limitation")),
};
}
export async function fetchM48TRiskQualityResult(
resultId: string,
{
fetcher = fetch,
signal,
}: { fetcher?: LaboratoryFetch; signal?: AbortSignal } = {},
): Promise<M48TRiskQualityResult> {
if (!/^m48t-risk-quality-temporal-lab-[a-f0-9]{64}$/.test(resultId)) {
throw new M48TContractError("M4.8T result identity недопустима.");
}
const response = await fetcher(`/api/v1/laboratory/m48t/risk-quality/results/${resultId}`, {
method: "GET",
headers: { Accept: "application/json" },
signal,
});
if (!response.ok) throw new M48TContractError(`M4.8T недоступен: HTTP ${response.status}.`);
return parseResult(await response.json(), resultId);
}