From 6c5aa93140f406ded2baf8a11aaea4a2aa5b82d2 Mon Sep 17 00:00:00 2001 From: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com> Date: Mon, 12 Oct 2026 05:35:04 +0000 Subject: [PATCH] fix(evidence): authenticate a single record before classifying it as not-bundle The schema-only check admitted a record whose evidence_id no longer matches its content, so a tampered record was reported as a caller selection error instead of an integrity mismatch. Use the authenticating Evidence parser; only an authentic record is a mis-selected file. Co-Authored-By: Claude Opus 5.5 --- src/domain/evidenceBundle.ts | 13 ++++++++++--- .../filesystem/evidenceBundleFiles.test.ts | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) 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" }, + }); + }); +});