diff --git a/.releaserc.json b/.releaserc.json
index 5544cee6..ea5f06dc 100644
--- a/.releaserc.json
+++ b/.releaserc.json
@@ -5,7 +5,7 @@
["@semantic-release/commit-analyzer", {
"preset": "conventionalcommits",
"releaseRules": [
- { "breaking": true, "release": "minor" },
+ { "breaking": true, "release": "major" },
{ "type": "feat", "release": "minor" },
{ "type": "fix", "release": "patch" },
{ "type": "perf", "release": "patch" },
diff --git a/CLAUDE.md b/CLAUDE.md
index 2e84ad6f..e0f5a616 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -239,10 +239,12 @@ say so. Twice in one wave that phrasing turned an obvious fix into a wait.
## Versioning
-Until the `v1.3.0` tag, `docs/decisions/0001-versioning-and-api-stability.md` governs: breaking
-changes are allowed, they map to a **minor** bump, and no `[Obsolete]` shim is introduced to dodge
-one. `eng/verify-release-config.mjs` enforces both ends of that and fails the build if the rule
-and the changelog disagree.
+1.3.0 is out (`v1.3.0`), so the window that `docs/decisions/0001-versioning-and-api-stability.md`
+describes is closed and SemVer holds. A breaking change needs the `!` and a `BREAKING CHANGE:` footer in
+the commit message and publishes a **major** version: `.releaserc.json` maps `breaking` to `major`, and
+`eng/verify-release-config.mjs` fails the build if it maps to anything else. A deprecation is an
+`[Obsolete]` member that a later major removes. The decision record stays as the account of how 1.3.0
+came about.
## Upstream
diff --git a/GitVersion.yml b/GitVersion.yml
index 952c0981..28ab2a60 100644
--- a/GitVersion.yml
+++ b/GitVersion.yml
@@ -72,12 +72,12 @@ branches:
# artifact list reads exactly like one. With the label it is `1.2.4-ci.12` and says so, which
# is the whole of what this needs to fix.
#
- # Increment stays Patch. Raising it to Minor while the work heads for 1.3.0 would name CI
- # artifacts after the version they are heading for -- but `increment` is unconditional, so it
- # would go on producing 1.4.0-ci.N after 1.3.0 ships instead of 1.3.1-ci.N, and nothing would
- # restore it. One temporary override with a machine-enforced expiry (breaking -> minor, in
- # .releaserc.json) is a debt worth carrying; a second one, for nothing but the cosmetics of an
- # artifact name, is not.
+ # Increment stays Patch. Raising it to Minor while the work headed for 1.3.0 would have named CI
+ # artifacts after the version they were heading for -- but `increment` is unconditional, so it
+ # would have gone on producing 1.4.0-ci.N after 1.3.0 shipped instead of 1.3.1-ci.N, and nothing
+ # would restore it. The one temporary override this repository carried, with a machine-enforced
+ # expiry (breaking -> minor, in .releaserc.json), was worth its cost; a second one, for nothing
+ # but the cosmetics of an artifact name, was not.
label: ci
increment: Patch
pull-request:
diff --git a/README.md b/README.md
index e1f6b393..5275acf1 100644
--- a/README.md
+++ b/README.md
@@ -48,14 +48,11 @@ Everything targets `netstandard2.0` and `net10.0`.
## Status
-The 1.0.0 – 1.2.3 releases are **withdrawn from nuget.org**: they were published as stable before the API
-had been reviewed against the specifications. **1.3.0 will be the first release whose API is
-stable**, and the surface can still change until it is tagged — see
-[Versioning](docs/decisions/0001-versioning-and-api-stability.md) for what that window is for.
-
-Which means there is **nothing to install from nuget.org until 1.3.0 ships**: the `dotnet add
-package` lines below have no listed version to resolve, and a withdrawn release comes back only
-on an exact version pin. Build from source in the meantime.
+**1.3.0 is the first stable release.** From 1.3.0 on the public API follows SemVer: a breaking change costs a
+major version, and a deprecation is an `[Obsolete]` member that a later major removes. The 1.0.0 – 1.2.3
+releases were published as stable before the API had been reviewed against the specifications; they are
+unlisted and deprecated on nuget.org and should not be used. See
+[Versioning](docs/decisions/0001-versioning-and-api-stability.md) for how that came about.
## Install
diff --git a/docs/architecture/arc42-CanKit.Pro.md b/docs/architecture/arc42-CanKit.Pro.md
index 594cf4c9..874caa23 100644
--- a/docs/architecture/arc42-CanKit.Pro.md
+++ b/docs/architecture/arc42-CanKit.Pro.md
@@ -151,7 +151,7 @@ Zero-Copy) erhöhen den Aufwand für Q4 und für einen sicheren **Frame-Ownershi
## 2.2 Organisatorische Randbedingungen
- **OSS-Paket** (MIT, `LICENSE`), als NuGet-Pakete gemeinsam versioniert und veröffentlicht. Die
- Releases 1.0.0 – 1.2.3 sind zurückgezogen; 1.3.0 wird der erste Release mit stabiler API
+ Releases 1.0.0 – 1.2.3 sind zurückgezogen; 1.3.0 ist der erste Release mit stabiler API
(README § Status, `docs/decisions/0001-versioning-and-api-stability.md`).
- **Eine CI über die gesamte Solution** (`.github/workflows/ci.yml`; Trigger: Push auf `main`,
Pull Requests, `merge_group`). Die adapterweisen Pfadfilter und Solution-Filter der Erstfassung
diff --git a/docs/decisions/0001-versioning-and-api-stability.md b/docs/decisions/0001-versioning-and-api-stability.md
index 021ff2b5..6cb4a6fd 100644
--- a/docs/decisions/0001-versioning-and-api-stability.md
+++ b/docs/decisions/0001-versioning-and-api-stability.md
@@ -1,7 +1,7 @@
# Versioning: 1.3.0 is the first stable release
-**Status:** accepted, 2026-09-12. Resolves
-[#61](https://github.com/dborgards/CanKit.Pro/issues/61).
+**Status:** accepted, 2026-09-12; carried out with the release of 1.3.0 on 2026-09-30, see
+[Outcome](#outcome) at the end. Resolves [#61](https://github.com/dborgards/CanKit.Pro/issues/61).
## Context
@@ -183,3 +183,36 @@ versions.
Normal SemVer. A breaking change costs a major version; a deprecation is an `[Obsolete]` member
that a later major removes. The API approval tests are what make an accidental break visible in
the pull request that causes it.
+
+## Outcome
+
+Written on 2026-09-30, after the release; the text above is left as decided.
+
+1.3.0 was released on 2026-09-30: tag `v1.3.0`, all nine packages on nuget.org, and the changelog
+commit `chore(release): 1.3.0` on `main`.
+
+Against the checklist:
+
+1. Every `type: bug` issue was closed. The two issues open at the time, [#246](https://github.com/dborgards/CanKit.Pro/issues/246)
+ (documentation) and [#240](https://github.com/dborgards/CanKit.Pro/issues/240) (a test that failed
+ once on CI), are not of that type.
+2. [#52](https://github.com/dborgards/CanKit.Pro/issues/52) was closed with the normative negative tests.
+3. [#23](https://github.com/dborgards/CanKit.Pro/issues/23), [#37](https://github.com/dborgards/CanKit.Pro/issues/37),
+ [#44](https://github.com/dborgards/CanKit.Pro/issues/44) and [#82](https://github.com/dborgards/CanKit.Pro/issues/82)
+ had landed.
+4. The approval baselines were gone through for shapes that are hard to change later. That review was not
+ line by line, and it led to three further breaking changes before the tag: `SendConfirmed` became
+ `SendConfirmedAsync` ([#238](https://github.com/dborgards/CanKit.Pro/pull/238)), and `IProtocolActor.PostAsync`
+ ([#242](https://github.com/dborgards/CanKit.Pro/pull/242)) and `IIsoTpChannel.SettleAsync`
+ ([#244](https://github.com/dborgards/CanKit.Pro/pull/244)) gained a `CancellationToken`.
+ The maintainer took the surface as it then stood over as final by starting the release.
+5. Each package README states what is validated and what is not
+ ([#245](https://github.com/dborgards/CanKit.Pro/pull/245)).
+
+The pipeline dry run described above failed on its first attempt: the version-resolution step ran
+`git push --dry-run` against GitHub in a job that deliberately holds no credentials
+([#243](https://github.com/dborgards/CanKit.Pro/pull/243)). It passed after that fix, and 1.3.0 was cut from
+the commit it had passed on.
+
+The `breaking -> minor` override in `.releaserc.json` was reverted to `major` in the change that adds this
+section, together with the texts that described the window as open.
diff --git a/docs/index.md b/docs/index.md
index e9cfe408..057fdc81 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -34,12 +34,6 @@ designed once instead of improvised in every stack.
[](https://github.com/dborgards/CanKit.Pro/blob/main/LICENSE)
-!!! warning "Nothing to install from nuget.org right now"
-
- 1.0.0 – 1.2.3 are withdrawn, and 1.3.0 is not out yet, so the version badge above reads from
- a feed with no listed release and `dotnet add package` has nothing to resolve. Build from
- source until 1.3.0 ships. See [Versioning](decisions/0001-versioning-and-api-stability.md).
-
diff --git a/docs/packages/index.md b/docs/packages/index.md
index 254c0239..d2f9e83f 100644
--- a/docs/packages/index.md
+++ b/docs/packages/index.md
@@ -8,20 +8,13 @@ description: The nine CanKit.Pro packages, what layer each one lives on, and wha
Nine packages, one version number, released together to nuget.org. Take only the layers you need:
an ISO-TP application pulls in five of them, a plain demultiplexer one.
-!!! warning "1.0.0 – 1.2.3 are withdrawn"
+!!! note "1.0.0 – 1.2.3 are withdrawn"
These six versions were published as stable before the API had been reviewed against the
- specifications, and are unlisted and deprecated on nuget.org. **1.3.0 will be the first
- release whose API is stable**; until it is tagged, the public surface can still change. See
+ specifications, and are unlisted and deprecated on nuget.org. **1.3.0 is the first release
+ whose API is stable**; use it or later. See
[Versioning](../decisions/0001-versioning-and-api-stability.md).
- **So there is nothing to install from nuget.org right now.** The `dotnet add package` lines
- below have no listed version to resolve until 1.3.0 ships; a withdrawn release comes back
- only on an exact version pin, which is not recommended. Build from source in the meantime.
-
- The version badges in the tables below read from the nuget.org feed, so during this window
- they show a withdrawn version or nothing at all. They become meaningful again with 1.3.0.
-
Everything targets `netstandard2.0` and `net10.0`, so .NET Framework 4.6.2+, .NET 8 and .NET 10
all work. Every package depends on `CanKit.Abstractions` where it touches a bus and on nothing
vendor-specific anywhere.
diff --git a/docs/release-process.md b/docs/release-process.md
index 9a48c73e..025905ef 100644
--- a/docs/release-process.md
+++ b/docs/release-process.md
@@ -32,13 +32,13 @@ Conventional Commits since the last tag: a `fix` bumps the patch, a `feat` the m
`BREAKING CHANGE:` footer the major. It then writes the changelog, creates the tag, publishes the
GitHub Release and pushes the packages. It only runs on `main`.
-!!! note "Until 1.3.0, a breaking change bumps the minor"
+!!! note "Since 1.3.0, a breaking change bumps the major"
- `.releaserc.json` currently maps `breaking` to a **minor** release, so that the API
- corrections on the way to 1.3.0 cannot publish 2.0.0 by accident. This is temporary and is
- on the release checklist in
- [Versioning](decisions/0001-versioning-and-api-stability.md);
- `eng/verify-release-config.mjs` fails the build if the override outlives 1.3.0.
+ `.releaserc.json` maps `breaking` to **major** again. Until 1.3.0 it mapped to minor, so that the API
+ corrections before that release could not publish 2.0.0 by accident; how that came about is in
+ [Versioning](decisions/0001-versioning-and-api-stability.md).
+ `eng/verify-release-config.mjs` fails the build if the mapping is anything but major now that
+ 1.3.0 is in the changelog.
**GitVersion** answers *"what version is this commit?"* — for builds that are not releases. A
pull-request build or a CI artifact from `main` between releases gets a real, ordered SemVer
@@ -131,7 +131,7 @@ Each plugin runs in the order it appears in `.releaserc.json`, within each lifec
```
analyze → nothing to release? stop here
-verifyRelease → refuse a version below 1.3.0 while the ADR window is open (exec)
+verifyRelease → re-check the release configuration for the version about to go out (exec)
prepare → CHANGELOG.md regenerated (@semantic-release/changelog)
→ verify the nine packages `verify` packed (@semantic-release/exec, prepareCmd)
→ changelog committed and PUSHED to main (@semantic-release/git)
@@ -289,17 +289,14 @@ From the Actions tab: **Release → Run workflow**, leaving *dry run* checked. I
version, builds, tests and packs, and prints the release notes it would write — without tagging,
publishing, or requesting a NuGet credential.
-!!! warning "A dry run cannot succeed before 1.3.0"
+!!! note "A dry run has something to say only when a release is pending"
- The `verify` job refuses any version that is not 1.3.0 while the pre-1.3.0 window is open, and
- the commit analyser computes a patch version until a `feat` commit lands. So a dry run today
- stops at the version gate, having proved only that version resolution works.
-
- This is the gate doing its job, not a fault to route around: it refuses to release before the
- checklist in [Versioning](decisions/0001-versioning-and-api-stability.md) is done, and a dry
- run goes through the same gate as a real one on purpose. The first dry run that exercises the
- whole path is the one taken once the version reaches 1.3.0, and 1.3.0 should not be cut until
- that has been green.
+ The version is resolved from the commits since the last tag. If none of them releases (`docs:`,
+ `test:`, `chore:`, `ci:`, `refactor:`, `style:`), a dry run resolves no version and reports that there
+ is nothing to release. Build and test still run, but the Pack and Upload steps are skipped, because
+ they need a version: such a dry run does not exercise package creation. It resolves a version once a
+ commit of a releasing type has landed: `feat`, `fix`, `perf`, `revert`, `build(deps)`, or any breaking
+ commit.
Locally, the same analysis without a token, and without the workflow's gates:
diff --git a/src/CanKit.Pro.Actor/README.md b/src/CanKit.Pro.Actor/README.md
index 60254704..98ced2d7 100644
--- a/src/CanKit.Pro.Actor/README.md
+++ b/src/CanKit.Pro.Actor/README.md
@@ -5,11 +5,10 @@ Generic protocol-instance actor/scheduler for [CanKit](https://github.com/pkuyo/
layer (ISO-TP, J1939, CANopen, ...) can build on instead of hand-rolling locks, unsynchronized
`List`s, and busy-loop schedulers.
-Status: 1.0.0 – 1.2.3 are **withdrawn from nuget.org** — they were published as stable before
-the API had been reviewed. **1.3.0 will be the first release whose API is stable**; until it is
-tagged there is no listed version to install, so the `dotnet add package` line below resolves
-nothing and the withdrawn releases come back only on an exact version pin. The public surface
-can still change until then. See [Versioning](https://github.com/dborgards/CanKit.Pro/blob/main/docs/decisions/0001-versioning-and-api-stability.md).
+Status: **1.3.0 is the first stable release**: from 1.3.0 on the public API follows SemVer, so a breaking
+change costs a major version. 1.0.0 – 1.2.3 were published as stable before the API had been reviewed
+against the specifications; they are unlisted and deprecated on nuget.org and should not be used. See
+[Versioning](https://github.com/dborgards/CanKit.Pro/blob/main/docs/decisions/0001-versioning-and-api-stability.md).
## What is validated, and what is not
diff --git a/src/CanKit.Pro.Addressing/README.md b/src/CanKit.Pro.Addressing/README.md
index 1169bad7..3e96ac6b 100644
--- a/src/CanKit.Pro.Addressing/README.md
+++ b/src/CanKit.Pro.Addressing/README.md
@@ -6,11 +6,10 @@ PDU-Format/Source-Address composition and decomposition, J1939 NAME field access
classification helpers, as pure, dependency-free helper functions — no dependency on any other
CanKit package.
-Status: 1.0.0 – 1.2.3 are **withdrawn from nuget.org** — they were published as stable before
-the API had been reviewed. **1.3.0 will be the first release whose API is stable**; until it is
-tagged there is no listed version to install, so the `dotnet add package` line below resolves
-nothing and the withdrawn releases come back only on an exact version pin. The public surface
-can still change until then. See [Versioning](https://github.com/dborgards/CanKit.Pro/blob/main/docs/decisions/0001-versioning-and-api-stability.md).
+Status: **1.3.0 is the first stable release**: from 1.3.0 on the public API follows SemVer, so a breaking
+change costs a major version. 1.0.0 – 1.2.3 were published as stable before the API had been reviewed
+against the specifications; they are unlisted and deprecated on nuget.org and should not be used. See
+[Versioning](https://github.com/dborgards/CanKit.Pro/blob/main/docs/decisions/0001-versioning-and-api-stability.md).
## What is validated, and what is not
diff --git a/src/CanKit.Pro.CANopen/README.md b/src/CanKit.Pro.CANopen/README.md
index 7456f1c4..ab7dd668 100644
--- a/src/CanKit.Pro.CANopen/README.md
+++ b/src/CanKit.Pro.CANopen/README.md
@@ -1,10 +1,8 @@
# CanKit.Pro.CANopen
-Status: 1.0.0 – 1.2.3 are **withdrawn from nuget.org** — they were published as stable before
-the API had been reviewed. **1.3.0 will be the first release whose API is stable**. Until it is
-tagged there is no listed version to install, so the `dotnet add package` line below resolves
-nothing and the withdrawn releases come back only on an exact version pin. The
-public surface can still change until then. See
+Status: **1.3.0 is the first stable release**: from 1.3.0 on the public API follows SemVer, so a breaking
+change costs a major version. 1.0.0 – 1.2.3 were published as stable before the API had been reviewed
+against the specifications; they are unlisted and deprecated on nuget.org and should not be used. See
[Versioning](https://github.com/dborgards/CanKit.Pro/blob/main/docs/decisions/0001-versioning-and-api-stability.md).
## What is validated, and what is not
diff --git a/src/CanKit.Pro.IsoTp/README.md b/src/CanKit.Pro.IsoTp/README.md
index beb3c3ca..2c819c80 100644
--- a/src/CanKit.Pro.IsoTp/README.md
+++ b/src/CanKit.Pro.IsoTp/README.md
@@ -11,11 +11,9 @@ ISO 15765-2 (ISO-TP) implementation for [CanKit](https://github.com/pkuyo/CanKit
Overflow) and enforces N_As/N_Bs/N_Cr timers, reassembles inbound PDUs (SN-checked), and delivers
them via `ReceiveAsync` / `ReceiveAllAsync` / `DatagramReceived`.
-Status: 1.0.0 – 1.2.3 are **withdrawn from nuget.org** — they were published as stable before
-the API had been reviewed. **1.3.0 will be the first release whose API is stable**. Until it is
-tagged there is no listed version to install, so the `dotnet add package` line below resolves
-nothing and the withdrawn releases come back only on an exact version pin. The
-public surface can still change until then. See
+Status: **1.3.0 is the first stable release**: from 1.3.0 on the public API follows SemVer, so a breaking
+change costs a major version. 1.0.0 – 1.2.3 were published as stable before the API had been reviewed
+against the specifications; they are unlisted and deprecated on nuget.org and should not be used. See
[Versioning](https://github.com/dborgards/CanKit.Pro/blob/main/docs/decisions/0001-versioning-and-api-stability.md).
CAN-FD long-payload cases still get the least coverage of the two halves.
diff --git a/src/CanKit.Pro.J1939/README.md b/src/CanKit.Pro.J1939/README.md
index e11ac6fe..f8010054 100644
--- a/src/CanKit.Pro.J1939/README.md
+++ b/src/CanKit.Pro.J1939/README.md
@@ -134,11 +134,9 @@ catalog decodes signed parameters too.
## Status
-The 1.0.0 – 1.2.3 releases are **withdrawn from nuget.org** — they were published as stable before the API
-had been reviewed. **1.3.0 will be the first release whose API is stable**. Until it is
-tagged there is no listed version to install, so the `dotnet add package` line below resolves
-nothing and the withdrawn releases come back only on an exact version pin. The
-public surface can still change until then. See
+**1.3.0 is the first stable release**: from 1.3.0 on the public API follows SemVer, so a breaking
+change costs a major version. 1.0.0 – 1.2.3 were published as stable before the API had been reviewed
+against the specifications; they are unlisted and deprecated on nuget.org and should not be used. See
[Versioning](https://github.com/dborgards/CanKit.Pro/blob/main/docs/decisions/0001-versioning-and-api-stability.md).
## What is validated, and what is not
diff --git a/src/CanKit.Pro.J1939Tp/README.md b/src/CanKit.Pro.J1939Tp/README.md
index db1070b5..1a44f968 100644
--- a/src/CanKit.Pro.J1939Tp/README.md
+++ b/src/CanKit.Pro.J1939Tp/README.md
@@ -2,11 +2,10 @@
SAE J1939-21 Transport Protocol (TP) for CanKit.Pro. Implements both flavors of the J1939-21 §5.10 transport service:
-Status: 1.0.0 – 1.2.3 are **withdrawn from nuget.org** — they were published as stable before
-the API had been reviewed. **1.3.0 will be the first release whose API is stable**; until it is
-tagged there is no listed version to install, so the `dotnet add package` line below resolves
-nothing and the withdrawn releases come back only on an exact version pin. The public surface
-can still change until then. See [Versioning](https://github.com/dborgards/CanKit.Pro/blob/main/docs/decisions/0001-versioning-and-api-stability.md).
+Status: **1.3.0 is the first stable release**: from 1.3.0 on the public API follows SemVer, so a breaking
+change costs a major version. 1.0.0 – 1.2.3 were published as stable before the API had been reviewed
+against the specifications; they are unlisted and deprecated on nuget.org and should not be used. See
+[Versioning](https://github.com/dborgards/CanKit.Pro/blob/main/docs/decisions/0001-versioning-and-api-stability.md).
## What is validated, and what is not
diff --git a/src/CanKit.Pro.RawCan/README.md b/src/CanKit.Pro.RawCan/README.md
index a7958ef8..9e7bda76 100644
--- a/src/CanKit.Pro.RawCan/README.md
+++ b/src/CanKit.Pro.RawCan/README.md
@@ -4,11 +4,10 @@ Raw-CAN service layer for [CanKit](https://github.com/pkuyo/CanKit): multi-proto
demultiplexing / subscriptions (arc42 §5.3, ADR-5; SRS FR-RAW-010..015) and a TX-confirm
abstraction (arc42 §6.3, ADR-7; SRS FR-RAW-030..034).
-Status: 1.0.0 – 1.2.3 are **withdrawn from nuget.org** — they were published as stable before
-the API had been reviewed. **1.3.0 will be the first release whose API is stable**; until it is
-tagged there is no listed version to install, so the `dotnet add package` line below resolves
-nothing and the withdrawn releases come back only on an exact version pin. The public surface
-can still change until then. See [Versioning](https://github.com/dborgards/CanKit.Pro/blob/main/docs/decisions/0001-versioning-and-api-stability.md).
+Status: **1.3.0 is the first stable release**: from 1.3.0 on the public API follows SemVer, so a breaking
+change costs a major version. 1.0.0 – 1.2.3 were published as stable before the API had been reviewed
+against the specifications; they are unlisted and deprecated on nuget.org and should not be used. See
+[Versioning](https://github.com/dborgards/CanKit.Pro/blob/main/docs/decisions/0001-versioning-and-api-stability.md).
## What is validated, and what is not
diff --git a/src/CanKit.Pro.Reliability/README.md b/src/CanKit.Pro.Reliability/README.md
index af5efa59..c02cda25 100644
--- a/src/CanKit.Pro.Reliability/README.md
+++ b/src/CanKit.Pro.Reliability/README.md
@@ -6,11 +6,10 @@ checked and fired, and a **bus-state monitor** that pushes `ICanBus.BusState` tr
protocol instance — both composed on top of `CanKit.Pro.Actor`'s single-mailbox loop, so there are
no free-running timers, no busy loops, and no second background-exception channel.
-Status: 1.0.0 – 1.2.3 are **withdrawn from nuget.org** — they were published as stable before
-the API had been reviewed. **1.3.0 will be the first release whose API is stable**; until it is
-tagged there is no listed version to install, so the `dotnet add package` line below resolves
-nothing and the withdrawn releases come back only on an exact version pin. The public surface
-can still change until then. See [Versioning](https://github.com/dborgards/CanKit.Pro/blob/main/docs/decisions/0001-versioning-and-api-stability.md).
+Status: **1.3.0 is the first stable release**: from 1.3.0 on the public API follows SemVer, so a breaking
+change costs a major version. 1.0.0 – 1.2.3 were published as stable before the API had been reviewed
+against the specifications; they are unlisted and deprecated on nuget.org and should not be used. See
+[Versioning](https://github.com/dborgards/CanKit.Pro/blob/main/docs/decisions/0001-versioning-and-api-stability.md).
## What is validated, and what is not
diff --git a/src/CanKit.Pro.Uds/README.md b/src/CanKit.Pro.Uds/README.md
index b3415442..4b387f14 100644
--- a/src/CanKit.Pro.Uds/README.md
+++ b/src/CanKit.Pro.Uds/README.md
@@ -5,17 +5,14 @@ directly on top of `CanKit.Pro.IsoTp`'s `IIsoTpChannel`, so anything that speaks
(virtual loopback, PCAN, SocketCAN, Vector, Kvaser, ZLG, ControlCAN, ...) can be driven with
the same client.
-Status: 1.0.0 – 1.2.3 are **withdrawn from nuget.org** — they were published as stable before
-the API had been reviewed. **1.3.0 will be the first release whose API is stable**. Until it is
-tagged there is no listed version to install, so the `dotnet add package` line below resolves
-nothing and the withdrawn releases come back only on an exact version pin. The
-public surface can still change until then — `SendRawAsync`, the timing options and the
-NRC-mapping types most of all. See
+Status: **1.3.0 is the first stable release**: from 1.3.0 on the public API follows SemVer, so a breaking
+change costs a major version. 1.0.0 – 1.2.3 were published as stable before the API had been reviewed
+against the specifications; they are unlisted and deprecated on nuget.org and should not be used. See
[Versioning](https://github.com/dborgards/CanKit.Pro/blob/main/docs/decisions/0001-versioning-and-api-stability.md).
## What is validated, and what is not
-**Validated:** Each service listed under *Service coverage* (some of them thinly), negative-response handling and the timing options, by the test suite in `tests/CanKit.Pro.Tests`, against `SimulatedUdsEcu` — a scripted ECU simulation in this repository whose responses each test defines — over `CanKit.Adapter.Virtual`.
+**Validated:** Each service listed under *Service coverage* (some of them thinly), negative-response handling and the timing options, by the test suite in `tests/CanKit.Pro.Tests`, against `SimulatedUdsEcu` — a scripted ECU simulation in this repository whose responses each test defines — over `CanKit.Adapter.Virtual`. The thinnest coverage is the mapping of negative response codes onto `UdsNegativeResponseCode`: only a few codes are asserted by name. `SendRawAsync` and the timing options are exercised heavily, but likewise only against the simulation.
**Not validated:** Any real ECU, whose timing, negative-response usage and deviations from the standard the simulation does not reproduce, and conformance as a tester would judge it. Nothing in this package has run against real CAN hardware, a conformance tester or a third-party implementation: the test project references `CanKit.Adapter.Virtual` and no hardware adapter.