Files
rea/src/domain/functionDossierEvidence.ts
T
morluto 049132ab43 fix(evidence): preserve call coverage in function comparisons
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
2026-10-13 04:12:34 +08:00

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,
};
};