diff --git a/src/domain/evidenceBundle.ts b/src/domain/evidenceBundle.ts index 31603500ff..0e10310230 100644 --- a/src/domain/evidenceBundle.ts +++ b/src/domain/evidenceBundle.ts @@ -219,10 +219,17 @@ export const describeEvidenceBundleFailure = ( : `Evidence bundle validation failed: ${describeValidationFailure(cause)}. Recreate or re-export the bundle, then try again.`; }; -/** Identify a single Evidence record supplied where a bundle is expected. */ +/** + * Identify an authentic single Evidence record supplied where a bundle is + * expected. A record whose semantic identifier does not match its content is + * damaged, not a mis-selected file, so it remains an integrity failure. + */ export const singleEvidenceRecordId = (input: unknown): string | undefined => { - const record = evidenceSchema.safeParse(input); - return record.success ? record.data.evidence_id : undefined; + try { + return parseEvidence(input).evidence_id; + } catch { + return undefined; + } }; /** Explain how to obtain a bundle when one Evidence record was supplied. */ diff --git a/tests/boundary/filesystem/evidenceBundleFiles.test.ts b/tests/boundary/filesystem/evidenceBundleFiles.test.ts index c529fd0549..3f2bb0d48e 100644 --- a/tests/boundary/filesystem/evidenceBundleFiles.test.ts +++ b/tests/boundary/filesystem/evidenceBundleFiles.test.ts @@ -479,3 +479,21 @@ describe("evidence bundle filesystem adapter", () => { }); }); }); + +describe("evidence bundle single-record selection", () => { + it("keeps a tampered single record an integrity failure", async () => { + const directory = await createTestTempDirectory("rea-evidence-"); + const record = bundle().records[0]; + // A record whose identifier no longer matches its content is damaged, + // not a mis-selected file. + const tampered = join(directory, "tampered-record.json"); + await writeFile( + tampered, + JSON.stringify({ ...record, operation: "tampered_operation" }), + ); + expect(await readEvidenceBundle(tampered)).toMatchObject({ + ok: false, + error: { _tag: "EvidenceIntegrityError" }, + }); + }); +});