feat(lab): complete E30 evidence review gate
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { after, before, test } from "node:test";
|
||||
|
||||
import { createServer } from "vite";
|
||||
|
||||
let server;
|
||||
let parseE30EngineeringCatalog;
|
||||
let parseE30EngineeringDecision;
|
||||
let fetchE30EngineeringDecision;
|
||||
let E30EngineeringContractError;
|
||||
|
||||
const resultId = `e30-materialization-${"a".repeat(64)}`;
|
||||
const generationId = `e30-engineering-generation-${"b".repeat(64)}`;
|
||||
const itemId = `e30-review-item-${"c".repeat(64)}`;
|
||||
|
||||
function generation(overrides = {}) {
|
||||
return {
|
||||
generation_id: generationId,
|
||||
created_at_utc: "2026-07-26T22:01:18.464Z",
|
||||
materialization_id: resultId,
|
||||
producer: {
|
||||
kind: "ai-assisted-engineering-review",
|
||||
producer_id: "codex:a3-engineering-review",
|
||||
method_id: "camera-lidar-42-sheet-audit/v1",
|
||||
review_sheet_identity_sha256: "d".repeat(64),
|
||||
claims_human_ground_truth: false,
|
||||
},
|
||||
summary: {
|
||||
item_count: 486,
|
||||
reviewed_item_count: 486,
|
||||
verdict_distribution: {
|
||||
confirmed: 401,
|
||||
corrected: 80,
|
||||
"insufficient-evidence": 5,
|
||||
},
|
||||
detector_distribution: { valid: 259, "false-positive": 78 },
|
||||
projection_distribution: { aligned: 371, "not-assessable": 115 },
|
||||
point_ownership_distribution: { object: 108 },
|
||||
human_exception_count: 5,
|
||||
mean_confidence: 0.8705,
|
||||
},
|
||||
cause_distribution: {
|
||||
schema_version: "missioncore.e30-engineering-causes/v1",
|
||||
item_count_with_cause: 312,
|
||||
reasons: [
|
||||
{ reason_code: "detector_error", count: 109 },
|
||||
{ reason_code: "time_mismatch", count: 91 },
|
||||
],
|
||||
},
|
||||
human_exceptions: [{
|
||||
item_id: itemId,
|
||||
review_key: "semantic:162:7",
|
||||
source_stratum: "camera-only",
|
||||
confidence: 0.48,
|
||||
review_prompt: {
|
||||
question: "Белый кластер — самостоятельное препятствие?",
|
||||
focus: "Проверьте выбранные белые точки.",
|
||||
effects: {
|
||||
"object-present": "Сохранить занятую геометрию.",
|
||||
"background-or-noise": "Исключить кластер.",
|
||||
"insufficient-evidence": "Оставить неизвестным.",
|
||||
},
|
||||
},
|
||||
}],
|
||||
ai_review_complete: true,
|
||||
human_exception_complete: false,
|
||||
human_review_complete: false,
|
||||
lab_published: false,
|
||||
access: "read-only",
|
||||
authority: {
|
||||
commands_enabled: false,
|
||||
navigation_or_safety_accepted: false,
|
||||
},
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function catalog(overrides = {}) {
|
||||
return {
|
||||
schema_version: "missioncore.laboratory-e30-engineering-generations/v1",
|
||||
configured: true,
|
||||
items: [generation()],
|
||||
candidate_total: 1,
|
||||
invalid_total: 0,
|
||||
access: "read-only",
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function decision(overrides = {}) {
|
||||
return {
|
||||
schema_version: "missioncore.laboratory-e30-engineering-decision/v1",
|
||||
generation_id: generationId,
|
||||
decision: {
|
||||
sequence: 362,
|
||||
item_id: itemId,
|
||||
review_key: "semantic:343:2",
|
||||
source_stratum: "conflict",
|
||||
verdict: "corrected",
|
||||
effective_stratum: null,
|
||||
detector_assessment: "false-positive",
|
||||
projection_assessment: "aligned",
|
||||
point_ownership: "surface-or-background",
|
||||
cause_code: "detector_error",
|
||||
confidence: 0.95,
|
||||
human_exception_required: false,
|
||||
exception_reason: null,
|
||||
evidence_note: "Кадр 343. Рамка находится на ограждении.",
|
||||
review_sheet: {
|
||||
path: "conflict-01.jpg",
|
||||
sha256: "e".repeat(64),
|
||||
ordinal: 1,
|
||||
},
|
||||
...overrides,
|
||||
},
|
||||
access: "read-only",
|
||||
};
|
||||
}
|
||||
|
||||
before(async () => {
|
||||
server = await createServer({
|
||||
appType: "custom",
|
||||
logLevel: "silent",
|
||||
server: { middlewareMode: true },
|
||||
});
|
||||
({
|
||||
parseE30EngineeringCatalog,
|
||||
parseE30EngineeringDecision,
|
||||
fetchE30EngineeringDecision,
|
||||
E30EngineeringContractError,
|
||||
} = await server.ssrLoadModule(
|
||||
"/src/core/laboratory/e30Engineering.ts",
|
||||
));
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await server?.close();
|
||||
});
|
||||
|
||||
test("decodes immutable A3 summary and per-item engineering decision", () => {
|
||||
const decodedCatalog = parseE30EngineeringCatalog(catalog());
|
||||
const decodedDecision = parseE30EngineeringDecision(decision());
|
||||
|
||||
assert.equal(decodedCatalog.items[0].summary.reviewedItemCount, 486);
|
||||
assert.equal(decodedCatalog.items[0].summary.humanExceptionCount, 5);
|
||||
assert.equal(decodedCatalog.items[0].humanExceptions[0].reviewKey, "semantic:162:7");
|
||||
assert.equal(
|
||||
decodedCatalog.items[0].humanExceptions[0].reviewPrompt.effects["object-present"],
|
||||
"Сохранить занятую геометрию.",
|
||||
);
|
||||
assert.equal(decodedDecision.verdict, "corrected");
|
||||
assert.equal(decodedDecision.effectiveStratum, null);
|
||||
assert.equal(decodedDecision.detectorAssessment, "false-positive");
|
||||
});
|
||||
|
||||
test("rejects a generation that claims human ground truth", () => {
|
||||
assert.throws(
|
||||
() => parseE30EngineeringCatalog(catalog({
|
||||
items: [generation({
|
||||
producer: {
|
||||
...generation().producer,
|
||||
claims_human_ground_truth: true,
|
||||
},
|
||||
})],
|
||||
})),
|
||||
E30EngineeringContractError,
|
||||
);
|
||||
});
|
||||
|
||||
test("fetches one content-addressed item decision", async () => {
|
||||
const requests = [];
|
||||
const decoded = await fetchE30EngineeringDecision(
|
||||
resultId,
|
||||
generationId,
|
||||
itemId,
|
||||
{
|
||||
fetcher: async (input, init) => {
|
||||
requests.push({ input: String(input), method: init?.method });
|
||||
return new Response(JSON.stringify(decision()), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
assert.equal(decoded.pointOwnership, "surface-or-background");
|
||||
assert.deepEqual(requests, [{
|
||||
input:
|
||||
`/api/v1/laboratory/e30/reviews/${resultId}/engineering-generations/`
|
||||
+ `${generationId}/items/${itemId}`,
|
||||
method: "GET",
|
||||
}]);
|
||||
});
|
||||
Reference in New Issue
Block a user