# graph.inspect.v1 · Inspector Contract (2025-12-04) Replaces the archived Cartographer handshake note and grounds the Concelier/Excititor → Graph Indexer/API interface. Use this shape for any inspector payloads that carry SBOM relationships plus advisory/VEX linkouts destined for graph ingestion or replay. ## Purpose - Give Concelier (Link-Not-Merge v1) and Excititor a frozen, deterministic payload so graph nodes/edges can be regenerated or replayed offline. - Encode the evidence hashes and provenance needed for append-only rebuilds and audit trails. - Keep ordering stable to avoid hash churn between runs. ## Payload shape (summary) - `schemaVersion` — must be `graph.inspect.v1`. - `tenant`, `artifactDigest`, `sbomDigest`, `collectedAt`. - `components[]` (ordered): - `purl`, optional `version`, optional sorted `scopes[]`. - `relationships[]` → `contains|depends_on|provides|runtime_observed` with `targetPurl`, `scope?`, `source`, `evidenceHash`. - `advisories[]` → `advisoryId`, `source`, `status`, `severity?`, `cvss?`, `justification?`, `linksetDigest?`, `evidenceHash`, `modifiedAt`. - `vexStatements[]` → `statementId`, `source`, `status`, `justification`, `impactStatement?`, `knownExploited?`, `issuedAt`, `expiresAt?`, `evidenceHash`. - `provenance` → `source`, `collectedAt`, `eventOffset?`, `linksetDigest?`, `evidenceHash?`. - Optional `links.sbomObservationEventId` and `links.linksetDigest` for traceability. Full machine-readable schema: `docs/modules/graph/contracts/graph.inspect.v1.schema.json`. ## Determinism rules - Preserve input order for `components[]` and `relationships[]`; sort `scopes`, `advisories`, and `vexStatements` by (`source`, `advisoryId`/`statementId`) before emitting. - All timestamps UTC ISO-8601; hashes are SHA-256 hex. - Keep arrays unique where noted (`scopes`), and avoid null/empty strings. ## Graph mapping - `relationships` → graph edges: `contains/depends_on/provides/runtime_observed` align with `CONTAINS`, `DEPENDS_ON`, `PROVIDES`, `OBSERVED_RUNTIME`. - `advisories` → `advisory` nodes + `AFFECTED_BY` edges (use `linksetDigest` and `evidenceHash` for provenance). - `vexStatements` → `vex_statement` nodes + `VEX_EXEMPTS` edges (propagate `justification`, `knownExploited`, `impactStatement`). - `provenance` fields flow into graph `provenance` objects and `eventOffset` becomes the replay cursor. ## Validation ```sh # Example (offline-friendly if ajv is already installed locally) ajv validate -s docs/modules/graph/contracts/graph.inspect.v1.schema.json \ -d docs/modules/graph/contracts/examples/graph.inspect.v1.sample.json ``` Use any JSON Schema Draft 2020-12 validator if `ajv` is unavailable. ## Sample See `docs/modules/graph/contracts/examples/graph.inspect.v1.sample.json` for a one-component payload that exercises relationships, advisory observations, VEX statements, and provenance fields. ## Upstream alignment - Link-Not-Merge fixtures: `docs/modules/concelier/link-not-merge-schema.md`. - Excititor overlay prep: `docs/modules/excititor/prep/2025-11-20-graph-21-001-prep.md` and `...graph-21-002-prep.md`. - Graph canonical model: `docs/modules/graph/schema.md` (node/edge taxonomy the inspector feeds).