mirror of
https://github.com/morluto/rea.git
synced 2026-11-09 16:26:36 +00:00
fix(reconstruction): preserve unknown process case coverage (#9599)
fix(reconstruction): avoid inferring unobserved process cases
This commit is contained in:
1 parent
f20f05536e
commit
38be5fd9f2
2 files changed
+64
-14
No files matched your search
@@ -202,25 +202,25 @@ const deriveProcessCandidate = (
|
||||
}
|
||||
const { record: evidence, capture } = parsed.value;
|
||||
const observedCases: ReconstructionObligation["observed_cases"] = [
|
||||
{
|
||||
kind: capture.exit.code === 0 ? "positive" : "negative",
|
||||
evidence_id: evidence.evidence_id,
|
||||
location: "/normalized_result/exit",
|
||||
},
|
||||
...(capture.exit.reason !== "exited" ||
|
||||
(capture.exit.signal !== null && capture.exit.signal !== 0) ||
|
||||
capture.exit.code === null
|
||||
? []
|
||||
: [
|
||||
{
|
||||
kind:
|
||||
capture.exit.code === 0
|
||||
? ("positive" as const)
|
||||
: ("negative" as const),
|
||||
evidence_id: evidence.evidence_id,
|
||||
location: "/normalized_result/exit",
|
||||
},
|
||||
]),
|
||||
{
|
||||
kind: "teardown",
|
||||
evidence_id: evidence.evidence_id,
|
||||
location: "/normalized_result/settlement",
|
||||
},
|
||||
...(capture.exit.signal !== null || capture.exit.reason !== "exited"
|
||||
? [
|
||||
{
|
||||
kind: "cancellation" as const,
|
||||
evidence_id: evidence.evidence_id,
|
||||
location: "/normalized_result/exit",
|
||||
},
|
||||
]
|
||||
: []),
|
||||
];
|
||||
if (capture.manifest.executable_sha256 === null) {
|
||||
limitations.add(
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { createEvidenceBundle } from "../domain/evidenceBundle.js";
|
||||
import { processCaptureSchema } from "../domain/process/processCapture.js";
|
||||
import { FINALIZED_PROCESS_CAPTURE_EXAMPLE } from "../domain/process/processCapture.fixture.js";
|
||||
|
||||
import {
|
||||
build,
|
||||
@@ -167,6 +169,54 @@ describe("reconstruction obligation ledger Evidence provenance", () => {
|
||||
});
|
||||
|
||||
describe("reconstruction obligation ledger case closure", () => {
|
||||
it("does not turn a timeout with unknown exit code into negative or cancellation cases", () => {
|
||||
const capture = processEvidence(
|
||||
processCaptureSchema.parse(FINALIZED_PROCESS_CAPTURE_EXAMPLE),
|
||||
);
|
||||
const ledger = build(request([capture]));
|
||||
expect(
|
||||
ledger.obligations[0]?.observed_cases.map(({ kind }) => kind),
|
||||
).toEqual(["teardown"]);
|
||||
expect(ledger.obligations[0]?.diagnostics).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
code: "missing-original-case",
|
||||
detail: expect.stringContaining("negative"),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
code: "missing-original-case",
|
||||
detail: expect.stringContaining("cancellation"),
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("distinguishes signal termination from a known nonzero exit", () => {
|
||||
const signaled = processEvidence({
|
||||
exit: { code: null, signal: 15, reason: "exited" },
|
||||
});
|
||||
const nonzero = processEvidence({
|
||||
exit: { code: 2, signal: null, reason: "exited" },
|
||||
});
|
||||
const ambiguous = processEvidence({
|
||||
exit: { code: 2, signal: 15, reason: "exited" },
|
||||
});
|
||||
expect(
|
||||
build(request([signaled])).obligations[0]?.observed_cases.map(
|
||||
({ kind }) => kind,
|
||||
),
|
||||
).toEqual(["teardown"]);
|
||||
expect(
|
||||
build(request([nonzero])).obligations[0]?.observed_cases.map(
|
||||
({ kind }) => kind,
|
||||
),
|
||||
).toEqual(["negative", "teardown"]);
|
||||
expect(
|
||||
build(request([ambiguous])).obligations[0]?.observed_cases.map(
|
||||
({ kind }) => kind,
|
||||
),
|
||||
).toEqual(["teardown"]);
|
||||
});
|
||||
it("keeps unobserved original cases open", () => {
|
||||
const capture = processEvidence();
|
||||
const proof = proofEvidence("packaged-original-gap");
|
||||
|
||||
Reference in new issue
Block a user