fix(reconstruction): honor resolved unknown revisions (#9637)

This commit is contained in:
morluto authored and GitHub committed 2026-11-09 20:55:57 +08:00
1 parent 694edef951
commit b394d50943
3 files changed
+117 -2

No files matched your search

+5
View File
@@ -28,6 +28,11 @@ this effective scope. A claim verifier must commit to its own surfaces and
their reachable dependencies, including their artifact and implemented-owner
digests. Callers do not need to duplicate the transitive closure in the request.
Listed `residual_unknown_ids` select unknown identities from the Evidence bundle.
The evaluator uses each identity's latest revision: resolved questions do not
block the boundary, while reopened questions do. An active, unallowed question
retains its cited supporting, contradicting and mutation Evidence in the result.
## Comparable verifier Evidence
At least one record explicitly cited by the latest verifier observation must
+16 -2
View File
@@ -1,3 +1,4 @@
import { reconstructionUnknownHeads } from "./reconstructionUnknowns.js";
import type { ReconstructionCoverageScope } from "./reconstructionCoverageScope.js";
import type {
ReconstructionClosureResult,
@@ -396,14 +397,27 @@ const verifierResultMatchesContract = (
export const evaluateReconstructionCoverageRisks = (
context: ReconstructionEvaluationContext,
): void => {
for (const unknownId of context.coverage.residual_unknown_ids)
if (!context.boundary.allowed_unknown_ids.includes(unknownId))
const unknownHeads = reconstructionUnknownHeads(
context.coverage.evidence_bundle.unknowns,
);
for (const unknownId of new Set(context.coverage.residual_unknown_ids)) {
const unknown = unknownHeads.get(unknownId);
if (unknown?.status === "resolved") continue;
if (!context.boundary.allowed_unknown_ids.includes(unknownId)) {
if (unknown !== undefined)
addEvidence(context, [
...unknown.supporting_evidence_ids,
...unknown.contradicting_evidence_ids,
...unknown.mutation_evidence_ids,
]);
addReason(
context,
"active-unknown",
unknownId,
"Active residual unknown is not permitted by the completion boundary.",
);
}
}
for (const contradiction of context.coverage.contradictions)
if (
contradiction.status === "active" &&
@@ -9,11 +9,107 @@ import {
reconstructionCoverageDataFixture,
} from "../../../src/domain/reconstructionCoverage.fixture.js";
import { createEvidence } from "../../../src/domain/evidence.js";
import {
createResidualUnknown,
recordUnknownInputSchema,
updateResidualUnknown,
} from "../../../src/domain/residualUnknown.js";
import { createEvidenceBundle } from "../../../src/domain/evidenceBundle.js";
import { createTestBinarySession } from "../../fixtures/binarySession.js";
import { createServer } from "../../../src/server/createServer.js";
import { observed } from "../../fixtures/analysisExecution.js";
it("uses the latest listed unknown revision when evaluating a boundary", async () => {
await withCoverageMcp(async ({ client }) => {
const base = currentFixtureCoverage();
const [first, second] = base.evidence_bundle.records;
if (first === undefined || second === undefined)
throw new Error("Missing fixture Evidence");
const unknownSource = createEvidence(
undefined,
{ id: "unknown-source", name: "Unknown source", version: "1" },
{
operation: "observe_unknown",
parameters: {},
result: { evidence: true },
},
);
const input = recordUnknownInputSchema.parse({
question: "Is the route covered?",
supporting_evidence_ids: [unknownSource.evidence_id],
domain: "fixture",
severity: "medium",
required_authority: null,
required_confidence: "derived",
required_environment: null,
recommended_probes: [],
relationships: [],
});
const open = createResidualUnknown(input, first.evidence_id, null);
const resolved = updateResidualUnknown(
open,
{
...input,
unknown_id: open.unknown_id,
expected_revision: 1,
status: "resolved",
resolution: {
disposition: "withdrawn",
rationale: "No longer applicable",
evidence_ids: [],
},
},
second.evidence_id,
);
const reopened = updateResidualUnknown(
resolved,
{
...input,
unknown_id: open.unknown_id,
expected_revision: 2,
status: "investigating",
resolution: null,
},
second.evidence_id,
);
const coverage = (revisions: (typeof open)[]) => ({
...base,
evidence_bundle: createEvidenceBundle(
[...base.evidence_bundle.records, unknownSource],
revisions,
),
residual_unknown_ids: [open.unknown_id, open.unknown_id],
});
expect(
(await evaluate(client, coverage([open]))).structuredContent,
).toMatchObject({
status: "unknown",
evidence_ids: expect.arrayContaining([unknownSource.evidence_id]),
reasons: [
expect.objectContaining({
code: "active-unknown",
subject_id: open.unknown_id,
}),
],
});
expect(
(await evaluate(client, coverage([open, resolved]))).structuredContent,
).toMatchObject({ status: "ready", reasons: [] });
expect(
(await evaluate(client, coverage([open, resolved, reopened])))
.structuredContent,
).toMatchObject({
status: "unknown",
reasons: [
expect.objectContaining({
code: "active-unknown",
subject_id: open.unknown_id,
}),
],
});
});
});
describe("reconstruction coverage inline Evidence", () => {
it("evaluates inline fail-closed coverage without retaining request Evidence", async () => {
await withCoverageMcp(async ({ client, session }) => {