mirror of
https://github.com/morluto/rea.git
synced 2026-11-05 22:36:08 +00:00
fix(snapshot): decline ambiguous exact evidence replay (#7037)
This commit is contained in:
1 parent
238914974d
commit
07eb044f77
3 files changed
+169
-14
No files matched your search
@@ -422,6 +422,51 @@ describe("analysis snapshot canonical ordering and scope", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("does not select arbitrary provenance when multiple authenticated records match one replay entry", () => {
|
||||
const { current, snapshot } = snapshotWithHistoricalEvidence();
|
||||
const source = snapshot.evidence_bundle.records.find(
|
||||
(record) => record.operation === "unprofiled_query",
|
||||
)!;
|
||||
const alternative = createEvidence(
|
||||
ANALYSIS_SNAPSHOT_TARGET,
|
||||
ANALYSIS_SNAPSHOT_PROVIDER,
|
||||
{
|
||||
operation: current.operation,
|
||||
parameters: current.parameters,
|
||||
result: current.normalized_result,
|
||||
analysisProfile: ANALYSIS_SNAPSHOT_PROFILE,
|
||||
evidenceLinks: [source.evidence_id],
|
||||
},
|
||||
);
|
||||
expect(alternative.evidence_id).not.toBe(current.evidence_id);
|
||||
const ambiguous = parseAnalysisSnapshot({
|
||||
...snapshot,
|
||||
evidence_bundle: createEvidenceBundle([
|
||||
...snapshot.evidence_bundle.records,
|
||||
alternative,
|
||||
]),
|
||||
});
|
||||
expect(ambiguous.entries).toEqual(snapshot.entries);
|
||||
const reversedInsertion = parseAnalysisSnapshot({
|
||||
...ambiguous,
|
||||
evidence_bundle: createEvidenceBundle(
|
||||
[...ambiguous.evidence_bundle.records].reverse(),
|
||||
),
|
||||
});
|
||||
expect(reversedInsertion).toEqual(ambiguous);
|
||||
for (const candidate of [ambiguous, reversedInsertion])
|
||||
expect(
|
||||
snapshotEvidenceForQuery(candidate, {
|
||||
target: ANALYSIS_SNAPSHOT_TARGET,
|
||||
bindingProfile: ANALYSIS_SNAPSHOT_PROFILE,
|
||||
operation: current.operation,
|
||||
parameters: current.parameters,
|
||||
provider: ANALYSIS_SNAPSHOT_PROVIDER,
|
||||
evidenceProfile: ANALYSIS_SNAPSHOT_PROFILE,
|
||||
}),
|
||||
).toBeUndefined();
|
||||
});
|
||||
|
||||
describe("analysis snapshot Evidence binding", () => {
|
||||
it("finds only Evidence committed to the exact binding and profile", () => {
|
||||
const { current, snapshot } = snapshotWithHistoricalEvidence();
|
||||
|
||||
@@ -502,20 +502,31 @@ export const snapshotEvidenceForQuery = (
|
||||
(candidate) => candidate.query_id === queryId,
|
||||
);
|
||||
if (entry === undefined && workflowEntry === undefined) return undefined;
|
||||
const evidence = snapshot.evidence_bundle.records.find(
|
||||
(record) =>
|
||||
record.subject?.digest.sha256 === target.sha256 &&
|
||||
record.operation === operation &&
|
||||
record.provider.id === provider.id &&
|
||||
record.provider.name === provider.name &&
|
||||
record.provider.version === provider.version &&
|
||||
record.analysis_profile !== null &&
|
||||
analysisProfilesEqual(record.analysis_profile, evidenceProfile) &&
|
||||
canonicalJson(record.parameters) === encodedParameters &&
|
||||
((entry !== undefined && evidenceMatchesEntry(record, entry, snapshot)) ||
|
||||
(workflowEntry !== undefined &&
|
||||
evidenceMatchesWorkflowEntry(record, workflowEntry, snapshot))),
|
||||
);
|
||||
let evidence: Evidence | undefined;
|
||||
for (const record of snapshot.evidence_bundle.records) {
|
||||
if (
|
||||
!(
|
||||
record.subject?.digest.sha256 === target.sha256 &&
|
||||
record.operation === operation &&
|
||||
record.provider.id === provider.id &&
|
||||
record.provider.name === provider.name &&
|
||||
record.provider.version === provider.version &&
|
||||
record.analysis_profile !== null &&
|
||||
analysisProfilesEqual(record.analysis_profile, evidenceProfile) &&
|
||||
canonicalJson(record.parameters) === encodedParameters &&
|
||||
((entry !== undefined &&
|
||||
evidenceMatchesEntry(record, entry, snapshot)) ||
|
||||
(workflowEntry !== undefined &&
|
||||
evidenceMatchesWorkflowEntry(record, workflowEntry, snapshot)))
|
||||
)
|
||||
)
|
||||
continue;
|
||||
// Entries bind the result, not every part of the Evidence commitment
|
||||
// (for example, upstream links). Do not choose provenance by ID sort order.
|
||||
if (evidence !== undefined && evidence.evidence_id !== record.evidence_id)
|
||||
return undefined;
|
||||
evidence = record;
|
||||
}
|
||||
return evidence === undefined
|
||||
? undefined
|
||||
: rebindEvidenceToTargetPath(evidence, target);
|
||||
|
||||
Reference in new issue
Block a user