fix(comparison): preserve uncertainty and v1 inputs

This commit is contained in:
morluto 2026-07-24 14:40:56 +00:00
parent 9bd2ac590c
commit b9217dcd74
4 changed files with 39 additions and 3 deletions

View File

@ -163,7 +163,7 @@ const compareMappings = (
omittedCandidateReferences += omittedCandidates;
const classification = classifyMapping(
retainedCandidates,
omittedEvaluations === 0,
omittedCandidates === 0,
projection.absenceComplete,
);
const semantic = {

View File

@ -39,6 +39,13 @@ const dimensionSchema = z.object({
omitted_changes: z.number().int().min(0),
reason: z.string().nullable(),
});
const legacyUnknownDimension = {
status: "unknown" as const,
total_changes: 0,
changes: [],
omitted_changes: 0,
reason: "Dimension was not recorded by this version 1 capture diff.",
};
/** Completeness-aware changes across stable browser evidence dimensions. */
export const webCaptureDiffSchema = z.object({
@ -53,8 +60,8 @@ export const webCaptureDiffSchema = z.object({
network: dimensionSchema,
metadata: dimensionSchema,
webmcp: dimensionSchema,
accessibility: dimensionSchema,
storage: dimensionSchema,
accessibility: dimensionSchema.default(legacyUnknownDimension),
storage: dimensionSchema.default(legacyUnknownDimension),
}),
limitations: z.array(z.string()),
});

View File

@ -116,6 +116,23 @@ describe("historical source to bundle comparison", () => {
expect(result.coverage.status).toBe("partial");
});
it("keeps exact mappings unknown when candidate output is truncated", () => {
const result = compareSourceToBundle({
reference: historicalGraph("complete"),
application: {
evidenceId: EVIDENCE_ID,
rootArtifactSha256: HASH.artifact,
graph: applicationGraph("complete"),
},
limits: { ...limits(), max_candidate_nodes: 1 },
});
expect(item(result, "src/duplicated.ts").status).toBe("unknown");
expect(
item(result, "src/duplicated.ts").omitted_candidates,
).toBeGreaterThan(0);
});
it("reports the candidate frontier instead of deciding past a limit", () => {
const result = compareSourceToBundle({
reference: historicalGraph("complete", ["src/split.ts"]),

View File

@ -5,6 +5,7 @@ import { inspectWebPageInputSchema } from "../src/domain/browserObservation.js";
import {
compareWebCaptures,
compareWebCapturesInputSchema,
webCaptureDiffSchema,
} from "../src/domain/webCaptureDiff.js";
import {
startFakeCdpBrowser,
@ -59,6 +60,17 @@ describe("web capture diff", () => {
status: "unknown",
total_changes: 0,
});
const {
accessibility: _accessibility,
storage: _storage,
...legacy
} = result.dimensions;
const parsedLegacy = webCaptureDiffSchema.parse({
...result,
dimensions: legacy,
});
expect(parsedLegacy.dimensions.accessibility.status).toBe("unknown");
expect(parsedLegacy.dimensions.storage.status).toBe("unknown");
});
it("does not claim unchanged when a relevant section is incomplete", async () => {