Skip to content

baukit 0.5.2

Choose a tag to compare

@github-actions github-actions released this 30 Sep 21:13
· 411 commits to main since this release

baukit v0.5.2

One release train for the Rust crates, TypeScript packages, and templates.

Summary

baukit 0.5.2 closes the gaps that all eight products hit while adopting 0.5.1, so they can delete product code or finish a plan step they had to skip. It is a patch release by number, but a few interfaces changed shape. No product is live, so those breaks shipped without shims. They are listed below.

New

  • baukit-core: the baukit-webhook-v1 signature is runtime code now, in baukit_core::webhook_signature behind the webhook-signature feature. Senders sign with sign_webhook_hmac_sha256, and receivers call verify_webhook_hmac_sha256 with a list of candidate secrets, which covers key rotation. The shared vectors in fixtures/webhooks/signature-v1.json run against it.
  • baukit-core: PageKey takes any tie-breaker type, and Cursor::page_key_as reads it back, so a list ordered by a composite key such as (source, target) can use the shared cursor. page_key still means a UUID tie-breaker, and the wire format is unchanged.
  • baukit-egress: EgressRequest::with_response_body(ResponseBody::Discard) drops a 2xx body unread, so a webhook receiver that answers with a large body no longer fails delivery with ResponseTooLarge.
  • baukit-test: assert_request_matches_openapi and check_request_matches_openapi check a request body against the operation's requestBody, with the same media-type and format rules as the response check.
  • baukit-push: pending receipts record their owner, and PendingReceiptStore::erase_owner plus erase_owner_pending_receipts remove an erased owner's device tokens at once instead of after the 24-hour receipt window. Reference migration 0004 adds the column.
  • Chart: networkPolicy.additionalIngress, api.networkPolicy.additionalIngress, and worker.networkPolicy.additionalIngress. Default renders are byte-identical.
  • @baukit/a11y-core/web: announce(message, { assertive, liveRegionId }) speaks through a visually hidden ARIA live region without React Native. The root announce delegates to the same module on React Native Web.
  • @baukit/auth-node/keycloak-testing: allowKeycloakWebOrigin also adds the origin to the client's post.logout.redirect.uris. The entry stays ESM-only; Node 24 loads it through require(esm), and the package test now proves that from the packed archive.
  • CLI: baukit doctor accepts the PWA capability on a mobile-only product whose Expo web export serves the @baukit/pwa-web worker, and the strict quality gate checks the worker build in mobile/.
  • Docs: the calendar export recipe appends the final CRLF that ical-generator 11.1.1 omits, and asserts it in tests.

