{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://stella-ops.org/schemas/lnm-overlay.schema.json", "title": "StellaOps Link-Not-Merge Overlay Schema", "description": "Schema for Link-Not-Merge (LNM) overlay metadata and graph inspector integration. Unblocks EXCITITOR-GRAPH-21-001 through 21-005.", "type": "object", "definitions": { "LnmOverlay": { "type": "object", "description": "Link-Not-Merge overlay structure for VEX observation and linkset merge metadata", "required": ["overlay_id", "source_type", "timestamp"], "properties": { "overlay_id": { "type": "string", "format": "uuid", "description": "Unique identifier for this overlay" }, "source_type": { "type": "string", "enum": ["observation", "linkset", "advisory", "vex", "sbom"], "description": "Type of source contributing to this overlay" }, "source_ref": { "$ref": "#/definitions/SourceRef" }, "timestamp": { "type": "string", "format": "date-time", "description": "When this overlay was created" }, "version": { "type": "string", "description": "Version of the overlay schema" }, "links": { "type": "array", "items": { "$ref": "#/definitions/OverlayLink" }, "description": "Links to related entities" }, "conflicts": { "type": "array", "items": { "$ref": "#/definitions/ConflictMarker" }, "description": "Conflict markers from merge operations" }, "provenance": { "$ref": "#/definitions/OverlayProvenance" }, "indexes": { "$ref": "#/definitions/OverlayIndexes" } } }, "SourceRef": { "type": "object", "description": "Reference to the source document/entity", "required": ["type", "identifier"], "properties": { "type": { "type": "string", "enum": ["advisory", "vex", "sbom", "scan_result", "linkset", "observation"] }, "identifier": { "type": "string", "description": "Unique identifier of the source (e.g., advisory ID, SBOM digest)" }, "digest": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$", "description": "Content-addressable digest of the source" }, "uri": { "type": "string", "format": "uri", "description": "URI to retrieve the source" }, "fetched_at": { "type": "string", "format": "date-time" } } }, "OverlayLink": { "type": "object", "description": "Link between entities in the overlay graph", "required": ["link_type", "source", "target"], "properties": { "link_id": { "type": "string", "format": "uuid" }, "link_type": { "type": "string", "enum": [ "affects", "mitigates", "remediates", "supersedes", "references", "contains", "depends_on", "exploits", "derived_from" ], "description": "Semantic relationship type" }, "source": { "$ref": "#/definitions/EntityRef" }, "target": { "$ref": "#/definitions/EntityRef" }, "confidence": { "type": "number", "minimum": 0, "maximum": 1, "description": "Confidence score for this link" }, "evidence": { "type": "array", "items": { "$ref": "#/definitions/LinkEvidence" } }, "metadata": { "type": "object", "additionalProperties": true } } }, "EntityRef": { "type": "object", "description": "Reference to an entity in the graph", "required": ["entity_type", "identifier"], "properties": { "entity_type": { "type": "string", "enum": ["vulnerability", "component", "product", "advisory", "vex_statement", "sbom", "finding"] }, "identifier": { "type": "string", "description": "Entity identifier (CVE ID, PURL, product ID, etc.)" }, "version": { "type": "string", "description": "Version specifier if applicable" } } }, "LinkEvidence": { "type": "object", "description": "Evidence supporting a link relationship", "required": ["type"], "properties": { "type": { "type": "string", "enum": ["explicit", "inferred", "heuristic", "manual"] }, "source_ref": { "$ref": "#/definitions/SourceRef" }, "statement": { "type": "string", "description": "Evidence statement or justification" }, "score": { "type": "number", "minimum": 0, "maximum": 1 } } }, "ConflictMarker": { "type": "object", "description": "Marker for merge conflicts between overlapping sources", "required": ["conflict_type", "entities", "resolution_status"], "properties": { "conflict_id": { "type": "string", "format": "uuid" }, "conflict_type": { "type": "string", "enum": [ "status_mismatch", "severity_mismatch", "version_range_overlap", "product_identity_conflict", "justification_conflict", "timestamp_ordering" ], "description": "Type of conflict detected" }, "entities": { "type": "array", "items": { "$ref": "#/definitions/ConflictingEntity" }, "minItems": 2, "description": "Entities involved in the conflict" }, "resolution_status": { "type": "string", "enum": ["unresolved", "auto_resolved", "manually_resolved", "deferred"], "description": "Current resolution status" }, "resolution": { "$ref": "#/definitions/ConflictResolution" }, "detected_at": { "type": "string", "format": "date-time" } } }, "ConflictingEntity": { "type": "object", "description": "Entity involved in a conflict", "required": ["source_ref", "value"], "properties": { "source_ref": { "$ref": "#/definitions/SourceRef" }, "value": { "type": "object", "additionalProperties": true, "description": "The conflicting value from this source" }, "trust_level": { "type": "string", "enum": ["authoritative", "trusted", "community", "unknown"], "description": "Trust level of this source" }, "precedence": { "type": "integer", "minimum": 0, "description": "Precedence rank for resolution" } } }, "ConflictResolution": { "type": "object", "description": "Resolution decision for a conflict", "required": ["strategy", "resolved_at"], "properties": { "strategy": { "type": "string", "enum": [ "latest_wins", "highest_precedence", "most_specific", "manual_selection", "merge_composite" ], "description": "Resolution strategy used" }, "selected_source": { "$ref": "#/definitions/SourceRef" }, "resolved_value": { "type": "object", "additionalProperties": true, "description": "The resolved value" }, "justification": { "type": "string", "description": "Justification for the resolution" }, "resolved_at": { "type": "string", "format": "date-time" }, "resolved_by": { "type": "string", "description": "User or system that resolved the conflict" } } }, "OverlayProvenance": { "type": "object", "description": "Provenance information for the overlay", "properties": { "created_at": { "type": "string", "format": "date-time" }, "created_by": { "type": "string" }, "pipeline_id": { "type": "string", "description": "ID of the ingestion pipeline that created this overlay" }, "pipeline_version": { "type": "string" }, "input_digests": { "type": "array", "items": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" }, "description": "Digests of all inputs used to create this overlay" }, "attestation_ref": { "type": "string", "description": "Reference to DSSE attestation for this overlay" } } }, "OverlayIndexes": { "type": "object", "description": "Index configuration for graph inspector queries", "properties": { "by_vulnerability": { "$ref": "#/definitions/IndexConfig" }, "by_component": { "$ref": "#/definitions/IndexConfig" }, "by_product": { "$ref": "#/definitions/IndexConfig" }, "by_source": { "$ref": "#/definitions/IndexConfig" }, "by_conflict_status": { "$ref": "#/definitions/IndexConfig" } } }, "IndexConfig": { "type": "object", "description": "Configuration for a specific index", "properties": { "enabled": { "type": "boolean", "default": true }, "fields": { "type": "array", "items": { "type": "string" }, "description": "Fields to include in the index" }, "materialized": { "type": "boolean", "default": false, "description": "Whether to use a materialized view" }, "refresh_interval_seconds": { "type": "integer", "minimum": 0, "description": "Refresh interval for materialized views (0 = immediate)" } } }, "BatchVexFetchRequest": { "type": "object", "description": "Request for batched VEX document fetches", "required": ["product_ids"], "properties": { "product_ids": { "type": "array", "items": { "type": "string" }, "description": "Product identifiers (PURLs, CPEs) to fetch VEX for" }, "vulnerability_ids": { "type": "array", "items": { "type": "string" }, "description": "Optional: filter to specific vulnerabilities" }, "include_overlays": { "type": "boolean", "default": true, "description": "Include overlay metadata in response" }, "include_conflicts": { "type": "boolean", "default": false, "description": "Include conflict markers in response" }, "max_results": { "type": "integer", "minimum": 1, "maximum": 1000, "default": 100 }, "continuation_token": { "type": "string", "description": "Token for pagination" } } }, "BatchVexFetchResponse": { "type": "object", "description": "Response from batched VEX document fetch", "required": ["results", "total_count"], "properties": { "results": { "type": "array", "items": { "$ref": "#/definitions/VexOverlayResult" } }, "total_count": { "type": "integer", "minimum": 0 }, "continuation_token": { "type": "string" }, "fetch_timestamp": { "type": "string", "format": "date-time" } } }, "VexOverlayResult": { "type": "object", "description": "VEX result with overlay metadata", "required": ["product_id"], "properties": { "product_id": { "type": "string" }, "vex_statements": { "type": "array", "items": { "$ref": "#/definitions/VexStatementSummary" } }, "overlay": { "$ref": "#/definitions/LnmOverlay" }, "conflicts_count": { "type": "integer", "minimum": 0 } } }, "VexStatementSummary": { "type": "object", "description": "Summary of a VEX statement", "required": ["vulnerability_id", "status"], "properties": { "vulnerability_id": { "type": "string" }, "status": { "type": "string", "enum": ["not_affected", "affected", "fixed", "under_investigation"] }, "justification": { "type": "string" }, "source_ref": { "$ref": "#/definitions/SourceRef" }, "timestamp": { "type": "string", "format": "date-time" } } }, "GraphInspectorQuery": { "type": "object", "description": "Query for the graph inspector UI", "required": ["query_type"], "properties": { "query_type": { "type": "string", "enum": [ "entity_neighbors", "path_between", "conflicts_for_entity", "overlay_history", "affected_products", "vulnerability_coverage" ] }, "entity_ref": { "$ref": "#/definitions/EntityRef" }, "filters": { "$ref": "#/definitions/QueryFilters" }, "depth": { "type": "integer", "minimum": 1, "maximum": 10, "default": 2, "description": "Graph traversal depth" }, "include_metadata": { "type": "boolean", "default": true } } }, "QueryFilters": { "type": "object", "description": "Filters for graph queries", "properties": { "link_types": { "type": "array", "items": { "type": "string" }, "description": "Filter by link types" }, "entity_types": { "type": "array", "items": { "type": "string" }, "description": "Filter by entity types" }, "source_types": { "type": "array", "items": { "type": "string" }, "description": "Filter by source types" }, "time_range": { "type": "object", "properties": { "from": { "type": "string", "format": "date-time" }, "to": { "type": "string", "format": "date-time" } } }, "min_confidence": { "type": "number", "minimum": 0, "maximum": 1 }, "include_conflicts": { "type": "boolean", "default": false }, "conflict_status": { "type": "array", "items": { "type": "string", "enum": ["unresolved", "auto_resolved", "manually_resolved", "deferred"] } } } } }, "properties": { "overlays": { "type": "array", "items": { "$ref": "#/definitions/LnmOverlay" } } }, "examples": [ { "overlays": [ { "overlay_id": "550e8400-e29b-41d4-a716-446655440000", "source_type": "vex", "source_ref": { "type": "vex", "identifier": "CSAF-2025-0001", "digest": "sha256:abc123def456789...", "uri": "https://security.vendor.com/csaf/2025-0001.json" }, "timestamp": "2025-12-06T10:00:00Z", "version": "1.0.0", "links": [ { "link_id": "660e8400-e29b-41d4-a716-446655440001", "link_type": "affects", "source": { "entity_type": "vulnerability", "identifier": "CVE-2025-1234" }, "target": { "entity_type": "component", "identifier": "pkg:npm/lodash@4.17.20" }, "confidence": 0.95, "evidence": [ { "type": "explicit", "statement": "Vendor advisory explicitly lists lodash@4.17.20 as affected" } ] } ], "conflicts": [ { "conflict_id": "770e8400-e29b-41d4-a716-446655440002", "conflict_type": "status_mismatch", "entities": [ { "source_ref": { "type": "vex", "identifier": "CSAF-2025-0001" }, "value": { "status": "affected" }, "trust_level": "authoritative", "precedence": 1 }, { "source_ref": { "type": "vex", "identifier": "OPENVEX-COMM-2025-0001" }, "value": { "status": "not_affected" }, "trust_level": "community", "precedence": 3 } ], "resolution_status": "auto_resolved", "resolution": { "strategy": "highest_precedence", "selected_source": { "type": "vex", "identifier": "CSAF-2025-0001" }, "resolved_value": { "status": "affected" }, "justification": "Authoritative vendor source has highest precedence", "resolved_at": "2025-12-06T10:05:00Z", "resolved_by": "lnm-pipeline" }, "detected_at": "2025-12-06T10:00:00Z" } ], "provenance": { "created_at": "2025-12-06T10:00:00Z", "created_by": "lnm-pipeline", "pipeline_id": "lnm-ingestion-001", "pipeline_version": "2025.10.0", "input_digests": [ "sha256:abc123...", "sha256:def456..." ] }, "indexes": { "by_vulnerability": { "enabled": true, "fields": ["vulnerability_id", "status", "timestamp"], "materialized": true, "refresh_interval_seconds": 60 }, "by_component": { "enabled": true, "fields": ["component_purl", "version_range"], "materialized": false } } } ] } ] }