fix(evidence): retain malformed function observations
This commit is contained in:
1 parent
44310bba32
commit
39c7f7e359
2 files changed
+63
-7
No files matched your search
@@ -7,6 +7,7 @@ import { createAnalysisProfile } from "../domain/analysisProfile.js";
|
||||
import { ghidraFunctionDossier } from "../domain/ghidraValues.fixture.js";
|
||||
import type { BinaryTarget } from "../domain/binaryTargetTypes.js";
|
||||
import { err, ok } from "../domain/result.js";
|
||||
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
|
||||
|
||||
const provider = {
|
||||
id: "dossier-fixture",
|
||||
@@ -157,6 +158,49 @@ it.each(["provider-failure", "invalid-dossier"] as const)(
|
||||
_tag: "AnalysisOutputError",
|
||||
operation: "analyze_function",
|
||||
});
|
||||
expect(result.error.partialObservation).toBeUndefined();
|
||||
if (kind === "provider-failure")
|
||||
expect(result.error.partialObservation).toBeUndefined();
|
||||
else {
|
||||
const retained = parseEvidence(result.error.partialObservation);
|
||||
expect(retained.normalized_result).toEqual({ procedure: "incomplete" });
|
||||
expect(retained.subject?.local_path).toBe(target.path);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
it("retains malformed dossier facts and source links through public error projection", async () => {
|
||||
const source = createEvidence(undefined, provider, {
|
||||
operation: "health",
|
||||
parameters: {},
|
||||
result: "retained source",
|
||||
});
|
||||
const malformed = { procedure: "incomplete", partial: ["caller fact"] };
|
||||
const result = await executeFunctionAnalysisEvidence(
|
||||
{
|
||||
execute: async () =>
|
||||
ok(
|
||||
createAnalysisExecution(malformed, provider, {
|
||||
subject: null,
|
||||
rawResult: { text: "original provider output" },
|
||||
limitations: ["Incomplete provider response"],
|
||||
locations: [{ kind: "address", address: "0x401000" }],
|
||||
sourceEvidence: [source],
|
||||
}),
|
||||
),
|
||||
},
|
||||
parameters,
|
||||
target,
|
||||
);
|
||||
if (result.ok) throw new Error("Expected invalid dossier failure");
|
||||
expect(result.sourceEvidence).toEqual([source]);
|
||||
const projected = projectAnalysisError(result.error);
|
||||
const retained = parseEvidence(projected.details?.partial_observation);
|
||||
expect(retained.normalized_result).toEqual(malformed);
|
||||
expect(retained.raw_result).toEqual({ text: "original provider output" });
|
||||
expect(retained.subject).toBeNull();
|
||||
expect(retained.evidence_links).toEqual([source.evidence_id]);
|
||||
expect(retained.locations).toEqual([
|
||||
{ kind: "address", address: "0x401000" },
|
||||
]);
|
||||
expect(retained.limitations).toContain("Incomplete provider response");
|
||||
});
|
||||
@@ -49,9 +49,25 @@ export const executeFunctionAnalysisEvidence = async (
|
||||
);
|
||||
const sources = sourceLedger.recordsForAnalysis();
|
||||
if (!recorded.ok) return withEvidenceSources(recorded, sources);
|
||||
const observation = {
|
||||
...execution.value,
|
||||
sourceEvidence: sources,
|
||||
...(execution.value.subject === undefined && target !== undefined
|
||||
? { subject: target }
|
||||
: {}),
|
||||
};
|
||||
const dossier = parseFunctionDossier(execution.value.result);
|
||||
if (!dossier.ok) return withEvidenceSources(dossier, sources);
|
||||
const observation = execution.value;
|
||||
if (!dossier.ok) {
|
||||
dossier.error.retainPartialObservation(
|
||||
createAnalysisExecutionEvidence(
|
||||
"analyze_function",
|
||||
arguments_,
|
||||
observation,
|
||||
"observed",
|
||||
),
|
||||
);
|
||||
return withEvidenceSources(dossier, sources);
|
||||
}
|
||||
return withEvidenceSources(
|
||||
completeProviderEvidence(
|
||||
createAnalysisExecutionEvidence(
|
||||
@@ -59,11 +75,7 @@ export const executeFunctionAnalysisEvidence = async (
|
||||
arguments_,
|
||||
{
|
||||
...observation,
|
||||
sourceEvidence: sources,
|
||||
result: dossier.value,
|
||||
...(observation.subject === undefined && target !== undefined
|
||||
? { subject: target }
|
||||
: {}),
|
||||
},
|
||||
"observed",
|
||||
),
|
||||
|
||||
Reference in new issue
Block a user