0057 — Schema identifiers on GitHub Pages, the old ones kept as aliases¶
Status: accepted; the base moved to the sluis site by 0069 Date: 2026-09-30
Context¶
Every schema this project publishes names itself by $id: the record's
JSON Schema, the catalogue, framework profile and extension meta-schemas, and the
common catalogue's payload schemas. Those identifiers were under
https://schemas.truvity.com/audit/v1/, a name that was never served, and
that belongs to the publisher's organisation rather than to this
repository. An identifier that does not resolve makes the contract
unreadable to anyone outside, and one under a domain the project does not
control ties every archived record to it.
Two facts constrain the change. Archived catalogues and schemas are locked
for years and cannot be rewritten (0051:
decoders are kept for everything ever written), and they carry the old
identifiers, both as a schema's own $id and as the data_schema and
*_schema references in a catalogue document.
Decision¶
- The base is
https://truvity.github.io/audit/schemas/v1/. The record schema, the three meta-schemas and the common payload schemas (common/*.json) are generated or written under it, and the generator, the committed catalogue and the docs use it. - GitHub Pages serves those files at exactly those URLs.
.github/workflows/pages.yamldeploys them on a change to a schema;hack/pages-site.shassembles the site and fails when a file's$idis not the URL it would be served at, andjust checkruns it. - The old base is an alias.
catalogue.CanonicalIDmaps an id underhttps://schemas.truvity.com/audit/v1/onto the same path under the new base; the loader keys every schema by the canonical id and canonicalises every reference before looking it up. A catalogue and schemas from an archive, written entirely under the old identifiers, or a mixture of the two forms, load as before. Nothing is rewritten: an archived document is read and re-archived byte for byte, still saying what it said. - Only the exact legacy prefix is aliased. An adopter's own schemas keep whatever identifiers they chose.
- The alias is kept for as long as any archive written before this change can be read, which by 0051 is the retention period. It is removed only when no object under the old identifiers remains.
Consequences¶
- An
$idresolves, and a validator outside Go can fetch the schema by the name a record's catalogue gives it. - The site's URL depends on the repository's name and owner. Moving the repository moves the identifiers; that would be a new decision and another alias, not a silent change.
- The common catalogue stays at version
1.0.0. Only its identifiers change, not what any record under it means, and the version is stamped on every record the writer emits and used to find the catalogue that describes it: a bump would leave records already written under1.0.0pointing at a version no build carries. The bytes behind that version differ from before, but the alias makes the old and new forms the same catalogue to every reader here. A catalogue in the registry is unaffected: it is stored as the application registered it. - Pages must be enabled on the repository, a setting owned by whoever manages the repository's configuration.
Alternatives considered¶
- Keep the organisation domain and serve it. Needs a hosting arrangement outside this repository and ties the identifiers to it.
- Rewrite archived documents. Impossible under the lock, and it would change the bytes an auditor verifies.
- Keep the old identifiers forever and add a redirect. Leaves the unserved name as the canonical one, which is the fault being removed.