fix(lab): demote E40 to historical evaluation

This commit is contained in:
DCCONSTRUCTIONS
2026-07-30 22:18:46 +03:00
parent e4e5bf6ea1
commit 81d7ad1a77
7 changed files with 65 additions and 34 deletions
@@ -50,6 +50,11 @@ export interface E40CaseCatalog {
access: "read-only";
}
/**
* Immutable v1 storage vocabulary. Product UI interprets these legacy values
* only as support/challenge of the E37 engineering label; neither value
* establishes physical ground truth or authorizes an operational model.
*/
export type E40OperatorVerdict = "confirmed-error" | "rejected-error";
export interface E40OperatorDecision {
@@ -40,7 +40,10 @@ export function advancedLaboratoryWorkOptions(
{ id: "e37-ravnoves-acceptance", label: "LAB E37 · RAVNOVES00 acceptance R0" },
{ id: "e38-perception-baseline", label: "LAB E38 · perception quality R1" },
{ id: "e39-perception-refinement", label: "LAB E39 · perception refinement R1" },
{ id: "e40-perception-product-gate", label: "LAB E40 · leakage-resistant product gate" },
{
id: "e40-perception-product-gate",
label: "LAB E40 · historical visible engineering evaluation",
},
];
return options.filter(({ id }) => available.has(id));
}
@@ -112,33 +112,39 @@ function reviewPrompt(
if (item.reference.presence === "object-present") {
return {
question: `${subject} относится к отдельному видимому объекту?`,
question: (
`${subject} подтверждает инженерную метку E37 «объект присутствует»?`
),
evidence,
confirm: (
"Да — объект виден; эталон верен, расхождение E40 подтверждается."
"Да — наблюдение поддерживает инженерную метку E37."
),
reject: (
"Нет — это фон или часть среды; предполагаемая ошибка отклоняется."
"Нет — метка E37 оспорена и требует отдельной ревизии."
),
};
}
if (item.reference.presence === "background-or-noise") {
return {
question: `${subject} является фоном или шумом, а не объектом?`,
question: (
`${subject} подтверждает инженерную метку E37 «фон или шум»?`
),
evidence,
confirm: (
"Да — это фон или шум; эталон верен, расхождение E40 подтверждается."
"Да — наблюдение поддерживает инженерную метку E37."
),
reject: (
"Нет — отдельный объект есть; предполагаемая ошибка отклоняется."
"Нет — метка E37 оспорена и требует отдельной ревизии."
),
};
}
return {
question: "Проверяемый эталон точнее описывает кадр, чем решение E40?",
question: (
"Наблюдение поддерживает инженерную метку E37 для этого расхождения?"
),
evidence,
confirm: "Да — эталон верен, расхождение E40 подтверждается.",
reject: "Нет — эталон спорен, предполагаемая ошибка отклоняется.",
confirm: "Да — наблюдение поддерживает инженерную метку E37.",
reject: "Нет — метка E37 оспорена и требует отдельной ревизии.",
};
}
@@ -174,7 +180,7 @@ export function E40CaseReview({ resultId }: { resultId: string }) {
|| nextReview.reviewedItemCount > nextCatalog.total
) {
throw new Error(
"Операторская проверка E40 не совпадает с каталогом ошибок.",
"Операторская проверка E40 не совпадает с каталогом расхождений.",
);
}
setCatalog(nextCatalog);
@@ -335,7 +341,7 @@ export function E40CaseReview({ resultId }: { resultId: string }) {
) : error || !detail || !selectedCase ? (
<div className="e40-case-review__state" role="status">
<Icon name="alert" size={18} />
<span>{error ?? "Выберите ошибку для проверки."}</span>
<span>{error ?? "Выберите расхождение для проверки."}</span>
</div>
) : (
<LaboratoryEvidenceViewer
@@ -352,7 +358,7 @@ export function E40CaseReview({ resultId }: { resultId: string }) {
<div className="e40-case-review__controls">
<div
className="e40-case-review__pagination"
aria-label="Последовательная проверка ошибок"
aria-label="Последовательная проверка расхождений"
>
<IconButton
className="e40-case-review__glass-button"
@@ -403,7 +409,7 @@ export function E40CaseReview({ resultId }: { resultId: string }) {
overlay={(
<aside
className="e40-case-review__telemetry"
aria-label="Эталон и результат E40"
aria-label="Инженерная метка E37 и результат E40"
>
<div className="e40-case-review__telemetry-content">
<span>
@@ -436,7 +442,7 @@ export function E40CaseReview({ resultId }: { resultId: string }) {
<dt>{DIMENSION_LABELS[dimension]}</dt>
<dd>
<span>
Эталон ·{" "}
Инженерная метка E37 ·{" "}
{VALUE_LABELS[
stateValue(selectedCase.reference, dimension)
]}
@@ -461,9 +467,9 @@ export function E40CaseReview({ resultId }: { resultId: string }) {
{verdictPending
? "Сохраняем…"
: selectedDecision?.verdict === "confirmed-error"
? "Ошибка подтверждена"
? "Метка E37 поддержана"
: selectedDecision?.verdict === "rejected-error"
? "Расхождение отклонено"
? "Метка E37 оспорена"
: "Решение оператора"}
</span>
<div
@@ -478,7 +484,7 @@ export function E40CaseReview({ resultId }: { resultId: string }) {
? "true"
: undefined
}
label={prompt?.confirm ?? "Подтвердить ошибку модели"}
label={prompt?.confirm ?? "Поддержать метку E37"}
aria-pressed={
selectedDecision?.verdict === "confirmed-error"
}
@@ -495,7 +501,7 @@ export function E40CaseReview({ resultId }: { resultId: string }) {
? "true"
: undefined
}
label={prompt?.reject ?? "Отклонить ошибку модели"}
label={prompt?.reject ?? "Оспорить метку E37"}
aria-pressed={
selectedDecision?.verdict === "rejected-error"
}
@@ -32,8 +32,8 @@ export function E40Result({
result.developmentCrossValidation.protocols.wholeTrackOrSceneWindow.dimensions
);
const gateLabel = result.qualityGatePassed
? "Историческая оценка E40 пройдена"
: "Историческая оценка E40 не пройдена";
? "Порог исторического сравнения достигнут"
: "Порог исторического сравнения не достигнут";
return (
<LaboratoryWorkTemplate
summary={(
@@ -115,40 +115,40 @@ export function E40Result({
result={(
<LaboratoryResultSummary
title={result.qualityGatePassed
? "Source-scoped perception gate RAVNOVES00 закрыт"
: "Route-coordinate признаки исключены, но product gate ещё не закрыт"}
? "Историческое сравнение E40 завершено выше заданного порога"
: "Историческое сравнение E40 завершено ниже заданного порога"}
status={gateLabel}
statusTone={result.qualityGatePassed ? "success" : "warning"}
metrics={[
{
label: "Presence",
value: percent(dimensions.presence.accuracy),
hint: `${formatNumber(dimensions.presence.incorrect, 0)} ошибок · цель 90%`,
hint: `${formatNumber(dimensions.presence.incorrect, 0)} расхождений с E37 · порог 90%`,
},
{
label: "Geometry association",
value: percent(dimensions.geometryAssociation.accuracy),
hint: `${formatNumber(dimensions.geometryAssociation.incorrect, 0)} ошибок · цель 90%`,
hint: `${formatNumber(dimensions.geometryAssociation.incorrect, 0)} расхождений с E37 · порог 90%`,
},
{
label: "Freshness",
value: percent(dimensions.freshness.accuracy),
hint: `${formatNumber(dimensions.freshness.incorrect, 0)} ошибок · цель 90%`,
hint: `${formatNumber(dimensions.freshness.incorrect, 0)} расхождений с E37 · порог 90%`,
},
{
label: "High severity",
value: formatNumber(metrics.highSeverityFailures, 0),
hint: `учёт ${percent(metrics.accountingFraction)} · false free ${formatNumber(metrics.falseFreeClaims, 0)}`,
hint: `исторические расхождения · учёт ${percent(metrics.accountingFraction)} · false free ${formatNumber(metrics.falseFreeClaims, 0)}`,
},
]}
conclusion={{
proved: result.qualityGatePassed
? "На неизменяемом RAVNOVES00 все три task-level dimension достигли 90%, полный denominator учтён, ложное свободное пространство не опубликовано и high-severity ошибок нет."
? "В сравнении с инженерными метками E37 все три task-level dimension достигли 90%, полный denominator учтён, ложное свободное пространство не опубликовано и high-severity расхождений нет."
: `Development-профиль устойчив к двум зависимым разбиениям; historical visible evaluation завершён с полным учётом ${formatNumber(metrics.validationItems, 0)} кейсов и без ложного свободного пространства.`,
notProved: "Не доказаны независимая физическая ground truth, второй маршрут, другой риг, растительная среда, живой rover runtime, навигация, команды или safety.",
notProved: "Инженерные метки E37 не являются независимой физической ground truth. Не доказаны второй маршрут, другой риг, растительная среда, operational camera-first 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.`,
? "Сохранить E40 как воспроизводимое историческое сравнение. Не переносить его решения в runtime; следующий кандидат должен отдельно доказать camera-first semantic detection и LiDAR metric geometry."
: `Сохранить E40 только как каталог исторических расхождений и блокеров (${result.blockingChecks.join(", ")}). Не подбирать профиль по visible evaluation и не считать результат product gate.`,
}}
/>
)}
@@ -283,7 +283,7 @@ test("E40 reports historical visible evaluation with bounded camera-LiDAR case r
assert.match(e40Source, /Только camera-only использует softmax/);
assert.match(e40Source, /<E40CaseReview resultId=\{result\.resultId\}/);
assert.match(e40Source, /historical visible engineering evaluation/);
assert.match(e40Source, /не подбирая профиль по validation/);
assert.match(e40Source, /Не подбирать профиль по visible evaluation/);
assert.match(caseReviewSource, /<LaboratoryEvidenceViewer/);
assert.match(caseReviewSource, /<E30EvidenceProjection/);
assert.match(caseReviewSource, /<E30EvidencePointCloud/);
@@ -293,14 +293,26 @@ test("E40 reports historical visible evaluation with bounded camera-LiDAR case r
assert.match(caseReviewSource, /Расхождение исторической оценки E40/);
assert.match(caseReviewSource, /label="Предыдущее расхождение"/);
assert.match(caseReviewSource, /label="Следующее расхождение"/);
assert.match(caseReviewSource, /расхождение E40 подтверждается/);
assert.match(caseReviewSource, /предполагаемая ошибка отклоняется/);
assert.match(caseReviewSource, /наблюдение поддерживает инженерную метку E37/);
assert.match(caseReviewSource, /метка E37 оспорена/);
assert.match(caseReviewSource, /фиксированная stratum-policy, не вероятность/);
assert.match(e40Source, /не считать результат product gate/);
assert.doesNotMatch(caseReviewSource, /эталон верен/);
assert.doesNotMatch(caseReviewSource, /Ошибка подтверждена/);
assert.doesNotMatch(e40Source, /perception gate RAVNOVES00 закрыт/);
assert.doesNotMatch(
e40Source,
/className="laboratory-(?:summary|result-summary|result-metrics|result-conclusion)"/,
);
assert.match(advancedSource, /id: "e40-perception-product-gate"/);
assert.match(
advancedSource,
/LAB E40 · historical visible engineering evaluation/,
);
assert.doesNotMatch(
advancedSource,
/LAB E40 · leakage-resistant product gate/,
);
assert.match(advancedSource, /<E40Result/);
});