From ccfc1140f4c7fdd66c09a8fa573ff7726d083509 Mon Sep 17 00:00:00 2001 From: beamologist Date: Thu, 29 Oct 2026 01:12:55 +0100 Subject: [PATCH 1/2] release 0.9.0: the A0 re-seal, and what this release does not change libmacula 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. The 0.9.0 section already existed and was never tagged, so the entry goes there, under "Changed since this entry was written", with the structural-floor change that was sitting in Unreleased. What this release does not change is stated too: sealing is the default where the provider names a key and only there, and a procedure served with no policy is advertised open (macula-php#19). Refs macula-php#17, macula-php#19. --- CHANGELOG.md | 31 ++++++++++++++++++++++--------- README.md | 2 +- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a30dbde..2e5c80a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,15 +8,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Added - -- **The structural floor is gated in CI** (macula-io/macula-codebase-checks#9): `phpcs` - refuses a function that nests past three blocks (`phpcs.xml`, `Generic.Metrics.NestingLevel` - absoluteNestingLevel 3) and `phpmd` refuses one past cyclomatic complexity 9 (`phpmd.xml`, - `CyclomaticComplexity` reportLevel 9). Both thresholds are spelled out rather than left at - a tool default, both run as steps of the `php-test` job, and `composer lint` runs the same - two locally. The tree was already inside the floor: 56 files, no findings. - ## [0.9.0] - 2026-10-19 The wire 1.0 release, for the fleet's flag day (19 Oct 2026, 18:03 UTC): from @@ -25,6 +16,28 @@ then on every live station speaks wire 1.0 (macula 15) and nothing older, and v0.27.0-rc.8's; this package's code is 0.9.0-rc.6's. The entries for rc.1 to rc.6 below are what changed since 0.8.2. +### Changed since this entry was written + +- **libmacula 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-php#17). +- **The structural floor is gated in CI** (macula-io/macula-codebase-checks#9): `phpcs` refuses a + function that nests past three blocks (`phpcs.xml`, `Generic.Metrics.NestingLevel` + absoluteNestingLevel 3) and `phpmd` refuses one past cyclomatic complexity 9 (`phpmd.xml`, + `CyclomaticComplexity` reportLevel 9). Both thresholds are spelled out rather than left at a tool + default, both run as steps of the `php-test` job, and `composer lint` runs the same two locally. + The tree was already inside the floor: 56 files, no findings. + +### What this release does not change + +- Sealing is the default where the provider names a key, and only there: a call or stream is sealed + whenever the advertisement carries a KEM key, and a provider that names none is called in the + clear unless the caller asks for `Confidentiality::Required`. Refusing a clear call unless the + caller opts out is not in this release. +- A procedure served with no policy is advertised open: `serve` and `serveStream` take the policy as + a nullable parameter, and omitting it serves any caller (macula-php#19). + ## [0.9.0-rc.6] - 2026-10-17 ### Added diff --git a/README.md b/README.md index a3bd4d8..c2e533b 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ compatibility layer. | Calls by direct dial (`call`, `providers`) | ✅ | ✅ | Errors arrive as `ProviderError` / `RelayError`; a station's refusal of a serve or subscribe is a `RefusedError` with its `reason`, `registration` and `station`; every other failure is a `MaculaException` whose `kind` is the library's error kind | | UCANs (`NodeKey::ucan`, `Ucan::proofId`, `ucan:`/`proofs:`, `ServePolicy`) | ✅ | ✅ | A token minted for the node that presents it, delegated by `prf`; a procedure served under `ServePolicy::ucanRequired` or `realmMemberRequired` reaches its handler only with a chain the policy accepts, refused otherwise as `ProviderError` `unauthorized` | | The seal report (`callReport`, `Stream::report`) | ✅ | — | Whether the exchange behind a result was sealed, to which provider and key | -| End-to-end sealing (`confidential:`, `kemAdvertise:`) | ✅ | ✅ | A call or stream is sealed whenever the provider's advertisement names a KEM key; `Confidentiality::Required` fails with `ConfidentialityError` rather than go in the clear; a served `Request` says whether it came `sealed` | +| End-to-end sealing (`confidential:`, `kemAdvertise:`) | ✅ | ✅ | A call or stream is sealed whenever the provider's advertisement names a KEM key; `Confidentiality::Required` fails with `ConfidentialityError` rather than go in the clear; a served `Request` says whether it came `sealed`. A keyed provider that refuses a call `sealed_required` has it resealed to the key in the refusal's signed tbs and answered, the key that provider holds now, rather than failing on a stale keyless candidate (macula-go v0.29.0) | | A node's own namespace (`ownProcedure`) | ✅ | ✅ | `~/`: served and called with no org and no realm key; the node's signature authorizes it | | Streams (`openStream`, `serveStream`) | ✅ | ✅ | Server, client and bidi; a QUIC stream per session, released on every path | | Publish/subscribe | ✅ | ✅ | Signed publications, delivered once across links | From fb6adfc0f491ae5809149ff7c3b0c78161210d9b Mon Sep 17 00:00:00 2001 From: beamologist Date: Thu, 29 Oct 2026 01:41:50 +0100 Subject: [PATCH 2/2] release 0.9.0 r1: the intro names the library that ships, and a key needs an opt-in Review of #20: - the 0.9.0 intro still said libmacula is macula-go v0.27.0 while the pin and the entry below say v0.29.0, and the heading was dated 19 October on a release first tagged now. The intro names v0.29.0 with the flag-day version as history, and the heading carries the day it is released. - kemAdvertise is false by default (src/Pool.php:48), so two pools on default arguments talk in the clear. Without that the note reads as more than it does. - the unary half of the open default is filed as macula-php#21 and named beside macula-php#19 in the note. Refs macula-php#17, macula-php#19, macula-php#21. --- CHANGELOG.md | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e5c80a..527a928 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,20 +8,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [0.9.0] - 2026-10-19 +## [0.9.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.8.2 can no longer connect. libmacula is macula-go v0.27.0, whose code is -v0.27.0-rc.8's; this package's code is 0.9.0-rc.6's. The entries for rc.1 to -rc.6 below are what changed since 0.8.2. +0.8.2 can no longer connect. libmacula 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.9.0-rc.6's. The entries for rc.1 to rc.6 below are what changed since 0.8.2. ### Changed since this entry was written -- **libmacula 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-php#17). +- **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-php#17). - **The structural floor is gated in CI** (macula-io/macula-codebase-checks#9): `phpcs` refuses a function that nests past three blocks (`phpcs.xml`, `Generic.Metrics.NestingLevel` absoluteNestingLevel 3) and `phpmd` refuses one past cyclomatic complexity 9 (`phpmd.xml`, @@ -31,12 +30,15 @@ rc.6 below are what changed since 0.8.2. ### What this release does not change -- Sealing is the default where the provider names a key, and only there: a call or stream is sealed - whenever the advertisement carries a KEM key, and a provider that names none is called in the - clear unless the caller asks for `Confidentiality::Required`. Refusing a clear call unless the - caller opts out is not in this release. -- A procedure served with no policy is advertised open: `serve` and `serveStream` take the policy as - a nullable parameter, and omitting it serves any caller (macula-php#19). +- Sealing is the default where the provider names a key, and only there. A provider names a KEM key + only when it opts in with `kemAdvertise: true`, which is off by default (`src/Pool.php:48`), so two + pools on default arguments talk in the clear. A call or stream is sealed whenever the advertisement + carries a key, and a provider that names none is called in the clear unless the caller asks for + `Confidentiality::Required`. Refusing a clear call unless the caller opts out is not in this + release. +- A procedure served with no policy is advertised open, unary and streaming alike: `serve` and + `serveStream` take the policy as a nullable parameter, and omitting it serves any caller + (macula-php#19 for streams, macula-php#21 for unary). ## [0.9.0-rc.6] - 2026-10-17