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
Policy Lint & Smoke / policy-lint (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
4.5 KiB
4.5 KiB
advisory.linkset.updated@1 · Event contract
Purpose: unblock CONCELIER-LNM-21-005 by freezing the platform event shape for linkset changes emitted by Concelier. This is the only supported event for linkset churn; downstreams subscribe for graph overlays, policy evaluations, and replay bundles.
Envelope & transport
- Subject:
concelier.advisory.linkset.updated.v1 - Type/version:
advisory.linkset.updated@1 - Transport: NATS (primary), Redis Stream
concelier:advisory.linkset.updated:v1(fallback). Both carry the same DSSE envelope. - DSSE payloadType:
application/vnd.stellaops.advisory.linkset.updated.v1+json. - Signature: Ed25519 via Platform Events signer; attach Rekor UUID when available. Offline kits treat the envelope as the source of truth.
Payload (JSON)
| Field | Type | Rules |
|---|---|---|
eventId |
string (uuid) | Generated by publisher; idempotency key. |
tenantId |
string | urn:tenant:{uuid}; required for multi-tenant routing. |
linksetId |
string (ObjectId) | Mongo _id of the linkset document. |
advisoryId |
string | Upstream advisory identifier (e.g., CVE, GHSA, vendor id). |
source |
string | Linkset source/adapter identifier (lowercase). |
observationIds |
string[] | Array of observation ObjectIds included in this linkset; sorted ASCII. |
delta |
object | Change description: { type, observationsAdded, observationsRemoved, confidenceChanged, conflictsChanged }. |
confidence |
number (0–1, nullable) | Correlation confidence score; null if not computed. |
conflicts |
object[] | Array of { field, reason, sourceIds[] } conflict summaries; sorted by field then reason. |
provenance |
object | { observationHashes[], toolVersion?, policyHash? } for replay/audit. |
createdAt |
string (ISO-8601 UTC) | Timestamp when linkset was built. |
replayCursor |
string | Monotone cursor for offline bundle ordering (tick from createdAt). |
builtByJobId |
string (optional) | Job ID that built this linkset. |
traceId |
string (optional) | Propagated from ingest job/request; aids join with logs/metrics. |
Delta object
| Field | Type | Rules |
|---|---|---|
type |
string | "created" or "updated". |
observationsAdded |
string[] | Observation IDs added since previous version. |
observationsRemoved |
string[] | Observation IDs removed since previous version. |
confidenceChanged |
boolean | True if confidence score changed. |
conflictsChanged |
boolean | True if conflicts array changed. |
Determinism & ordering
- Arrays sorted ASCII; objects field-sorted when hashing.
eventId+replayCursorprovide exactly-once consumer handling; duplicates must be ignored when observation hashes unchanged.- No judgments: only raw facts, delta descriptions, and provenance pointers; any derived severity/merge content is forbidden.
Error contracts for Scheduler
- Retryable NATS/Redis failures use backoff capped at 30s; after 5 attempts, emit
concelier.events.dlqwith the same envelope anderrorfield describing transport failure. - Consumers must NACK on schema validation failure; publisher logs
ERR_EVENT_SCHEMAand quarantines the offending linkset id.
Sample payload
{
"eventId": "550e8400-e29b-41d4-a716-446655440000",
"tenantId": "urn:tenant:acme-corp",
"linksetId": "6744abcd1234567890abcdef",
"advisoryId": "CVE-2024-1234",
"source": "nvd",
"observationIds": ["674400001234567890abcdef", "674400001234567890abcde0"],
"delta": {
"type": "created",
"observationsAdded": ["674400001234567890abcdef", "674400001234567890abcde0"],
"observationsRemoved": [],
"confidenceChanged": true,
"conflictsChanged": false
},
"confidence": 0.85,
"conflicts": [],
"provenance": {
"observationHashes": ["sha256:abc123", "sha256:def456"],
"toolVersion": "1.0.0",
"policyHash": null
},
"createdAt": "2025-11-27T12:00:00.000Z",
"replayCursor": "638688000000000000",
"builtByJobId": "job-12345",
"traceId": "trace-67890"
}
Schema
advisory.linkset.updated@1.schema.json provides a JSON Schema (draft 2020-12) for runtime validation; any additional fields are rejected.
Implementation (LNM-21-005)
- Event type defined in
StellaOps.Concelier.Core.Linksets.AdvisoryLinksetUpdatedEvent. - Publisher interface:
IAdvisoryLinksetEventPublisher. - Outbox interface:
IAdvisoryLinksetEventOutbox. - Configuration:
AdvisoryLinksetEventPublisherOptions.
Change control
- Add-only. Adjusting delta types or conflict codes requires new version
advisory.linkset.updated@2and a sprint note.