§6 Looking ahead — 1.0.x → 1.1
Status: 1.1 is a DRAFT. standards/ver/1.1-draft/ is unratified. All five of its ADRs are now Accepted (23 August 2026 owner review) and the standards track has no open decisions — but ratification is gated on ten blocking deliverable and evidence rows in that directory's RELEASE.md, none of which exists yet. Do not implement against it for production. This section exists so that the shape of the migration is known in advance.
6.1 The rules that will govern it
- A 1.0 Record stays valid under 1.0.x forever and needs no edit. Nothing in 1.1 re-grades a published Record, there is no flag day, and there is no forced re-ingest. What changed at the owner review is what happens when you choose to migrate.
- Migrating to 1.1 is a real migration, not a version bump. An earlier revision of the draft promised that a 1.0.1-valid Record needed exactly two edits — declare
"1.1", statedim/dtype— because its schema was a superset of 1.0.1 for every shared structure. That promise is withdrawn. It was paid for by leaving the standard's own machine-checkable rules out of the schema, and the owner review reversed the trade: every rule JSON Schema can express is now expressed.
Draft §12.1 is the enumeration — fourteen rows, each with the validator failure pointer it produces — and it is measured, not asserted. Measured against this repository: the 1.0.1 golden example needs two of the fourteen (three failure pointers: /ver_version and one per reference block), and across the ten conformance/valid/ fixtures only three more rows are reached, in two fixtures. The likely shape of your own migration is small — but it is not zero, and it is not two edits.
ver_versionmoves to"1.1"only when you use a 1.1 field. Emitting"1.1"on a Record that uses nothing new gains you nothing and costs you every 1.0 consumer, which will decline it. Emitting"1.0"on a Record that does use a 1.1 field is worse: it invites a 1.0 consumer to parse a document whose shape it does not know.cpnp_versiondoes not move. CPNP-1 is unchanged across the whole of VER 1.x. Everypixel_hashyou have computed stays valid and stays comparable. Any change to CPNP is CPNP-2 and therefore VER 2.0, with a dual-publish migration window.- The edits most likely to bite you, in the order they will:
- Every
referenceblock needsset_manifest_sha256. This is the one edit every 1.0.1-valid Record in this repository needs. A tolerance claim bound only to a URI is a claim about whatever that URI serves today, so 1.1 requires the digest of the reference-set manifest. You will need to publish that manifest, which is why it is also a blocking ratification deliverable. embedding.dimanddtypebecome REQUIRED (ADR-0008). The 1.0 profile warns today (VER606), so this one is free if you act now.- **A
binaryspace must declaremetric: "hamming",normalization: "none", andtolerance_hamming_max** instead of a cosine tolerance, and a binary embedding may not use the inlinevectorarray. If you have abinaryspace today it almost certainly declaresmetric: "cosine", which was legal and unusable. - **
redactions[].salted_sha256becomescommitment_sha256+commitment_alg+ a requiredstate, with a new preimage.** Recompute from the salt; see §5's warning about keeping salts. - A float space's
tolerance_cosinemust be ≥ 0.99, and every integrity-relevant URI must carry its digest (descriptor_uri⇒descriptor_sha256,recipe_uri⇒recipe_sha256,checkpoint_uri⇒revision). - **A metadata family occupying more than one
raw[]entry must carryindexon each.** - Seven objects are closed, so an undeclared member inside
identity.content_hash/pixel_hash,model,reference, a space'sprovenance,metadata.trust[],conflicts[].values[]orembeddings[].recipeis now rejected. Put deployment data inextensions(1.1 §13), which exists for exactly this.
- Every
- **Three rules still narrow at the conformance level rather than the schema level**, and the reasons are now stated per rule (1.1 §15.4): the size limits (1.1 §7 — serialized record ≤ 10 MiB, decoded inline raw ≤ 6 MiB, decoded single vector ≤ 6 MiB — which no JSON Schema keyword can express portably; the earlier draft's 16 MiB decoded-raw figure was unreachable inside a 10 MiB document and is corrected),
space_iduniqueness (1.1 §11.4 — inexpressible, soVER401enforces it for the life of VER 1.x), and per-kindpreprocessingcompleteness (VER405, deliberately a warning). An oversized 1.0 Record is 1.1-non-conformant, not 1.1-schema-invalid. The size numbers are unratified and no corpus supports them yet. If your Records run large, say so during ratification — that is what the evidence row is for.
6.2 Producer preparation you can do today
None of this requires 1.1, and all of it makes the eventual move trivial:
- Emit
embedding.dimanddtypeon every embedding, equal to the descriptor's. ClearsVER606now and satisfies ADR-0008 later. - Stop minting
space_ids under authorities you do not control. 1.1 §11.3 addsdescriptor_sha256binding and §2.2 drafts a registry mechanism (the registry document itself is a ratification item); both assume the authority label means something. - Publish a
referenceblock —set_uriandtolerance_cosine— and state the preprocessing your space actually uses, for every space you ask anyone to trust. Together those are what E13 means by a "full space descriptor": the complete §6.1 field set, which for a visual space isresize,interpolation,antialias,crop,mean,std,channel_order, and for a text space istokenizer,tokenizer_sha256,max_length,truncation,casing. ClearsVER404andVER405. - Keep your weights reproducible, and keep the file list. ADR-0007 does not redefine
weights_sha256— that field keeps annex E29's reading in every release of VER: SHA-256 over an artifact you choose, comparable only within your own output, and you SHOULD document which artifact it was. The reproducible cross-producer pin is the newmodel.bundle.manifest_sha256: SHA-256 of the RFC 8785 JCS canonicalization of `{files: [{path, byte_length, sha256}]}pre-sorted by path, underbundle_digest_alg: "ver-bundle-manifest/1"`. What you have to do today is retain the list of files your forward pass actually reads — a pipeline that loads a model through a framework cache API often does not know, which is exactly how the reference implementation ended up hashing whatever it found (SC-01,SC-02,SC-03). - Pin a checkpoint revision. If your checkpoint is remotely resolvable, 1.1 requires
model.revisionbesidemodel.checkpoint_uri. A mutable branch name means onespace_iddenotes different weights over time, which violates §6.2 immutability today, not in 1.1 (SC-05). - Keep every redaction salt you have ever used. The 1.1 commitment is not a rename of
salted_sha256; its preimage is different, so the digest must be recomputed from the salt and the value. A discarded salt is a redaction entry that can never be migrated. See §5. - Record your compute environment somewhere you can retrieve it. 1.1 §9's per-embedding
computeblock wants `{runtime, runtime_version, precision, device_class}`, and reconstructing it after the fact is guesswork. - Do not invent extension fields. The record root is closed and stays closed; 1.1 §13 adds a single namespaced
extensionsobject. Vendor fields scattered through closed objects are exactly what that section exists to prevent.
6.3 Consumer preparation
- Version-gate before parsing. Read
ver_versionfirst. A 1.0 consumer meeting"1.1"should decline or quarantine, not attempt a partial parse. - Do not equate unknown with invalid on open value spaces. 1.1 opens
provenance.chain[].action(and later perceptual algorithms, source classes, and segment families) to a registry. A consumer meeting an unregistered action must treat it as opaque and keep the Record, not reject it. This is the behaviour ADR-0004 depends on, and it is worth implementing before 1.1 ships. - Do not read
unverifiableasvalid. 1.1 §6 addsc2pa.status: "unverifiable"for the case where validation could not be performed. It is not a pass. This is the single most likely 1.1 misread, and it is precisely why the value isver_version-gated instead of back-published into 1.0. Branch on the machine-readablereason, never onerror_detail, which is optional and non-normative. - Do not read a redaction commitment as proof that a value existed. It binds the producer to a value no later than signing time; it says nothing about what was in the Asset. Verifying one requires the salt, and the protocol for disclosing a salt to an authorized challenger is explicitly **out of scope for VER 1.1** — if you need it, you need something this standard does not supply (1.1 §5.3).
- **Resolve a parent by
record_urior{producer_id, record_id}, never bypixel_hash.** Apixel_hashmatch is a candidate: distinct Assets that render to one Canonical Buffer share it by design (annex E27). Never use it as a join key, and never compare one acrosscpnp_versionvalues — which is why 1.1 carries the parent'spixel_hashas{value, cpnp_version}.
6.4 Wire-profile notes (VER-F)
The atproto lexicon org.verstandard.record is a projection of the Record onto a federation transport, with its own lifecycle. It is frozen alongside 1.0.0 at standards/ver/1.0.0/wire-profile/.
- The wire profile has no versioning or negotiation mechanism today (
WIRE-15): one unversioned NSID, no capability field. 1.1 §14.1's strategy is a hybrid: the collection NSID stays stable across VER 1.x;verVersionandcpnpVersionbecome REQUIRED on the wire and are the negotiation signal; identity- and security-critical structures stay closed; and extensibility is exactly one namespacedextmap that a consumer MUST ignore when it does not recognise a key. A new NSID is minted only for a breaking wire major, which does not affect the Record standard — a VER-F 2 lexicon still carries VER 1.x Records. - Propagate
verVersionandcpnpVersionfrom the Record being projected, never from a class default (WIRE-13,WIRE-14, annex N6). A defaultedcpnpVersionis an assertion about whichpixel_hashuniverse a digest belongs to, made by code that did not check. - The wire's
identity.width/heightare Canonical Buffer dimensions (annex E2,WIRE-33). Do not populate them from a pre-orientation source. - The wire profile is strictly weaker than the Record schema today (
WIRE-07): not one hash-bearing lexicon field carries a pattern or a length constraint. Until 1.1 §14.3 lands, **validate every arriving wire record yourself** before letting any field reach a filesystem path, a database key, or a decoder. The one exploitable instance of this — an unvalidatedpixelSha256interpolated into a path — is fixed in this branch (WIRE-06), but the class is open. - A wire record is not a conformant VER Record (
WIRE-25). It carries no Layer 2 content and no conformance level. Treat it as a discovery signal that points at a Record, not as the Record.
