Changing a standard type's encoding
Upgrading Jadpo never makes your stored data unreadable. A Jadpo release changes how a standard type is sent, stored or written as text only together with a reader for the old form and a release note. A golden file per type, built from its examples, pins every form, so a change can't pass unnoticed.
A value outlives the release that wrote it wherever it is kept: in a column, in an event waiting to be delivered, in a passkey, in a signed session cookie. Each of those records which encoding wrote it. So a release that changes a form reads what an earlier release kept with that release's reader, and an upgrade never strands it.
The encodings each release writes, as its release notes list them:
| Encoding | Release | What it changed |
|---|---|---|
| 1 | 0.1.0 | The first: every standard type's forms as its golden file holds them |
- What a golden file pins. For each valid example of the type: its
canonical text (
nonefor a type with no single text form, or for a secret value), the JSON the route codec writes, and each storage column's value as it is written into a statement, which is the value the runtime binds. Above them it records each column's suffix, PostgreSQL type and comment. A secret value's JSON is the redaction the codec writes, and a secret value is storednever.FeatureandFeatureCollectionare read and written through a program whose properties are{ name }, as their examples' are, since their second type argument is always your app's own object. People's formats aren't pinned: CLDR's wording isn't an encoding, and no stored value holds it. - One encoding number for a whole release, currently 1, not one per type. A row or a token holds values of many types, so one number says which reader each needs. A golden file records the encoding that last changed it. A form whose type's file records an encoding at or past the release's can't be rewritten, so changing a form means raising the encoding, and the release notes' row for that encoding must name every type whose file it changed. A new type, or an example added or dropped, changes no form. A type dropped from the release keeps failing the test, since a release keeps reading every type it wrote.
- Where the encoding is recorded: in a signed part's payload (
enc); injadpo_outbox.encodingfor an event's payload, which a delivery reads it by; injadpo_batch_runs.encodingfor a batch run's saved values andkey:; and injadpo_passkeys.encodingfor a passkey, which is stored asWebAuthnCredential's contract JSON (Encodings in system tables). A sealed value keeps its own version byte, which says how it is sealed, not how what it holds is written. An idempotency key's stored response is the bytes that were sent, read back as they were, and holds no encoding. - What was kept before encodings were recorded is read as it was
written, by the reader it was kept with: a signed part without
enc, whose members are encoding 1's, and a passkey whoseencodingisNULL, whose count is a number or its digits. - An encoding this release doesn't know, a later release's, is never
guessed at. A signed part with one opens nothing and the record is
read, a passkey is refused, an event's delivery is parked and a batch
run ends
failed. - An entity's own columns record no encoding. A form that changes
their columns' types shows in the migration snapshot, so
jadpo checkasks for a migration. A form that changes what a column of the same type holds needs the release to provide the migration that rewrites stored values. No release has needed one yet.
Markdown for agents: /docs/standard-type-encodings.md.Built from Jadpo main at a707efb.