feat(lab): publish E40 perception product gate
This commit is contained in:
@@ -12,6 +12,7 @@ import { E35Result } from "./E35Result";
|
||||
import { E37Result } from "./E37Result";
|
||||
import { E38Result } from "./E38Result";
|
||||
import { E39Result } from "./E39Result";
|
||||
import { E40Result } from "./E40Result";
|
||||
import { RecordedReplayEvidence } from "./RecordedReplayEvidence";
|
||||
|
||||
export type AdvancedLaboratoryWorkId =
|
||||
@@ -22,7 +23,8 @@ export type AdvancedLaboratoryWorkId =
|
||||
| "e35-degradation-recovery"
|
||||
| "e37-ravnoves-acceptance"
|
||||
| "e38-perception-baseline"
|
||||
| "e39-perception-refinement";
|
||||
| "e39-perception-refinement"
|
||||
| "e40-perception-product-gate";
|
||||
|
||||
type LaboratoryWorkspaceProps = WorkspaceRendererProps & {
|
||||
SpatialView: ComponentType<WorkspaceRendererProps>;
|
||||
@@ -40,6 +42,7 @@ export function isAdvancedLaboratoryWorkId(
|
||||
|| value === "e37-ravnoves-acceptance"
|
||||
|| value === "e38-perception-baseline"
|
||||
|| value === "e39-perception-refinement"
|
||||
|| value === "e40-perception-product-gate"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -96,6 +99,12 @@ export function advancedLaboratoryWorkOptions(
|
||||
label: "LAB E39 · perception refinement R1",
|
||||
});
|
||||
}
|
||||
if (results.e40) {
|
||||
options.push({
|
||||
id: "e40-perception-product-gate",
|
||||
label: "LAB E40 · leakage-resistant product gate",
|
||||
});
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
@@ -133,6 +142,9 @@ export function AdvancedLaboratoryResult({
|
||||
failedSessionId: string | null;
|
||||
replayError: string | null;
|
||||
}) {
|
||||
if (workId === "e40-perception-product-gate" && results.e40) {
|
||||
return <E40Result rigLabel={rigLabel} result={results.e40} />;
|
||||
}
|
||||
if (workId === "e39-perception-refinement" && results.e39) {
|
||||
return <E39Result rigLabel={rigLabel} result={results.e39} />;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
import {
|
||||
LaboratoryEvidence,
|
||||
LaboratoryMetricGrid,
|
||||
LaboratoryResultSummary,
|
||||
LaboratorySummary,
|
||||
LaboratoryWorkTemplate,
|
||||
} from "../../components/laboratory/LaboratoryPresentation";
|
||||
import type {
|
||||
E40PerceptionProductGateResult,
|
||||
} from "../../core/laboratory/e40ProductGate";
|
||||
import { formatNumber } from "../../presentation";
|
||||
|
||||
function percent(value: number): string {
|
||||
return `${(value * 100).toLocaleString("ru-RU", {
|
||||
maximumFractionDigits: 1,
|
||||
})}%`;
|
||||
}
|
||||
|
||||
export function E40Result({
|
||||
rigLabel,
|
||||
result,
|
||||
}: {
|
||||
rigLabel: string;
|
||||
result: E40PerceptionProductGateResult;
|
||||
}) {
|
||||
const metrics = result.metrics;
|
||||
const dimensions = metrics.dimensions;
|
||||
const contiguous = (
|
||||
result.developmentCrossValidation.protocols.contiguousSourceTime.dimensions
|
||||
);
|
||||
const grouped = (
|
||||
result.developmentCrossValidation.protocols.wholeTrackOrSceneWindow.dimensions
|
||||
);
|
||||
const gateLabel = result.qualityGatePassed
|
||||
? "RAVNOVES00 product gate пройден"
|
||||
: "RAVNOVES00 product gate не пройден";
|
||||
return (
|
||||
<LaboratoryWorkTemplate
|
||||
summary={(
|
||||
<LaboratorySummary
|
||||
title="LAB E40 · leakage-resistant product gate"
|
||||
description="После E39 проверена route-coordinate-free модель: смежные кадры, целые track и scene-window изолированы при development-проверке, а sealed validation исполнен один раз на Worker 006."
|
||||
status={gateLabel}
|
||||
statusTone={result.qualityGatePassed ? "success" : "warning"}
|
||||
facts={[
|
||||
{
|
||||
label: "Конфигурация",
|
||||
value: `${rigLabel} · ${result.sourceDisplayName}`,
|
||||
},
|
||||
{
|
||||
label: "Development",
|
||||
value: `${formatNumber(metrics.developmentItems, 0)} · dual 5-fold`,
|
||||
},
|
||||
{
|
||||
label: "Validation",
|
||||
value: `${formatNumber(metrics.validationItems, 0)} · sealed`,
|
||||
},
|
||||
{
|
||||
label: "Исполнение",
|
||||
value: `Worker 006 · ${result.workerNode}`,
|
||||
},
|
||||
]}
|
||||
brief={{
|
||||
question: "Удерживает ли perception выбранного сенсорного рига не менее 90% по presence, geometry association и freshness после удаления route-coordinate leakage и группировки зависимых кадров?",
|
||||
approach: "Для 340 development-кейсов зафиксированы 125 признаков без frame index, session time, review ordinal, track ID и абсолютных map-координат. Консервативная stratum-policy и camera-only softmax прошли два групповых пятифолдовых протокола; validation labels при выборе и обучении не использовались.",
|
||||
principalResult: `Development: contiguous presence ${percent(contiguous.presence.accuracy)}, grouped presence ${percent(grouped.presence.accuracy)}. Sealed validation: presence ${percent(dimensions.presence.accuracy)}, geometry ${percent(dimensions.geometryAssociation.accuracy)}, freshness ${percent(dimensions.freshness.accuracy)}.`,
|
||||
limitation: "Это source-scoped доказательство только для RAVNOVES00 на инженерно проверенной разметке. Оно не доказывает перенос на другой маршрут, растительность, камеру, риг или живой ровер и не выдаёт навигационных либо safety-полномочий.",
|
||||
}}
|
||||
method={{
|
||||
completeness: "complete",
|
||||
executionClass: "deterministic",
|
||||
pipelineId: result.profileId,
|
||||
components: [
|
||||
{
|
||||
kind: "source",
|
||||
name: "E37 frozen acceptance contract",
|
||||
version: `${formatNumber(metrics.developmentItems, 0)} development + ${formatNumber(metrics.validationItems, 0)} sealed validation`,
|
||||
role: "неизменяемый denominator и reference-метрики трёх измерений",
|
||||
identitySha256: null,
|
||||
},
|
||||
{
|
||||
kind: "algorithm",
|
||||
name: "Conservative evidence-stratum policy",
|
||||
version: "agree · conflict · geometry-only · unknown",
|
||||
role: "явные безопасные terminal outcomes без свободного пространства",
|
||||
identitySha256: null,
|
||||
},
|
||||
{
|
||||
kind: "model",
|
||||
name: "Camera-only deterministic softmax",
|
||||
version: "125 route-coordinate-free structured-image features",
|
||||
role: "presence для camera-only при dual grouped development CV",
|
||||
identitySha256: null,
|
||||
},
|
||||
{
|
||||
kind: "runtime",
|
||||
name: "Worker 006",
|
||||
version: result.workerNode,
|
||||
role: "одно sealed evaluation в package-bound контейнере без командных полномочий",
|
||||
identitySha256: null,
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
evidence={(
|
||||
<LaboratoryEvidence
|
||||
eyebrow="GROUPED DEVELOPMENT → SEALED VALIDATION"
|
||||
title="Устойчивость без route-coordinate leakage"
|
||||
kind="diagnostic-model"
|
||||
>
|
||||
<LaboratoryMetricGrid
|
||||
metrics={[
|
||||
{
|
||||
label: "Contiguous time CV",
|
||||
value: percent(contiguous.presence.accuracy),
|
||||
hint: `presence · geometry ${percent(contiguous.geometryAssociation.accuracy)}`,
|
||||
},
|
||||
{
|
||||
label: "Whole track / scene CV",
|
||||
value: percent(grouped.presence.accuracy),
|
||||
hint: `presence · geometry ${percent(grouped.geometryAssociation.accuracy)}`,
|
||||
},
|
||||
{
|
||||
label: "Sealed presence",
|
||||
value: percent(dimensions.presence.accuracy),
|
||||
hint: `${formatNumber(dimensions.presence.correct, 0)} / ${formatNumber(dimensions.presence.total, 0)} · цель 90%`,
|
||||
},
|
||||
{
|
||||
label: "Sealed freshness",
|
||||
value: percent(dimensions.freshness.accuracy),
|
||||
hint: `${formatNumber(dimensions.freshness.correct, 0)} / ${formatNumber(dimensions.freshness.total, 0)} · цель 90%`,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</LaboratoryEvidence>
|
||||
)}
|
||||
result={(
|
||||
<LaboratoryResultSummary
|
||||
title={result.qualityGatePassed
|
||||
? "Source-scoped perception gate RAVNOVES00 закрыт"
|
||||
: "Route-coordinate признаки исключены, но product gate ещё не закрыт"}
|
||||
status={gateLabel}
|
||||
statusTone={result.qualityGatePassed ? "success" : "warning"}
|
||||
metrics={[
|
||||
{
|
||||
label: "Presence",
|
||||
value: percent(dimensions.presence.accuracy),
|
||||
hint: `${formatNumber(dimensions.presence.incorrect, 0)} ошибок · цель 90%`,
|
||||
},
|
||||
{
|
||||
label: "Geometry association",
|
||||
value: percent(dimensions.geometryAssociation.accuracy),
|
||||
hint: `${formatNumber(dimensions.geometryAssociation.incorrect, 0)} ошибок · цель 90%`,
|
||||
},
|
||||
{
|
||||
label: "Freshness",
|
||||
value: percent(dimensions.freshness.accuracy),
|
||||
hint: `${formatNumber(dimensions.freshness.incorrect, 0)} ошибок · цель 90%`,
|
||||
},
|
||||
{
|
||||
label: "High severity",
|
||||
value: formatNumber(metrics.highSeverityFailures, 0),
|
||||
hint: `учёт ${percent(metrics.accountingFraction)} · false free ${formatNumber(metrics.falseFreeClaims, 0)}`,
|
||||
},
|
||||
]}
|
||||
conclusion={{
|
||||
proved: result.qualityGatePassed
|
||||
? "На неизменяемом RAVNOVES00 все три task-level dimension достигли 90%, полный denominator учтён, ложное свободное пространство не опубликовано и high-severity ошибок нет."
|
||||
: `Development-профиль устойчив к двум зависимым разбиениям; sealed evaluation завершён с полным учётом ${formatNumber(metrics.validationItems, 0)} кейсов и без ложного свободного пространства.`,
|
||||
notProved: "Не доказаны независимая физическая ground truth, второй маршрут, другой риг, растительная среда, живой rover runtime, навигация, команды или safety.",
|
||||
decision: result.qualityGatePassed
|
||||
? "Зафиксировать RAVNOVES00 perception gate как закрытый source-scoped этап. Следующий шаг — temporal product state и live-rover replay без расширения полномочий."
|
||||
: `Не принимать source-scoped product gate. Разбирать только оставшиеся sealed ошибки и блокеры (${result.blockingChecks.join(", ")}), не подбирая профиль по validation.`,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -72,6 +72,7 @@ const EMPTY_ADVANCED_RESULTS: AdvancedLaboratoryResults = {
|
||||
e37: null,
|
||||
e38: null,
|
||||
e39: null,
|
||||
e40: null,
|
||||
};
|
||||
|
||||
function laboratoryWorkOrdinal(value: string): number {
|
||||
@@ -625,7 +626,7 @@ export function LaboratoryArchiveWorkspace(props: LaboratoryWorkspaceProps) {
|
||||
e28.status === "rejected" ? "E28" : null,
|
||||
e29.status === "rejected" ? "E29" : null,
|
||||
e30.status === "rejected" ? "E30" : null,
|
||||
advanced.status === "rejected" ? "E31–E35" : null,
|
||||
advanced.status === "rejected" ? "E31–E40" : null,
|
||||
].filter(Boolean);
|
||||
setEvidenceError(
|
||||
failures.length
|
||||
|
||||
Reference in New Issue
Block a user