diff --git a/CHANGELOG.md b/CHANGELOG.md index a30dbde..527a928 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,22 +8,37 @@ 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 +## [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 + +- **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`, + `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 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 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 |