# 5. Versioning, Error Registry, and Extensibility ## 5.1 Versioning - The protocol version is carried in every operation: `"v": "omp/0.2"`. - The version string grammar is `omp/.` with decimal integers. - A verifier implementing `omp/0.2` MUST reject any other version value with `ERR_VERSION`. Pre-1.0, every minor version is a distinct wire dialect: 0.x makes no compatibility promises between minors (this is explicit so early implementations don't guess). - From `omp/1.0` onward the policy will be: same-major = forward-readable (unknown *optional* body members tolerated per the rules of that major), different-major = reject. That policy is recorded here for planning and is not in force for 0.2. - Mixed-version logs: a log MAY contain operations of multiple versions over its history (e.g. after an upgrade). Validation of each operation uses that operation's own `v`. An `omp/0.2`-only verifier defers nothing and rejects non-0.2 operations; a multi-version verifier applies each version's rules. References across versions are permitted; hashes and signatures are version-prefix-domain-separated (`01-…` §1.4) so there is no cross-version ambiguity about bytes. ## 5.2 Error and event registry Codes are stable strings; the conformance suite keys expected outcomes to them. Stages refer to the validation pipeline (`03-…` §3.2). | Code | Kind | Stage | Meaning | |---|---|---|---| | `ERR_ENCODING` | reject | 1 | Not UTF-8, not JSON, or nesting too deep. | | `ERR_CANONICAL` | reject | 2 | Valid JSON but not OMP-CJ canonical bytes (whitespace, unsorted members, non-minimal escapes, non-canonical or non-integer numbers, duplicate members). | | `ERR_VERSION` | reject | 3 | Missing/unsupported `v`. | | `ERR_SCHEMA` | reject | 4 | Structural violation: missing/unknown members, wrong types, bad identifier grammar, bad enum value, malformed timestamp, unsorted/duplicate `caps`, bad base64url, duplicate `derived_from`/`deps`/`inputs` entries. | | `ERR_LIMIT` | reject | 5 | A size/cardinality limit exceeded (`01-…` §1.6). | | `ERR_RANGE` | reject | 6 | Numeric domain violation (`confidence_ppm`, `max_depth`, `seq`/`lc` ≥ 1, `size` ≥ 0). | | `ERR_SIG` | reject | 7 | Signature does not verify over the preimage against `author`. | | `ERR_CHAIN` | reject | 8 | `seq`/`prev` inconsistency: `seq`=1 with non-null `prev`, `seq`>1 with null `prev`, known `prev` with wrong author/log/seq. | | `ERR_CLOCK` | reject | 9 | `lc` not strictly greater than a known `prev`/`deps` ancestor's `lc`. | | `ERR_REF` | reject | 10 | A known referenced operation has the wrong type or wrong log; `inline_b64` hash/size mismatch; `subject` ≠ `log`; `target` = `replacement`; inference `grant` not a grant. | | `ERR_AUTHZ` | reject | 11 | Author lacked the required capability at the operation's causal position (`04-…` §4); genesis rule violation; scope/delegation-depth violation. | | `DEFER_MISSING_DEP` | defer | 8–11 | A referenced operation is unknown; park and retry on arrival. Not a failure. | | `WARN_EQUIVOCATION` | event | merge | Two distinct ops share `(log, author, seq)` (`03-…` §3.4). Both retained. | | `WARN_POST_REVOCATION_CONCURRENT` | event | merge | An accepted op is concurrent with the revocation of its authorizing grant (`04-…` §4.6.3). | Implementations MAY define additional diagnostic detail but MUST report one of these codes as the primary verdict, and MUST report the first-failing-stage code when multiple stages would fail. ## 5.3 Extensibility 1. **Extension members:** any object (envelope or body, any depth) MAY carry members matching `^x_[a-z0-9_]+$`. They are signed (part of canonical bytes), MUST round-trip byte-exactly through any conforming store-and-forward, MUST obey OMP-CJ value rules (no floats, depth/size limits), and MUST NOT change the meaning of standard members. Verifiers MUST accept and preserve them and MUST NOT base validation verdicts on them. 2. **Extension sources:** `evidence-ingest.source` values matching `^x-[a-z0-9-]+$`. 3. **Predicates:** the predicate namespace is open except that `omp.*` is reserved for the core ontology shipped with the derivation engine milestone. Implementations SHOULD namespace their predicates by reverse-DNS-style prefixes (`com_example.foo` style is discouraged; use `example.foo`). 4. **What is NOT extensible in 0.2:** operation types (exactly seven; an unknown `type` is `ERR_SCHEMA`), capability names, hash/signature suites, the envelope member set. Each of these widens only via a version bump. This is a deliberate interop guarantee: a 0.2 verifier can fully validate any 0.2 log with zero out-of-band knowledge. ## 5.4 Canonicalization stability guarantee The tuple (OMP-CJ rules, domain prefix `omp/0.2:op\n`, SHA-256, Ed25519) is frozen for `omp/0.2`. Any change to any element of that tuple requires a new version string, which changes the domain prefix, which prevents cross-version signature confusion by construction.