Published schemas¶
Opencomplai writes several JSON files that other programs read: the signed scan artifact, the gap report, the Annex IV dossier, the deployer pack, agent attestations, and the payloads a dashboard accepts. Each has a JSON Schema (draft 2020-12). This page lists every schema, who writes it and who reads it, and states how the schemas are versioned.
Paths under dashboard-saas/ exist in the enterprise repository only and are written as code spans, not links.
Index¶
The schemas under packages/core/src/opencomplai_core/data/ ship with the CLI. The ones under dashboard-saas/schemas/ are vendored by the dashboard and pinned (see Pin and re-pin rules).
| File | $id | Owner and source | Producer | Consumer | Status |
|---|---|---|---|---|---|
scan_status_artifact.schema.json | https://schemas.opencomplai.dev/scan_status_artifact/v1 | Core. Generated from the ScanStatusArtifact model by scripts/generate_artifact_schemas.py. | opencomplai check | Anyone validating compliance-artifact.json | Published, v1. |
gap_report.schema.json | https://schemas.opencomplai.dev/gap_report/v1 | Core. Generated from the GapReport model by the same script. | opencomplai gaps --output json, check --with-gaps | opencomplai diff, report tooling | Published, v1. |
annex_iv_dossier.schema.json | none yet | Core. Generated from the AnnexIVDossier model by scripts/generate_dossier_schema.py. | opencomplai docs generate | Auditors and CI that validate a dossier | Published, no $id. A drift test keeps it in step with the model. |
deployer_pack.schema.json | https://schemas.opencomplai.dev/deployer_pack/v1 | Core. Generated from the DeployerPack model. | opencomplai deployer-pack build | opencomplai verify --kind deployer-pack | Published, v1. |
agent_attestation_v1.schema.json | none; the document fixes schema_version to agent_attestation/v1 | Core. Mirrors the signed attestation record. | opencomplai agents attest | opencomplai verify --kind agent-attestation | Published, versioned by its file name and schema_version. |
first_scan_status.schema.json | https://schemas.opencomplai.dev/first_scan_status/v1 | Dashboard, vendored. Source: the PRD's section on the status artifact. | opencomplai push (maps a scan artifact onto it) | Dashboard ingest, POST /v1/ingest/scan-status | Published, v1. The effective allowlist of what the dashboard may store. |
dossier_envelope.schema.json | https://schemas.opencomplai.dev/dossier_envelope/v1 | Dashboard, vendored. Mirrors the metadata fields of AnnexIVDossier. | The CLI's publish module, from a dossier made by opencomplai docs generate | Dashboard ingest, POST /v1/ingest/dossier-envelope | Published, v1. Carries metadata only; the dossier bundle never crosses the boundary. |
metrics_payload.schema.json | https://schemas.opencomplai.dev/metrics_payload/v1 | Dashboard, vendored. Source: the egress allowlist. | Clients that send aggregated metrics | Dashboard ingest, POST /v1/ingest/metrics | Published, v1. Every field comes from the allowlist. |
error_envelope.schema.json | https://schemas.opencomplai.dev/error_envelope/v1 | Dashboard, vendored. Mirrors the gateway's ErrorEnvelope. | Dashboard API error responses | API clients | Published, v1. |
deployer_pack.schema.json (vendored copy) | https://schemas.opencomplai.dev/deployer_pack/v1 | Dashboard, vendored copy of the core file; a test keeps the two equal. | opencomplai deployer-pack build | Not an ingest kind: packs are generated offline and never uploaded | Vendored copy, same $id as the core file. |
Other files in dashboard-saas/schemas/ are not JSON Schemas but are part of the pinned set:
| File | What it is |
|---|---|
PIN.json | The pinned source commit, the date, a note on each re-pin, and the list of vendored files with their sources. |
MANIFEST.sha256 | A SHA-256 per file in the directory, for every file except itself. |
CHANGELOG.md | One row per PIN.json bump: date, previous and new SHA, reason, reviewer. |
allowed_fields.json | The egress allowlist of fields. |
checker_golden_vectors.json | Shared test vectors for the applicability checker, asserted from both the core and the dashboard suites. |
signature_spec.md | How the artifact signature is canonicalised. |
Versioning policy¶
$id pattern¶
A published schema's $id is https://schemas.opencomplai.dev/<name>/v<major>, where <name> is the file name without .schema.json and <major> is a single integer. The artifact also carries a schema_version string that matches the major (1); it lives in the schema document, not on the model, so it never changes signed bytes. The host is an identifier, not a promise that the URL resolves.
A schema without an $id (the dossier, the attestation) is identified by its file name until one is added. Adding an $id to the dossier schema must not reuse the dashboard's first_scan_status name.
Pin and re-pin rules¶
The dashboard never edits a vendored schema by hand. It re-pins:
- Edit the schema, in core first when the source is a model, and regenerate it.
- Update
PIN.json: the pinned commit SHA, the date and the note. A commit cannot name its own SHA, so the new SHA is the parent of the commit that widens the schema together with the model. - Add a row to
CHANGELOG.mdfor the bump. - Run
python dashboard-saas/scripts/schema_drift_check.py --regenlast, to rewriteMANIFEST.sha256.
dashboard-saas/scripts/schema_drift_check.py --verify fails the build when any file in the directory changed without a new manifest, or when PIN.json names a commit that has no changelog row. The changelog file is itself hashed, so touching it without the re-pin fails the same gate. Adding a vendored file that is not an ingest kind needs a changelog row but leaves the pinned SHA and the ingest contract unchanged.
The ingest schema's summaries block follows one more rule. It is a single optional object with five closed sub-objects (oversight, agents, qms, incidents, packs) made of leaf values only: integers, booleans, enumerations, SHA-256 hashes and dates matched by a pattern, with bounded string lengths and capped arrays. It has no free text and no open object. A guard test in the ingest service walks the schema definitions and fails if a later widening adds one. Nothing is added to the egress allowlist for it.
Compatibility promise¶
Needs founder review
This section describes what has been done so far. It is not yet a reviewed public commitment.
Observed practice, from the changelog's rows so far:
- Changes to a published schema have been additive: a new optional property, a wider enumeration, a new optional block.
additionalProperties: falsehas been kept, so a field the schema does not name is still rejected.- The required fields and the minimum length of
commit_refhave not changed. - A change that would remove or rename a field, make an optional field required, narrow a type, or open a closed object would be a new major version with a new
$id.
Because of the closed shape, a producer that writes a newer optional field to a dashboard still on an older pin is rejected. The changelog records a re-pin made for that reason.