Where
docs/src/content/docs/reference/version-policy.mdx:38-42 (and its German mirror),
against CHANGELOG.md:540-591 (0.12.2) and CHANGELOG.md:593-604 (0.12.1).
What is wrong
The published policy promises that a patch release carries no breaking change:
docs/src/content/docs/reference/version-policy.mdx:36-42
## Versioning until 1.0
Pre-1.0:
- **Patch versions (0.x.Y)** — bug fixes, no breaking changes.
- **Minor versions (0.X.0)** — new features, may include
breaking changes.
The project has cut three patch releases — 0.9.1, 0.12.1 and 0.12.2. Two of the three
carry an explicit BREAKING marker in the CHANGELOG, both of them in the current minor
line.
0.12.1 broke a constructor:
CHANGELOG.md:593-600
## [0.12.1] — 2026-08-03
### Changed
- **BREAKING — `ReplicatedEventSourcedActor` no longer takes a `Cluster`, and
`replicaId` now has a default** (#833). Both existed only because the actor
could not reach its own cluster; now that it can, they are boilerplate every
subclass was copying:
0.12.2 changed the stored payload encoding on every backend, and the entry states the
forward-incompatibility itself:
CHANGELOG.md:540-561
## [0.12.2] — 2026-08-04
### Fixed
- **BREAKING — persistence stores no longer silently corrupt rich payload
types** (#888). Every journal, snapshot store and durable-state store wrote
payloads with bare `JSON.stringify`, so a persisted `Set`/`Map` recovered as
`{}`, a `Date` as a string, a `Uint8Array` as an index-keyed object, and a
`bigint` threw — and because the write path folds the original object, the
corruption only surfaced on the next recovery. Payloads now use the tagged
JSON tree format `JsonSerializer` already used (`__date__`, `__bytes__`,
`__map__`, `__set__`, `__bigint__`, plus a new `__literal__` escape so user
data shaped like a tag round-trips as data), on every backend.
**Migration:** none for readers — rows written by older versions decode
unchanged. Rows written from this version on carry tag objects where plain
JSON would corrupt the value, so *older* framework versions (and
non-actor-ts JSON consumers) reading *new* rows see the tag shape instead of
a bare value.
The second is the sharper one for an operator. "Older framework versions reading new
rows see the tag shape instead of a bare value" is precisely the state a rolling deploy
occupies: while pods on 0.12.1 and 0.12.2 coexist, the old pods read rows the new pods
wrote. A change with that property arriving under a patch version arrives by default —
^0.12.0 and ~0.12.0 both resolve it without the operator choosing it.
Two further gaps follow from the same section, and are the reason this cannot be closed
by editing one bullet:
- No supported-versions statement. The policy says nothing about which lines receive
fixes. In practice there is no patch-only maintenance line: a security fix landing on
develop reaches a consumer only through the next release off develop, which — by
the project's own minor-version rule — may include breaking changes. So "take the
security fix" and "take an API break" are currently the same action.
## After 1.0 is the only place strictness is promised, which leaves the pre-1.0
reader with a rule the release history contradicts rather than an honest caveat.
Fix
Make the document describe what the project actually does, rather than tightening the
practice to match a rule the project has twice chosen not to follow — pre-1.0, a hard cut
is deliberate policy (AGENTS.md, Breaking changes), and that is fine as long as it is
stated:
- Reword the pre-1.0 patch bullet: a patch is bug fixes and does not add features,
but pre-1.0 it may carry a breaking fix when the alternative is leaving data
corruption in place. Link the two precedents by version so the claim is checkable.
- Add a Supported versions section — realistically "latest minor only, no
backports" — so a consumer pinning ~0.12.0 knows they are pinning to a line that
receives nothing.
- Add a one-line rolling-deploy caveat to the patch bullet pointing at
operations/upgrades/rolling-migration, since the 0.12.2 change is exactly the case
where reading the CHANGELOG before a patch bump is load-bearing.
- Mirror all of it into
docs/src/content/docs/de/reference/version-policy.mdx.
If the project would rather keep the strict rule, the equivalent fix is a documented
maintenance line — but that is a process commitment, not a docs edit, and should be
decided explicitly rather than implied by a bullet.
Acceptance sketch
Verification status
Confirmed by reading, and quantified: the CHANGELOG's three patch sections were
sliced by heading offset and the BREAKING marker counted per section — 0.9.1: 0,
0.12.1: 1, 0.12.2: 1. Both sides are quoted verbatim above. A grep for
support|security|maintenance|backport over version-policy.mdx returns nothing, which
is the basis for the "no supported-versions statement" half.
Not reproduced by execution — this is a policy contradiction between two documents, and
there is nothing to run.
Part of the production-readiness review batch — tracked in #913.
Where
docs/src/content/docs/reference/version-policy.mdx:38-42(and its German mirror),against
CHANGELOG.md:540-591(0.12.2) andCHANGELOG.md:593-604(0.12.1).What is wrong
The published policy promises that a patch release carries no breaking change:
The project has cut three patch releases — 0.9.1, 0.12.1 and 0.12.2. Two of the three
carry an explicit
BREAKINGmarker in the CHANGELOG, both of them in the current minorline.
0.12.1broke a constructor:0.12.2changed the stored payload encoding on every backend, and the entry states theforward-incompatibility itself:
The second is the sharper one for an operator. "Older framework versions reading new
rows see the tag shape instead of a bare value" is precisely the state a rolling deploy
occupies: while pods on 0.12.1 and 0.12.2 coexist, the old pods read rows the new pods
wrote. A change with that property arriving under a patch version arrives by default —
^0.12.0and~0.12.0both resolve it without the operator choosing it.Two further gaps follow from the same section, and are the reason this cannot be closed
by editing one bullet:
fixes. In practice there is no patch-only maintenance line: a security fix landing on
developreaches a consumer only through the next release offdevelop, which — bythe project's own minor-version rule — may include breaking changes. So "take the
security fix" and "take an API break" are currently the same action.
## After 1.0is the only place strictness is promised, which leaves the pre-1.0reader with a rule the release history contradicts rather than an honest caveat.
Fix
Make the document describe what the project actually does, rather than tightening the
practice to match a rule the project has twice chosen not to follow — pre-1.0, a hard cut
is deliberate policy (
AGENTS.md, Breaking changes), and that is fine as long as it isstated:
but pre-1.0 it may carry a breaking fix when the alternative is leaving data
corruption in place. Link the two precedents by version so the claim is checkable.
backports" — so a consumer pinning
~0.12.0knows they are pinning to a line thatreceives nothing.
operations/upgrades/rolling-migration, since the 0.12.2 change is exactly the casewhere reading the CHANGELOG before a patch bump is load-bearing.
docs/src/content/docs/de/reference/version-policy.mdx.If the project would rather keep the strict rule, the equivalent fix is a documented
maintenance line — but that is a process commitment, not a docs edit, and should be
decided explicitly rather than implied by a bullet.
Acceptance sketch
Verification status
Confirmed by reading, and quantified: the CHANGELOG's three patch sections were
sliced by heading offset and the
BREAKINGmarker counted per section —0.9.1: 0,0.12.1: 1,0.12.2: 1. Both sides are quoted verbatim above. A grep forsupport|security|maintenance|backportoverversion-policy.mdxreturns nothing, whichis the basis for the "no supported-versions statement" half.
Not reproduced by execution — this is a policy contradiction between two documents, and
there is nothing to run.
Part of the production-readiness review batch — tracked in #913.