§12 Embedding dim and dtype become REQUIRED (ADR-0008)
vector_b64 is documented as “dtype-tagged via the embedding's dtype field” while dtype is optional, and vector_ref names a byte_length with no rule relating it to dim × sizeof(dtype). A conformant 1.0 vector can therefore be literally undecodable by a consumer that has not resolved the space descriptor — and a consumer streaming records at volume routinely has not.
For a Record with
ver_version: "1.1",embeddings[].dimandembeddings[].dtypeare REQUIRED. Their values MUST equal the referenced descriptor'sdimanddtype(VER601,VER602— a cross-object rule the schema cannot carry).
It applies to 1.1 Records only; 1.0 Records keep E24's inheritance rule (absent members inherit from the descriptor and MUST NOT contradict it). Records that would have to be rewritten are records that were already ambiguous. The gate is the Record's declared ver_version, and in a schema whose ver_version is const: "1.1" a flat required entry is the gated form: the const already partitions the document set, so an if/then on a sibling property would test a condition that is true of every instance the schema can accept (ADR-0008, VERSIONING.md §2.2). A multi-version schema would need the conditional; this one does not.
12.1 What a 1.0.1-valid Record must change
This is the migration, enumerated. Every row is a real edit; the failure pointer column is what jsonschema emits when a 1.0.1-valid Record is validated against ver-record.schema.json in this directory, so the list is empirical rather than asserted. RELEASE.md § "Verification" carries the command that reproduces it.
| # | Edit | Failure pointer when it is not made | Why |
|---|---|---|---|
| 1 | ver_version → "1.1" | /ver_version (const) | The version gate (§1) |
| 2 | State dim and dtype on every embedding | /embeddings/N/dim, /embeddings/N/dtype (required) | §12, ADR-0008 |
| 3 | Add set_manifest_sha256 to every reference block | /spaces/N/reference (required) | §8.2, §15.3 — a tolerance claim must name the set it was measured on |
| 4 | Add descriptor_sha256 wherever descriptor_uri is present | /spaces/N (required) | §11.3, §15.3 |
| 5 | Add recipe_sha256 wherever recipe_uri is present | /lineage (required) | §3.3, §15.3 — 1.1-only structure, so no 1.0.1 Record is affected |
| 6 | A binary space: set metric to hamming, normalization to none, replace tolerance_cosine* with tolerance_hamming_max | /spaces/N/metric (const), /spaces/N/normalization (const), /spaces/N/reference (required and not) | §11.2 |
| 7 | A float space whose tolerance_cosine is below 0.99: raise it, or withdraw the conformance claim | /spaces/N/reference/tolerance_cosine (minimum) | §8.2 |
| 8 | A binary embedding carrying an inline vector: re-carry as vector_b64 or vector_ref | /embeddings/N (not) | §11.2 |
| 9 | A family occupying more than one raw[] entry: add index to each | /metadata/raw/N (required) | §10.1 |
| 10 | Rename redactions[].salted_sha256 → commitment_sha256, add commitment_alg and state, recomputing the digest under §5.3 | /metadata/redactions/N (required and additionalProperties) | §5.2 — the preimage changed, so the value changes; a renamed member carrying the old digest would be a false commitment |
| 11 | Same rename inside every redacted-value object in metadata.normalized | /metadata/normalized/<key> (additionalProperties) | §5.2 |
| 12 | Remove any undeclared member from identity.content_hash/pixel_hash, model, reference, the space's provenance, metadata.trust[], conflicts[].values[], embeddings[].recipe | … (additionalProperties) | §15.2 — the seven objects closed at 1.1 |
| 13 | Add provenance.registry if the chain carries a bare action token outside §2.3's sixteen | /provenance (required) | §2.2 condition 2 — unreachable for a 1.0.1 Record, whose action enum is the core six |
| 14 | Add provenance.signature if the chain carries a sign event | /provenance (required) | §2.3.3 — likewise 1.1-only |
Measured against the artifacts in this repository. The 1.0.1 golden example (standards/ver/1.0.1/example-record.json) needs rows 1 and 3 only, and fails on exactly three pointers: /ver_version, /spaces/0/reference, /spaces/1/reference. Across the ten fixtures in conformance/valid/, rows 1 and 3 account for every failure in eight of them; two fixtures reach three further rows between them — binary-dtype.json trips row 6 (/spaces/0/metric, and two more errors on /spaces/0/reference) and redacted-with-proof.json trips rows 10 and 11 (two errors on /metadata/redactions/0, one on /metadata/normalized/Iptc4xmpExt:PersonInImage). Five of the fourteen rows are reached by that corpus; nine — rows 2, 4, 5, 7, 8, 9, 12, 13 and 14 — are reached by nothing in it. That says as much about the corpus as about the migration, and is one reason ratification requires 1.1 fixtures of its own (RELEASE.md).
12.2 Tightenings, and where each is enforced
Every row below is a tightening in the sense COMPATIBILITY.md §6 uses: a Record that was 1.0-valid can be 1.1-invalid or 1.1-non-conformant. None applies retroactively — a 1.0 Record is judged by 1.0.
| Tightening | Where | Enforced by |
|---|---|---|
dim/dtype REQUIRED for 1.1 Records | §12 | Schema — flat required, gated by ver_version: const "1.1" |
binary: metric = hamming, normalization = none, no inline vector, and the converse on hamming | §11.2 | Schema |
binary reference claims: tolerance_hamming_max required, cosine tolerances forbidden | §11.2, §8.2 | Schema |
tolerance_cosine ≥ 0.99 for float spaces, and required for float and int8 | §8.2 | Schema |
index REQUIRED when a family occupies > 1 segment | §10.1 | Schema |
set_manifest_sha256 REQUIRED in reference | §8.2 | Schema |
descriptor_uri ⇒ descriptor_sha256; recipe_uri ⇒ recipe_sha256; checkpoint_uri ⇒ revision | §15.3 | Schema |
Redaction: state required, commitment required for producer_performed, forbidden for upstream_withheld | §5.2 | Schema |
sign ⇒ provenance.signature; unregistered bare token ⇒ provenance.registry | §2.3.3, §2.2 | Schema |
| Seven objects closed | §15.2 | Schema |
| Record / raw-bytes / inline-vector size limits | §7 | Profile (VER104) — not portably encodable (§15.4) |
space_id unique within spaces[] | §11.4 | Profile (VER401) — inexpressible (§15.4) |
| Fusion recipe is part of a fused space's identity | §11.5 | Profile — a cross-Record rule (§15.4) |
dim/dtype equal the descriptor's | §12 | Profile (VER601, VER602) — cross-object (§15.4) |
Vector byte length matches dim × sizeof(dtype) | §11.2 | Profile (VER603–VER605) — cross-member (§15.4) |
Not counted here: §2.3's prohibition on recording a geometric or tonal edit as transcode. That names a misdeclaration which was already a misdeclaration under 1.0's definition of transcode and was merely undetectable, so no Record changes conformance status by it.
