Treat missing, partial, unknown, and unresolved call coverage as insufficient for call-set equality. Combine IDA caller/callee coverage without losing either explanation and recheck source coverage when verifying historical comparisons. Scope generated function-comparison unknowns with optional typed comparison/dimension facts, preserving legacy IDs and revision digests when absent. Keep unrelated dimensions conclusive, explicit dependencies applicable, and ambiguous function identity unknown. A confirmed change for matched functions remains a failure even if calls are incomplete. Validation: function/reconstruction/residual-unknown and bundle tests, recorded IDA protocol regression, public MCP comparison/verification, and advertised SDK JSON Schema checks. Real IDA provider execution was not verified. Fixes #2222
39 lines
1.5 KiB
TypeScript
39 lines
1.5 KiB
TypeScript
import { parseEvidence, type Evidence } from "./evidence.js";
|
|
import { compareUnicodeCodePoints } from "./unicodeCodePointOrder.js";
|
|
import { functionDossierSchema, type FunctionDossier } from "./hopperValues.js";
|
|
import { functionCallCoverageLimitations } from "./functionCallCoverage.js";
|
|
|
|
/** Complete function observation parsed from one analyze_function Evidence record. */
|
|
export interface FunctionSnapshot {
|
|
readonly evidence: Evidence;
|
|
readonly subject: NonNullable<Evidence["subject"]>;
|
|
readonly dossier: FunctionDossier;
|
|
readonly limitations: readonly string[];
|
|
readonly callCoverageLimitations: readonly string[];
|
|
}
|
|
|
|
/** Parse one complete analyze_function Evidence record for comparison workflows. */
|
|
export const parseFunctionEvidence = (input: unknown): FunctionSnapshot => {
|
|
const evidence = parseEvidence(input);
|
|
if (evidence.operation !== "analyze_function")
|
|
throw new TypeError(
|
|
"Function comparison requires analyze_function Evidence",
|
|
);
|
|
if (evidence.subject === null)
|
|
throw new TypeError("Function comparison requires artifact-bound Evidence");
|
|
const dossier = functionDossierSchema.parse(evidence.normalized_result);
|
|
const callCoverageLimitations = functionCallCoverageLimitations(
|
|
evidence.relationship_coverage,
|
|
dossier,
|
|
);
|
|
return {
|
|
evidence,
|
|
subject: evidence.subject,
|
|
dossier,
|
|
limitations: [
|
|
...new Set([...evidence.limitations, ...dossier.limitations]),
|
|
].sort((left, right) => compareUnicodeCodePoints(left, right)),
|
|
callCoverageLimitations,
|
|
};
|
|
};
|