# Assertion Envelope — Specification v1.2 **Status**: stable. Declared v1.0 upon the first real federated exchange between two distinct jurisdictions — openathle → Prismagram, endorsed 2026-09-08 — the trigger `OPENING.md` names. Versioned under the compatibility policy below, never by ADR status (ADR-061 §3.3 as amended by A1: the contract is published, versioned and deprecated — it is not proposed or endorsed). **Mandated by**: ADR-061 §10.2. The ten-field sketch of ADR-061 §3.3 is the documented origin of this text and is not normative. Where they differ, this specification prevails. **Normative language**: English. A French companion may exist; it is not normative. The key words MUST, MUST NOT, SHOULD and MAY are to be read as in RFC 2119. --- ## 1. Purpose The envelope is the single exchange format for assertions between jurisdictions. A jurisdiction is an authority that asserts — a project, a platform, an organisation; the topology is fractal and the roles are relative. The envelope carries what a jurisdiction states, with its provenance and its confidence, so that another jurisdiction can reference, annotate and aggregate it — never amend it. One design intent governs every rule below: **divergence is exposed, not reconciled**. A message that cannot be fully understood is preserved, not rejected; a disagreement between jurisdictions becomes a `conflict` assertion, not an overwrite. ## 2. Intangible invariants No future version of this contract, major versions included, may: 1. rewrite an assertion's identity in transit; 2. alter an assertion's provenance or confidence in transit; 3. introduce any cross-jurisdiction overwrite or amendment operation; 4. abandon the append-only character of exchanges. These four derive from ADR-061 §3.2 and §2.2. They are constitutive of the federation and are not negotiable by this contract. A version that violated them would not be a new version of the envelope; it would be a different product. ## 3. Message An envelope message is a single assertion, encoded as a JSON object or an equivalent YAML mapping, validating against `schema/assertion.schema.json`. ```yaml envelope: "1.0" id: openathle/PU-001 class: traversal subject: "Renouvellement de licence athlète, saison N+1" statement: "Permettre à un athlète de reconduire sa licence sans ressaisir son dossier." evidence: - kind: source ref: "docs/parcours/PU-001-renouvellement-licence.md" provenance: imported confidence: 0.4 endorsement: null jurisdiction: openathle at: "2026-09-04T00:00:00Z" lifecycle: proposed relations: depends_on: [openathle/ADR-025, openathle/ADR-014] deadline: null falsification: null ``` ## 4. Fields Fifteen fields. Eleven are required; `endorsement`, `deadline`, `falsification` are required but nullable; `relations` and `evidence` may be empty. Producers MUST NOT add fields outside this table except extension fields (§7). | # | Field | Type | Constraint | |---|---|---|---| | 1 | `envelope` | string | REQUIRED. The version of this contract, e.g. `"1.0"`. A message that does not declare its version is not versioned — it is only dated by its documents (A1 §3). SHOULD be the first key | | 2 | `id` | string | REQUIRED. `/`. The prefix names the asserting authority. Never rewritten in transit (§2.1) | | 3 | `class` | string | REQUIRED. One of §5 | | 4 | `subject` | string | REQUIRED. What the assertion is about | | 5 | `statement` | string | REQUIRED. What is asserted, in one sentence or few | | 6 | `evidence` | list of `{kind, ref}` | REQUIRED, MAY be empty. A conflict without evidence asks to be believed; evidence names where the fact lives | | 7 | `provenance` | string | REQUIRED. One of §6. Transported verbatim (§2.2) | | 8 | `confidence` | number | REQUIRED. `0.0`–`1.0`. Transported verbatim. Interpretation policies — decay, half-life, thresholds — are consumer-local readings and MUST NOT modify the transported value. A consumer that *exposes* such a reading declares it (field 15, §4.1) | | 9 | `endorsement` | object or null | REQUIRED. `{by, at, rite}`; `rite` is one of `pr_approval`, `ui`, `batch`. `null` means: no human has endorsed this — which is a fact, not a defect | | 10 | `jurisdiction` | string | REQUIRED. MUST equal the prefix of `id`. Lowercase ASCII, no separators | | 11 | `at` | string | REQUIRED. RFC 3339 timestamp of the asserted state | | 12 | `lifecycle` | string | REQUIRED. One of `proposed`, `endorsed`, `superseded`, `rejected`, `under_revision` | | 13 | `relations` | object | REQUIRED, MAY be empty. Keys among `amends`, `supersedes`, `depends_on`, `satellite_of`, `confirms` (v1.2); values are lists of prefixed ids | | 14 | `deadline` | string or null | REQUIRED. RFC 3339. When a falsifiable statement expires into a verdict | | 15 | `falsification` | string or null | REQUIRED. What observation would make this assertion false. A hypothesis without one is not a hypothesis | `lifecycle` states what the *origin* jurisdiction declares about its own assertion; `endorsement` records the proven event. The two are irreducible: a declared status is not an approval (ADR-070 §3.2). ### 4.1 Declared readings (v1.1) | # | Field | Type | Rule | |---|---|---|---| | 15 | `confidence_reading` | object | OPTIONAL. Present only when the sender exposes a value it has itself derived from `confidence`. Keys: `policy` (string, the reading's name), `version` (string), `value` (number `0.0`–`1.0`), `as_of` (RFC 3339 timestamp). All four REQUIRED when the object is present | A decayed confidence is a reading, not a fact. Two auditors applying two decay functions to the same verbatim value, on two dates, would disagree without either being wrong — and neither could say why. This field makes the reading quotable: the verbatim value stays in field 8, the reading stands beside it, named, versioned and dated. It is OPTIONAL because a consumer that never exposes a derived value never owes one; it is not optional for those who do (§9). ### 4.2 `confirms` — the measure names what it examined (v1.2) A `measure` assertion MAY carry `relations.confirms`: the prefixed ids of the assertions it examined. The direction is deliberate and it is the whole point: **the measure declares what it confirms; the confirmed assertion is never edited to point back.** Three reasons, each sufficient. The confirmed assertion already exists and is append-only. The instrument already knows what it measured — the link is inferred, never typed. And the author of a confirmation is the machine that measured, not the agent whose claim is being confirmed: a producer MUST NOT emit `confirms` on anything but a `measure` of provenance `measured`. A consumer MAY derive, from `confirms`, which assertions have been examined and when — and MAY treat an assertion that no measure has ever confirmed differently from one that has. That reading is consumer-local (§4.1). ## 5. Classes `invariant`, `step_realized`, `transition`, `traversal`, `stressor`, `decision`, `constraint`, `measure`, `conflict`, `hypothesis`. Internal cardinality rules of any jurisdiction do not bind this contract (A1 §2.6, decision 4). Adding a class is a MINOR change under §8, because of the consumer tolerance rule: a consumer that meets an unknown class MUST treat the message as opaque-but-preserved, MUST NOT reject it, and MUST NOT interpret its body. ## 6. Provenances `human`, `agent:`, `inferred`, `measured`, `imported`. Axes never mix: `inferred` is a provenance, not a class. `imported` marks what crossed a jurisdiction boundary: the importer is not the author, and importing never upgrades confidence. ## 7. Extensions A jurisdiction MAY attach fields named `x__`. Consumers MUST preserve them on relay and MAY ignore them. Promotion of an extension to a standard field is a contract change under §8. ## 8. Compatibility policy - Versioning is `MAJOR.MINOR`. MINOR: additions (fields, classes, relation kinds, rites) that consumers can ignore or treat as opaque. MAJOR: removal, renaming, or semantic change of anything existing. - **v1.0 is substantively identical to v0.1**: no field, class, provenance, rite or rule changed — the draft survived its first real exchange and is declared stable, nothing more. Consumers MUST treat `envelope: "0.1"` messages as v1.0 messages; the schema accepts both values. This equivalence is specific to this pair and will not be repeated across future MAJORs. - **v1.1 adds field 15 `confidence_reading`** (§4.1) and the consumer rule that governs it (§9). Additive and ignorable: a v1.0 consumer that meets the field preserves it and moves on, exactly as §8 requires of any unknown field. No existing field, class, provenance or rule changed. - **v1.2 adds the relation kind `confirms`** (§4.2), carried by measures only. Additive and ignorable: a consumer that does not know the kind preserves it as any unknown key of `relations` and moves on. - At most **two published versions per year**. Deprecation is announced in this file at least one version before removal. - Consumers MUST accept any message whose `envelope` shares their MAJOR and declares an equal or lower MINOR, and SHOULD accept a higher MINOR by ignoring what they do not know. - Unknown fields: preserved on relay, never silently dropped, never a reason to reject. - The `envelope` field itself is the last change that was free to make; from v0.1 onward its removal or renaming is a contract-breaking impossibility (§2 does not list it, but §8 does: it is how every other promise is checked). ## 9. Conformance Two profiles. The test set in `conformance/` is normative: an implementation that fails it does not conform, whatever its documentation says. **Producer** — MUST emit messages that validate against the schema; MUST prefix `id` with its own jurisdiction and set `jurisdiction` to that prefix; MUST NOT emit an endorsement it did not witness as a dated event; MUST NOT emit `measured` provenance for anything a machine did not measure. **Consumer** — MUST NOT mutate `id`, `provenance` or `confidence` of a received assertion; MUST, when it presents or relays a confidence value it has derived from the transported one, carry the verbatim value unchanged **and** declare the applied reading in `confidence_reading` (§4.1) — an undeclared derived value is not conformant, because nobody can reproduce it; MUST NOT reject messages carrying unknown classes or unknown fields (preserve, expose, move on); MUST record received assertions append-only; MAY annotate, reference and aggregate received assertions under its own identity, and MUST NOT present the result as the origin's. ## 10. What this contract does not do It does not say how assertions are stored, projected, displayed or decayed — those are jurisdiction-local. It says only that a decay, once shown, names itself (§4.1): the contract governs what is claimed, never how it is computed. It does not transport source documents: sealing and encrypting source payloads is storage, not exchange. It does not decide who is right: it keeps both parties quotable, at their own risk.