From 1a1e4eb7c0a66aacd230b211fa009a46a72249e7 Mon Sep 17 00:00:00 2001 From: "glm-5.3-flash" Date: Sat, 17 Oct 2026 14:28:57 +0000 Subject: [PATCH] =?UTF-8?q?chore(release):=200.10.0=20=E2=80=94=20the=20ga?= =?UTF-8?q?teway=20ownership=20seam?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The review-012 batch rides this tag: the dispatch-spine ownership provider threading (with_ownership_provider) and the loud default (FORBIDDEN, pre-dispatch, for resource_type-gated ops on an unwired spine) with the with_static_ownership_fallback escape hatch. Verified: 698 tests (incl. stub guard), clippy --all-targets --all-features -D warnings, fmt --check, cargo doc, wasm32 check+clippy, fuzz corpus replay 5/5, semver-checks (additive API diff; two new builder methods only), publish --dry-run clean. --- CHANGELOG.md | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bdbb1a3..fd9fd52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,75 @@ All notable changes to this crate are documented here. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this crate adheres to [Semantic Versioning](https://semver.org/). +## [0.10.0] - 2026-10-17 + +The gateway ownership seam (review 012, downstream evidence from +alkgit's LFS POC — POC-L): the gateway dispatch spine can now consult a +runtime ownership provider, and the previously-silent static fallback +becomes loud — `FORBIDDEN` rather than admission-by-claim — unless the +deployment wires the provider or declares the static fallback +explicitly. This closes the two-authorization-paths drift: a +namespace-ACL-gated op served through a door ran against the +token-carried static claim, while the same op on the native wire +consulted the revocable grant table. One behavior break (the loud +default, below); the wire surface and `OperationContext` shape are +unchanged. + +### Added + +- **`GatewayDispatch::with_ownership_provider` (ADR-048 amendment + "Ownership provider threading").** An `Option>` on the spine, wired by the dispatcher-identical + builder and read by the shared root-context builder so all three + dispatch entry points (`invoke`, `invoke_streaming`, `invoke_sink`) + thread it into `OperationContext.ownership`. `None` (the default) + previously hardwired the static fallback; now it activates the loud + default below. Regression tests: + `gateway_with_provider_consults_the_live_grant_table` (revocation is + live on the gateway surface) and + `gateway_streaming_with_provider_denies_a_static_claim_only_identity`. +- **`GatewayDispatch::with_static_ownership_fallback`** — the declared + opt-in to the ADR-011 static `Identity.resources` fallback, for + deployments that genuinely have no runtime ownership model. Turns the + door contract from a doc line into an enforceable construct: the + static fallback survives only as a code-review-visible declaration, + never as the accidental default. Regression test: + `gateway_static_fallback_opt_out_serves_resource_gated_ops`. + +### Changed + +- **The loud ownership-wiring default (review 012 decision 2; ADR-048 + "The loud default").** The spine refuses (an error envelope, + `FORBIDDEN`, pre-dispatch, all three entry points) an op whose spec + carries `access_control.resource_type` when no ownership provider is + wired and no static fallback is declared. **Behavior break for any + deployment serving `resource_type`-gated ops through an unwired + spine** — the survey (review 012) found no published consumer relies + on the silent fallback (alkhttp, the only live spine consumer, is + unpublished; alkblobs, the only live `resource_type` op producer, + serves native-wire with providers wired). The predicate is + `resource_type` (covering the `list`/`owns_any` case where + `resource_id_path` is `None`), not `resource_id_path`; + `resource_action`-only ACLs and Internal-visibility ops are exempt + (no provider is consulted for those even on the native wire — static + resolution there is family-wide semantics). The refusal message is + operator-directed (names the wired opt-ins) and indistinguishable in + code from a normal ACL denial. Regression tests: + `gateway_refuses_a_resource_gated_op_without_a_provider`, + `gateway_streaming_and_sink_refuse_a_resource_gated_op_without_a_provider`, + and `gateway_refusal_spares_action_only_internal_and_unknown_ops`. + Specs: ADR-048's "Ownership provider threading" and "The loud + default" sections; the finding is + `docs/reviews/012-gateway-ownership-seam-consumer-input.md`. + +### Verified + +- 698 tests pass (including the stub guard); `clippy --all-targets + --all-features -- -D warnings`, `fmt --check`, `cargo doc`, + wasm32-unknown-unknown check + clippy, fuzz corpus replay + (`cargo test --manifest-path fuzz/shared/Cargo.toml`, 5/5), + `cargo semver-checks`, and `cargo publish --dry-run` clean. + ## [0.9.0] - 2026-10-14 The stub sweep: four registered-but-always-failing stubs shipped across @@ -834,6 +903,7 @@ Vendored core types (`Connection`, `ProtocolHandler`, `BiStream`, (ADR-046), the channels protocol with openable-ALPNs-as-operations (ADR-047), and the `ChannelClient` transport-agnostic client. +[0.10.0]: https://git.alk.dev/alkdev/alkcall/releases/tag/v0.10.0 [0.9.0]: https://git.alk.dev/alkdev/alkcall/releases/tag/v0.9.0 [0.8.1]: https://git.alk.dev/alkdev/alkcall/releases/tag/v0.8.1 [0.8.0]: https://git.alk.dev/alkdev/alkcall/releases/tag/v0.8.0 diff --git a/Cargo.lock b/Cargo.lock index 959adb7..0ccd2af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,7 +27,7 @@ dependencies = [ [[package]] name = "alkcall" -version = "0.9.0" +version = "0.10.0" dependencies = [ "async-trait", "bytes", diff --git a/Cargo.toml b/Cargo.toml index 4a8206f..1582f0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "alkcall" -version = "0.9.0" +version = "0.10.0" edition = "2021" rust-version = "1.88" license = "MIT OR Apache-2.0"