Breaking

  • baukit-test: the webhook signature functions moved to baukit_core::webhook_signature with no re-export, and OpenApiResponseError is now OpenApiContractError.
  • baukit-egress: under AddressPolicy::AllowLoopback, plain HTTP reaches only loopback destinations, checked on address literals and DNS answers. Anything else fails with Destination(Scheme).
  • baukit-push: PendingReceipt has an owner_id, record_accepted and accepted_receipts take the owner, and PendingReceiptStore has a new required erase_owner. Migration 0004 deletes pending rows recorded before it, so those tickets lose their receipt check.
  • deploy/media-grants/njs/media-grant.js refuses absolute-form request targets (GET http://host/path) and request lines without an HTTP version. A new shared vector, absolute-form-target, pins the Rust side to invalid_path.

The sections below list every change per crate and package.

Verification

Every step of the local CI mirror passed on main before the version bump, and make ci passed again on the release commit. The mirror covered make ci, all Rust tests including Docker-gated ones (727), cargo deny, MSRV 1.95, browser Dexie conformance (36 tests), both media-grant vector suites under njs and QuickJS, the metric-name lint, the backend, web, and mobile generated fixture with coverage floors, and the MCP fixture gate. A live Keycloak 26.7.0 container checked the post-logout redirect, and a live nginx smoke run checked the absolute-form rejection. The Android emulator gates were not rerun, because this train touches no Android, Expo SQLite, notification, or localization code. iOS and physical devices were not tested.

Rust crates

baukit-auth

  • No component-specific changes in this train.

baukit-config

  • No component-specific changes in this train.

baukit-core

Added

  • Add the optional webhook-signature feature and the webhook_signature module with
    webhook_signing_input, sign_webhook_hmac_sha256, verify_webhook_hmac_sha256,
    WEBHOOK_SIGNATURE_VERSION, and WEBHOOK_SIGNATURE_PREFIX. Senders and receivers now apply the
    baukit-webhook-v1 signature at runtime instead of copying it from baukit-test. The feature
    adds base64 and ring. fixtures/webhooks/signature-v1.json runs against it.
  • Add a tie-breaker type parameter to pagination::PageKey<T, K = Uuid> and
    Cursor::page_key_as::<T, K>(). Cursor::from_page_key and Page::from_rows accept any
    K: Display, so a list ordered by a composite key such as (source, target) or by a non-UUID
    ID keeps the filter binding, version check, and size bound. PageKey<T> and
    Cursor::page_key::<T>() still mean a UUID tie-breaker, and the cursor wire format is
    unchanged.

Changed

  • fixtures/media-grants/vectors-v1.json gains an absolute-form-target case: a path carrying a
    scheme and host is invalid_path. The nginx verifier in deploy/media-grants now refuses a
    request whose request line has an absolute-form target (GET http://host/path).

baukit-credential-vault

  • No component-specific changes in this train.

baukit-egress

Added

  • ResponseBody and EgressRequest::with_response_body. ResponseBody::Discard
    drops a 2xx body unread, so a webhook receiver that answers 2xx with a body
    above max_response_bytes counts as delivered instead of failing with the
    permanent ResponseTooLarge. ResponseBody::Read stays the default.
  • AddressPolicy::permits_plain_http(address).
  • fixtures/egress/address-policy-v1.json gains five plain-http literal cases.

Breaking

  • Under AddressPolicy::AllowLoopback, plain http reaches loopback
    addresses only. An http URL with a non-loopback literal, or a host name
    with any non-loopback answer, fails with
    EgressError::Destination(DestinationRejection::Scheme) before a
    connection. Before, the policy turned off https-only for every host. Local
    development setups that sent http to a non-loopback host must use https
    or a loopback address.
  • EgressRequest's Debug output adds the response_body field.

baukit-events

  • No component-specific changes in this train.

baukit-http

  • No component-specific changes in this train.

baukit-integrations

  • No component-specific changes in this train.

baukit-jobs

  • No component-specific changes in this train.

baukit-openapi

  • No component-specific changes in this train.

baukit-ops

  • No component-specific changes in this train.

baukit-push

Added

  • Pending receipts record their owner. Migration
    0004_baukit_push_pending_receipt_owners.sql
    (POSTGRES_PUSH_PENDING_RECEIPT_OWNERS_MIGRATION_SQL) adds a non-null
    owner_id column to push_pending_receipts, and its header shows the owner
    foreign key with ON DELETE CASCADE. Erasing an owner now removes the device
    tokens their pending tickets hold at once instead of up to 24 hours later.
  • Add PendingReceiptStore::erase_owner, implemented by
    PostgresPendingReceiptStore and MemoryPendingReceiptStore, and
    erase_owner_pending_receipts, which takes any PgExecutor for the
    product's erasure transaction.

Breaking

  • PendingReceipt has a new owner_id field.
  • PendingReceiptStore::record_accepted and accepted_receipts take the
    owner as their first argument.
  • PendingReceiptStore has a new required method, erase_owner. Custom
    implementations must add it.
  • Migration 0004 deletes every pending ticket recorded before it runs. A
    dead token among them is reported again by the next send to it.

baukit-ratelimit

  • No component-specific changes in this train.

baukit-runtime

  • No component-specific changes in this train.

baukit-sync

  • No component-specific changes in this train.

baukit-telemetry

  • No component-specific changes in this train.

baukit-test

Added

  • Add assert_request_matches_openapi and check_request_matches_openapi with
    ObservedRequest. They check a request body's media type and JSON body against the operation's
    requestBody, resolving components.requestBodies references, and treat an empty body as
    missing only when the request body is required.

Breaking

  • Rename OpenApiResponseError to OpenApiContractError. Request and response checks now share
    it, and its location names either the response status or request.

  • Remove webhook_signing_input, sign_webhook_hmac_sha256, and verify_webhook_hmac_sha256.
    They moved unchanged to baukit_core::webhook_signature (feature webhook-signature), so tests
    and production code share one implementation. Import them from there. The signature vector test
    moved to baukit-core.

TypeScript packages

a11y-core

Patch Changes

  • 91d4641: @baukit/a11y-core/web exports announce(message, { assertive, liveRegionId }), AnnounceOptions, and DEFAULT_LIVE_REGION_ID, so a plain React web app can speak outcomes through a visually hidden ARIA live region without React Native in its dependency tree. The call shape and the region match the root export, which now delegates to the same web module on React Native Web.
  • Release the coordinated baukit 0.5.2 train.

analytics-core

Patch Changes

  • Release the coordinated baukit 0.5.2 train.

analytics-posthog-native

Patch Changes

  • Release the coordinated baukit 0.5.2 train.
  • Updated dependencies
    • @baukit/analytics-core@0.5.2

analytics-posthog-web

Patch Changes

  • Release the coordinated baukit 0.5.2 train.
  • Updated dependencies
    • @baukit/analytics-core@0.5.2

api-runtime

Patch Changes

  • Release the coordinated baukit 0.5.2 train.

auth-native

Patch Changes

  • Release the coordinated baukit 0.5.2 train.

auth-node

Patch Changes

  • bfc7aac: allowKeycloakWebOrigin(stack, origin) also adds <origin>/* to the web client's post.logout.redirect.uris attribute, keeping the other attributes and any existing entries, so a signed-out test lands back on the app. A + entry already covers the redirect URIs and stays as it is. The /keycloak-testing subpath stays ESM only; the README now states that CommonJS consumers load it through Node 24 require(esm) and type-check it with "module": "node20" or "nodenext", and the packed-exports test loads it with require.
  • Release the coordinated baukit 0.5.2 train.

auth-web

Patch Changes

  • Release the coordinated baukit 0.5.2 train.

data-contracts-dexie

Patch Changes

  • Release the coordinated baukit 0.5.2 train.
  • Updated dependencies
    • @baukit/data-contracts@0.5.2

data-contracts-expo-sqlite

Patch Changes

  • Release the coordinated baukit 0.5.2 train.
  • Updated dependencies
    • @baukit/data-contracts@0.5.2

data-contracts

Patch Changes

  • Release the coordinated baukit 0.5.2 train.

events

Patch Changes

  • Release the coordinated baukit 0.5.2 train.

integrations-client

Patch Changes

  • Release the coordinated baukit 0.5.2 train.

localization-core

Patch Changes

  • Release the coordinated baukit 0.5.2 train.

notifications-core

Patch Changes

  • Release the coordinated baukit 0.5.2 train.
  • Updated dependencies
    • @baukit/localization-core@0.5.2

notifications-expo

Patch Changes

  • Release the coordinated baukit 0.5.2 train.
  • Updated dependencies
    • @baukit/notifications-core@0.5.2

preferences-core

Patch Changes

  • Release the coordinated baukit 0.5.2 train.

pwa-web

Patch Changes

  • Release the coordinated baukit 0.5.2 train.

sync-client

Patch Changes

  • Release the coordinated baukit 0.5.2 train.

ui-tokens

Patch Changes

  • Release the coordinated baukit 0.5.2 train.

Commits

  • chore: prepare baukit v0.5.2 (944065a)
  • feat(core): allow a non-UUID pagination tie-breaker (1ecb810)
  • feat(test): validate request bodies against OpenAPI (e66d2ed)
  • feat(egress): runtime webhook signature, discardable response bodies, loopback-only plain http (7cd6bd9)
  • docs(evidence): record the 0.5.2 follow-ups for Keycloak, announce, and mobile PWA (edb0fb6)
  • feat(cli): accept the PWA capability on a mobile-only product (ea4fe71)
  • feat(a11y-core): export announce from the web entry (91d4641)
  • fix(auth-node): allow the post-logout redirect in allowKeycloakWebOrigin (bfc7aac)
  • docs(calendar): append the final CRLF that ical-generator omits (b5cd4aa)
  • fix(media-grants): refuse absolute-form request targets at the nginx edge (d2d363b)
  • feat(chart): render networkPolicy.additionalIngress release-wide and per process (a823991)
  • fix(push): record the owner of pending receipts so erasure removes them (019ca9b)
  • docs(plan): record Schlauzug adoption of 0.5.1 (1b587d1)
  • docs(plan): record Solo Leveling System adoption of 0.5.1 (687ed62)
  • docs(plan): record Tiefgang adoption of 0.5.1 (38c99ee)
  • docs(plan): record Runtime Analyzer adoption of 0.5.1 (ec007c6)
  • docs(plan): record Eigenruhe adoption of 0.5.1 (424b5f8)
  • docs(plan): record Redemut adoption of 0.5.1 (eb1533e)
  • docs(plan): record Leitbild adoption of 0.5.1 (d60088e)
  • docs(plan): record Hebkit adoption of 0.5.1 (da6648a)
  • docs(plan): track product adoption of 0.5.1 (5189557)