Files
git.stella-ops.org/docs/advisory-ai/evidence-payloads.md
StellaOps Bot f43e828b4e
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
feat: Implement MongoDB orchestrator storage with registry, commands, and heartbeats
- Added NullAdvisoryObservationEventTransport for handling advisory observation events.
- Created IOrchestratorRegistryStore interface for orchestrator registry operations.
- Implemented MongoOrchestratorRegistryStore for MongoDB interactions with orchestrator data.
- Defined OrchestratorCommandDocument and OrchestratorCommandRecord for command handling.
- Added OrchestratorHeartbeatDocument and OrchestratorHeartbeatRecord for heartbeat tracking.
- Created OrchestratorRegistryDocument and OrchestratorRegistryRecord for registry management.
- Developed tests for orchestrator collections migration and MongoOrchestratorRegistryStore functionality.
- Introduced AirgapImportRequest and AirgapImportValidator for air-gapped VEX bundle imports.
- Added incident mode rules sample JSON for notifier configuration.
2025-11-22 12:35:38 +02:00

105 lines
5.7 KiB
Markdown

# Advisory AI Evidence Payloads (LNM-Aligned)
_Updated: 2025-11-18 · 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.
## 1) Input envelope (per task)
```json
{
"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|severities` | `normalized` | Used as hints only; never overwrite observation fields. |
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
```json
{
"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.