66 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			66 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # Event Envelope Schemas
 | ||
| 
 | ||
| Platform services publish strongly typed events; the JSON Schemas in this directory define those envelopes. File names follow `<event-name>@<version>.json` so producers and consumers can negotiate contracts explicitly.
 | ||
| 
 | ||
| ## Catalog
 | ||
| - `scanner.report.ready@1.json` — emitted by Scanner.WebService once a signed report is persisted (payload embeds the canonical report plus DSSE envelope). Consumers: Notify, UI timeline.
 | ||
| - `scanner.scan.completed@1.json` — emitted alongside the signed report to capture scan outcomes/summary data for downstream automation. Consumers: Notify, Scheduler backfills, UI timelines.
 | ||
| - `scheduler.rescan.delta@1.json` — emitted by Scheduler when BOM-Index diffs require fresh scans. Consumers: Notify, Policy Engine.
 | ||
| - `attestor.logged@1.json` — emitted by Attestor after storing the Rekor inclusion proof. Consumers: UI attestation panel, Governance exports.
 | ||
| 
 | ||
| Additive payload changes (new optional fields) can stay within the same version. Any breaking change (removing a field, tightening validation, altering semantics) must increment the `@<version>` suffix and update downstream consumers.
 | ||
| 
 | ||
| ## Envelope structure
 | ||
| All event envelopes share the same deterministic header. Use the following table as the quick reference when emitting or parsing events:
 | ||
| 
 | ||
| | Field | Type | Notes |
 | ||
| |-------|------|-------|
 | ||
| | `eventId` | `uuid` | Must be globally unique per occurrence; producers log duplicates as fatal. |
 | ||
| | `kind` | `string` | Fixed per schema (e.g., `scanner.report.ready`). Downstream services reject unknown kinds or versions. |
 | ||
| | `tenant` | `string` | Multi‑tenant isolation key; mirror the value recorded in queue/Mongo metadata. |
 | ||
| | `ts` | `date-time` | RFC 3339 UTC timestamp. Use monotonic clocks or atomic offsets so ordering survives retries. |
 | ||
| | `scope` | `object` | Optional block used when the event concerns a specific image or repository. See schema for required fields (e.g., `repo`, `digest`). |
 | ||
| | `payload` | `object` | Event-specific body. Schemas allow additional properties so producers can add optional hints (e.g., `reportId`, `quietedFindingCount`) without breaking consumers. For scanner events, payloads embed both the canonical report document and the DSSE envelope so consumers can reuse signatures without recomputing them. See `docs/runtime/SCANNER_RUNTIME_READINESS.md` for the runtime consumer checklist covering these hints. |
 | ||
| 
 | ||
| When adding new optional fields, document the behaviour in the schema’s `description` block and update the consumer checklist in the next sprint sync.
 | ||
| 
 | ||
| ## Canonical samples & validation
 | ||
| Reference payloads live under `docs/events/samples/`, mirroring the schema version (`<event-name>@<version>.sample.json`). They illustrate common field combinations, including the optional attributes that downstream teams rely on for UI affordances and audit trails. Scanner samples reuse the exact DSSE envelope checked into `samples/api/reports/report-sample.dsse.json`, and a unit test (`ReportSamplesTests`) guards that the payload/base64 remain canonical.
 | ||
| 
 | ||
| Run the following loop offline to validate both schemas and samples:
 | ||
| 
 | ||
| ```bash
 | ||
| # Validate schemas (same check as CI)
 | ||
| for schema in docs/events/*.json; do
 | ||
|   npx ajv compile -c ajv-formats -s "$schema"
 | ||
| done
 | ||
| 
 | ||
| # Validate canonical samples against their schemas
 | ||
| for sample in docs/events/samples/*.sample.json; do
 | ||
|   schema="docs/events/$(basename "${sample%.sample.json}").json"
 | ||
|   npx ajv validate -c ajv-formats -s "$schema" -d "$sample"
 | ||
| done
 | ||
| ```
 | ||
| 
 | ||
| Consumers can copy the samples into integration tests to guarantee backwards compatibility. When emitting new event versions, include a matching sample and update this README so air-gapped operators stay in sync.
 | ||
| 
 | ||
| ## CI validation
 | ||
| The Docs CI workflow (`.gitea/workflows/docs.yml`) installs `ajv-cli` and compiles every schema on pull requests. Run the same check locally before opening a PR:
 | ||
| 
 | ||
| ```bash
 | ||
| for schema in docs/events/*.json; do
 | ||
|   npx ajv compile -c ajv-formats -s "$schema"
 | ||
| done
 | ||
| ```
 | ||
| 
 | ||
| Tip: run `npm install --no-save ajv ajv-cli ajv-formats` once per clone so `npx` can resolve the tooling offline.
 | ||
| 
 | ||
| If a schema references additional files, include `-r` flags so CI and local runs stay consistent.
 | ||
| 
 | ||
| ## Working with schemas
 | ||
| - Producers should validate outbound payloads using the matching schema during unit tests.
 | ||
| - Consumers should pin to a specific version and log when encountering unknown versions to catch missing migrations early.
 | ||
| - Store real payload samples under `docs/events/samples/` (mirrors the schema version) and mirror them into `samples/events/` when you need fixtures in integration repositories.
 | ||
| 
 | ||
| Contact the Platform Events group in Docs Guild if you need help shaping a new event or version strategy.
 |