mirror of
https://github.com/morluto/rea
synced 2026-10-26 06:16:17 -04:00
fix(reconstruction): include constituent unknowns in overall function claims
Have the function observation owner select aggregate dimensions before residual-unknown lookup. Retain independent dimension scope, unknown citations and recommended probes through the public MCP verifier. Validation is pending the centrally coordinated lane; single-file formatting and lint completed.
This commit is contained in:
@@ -64,7 +64,7 @@ it("keeps explicit dependencies while excluding unrelated scoped unknowns", () =
|
||||
]),
|
||||
comparisonId,
|
||||
[ev("b")],
|
||||
"calls",
|
||||
["calls"],
|
||||
);
|
||||
expect(selected.map(({ unknown_id }) => unknown_id)).toEqual([
|
||||
calls.unknown_id,
|
||||
|
||||
@@ -28,17 +28,15 @@ export const reconstructionClaimUnknowns = (
|
||||
heads: ReadonlyMap<string, ResidualUnknown>,
|
||||
comparisonId: string,
|
||||
sourceIds: readonly string[],
|
||||
dimension?: string,
|
||||
dimensions?: readonly string[],
|
||||
): ResidualUnknown[] => {
|
||||
const appliesToClaim = (item: ResidualUnknown): boolean => {
|
||||
const scope = item.comparison_conclusion_scope;
|
||||
return (
|
||||
scope === undefined ||
|
||||
(scope.comparison_evidence_id === comparisonId &&
|
||||
(dimension === undefined ||
|
||||
scope.dimensions.some(
|
||||
(scopedDimension) => scopedDimension === dimension,
|
||||
)))
|
||||
(dimensions === undefined ||
|
||||
scope.dimensions.some((dimension) => dimensions.includes(dimension))))
|
||||
);
|
||||
};
|
||||
const evidenceIds = new Set([comparisonId, ...sourceIds]);
|
||||
|
||||
@@ -153,15 +153,13 @@ const evaluateClaim = (
|
||||
...authorityLimitations(claim, sources, sides),
|
||||
...callCoverage.blockers,
|
||||
];
|
||||
const relatedUnknowns = reconstructionClaimUnknowns(
|
||||
const relevantUnknowns = reconstructionClaimUnknowns(
|
||||
heads,
|
||||
comparison.evidence_id,
|
||||
allSourceIds,
|
||||
claim.dimension,
|
||||
observation.selectedDimensions ?? [claim.dimension],
|
||||
);
|
||||
const relevantUnknowns = relatedUnknowns;
|
||||
const status = classify(observed, blockers, relevantUnknowns);
|
||||
const displayedUnknowns = relevantUnknowns;
|
||||
return reconstructionClaimResultSchema.parse({
|
||||
claim_id: claim.claim_id,
|
||||
kind: claim.kind,
|
||||
@@ -172,13 +170,13 @@ const evaluateClaim = (
|
||||
left_evidence_ids: sides.left,
|
||||
right_evidence_ids: sides.right,
|
||||
evidence_links: uniqueSorted([comparison.evidence_id, ...allSourceIds]),
|
||||
unknown_ids: displayedUnknowns.map(({ unknown_id: id }) => id),
|
||||
unknown_ids: relevantUnknowns.map(({ unknown_id: id }) => id),
|
||||
limitations: uniqueSorted([
|
||||
...comparison.limitations,
|
||||
...observation.limitations,
|
||||
...blockers,
|
||||
...callCoverage.diagnostics,
|
||||
...displayedUnknowns.map(
|
||||
...relevantUnknowns.map(
|
||||
({ question }) => `Residual unknown: ${question}`,
|
||||
),
|
||||
]),
|
||||
@@ -279,6 +277,7 @@ const comparisonObservation = (
|
||||
readonly status: ObservedStatus;
|
||||
readonly limitations: readonly string[];
|
||||
readonly hasIndependentFunctionChange?: boolean;
|
||||
readonly selectedDimensions?: readonly string[];
|
||||
} => {
|
||||
if (claim.kind === "behavioral") {
|
||||
const parsed = readComparisonResult(evidence, "compare_process_captures");
|
||||
@@ -306,6 +305,10 @@ const comparisonObservation = (
|
||||
if (claim.dimension === "overall")
|
||||
return {
|
||||
status: result.status,
|
||||
selectedDimensions: [
|
||||
"overall",
|
||||
...result.dimensions.map(({ dimension }) => dimension),
|
||||
],
|
||||
limitations: result.dimensions.flatMap(
|
||||
({ limitations }) => limitations,
|
||||
),
|
||||
|
||||
@@ -592,3 +592,111 @@ const close = async (
|
||||
) => {
|
||||
await Promise.allSettled([client.close(), server.close(), session.close()]);
|
||||
};
|
||||
|
||||
it("keeps an aggregate function reconstruction unknown while a constituent dimension is unresolved", async () => {
|
||||
const { session, server, client } = await connected();
|
||||
try {
|
||||
const left = FUNCTION_COMPARISON_EXAMPLE.left;
|
||||
const right = createEvidence(
|
||||
{
|
||||
path: "/tmp/rebuilt-function",
|
||||
sha256: "2".repeat(64),
|
||||
format: "mach-o",
|
||||
},
|
||||
left.provider,
|
||||
{
|
||||
operation: left.operation,
|
||||
parameters: left.parameters,
|
||||
result: left.normalized_result,
|
||||
confidence: left.confidence,
|
||||
authority: left.authority,
|
||||
relationshipCoverage: { status: "complete" },
|
||||
},
|
||||
);
|
||||
const compared = await client.callTool({
|
||||
name: "compare_functions",
|
||||
arguments: { left, right },
|
||||
});
|
||||
expect(compared.isError).not.toBe(true);
|
||||
const comparison = inlineEvidence(compared.structuredContent);
|
||||
const specification = {
|
||||
name: "Function reconstruction",
|
||||
claims: ["overall", "pseudocode", "assembly"].map((dimension) => ({
|
||||
kind: "structural-function",
|
||||
claim_id: dimension,
|
||||
title: dimension,
|
||||
dimension,
|
||||
comparison_evidence_id: comparison.evidence_id,
|
||||
})),
|
||||
};
|
||||
const baseline = await client.callTool({
|
||||
name: "verify_reconstruction",
|
||||
arguments: { specification },
|
||||
});
|
||||
expect(
|
||||
inlineEvidence(baseline.structuredContent).normalized_result,
|
||||
).toMatchObject({ status: "pass" });
|
||||
const recorded = await client.callTool({
|
||||
name: "record_unknown",
|
||||
arguments: {
|
||||
question: "Does the pseudocode preserve the unresolved edge case?",
|
||||
severity: "high",
|
||||
domain: "function-comparison",
|
||||
supporting_evidence_ids: [comparison.evidence_id],
|
||||
contradicting_evidence_ids: [],
|
||||
required_authority: null,
|
||||
required_confidence: "derived",
|
||||
required_environment: null,
|
||||
recommended_probes: [
|
||||
{
|
||||
operation: "analyze_function",
|
||||
rationale: "Resolve the pseudocode edge case.",
|
||||
},
|
||||
],
|
||||
relationships: [],
|
||||
comparison_conclusion_scope: {
|
||||
comparison_evidence_id: comparison.evidence_id,
|
||||
dimensions: ["pseudocode"],
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(recorded.isError).not.toBe(true);
|
||||
const result = await client.callTool({
|
||||
name: "verify_reconstruction",
|
||||
arguments: { specification },
|
||||
});
|
||||
const payload = inlineEvidence(result.structuredContent).normalized_result;
|
||||
expect(payload).toMatchObject({
|
||||
status: "unknown",
|
||||
claims: {
|
||||
items: [
|
||||
{ claim_id: "assembly", status: "pass", unknown_ids: [] },
|
||||
{
|
||||
claim_id: "overall",
|
||||
status: "unknown",
|
||||
unknown_ids: [expect.stringMatching(/^unk_/u)],
|
||||
},
|
||||
{
|
||||
claim_id: "pseudocode",
|
||||
status: "unknown",
|
||||
unknown_ids: [expect.stringMatching(/^unk_/u)],
|
||||
},
|
||||
],
|
||||
},
|
||||
recommended_probes: [
|
||||
expect.objectContaining({ claim_ids: ["overall", "pseudocode"] }),
|
||||
],
|
||||
});
|
||||
const overallOnly = await client.callTool({
|
||||
name: "verify_reconstruction",
|
||||
arguments: {
|
||||
specification: { ...specification, claims: [specification.claims[0]] },
|
||||
},
|
||||
});
|
||||
expect(
|
||||
inlineEvidence(overallOnly.structuredContent).normalized_result,
|
||||
).toMatchObject({ status: "unknown", summary: { unknown: 1 } });
|
||||
} finally {
|
||||
await close(session, server, client);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user