# Versioning

> How the Weald Protocol is allowed to change: three change classes, a mechanical test for what breaks an implementation, and the notice a break carries.

Source: https://getweald.com/docs/protocol/versioning
Last modified: 2026-08-04

---

## How it changes

Last updated 2026-08-04

Weald Protocol governance defines three change classes and a mechanical test for whether a change breaks an existing implementation. Breaking changes take a version, carry a thirty day public comment period, and are announced before they ship. The document is honest about being maintained by one person and names the trigger to replace that arrangement.

## The three classes

*How a change is classified*

| Class | Test | What it costs |
| --- | --- | --- |
| Editorial | No conforming implementation behaves differently | Nothing. Ships when written |
| Compatible | An old implementation still interoperates with a new one | A release note |
| Breaking | An old implementation stops interoperating | A version, thirty days notice, and an announcement |

The test is mechanical rather than a judgement call, which stops a breaking change being reclassified as a compatible one by whoever is in a hurry.

## What counts as breaking

Four things, and the list is short on purpose: changing the pinned ciphersuite, removing a field a conforming implementation reads, tightening a validation rule so that previously accepted frames are refused, and changing the meaning of an existing error code.

Adding an optional field, adding an error code, and relaxing a rule are compatible. Renaming anything is breaking, even when the bytes are identical, because a name is part of the contract an implementer coded against.

## Deprecation

A ciphersuite change carries a five stage calendar over eighteen months, with two named emergency exceptions. An emergency exception is a real cryptographic break, and it is named in the document rather than left to discretion.

Nothing is removed without having first been deprecated for the length of that calendar.

## Version negotiation

A client offers its maximum version in its connect frame; its minimum is a build constant on both sides. The relay selects the lower of the two ceilings and states the selection, and a selection outside the client's own range aborts the connection rather than continuing. The selection is signed into the challenge the client answers, so a downgrade breaks the signature rather than the connection.

Version 4 is current, and version 1 is still served.

## Version 1 against version 2

*What version 2 adds*

| Change | Class |
| --- | --- |
| The LIVE frame, tag 21, for presence and typing | Compatible |
| The KEYS frame, tag 22, for MLS key packages | Compatible |
| Kind 0x0022 dm.welcome | Compatible |
| Kind 0x00F0 ephemeral retired to reserved, unused | Editorial: it was never implemented |
| Nothing about the envelope |  |

Every row is compatible under the mechanical test above, so a version 1 client keeps working against a version 2 relay. It is not sent a frame it does not know: the relay filters the two new frames on the negotiated version, which matters because an unknown tag is a decode failure and a closed socket rather than something a client can ignore.

A version 2 client against a version 1 relay learns the selection from the acknowledgement and reports presence and private messaging as unavailable. Unavailable is a different statement from everybody being offline, and it is the one the client makes.

## Who maintains it

One person, and the document says so. It also names the trigger for changing that: a second independent implementation, at which point the change process stops being a policy one party can revise.

Anyone deciding whether to build against this needs to know how many people can change it out from under them.

## The document

Governance, the change classes and the comment period are published in the conformance document set.
