Files
git.stella-ops.org/docs/advisory-ai/evidence-payloads.md
StellaOps Bot 6bee1fdcf5
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
work
2025-11-25 08:01:23 +02:00

5.9 KiB

Advisory AI Evidence Payloads (LNM-Aligned)

Updated: 2025-11-24 · Owner: Advisory AI Docs Guild · Sprint: 0111 (AIAI-RAG-31-003)

This document defines how Advisory AI consumes Link-Not-Merge (LNM) observations and linksets for Retrieval-Augmented Generation (RAG). It aligns payloads with the frozen LNM v1 schema (docs/modules/concelier/link-not-merge-schema.md, 2025-11-17) and replaces prior draft payloads. CLI/Policy artefacts (CLI-VULN-29-001, CLI-VEX-30-001, policyVersion digests) are referenced but optional at runtime; missing artefacts trigger deterministic 409 advisory.contextUnavailable responses rather than fallback merging. A deterministic SBOM context fixture lives at out/console/guardrails/cli-vuln-29-001/sample-sbom-context.json (SHA256 421af53f9eeba6903098d292fbd56f98be62ea6130b5161859889bf11d699d18) and is used in the examples below.

1) Input envelope (per task)

{
  "advisoryKey": "csaf:redhat:RHSA-2025:1001",
  "profile": "fips-local",
  "policyVersion": "2025.10.1",
  "lnm": {
    "observationIds": ["6561e41b3e3f4a6e9d3b91c1", "6561e41b3e3f4a6e9d3b91c2"],
    "linksetId": "6561e41b3e3f4a6e9d3b91d0",
    "provenanceHash": "sha256:0f7c...9ad3"
  },
  "sbom": {
    "artifactId": "registry.stella-ops.internal/runtime/api",
    "purl": "pkg:oci/runtime-api@sha256:d2c3...",
    "timelineClamp": 500,
    "dependencyPathClamp": 200
  }
}

Rules:

  • lnm.linksetId and lnm.observationIds are required. Missing values → 409 advisory.contextUnavailable.
  • provenanceHash must match the hash list embedded in the LNM linkset; Advisory AI refuses linksets whose hashes mismatch.
  • SBOM fields optional; if absent, remediation tasks skip SBOM deltas and still return deterministic outputs.

2) Canonical chunk mapping

LNM source Advisory AI chunk Transformation
advisory_observations._id source_id Stored verbatim; used for citations.
advisory_observations.advisoryId advisory_key Also populates content_hash seed.
advisory_observations.summary text Trimmed, Markdown-safe.
advisory_observations.affected[].purl purl Lowercased, deduped; no range merging.
advisory_observations.severities[] severity Passed through; multiple severities allowed.
advisory_observations.references[] references Sorted for determinism.
advisory_observations.relationships[] relationships Surface upstream type/source/target/provenance; no merge.
advisory_observations.provenance.sourceArtifactSha content_hash Drives dedup + cache key.
advisory_linksets.conflicts[] conflicts Serialized verbatim for conflict tasks.
`advisory_linksets.normalized.purls versions ranges

Chunk ordering: observations sorted by (source, advisoryId, provenance.fetchedAt) as per LNM invariant; chunks are emitted in the same order to keep cache keys stable. SBOM deltas, when present, append after observations but before conflict echoes to keep hashes reproducible with and without SBOM context.

3) Output citation rules

  • citations[n].sourceId points to the LNM source_id; citations[n].uri must remain the upstream reference URI when present.
  • If SBOM deltas are included, they appear as separate citations with kind: "sbom" and sourceId built from SBOM context digest (sbom:{artifactId}:{digest}).
  • Conflict outputs must echo linkset.conflicts[].reason in the Markdown body with matching citation indexes; guardrails block outputs where a conflict reason lacks a citation.

4) Error conditions (aligned to LNM)

Condition Code Notes
Missing lnm.linksetId or lnm.observationIds 409 advisory.contextUnavailable Caller should pass LNM IDs; retry once upstream emits them.
Hash mismatch between provenanceHash and linkset 409 advisory.contextHashMismatch Indicates tampering or stale payload; retry after refreshing linkset.
Observation count exceeds clamp (defaults: 200 obs, 600 chunks) 413 advisory.contextTooLarge Caller may request narrower preferredSections or reduce obs set.
Conflicts array empty for conflict task 422 advisory.conflict.noConflicts Signals upstream data gap; reported to Concelier.

5) Sample normalized RAG bundle

{
  "taskType": "Summary",
  "advisoryKey": "csaf:redhat:RHSA-2025:1001",
  "lnmBundle": {
    "linksetId": "6561e41b3e3f4a6e9d3b91d0",
    "provenanceHash": "sha256:0f7c...9ad3",
    "chunks": [
      {
        "source_id": "concelier:ghsa:GHSA-xxxx:obs:6561e41b3e3f4a6e9d3b91c1",
        "content_hash": "sha256:1234...",
        "advisory_key": "csaf:redhat:RHSA-2025:1001",
        "purl": "pkg:maven/org.example/foo@1.2.3",
        "severity": [{"system":"cvssv3","score":7.8,"vector":"AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}],
        "references": ["https://access.redhat.com/errata/RHSA-2025:1001"],
        "relationships": [{"type":"affects","source":"nvd","target":"cpe:/o:redhat:enterprise_linux:9"}]
      }
    ],
    "conflicts": [
      {"field":"affected.versions","reason":"vendor_range_differs","values":["<1.2.0","<=1.2.3"]}
    ]
  },
  "sbomSummary": {
    "artifactId": "registry.stella-ops.internal/runtime/api",
    "versionTimeline": 8,
    "dependencyPaths": 5
  }
}

Operators can store this bundle alongside plan cache entries; the lnmBundle.provenanceHash proves the evidence set matches the frozen Concelier linkset.

6) Operator validation steps

  • Verify LNM collections at schema v1 (2025-11-17 freeze) before enabling Advisory AI tasks.
  • Ensure lnm.provenanceHash matches linkset observationHashes before calling Advisory AI.
  • Keep clamps deterministic: observations ≤200, chunks ≤600, timeline entries ≤500, dependency paths ≤200 (defaults; override only if documented).
  • When running offline, include LNM linkset exports in the Offline Kit to preserve citation replay.