Markdown for LLMs
Arxo Change Protocol
The source Markdown for this article. Copy it into your assistant or download it as a text file.
# Arxo Change Protocol
The Arxo Change Protocol turns a change of the rules into an object: the
states before and after, the world the change applies to, the mode of
entry into force, and the dossier assembled from them. Where the
[Arxo Fact Protocol](https://github.com/arxohq/law/blob/master/docs/protocols/01-fact-protocol) and the
[Arxo Decision Protocol](https://github.com/arxohq/law/blob/master/docs/protocols/02-decision-protocol) answer what follows from
the rules for these facts, the Change Protocol answers what would change
if the rules changed.
## The change set
A [change-set](/protocols/schemas/change-set/) names one normative
change. Its load bearing parts are:
- the [`units`](/protocols/schemas/change-set/): one or more pairs of
states — `before` and `after` — each a dated edition of a package, a
draft model over it, or a release of a case package;
- the [`world`](/protocols/schemas/change-set/): the dependency closure
the change is read against, plus a `boundary` statement saying what the
world does not contain — anything outside the closure is outside the
dossier by construction;
- the [`intent`](/protocols/schemas/change-set/): the expected changes
stated before measuring, the protected goals and the protected scope;
- the [`commencement`](/protocols/schemas/change-set/): the mode of entry
into force;
- the [`producers`](/protocols/schemas/change-set/): the artifacts the
dossier is assembled from, each with the tool that made it, its path and
the hash of its bytes. The dossier builder reads them and never
re-executes anything.
A small change set — one package, two dated editions, one producer
artifact — looks like this:
<!-- schema: change-set -->
```json
{
"schemaVersion": "law.change-set/0.1",
"id": "urn:change:demo-parking-fine-2026",
"kind": "edition-change",
"title": {
"en": "City parking fines, 2025 edition against 2026 edition"
},
"legalStatus": "draft",
"units": [
{
"subject": "package",
"package": "demo.parking",
"before": {
"kind": "edition",
"label": "2025 edition",
"edition": "PARKING_2025",
"editionDate": "2025-01-01"
},
"after": {
"kind": "edition",
"label": "2026 edition",
"edition": "PARKING_2026",
"editionDate": "2026-01-01"
}
}
],
"world": {
"root": "demo.parking",
"closure": [
{
"name": "demo.parking",
"version": "1.0.0"
}
],
"boundary": "Only the city parking package; the national traffic rules it references are pinned and unchanged."
},
"producers": [
{
"tool": "scenarios",
"path": "analysis/scenarios.json",
"sha256": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"role": "end-to-end"
}
]
}
```
The `legalStatus` names the status of the after state, not of the model:
a draft is not law.
## The dossier
A [change-dossier](/protocols/schemas/change-dossier/) is the case for or
against the change, assembled from the producers' artifacts: what was
measured, which goals held, which objections were raised and answered,
which computations were re-run under the old program, and what remains
unverified. Its deterministic core carries its own hash, so a reader can
tell whether the dossier in front of them is the one the builder built.
Three invariants hold for every dossier. It proves only what is
formalized — the measure and the world boundary are printed always.
Statistics over a sample are not a legal answer for a case. And accepting
a scenario into the bank, objections included, gives it no legal force.