fix(browser): keep code absence unknown without worker inventory

This commit is contained in:
morluto
2026-10-24 03:00:02 +08:00
parent b4502be51a
commit 209c42c346
5 changed files with 59 additions and 1 deletions
@@ -140,6 +140,11 @@ classification:
Nodes beneath a mapped artifact prefix also stay unknown when a runtime
script or worker under that mapping has no artifact path.
Script inventory completeness remains a separate reported fact. Unavailable,
truncated, or attach-limited worker inventory prevents negative code-presence
claims even when the selected page's script inventory is complete. Accepted
positive script correspondences remain loaded.
None of these states proves feature execution, initialization order,
reachability, or causality. In particular, `not-observed-in-capture` never means
globally unloaded.
@@ -70,7 +70,9 @@ const classifyLayer = (
options.reconciliationComplete &&
layer.graph.coverage.status === "complete" &&
scopedEntities.length > 0 &&
scopedEntities.every(({ capture }) => capture.scriptsCompleteWithinScope);
scopedEntities.every(
({ capture }) => capture.codeInventoryCompleteWithinScope,
);
const states = nodes.map((node) => {
const runtimeNodeIds = uniqueSorted(direct.get(node.node_id) ?? []);
if (runtimeNodeIds.length > 0)
@@ -67,6 +67,7 @@ export const parseActiveElectronCapture = (
inspection: normalizeInspection(result),
captureSha256: digestCanonicalValue(result, "Runtime reconciliation"),
scriptsCompleteWithinScope: false,
codeInventoryCompleteWithinScope: false,
};
};
@@ -39,6 +39,7 @@ interface RuntimeCaptureBase {
readonly evidence: Evidence;
readonly captureSha256: string;
readonly scriptsCompleteWithinScope: boolean;
readonly codeInventoryCompleteWithinScope: boolean;
}
interface NormalizedV8Inspection {
@@ -199,6 +200,9 @@ const parseBrowserCapture = (
inspection,
captureSha256: digestCanonicalValue(inspection, "Runtime reconciliation"),
scriptsCompleteWithinScope: scriptsComplete(inspection.completeness),
codeInventoryCompleteWithinScope: codeInventoryComplete(
inspection.completeness,
),
};
};
@@ -241,6 +245,9 @@ const parseElectronCapture = (
inspection,
captureSha256: digestCanonicalValue(inspection, "Runtime reconciliation"),
scriptsCompleteWithinScope: scriptsComplete(inspection.completeness),
codeInventoryCompleteWithinScope: codeInventoryComplete(
inspection.completeness,
),
};
};
@@ -273,6 +280,7 @@ const parseV8Capture = (
inspection: normalizeV8Inspection(result),
captureSha256: digestCanonicalValue(result, "Runtime reconciliation"),
scriptsCompleteWithinScope: false,
codeInventoryCompleteWithinScope: false,
};
};
@@ -505,3 +513,11 @@ const scriptsComplete = (completeness: {
!completeness.truncated_sections.includes("scripts") &&
!completeness.unavailable_sections.includes("scripts") &&
completeness.dropped_events.scripts === 0;
// Missing worker inventory cannot establish absence of a worker code asset,
// even when the selected page's own script inventory is complete.
const codeInventoryComplete = (completeness: BrowserCompleteness): boolean =>
scriptsComplete(completeness) &&
!completeness.unavailable_sections.includes("workers") &&
!completeness.truncated_sections.includes("workers") &&
!completeness.attach_limited_sections.includes("workers");
@@ -229,6 +229,40 @@ it("keeps static load states unknown when one scoped capture omits scripts", asy
);
});
it("preserves positive script matches without inventing worker absence when workers are unavailable", async () => {
const fixture = await applicationFixture();
const staticEvidence = await analyzeFixture(fixture);
const reconcile = (workersUnavailable: boolean) =>
reconcileInput({
static_layers: [{ role: "application", analysis: staticEvidence }],
runtime_observations: [
electronRuntimeEvidence(fixture, SOURCE, {
includeWorker: false,
workersUnavailable,
}),
],
});
const complete = reconcile(false);
const incomplete = reconcile(true);
expect(complete.summary.static_not_observed).toBeGreaterThan(0);
expect(incomplete.summary.static_not_observed).toBe(0);
expect(incomplete.runtime_captures[0]?.scripts_complete_within_scope).toBe(
true,
);
expect(incomplete.static_load_states).toContainEqual(
expect.objectContaining({
status: "loaded",
reason: "runtime-script-correspondence",
}),
);
expect(incomplete.static_load_states).toContainEqual(
expect.objectContaining({
status: "unknown",
reason: "static-or-runtime-coverage-incomplete",
}),
);
});
it("reconciles active Electron as a partial target-only runtime capture", async () => {
const fixture = await applicationFixture();
const staticEvidence = await analyzeFixture(fixture);