fix(javascript): preserve graph facts across omissions and versions

Omit absent inventory facts without erasing explicit unknowns. Compare canonical file occurrences by source path and digest while preserving complete container provenance in observations and Evidence.

Consolidate candidate-capacity fixtures around unresolved alternatives and update inventory coverage and source-occurrence oracles. Preserve resource, identity, relationship uncertainty, cancellation, and transfer regressions.
This commit is contained in:
morluto committed 2026-10-24 06:20:36 +08:00
1 parent 9dde3fd6a4
commit 30db499db3
9 files changed
+243 -29

No files matched your search

@@ -7,6 +7,7 @@ import type {
ApplicationNode,
} from "./javascriptApplicationGraphSchemas.js";
import type { JavaScriptApplicationGraph } from "./javascriptApplicationGraph.js";
import { javaScriptFileOccurrenceSchema } from "./javascriptArtifactFiles.js";
import { applicationEndpointCorrespondence } from "./javascriptApplicationEndpointCorrespondence.js";
import type { ApplicationVersionComparisonItem } from "./javascriptApplicationVersionComparisonSchemas.js";
import type {
@@ -506,13 +507,33 @@ const properties = (node: ApplicationNode) =>
node.observations
.map(({ label, properties: values, source_map_reference }) => ({
label,
properties: values,
properties: comparisonPropertyValues(values),
source_map_reference,
}))
.sort((left, right) =>
compareUnicodeCodePoints(canonicalJson(left), canonicalJson(right)),
);
const comparisonPropertyValues = (
values: ApplicationNode["observations"][number]["properties"],
) => {
const occurrence = javaScriptFileOccurrenceSchema.safeParse(
values.file_occurrence,
);
if (!occurrence.success) return values;
// A containing artifact's digest locates this occurrence in one version;
// sibling changes do not establish a change to this file's own facts.
// Keep the occurrence's path and content digest comparable, and retain the
// complete provenance record on the original observation.
return {
...values,
file_occurrence: {
path: occurrence.data.path,
sha256: occurrence.data.sha256,
},
};
};
const indexRelationships = (
graph: JavaScriptApplicationGraph,
): RelationshipIndex => {