From 51050c4a664839c8521da74a15b7cca099c2ec4e Mon Sep 17 00:00:00 2001 From: beamologist Date: Thu, 29 Oct 2026 00:55:13 +0100 Subject: [PATCH 1/4] release 0.6.0: the A0 re-seal, and what this release does not change The native library is pinned to macula-go v0.29.0, the release that carries the A0 contract: a call a keyed provider refuses sealed_required is resealed to the key in the refusal's signed tbs and answered, instead of the caller failing on a stale keyless candidate. pyproject already says 0.6.0 and the version was never tagged, so the entry goes into the 0.6.0 section rather than a new one, with a subsection for what landed after it was written. What this release does not change is stated too: sealing stays preferred, not required, and a stream served with no policy is still advertised open (macula-py#18). Refs macula-py#15, macula-py#18. --- CHANGELOG.md | 21 +++++++++++++++++---- README.md | 6 ++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bffeb9c..217a27a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,6 @@ ## Unreleased -- CI type-checks every Python block in the README and the guides against the - package (`docs.yml`, macula-codebase-checks#8), on every change including - doc-only ones, and a release waits on it. - ## 0.6.0 (2026-10-19) The wire 1.0 release, for the fleet's flag day (19 Oct 2026, 18:03 UTC): from @@ -14,6 +10,23 @@ then on every live station speaks wire 1.0 (macula 15) and nothing older, and code is v0.27.0-rc.8's; this package's code is 0.6.0rc4's. The entries for 0.6.0rc1 to 0.6.0rc4 below are what changed since 0.5.0. +### Changed since this entry was written + +- **The native library is built from macula-go v0.29.0**, the release that carries the A0 contract: a + call a keyed provider refuses `sealed_required` is resealed to the key in the refusal's signed tbs + and answered, instead of the caller failing on a stale keyless candidate (macula-go v0.29.0, + macula-py#15). +- CI type-checks every Python block in the README and the guides against the package (`docs.yml`, + macula-codebase-checks#8), on every change including doc-only ones, and a release waits on it. + +### What this release does not change + +- Sealing stays preferred, not required, by default: a served procedure is `confidential="preferred"`, + which seals to the pool's key when it advertises one, and a caller still reaches a provider that + names no key in the clear. Refusing a clear call unless the caller opts out is not in this release. +- A stream served with no policy is still advertised open: `serve_stream` takes `policy` as an + optional keyword, and omitting it serves any caller (macula-py#18). + ## 0.6.0rc4 (2026-10-17) ### Added diff --git a/README.md b/README.md index b7049dd..fc0749f 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,12 @@ result, report = await caller.call_report(realm, procedure, payload, confidentia assert report.sealed and report.provider == provider.node_id() # seal_key_id: the key, 16 hex ``` +When a keyed provider refuses a call `sealed_required`, because its key rotated +between the advertisement the caller read and the call, the caller reseals to +the key in the refusal's signed tbs and the call is answered, the key that +provider holds now. Before macula-py 0.6.0 the call failed on that stale keyless +candidate (macula-go v0.29.0). + - `kem_advertise` is off by default. Enable it only once every station runs macula 12.11 or later and every caller can seal (macula 13, macula-go 0.18, macula-py 0.4 or later). From a4e9fd36566c097824d0e9d1406cd96777e5c08c Mon Sep 17 00:00:00 2001 From: beamologist Date: Thu, 29 Oct 2026 01:53:06 +0100 Subject: [PATCH 2/4] release 0.6.0 r0: the intro names the library that ships, and a key needs an opt-in The two corrections the php round needed, made here before review rather than after it: the 0.6.0 intro said libmacula is macula-go v0.27.0 while the pin is v0.29.0, so the intro names v0.29.0 with the flag-day version as history and the heading carries the release day; and a pool names a KEM key only with kem_advertise=True, off by default (src/macula_py/pool.py:483), so two pools on default arguments talk in the clear. The open default is stated for both shapes: serve and serve_stream take policy as an optional keyword (macula-py#18 covers streams; the unary twin has no issue yet and the Supervisor has that question). Refs macula-py#15, macula-py#18. --- CHANGELOG.md | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 217a27a..9583db0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,30 +2,33 @@ ## Unreleased -## 0.6.0 (2026-10-19) +## 0.6.0 (2026-10-29) The wire 1.0 release, for the fleet's flag day (19 Oct 2026, 18:03 UTC): from then on every live station speaks wire 1.0 (macula 15) and nothing older, and -0.5.0 can no longer connect. The native library is macula-go v0.27.0, whose -code is v0.27.0-rc.8's; this package's code is 0.6.0rc4's. The entries for -0.6.0rc1 to 0.6.0rc4 below are what changed since 0.5.0. +0.5.0 can no longer connect. The native library is macula-go v0.29.0, the +release that carries the A0 contract (v0.27.0 at the flag day); this package's +code is 0.6.0rc4's. The entries for 0.6.0rc1 to 0.6.0rc4 below are what changed +since 0.5.0. ### Changed since this entry was written -- **The native library is built from macula-go v0.29.0**, the release that carries the A0 contract: a - call a keyed provider refuses `sealed_required` is resealed to the key in the refusal's signed tbs - and answered, instead of the caller failing on a stale keyless candidate (macula-go v0.29.0, - macula-py#15). +- **A call a keyed provider refuses `sealed_required` is resealed and answered**, instead of the + caller failing on a stale keyless candidate: the caller seals again to the key in the refusal's + signed tbs, which is the key the provider holds now (macula-go v0.29.0, macula-py#15). - CI type-checks every Python block in the README and the guides against the package (`docs.yml`, macula-codebase-checks#8), on every change including doc-only ones, and a release waits on it. ### What this release does not change -- Sealing stays preferred, not required, by default: a served procedure is `confidential="preferred"`, - which seals to the pool's key when it advertises one, and a caller still reaches a provider that - names no key in the clear. Refusing a clear call unless the caller opts out is not in this release. -- A stream served with no policy is still advertised open: `serve_stream` takes `policy` as an - optional keyword, and omitting it serves any caller (macula-py#18). +- Sealing stays preferred, not required, by default, and a pool names a KEM key only when it opts in + with `kem_advertise=True`, which is off by default (`src/macula_py/pool.py:483`), so two pools on + default arguments talk in the clear. A served procedure is `confidential="preferred"`, which seals + to the pool's key when it advertises one, and a caller still reaches a provider that names no key + in the clear. Refusing a clear call unless the caller opts out is not in this release. +- A procedure served with no policy is still advertised open, unary and streaming alike: `serve` and + `serve_stream` take `policy` as an optional keyword, and omitting it serves any caller + (macula-py#18). ## 0.6.0rc4 (2026-10-17) From 124cda3b80ab411cc8d74ddb3551e8816b55d94f Mon Sep 17 00:00:00 2001 From: beamologist Date: Thu, 29 Oct 2026 01:57:38 +0100 Subject: [PATCH 3/4] release 0.6.0: the unary half of the open default is filed and named macula-py#20 is the unary twin of #18, filed from the source: serve takes policy as an optional keyword and libmacula serves any caller without one. The note points at both. Refs macula-py#18, macula-py#20. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9583db0..5fca6d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ since 0.5.0. in the clear. Refusing a clear call unless the caller opts out is not in this release. - A procedure served with no policy is still advertised open, unary and streaming alike: `serve` and `serve_stream` take `policy` as an optional keyword, and omitting it serves any caller - (macula-py#18). + (macula-py#18 for streams, macula-py#20 for unary). ## 0.6.0rc4 (2026-10-17) From 87b7610d10eb43ab3b3cfc1a88ef24e83c7dd514 Mon Sep 17 00:00:00 2001 From: beamologist Date: Thu, 29 Oct 2026 02:01:49 +0100 Subject: [PATCH 4/4] release 0.6.0 r1: sealed_required is a keyless advertisement, not a rotated key Review of #19: the paragraph gave the wrong cause. sealed_required comes from a caller holding a KEYLESS advertisement and calling clear; a caller holding an old key gets sealed_refused, with the current key id in detail. Reworded to match the changelog bullet and the mechanism. Refs macula-py#15. --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index fc0749f..f2490fe 100644 --- a/README.md +++ b/README.md @@ -158,11 +158,11 @@ result, report = await caller.call_report(realm, procedure, payload, confidentia assert report.sealed and report.provider == provider.node_id() # seal_key_id: the key, 16 hex ``` -When a keyed provider refuses a call `sealed_required`, because its key rotated -between the advertisement the caller read and the call, the caller reseals to -the key in the refusal's signed tbs and the call is answered, the key that -provider holds now. Before macula-py 0.6.0 the call failed on that stale keyless -candidate (macula-go v0.29.0). +When a keyed provider refuses a call `sealed_required`, because the advertisement +the caller read named no key, the caller reseals to the key in the refusal's +signed tbs and the call is answered, the key that provider holds now. Before +macula-py 0.6.0 the call failed on that stale keyless candidate (macula-go +v0.29.0). - `kem_advertise` is off by default. Enable it only once every station runs macula 12.11 or later and every caller can seal (macula 13, macula-go 0.18,