Skip to content

RegistryStack v0.38.0

Choose a tag to compare

@github-actions github-actions released this 01 Oct 16:49
· 371 commits to main since this release

Registry Stack v0.38.0

Registry Stack v0.38.0 is the beta-50 release. BReg can keep a subject-facing
access log for an entity that opts in, answers a row-boundary refusal on a
direct write as 412 precondition.failed, and recovers executor-denied
applications and superseded webhook work with new operator commands. Registry
Scheduling publishes the v1alpha2 HTTP contract, which carries opaque
external references on holds and appointments and lists a caller's
appointments by one of them. Evidence can read a signed assertion from
another Evidence deployment as a verified source, and the OID4VCI adapter
validates its whole catalog and every offer before a wallet spends its code.
Casework and Scheduling share one activation implementation and require
PostgreSQL 17.

This is the first release to publish Registry Messaging, Registry Render, and
the BReg citizen MCP gateway (breg-mcp) and review page (breg-review):

  • Registry Messaging: messaging and messagingctl Linux amd64 binaries, the
    ghcr.io/registrystack/messaging image, and a messaging namespace in the
    unified Node.js and Python clients.
  • Registry Render: a registry-render Linux amd64 binary and the
    ghcr.io/registrystack/registry-render image.
  • breg-mcp and breg-review: binaries for Linux amd64, Linux arm64, and
    macOS arm64, and the ghcr.io/registrystack/breg-mcp and
    ghcr.io/registrystack/breg-review images. The BReg installer does not
    install them.
  • The Evidence OID4VCI adapter gains the
    ghcr.io/registrystack/evidence-oid4vci image beside its existing binary.

The release also publishes discoveryctl for Linux amd64, and a standalone
Registry Scheduling runtime binary for Linux amd64 beside the existing image
and schedulingctl binaries.

Upgrade to v0.38.0 from v0.37.0. Move the Casework and Scheduling databases to
PostgreSQL 17 or newer first. Scheduling adds one schema migration, applied
with schedulingctl plan and apply. A BReg project whose access profiles
declare rowBoundaries compiles to a new registryRevision and must be
rebuilt and applied, and a Casework project whose BReg source pins that
project must be repinned. The Scheduling HTTP contract changes for callers,
so upgrade every client with its runtime.

Compatibility and migration

Run the same release on every runtime, tool, and client, and upgrade in the
order upgrade and retire
describes: BReg first, then Casework, then Evidence, then Scheduling, then the
clients. Take the backups it names first; no product migrates backwards.

Upgrade Base Registry Engine from v0.37.0

  • Do not upgrade a project that declares both rowBoundaries and a
    change-request planner to v0.38.0; see Known limitation.
  • Replace the breg and bregctl binaries or images. For a project that
    declares rowBoundaries, first rebuild and apply its package with the
    v0.38.0 bregctl, as the BREAKING entry on the generated OpenAPI document
    below describes. Then restart every breg process. The runtime file needs
    no change. An upgraded runtime and
    bregctl keep verifying and serving a database activated before
    subject access-log storage existed, without an apply; the next successor
    apply installs that storage, and a package that declares accessLog is
    never served without it.
  • BREAKING: a direct create, patch, or batch item whose resulting row falls
    outside the caller's row boundary answers 412 precondition.failed before
    any write, where it answered 503 service.unavailable. The body is the
    same value-free problem a stale If-Match answers, retrying the unchanged
    request cannot succeed, and the refusal is audited as a refusal. A batch
    carrying one such item commits none of them, and an import item is refused
    as an item. A genuine PostgreSQL privilege failure still answers 503.
    Handle a 412 on a create as a boundary refusal, not a retryable outage.
  • BREAKING: the generated OpenAPI document lists 412 precondition.failed on
    every create and batch operation reachable through a profile with
    rowBoundaries. The document is a packaged, byte-bound artifact that feeds
    registryRevision, so such a project compiles to a new registryRevision,
    and a package an earlier release built for it no longer loads. Rebuild it
    unchanged with the v0.38.0 bregctl: run
    bregctl test PROJECT --baseline-package DEPLOYED --runtime-config FILE --credentials FILE --output RECEIPT,
    then
    bregctl package PROJECT --baseline-package DEPLOYED --test-receipt RECEIPT --output BUILD,
    where DEPLOYED is the absolute directory of the deployed package. Check and
    apply BUILD/package with bregctl plan and bregctl apply, as step 4 of
    Upgrade in this order
    describes. This change leaves a project without rowBoundaries untouched.
  • A webhook destination that names localhost or a *.localhost host under
    a profile that denies loopback, such as productionHttps, is refused
    before startup. The send-time address policy already refused every delivery
    to it; use loopbackDevelopmentHttp for a local receiver.
  • bregctl generate evidence-source writes protocol
    breg-evidence-lookup-v2, so a source regenerated with v0.38.0 carries a
    new behaviorRevision, and
    accepting it with evidencectl source update changes the revisions of the
    Evidence questions that reach it. An imported source you do not regenerate
    is unchanged.

Upgrade Registry Casework from v0.37.0

  • BREAKING: caseworkctl plan, apply, and status, and casework serve
    startup, refuse a PostgreSQL server older than 17 with an upgrade
    instruction, before any migration or activation write. Upgrade the database
    server first, then replace the casework and caseworkctl binaries or
    images. Start the runtime only after the repin below, when it applies. No
    Casework schema migration is pending.
  • A Casework BReg source that pins a BReg project with rowBoundaries pins a
    registryRevision the upgraded BReg no longer serves, and Casework startup
    refuses it. After the BReg apply above, repin with
    caseworkctl source add BREG_PROJECT --project PROJECT --source-id ID --apply,
    then package, plan, and apply the Casework project once, and only then
    start casework, as step 5 of
    Upgrade in this order
    orders.

Upgrade Registry Scheduling from v0.37.0

  • BREAKING: schedulingctl plan, apply, and status, and
    scheduling serve startup, refuse a PostgreSQL server older than 17 with
    an upgrade instruction, before any migration or activation write. Upgrade
    the database server first.
  • Replace the scheduling and schedulingctl binaries or images. Migration
    10 adds the external-reference columns, and the runtime refuses to start
    until it is applied: run schedulingctl plan --runtime-config FILE, then
    schedulingctl apply --runtime-config FILE, and restart. Existing holds and
    appointments receive an empty reference set, and their stored idempotency
    hashes and receipts stay valid.
  • BREAKING: the HTTP contract is v1alpha2. HoldDocument and
    AppointmentDocument carry a required externalReferences array of
    {product, recordType, identifier} objects, so a client that refuses
    unknown members must be upgraded with the runtime. A hold and a direct
    booking may send externalReferences; confirmation, cancellation, reads,
    and idempotent replays keep the set, and a reschedule must omit it because
    the appointment keeps the set its hold or booking established. Upgrade the
    runtime before any client sends the field.
  • A reminder or observer destination on an https URL that names
    localhost or a *.localhost host is refused before startup. The
    send-time address policy already refused every delivery to it; use a plain
    http loopback destination for a local receiver.

Upgrade Evidence from v0.37.0

  • Replace the evidence binary or image, the evidencectl binary, and the
    evidence-oid4vci binary, or move the adapter to its image, and restart. No runtime file needs editing unless a bundle breaks
    the rule below.
  • BREAKING: a requirement's subjectRoles[].role is limited to 64 bytes
    instead of 128, in the bundle schema and at startup, to match the Evidence
    request contract. A bundle with a longer role fails startup; shorten the
    role and every grant, request, and derivation input that names it before
    replacing the binary.
  • BREAKING: evidence-oid4vci refuses a credential request whose inline
    proof jwk carries a member outside kty, crv, x, y, alg, kid,
    and use (with use only as sig), before any Evidence call, where it
    dropped the member and accepted the proof. A wallet that sends key_ops,
    x5t, jku, or another such member stops receiving credentials. Before
    cutting over, check that each wallet you serve sends only that member set.
  • evidence-oid4vci refuses its whole discovered catalog when any one
    definition fails the Evidence request contract, where it advertised the
    valid remainder. Run the adapter against its Evidence deployment before
    cutting over, and fix or withdraw any definition it names.

Upgrade Relay, Discovery, and Registry Manifest from v0.37.0

  • Replace the binaries or images and restart. Relay, Discovery, and Registry
    Manifest need no configuration, package, or database change in this
    release.

Adopt Registry Messaging, Registry Render, and the BReg citizen services

  • No earlier release carries these surfaces, so there is nothing to upgrade
    from a published release. A Messaging deployment built from source before
    v0.38.0 must move its database to PostgreSQL 17 or newer, set
    identity.databaseId, and activate its package with messagingctl plan
    and messagingctl apply before starting the runtime; messaging migrate
    is gone. The Messaging changelog lists every breaking change a source
    deployment crosses.

Base Registry Engine

  • An entity may declare accessLog to keep a subject-facing log of reads of
    its records: who read the record, when, and for which declared purpose. The
    subject reads it at GET /v1/records/{route}/{id}/access-log under a
    profile that currently grants get for the record and whose verified
    principal equals the stored subjectField. retentionDays defaults to 90
    and accepts 1 through 3650; a background worker erases expired rows every
    minute. trustedIntermediaries names the verified clients, at most 64,
    that may forward the original requester and purpose in the
    Registry-Access-Requester and Registry-Access-Purpose headers, and
    exemptions delay a documented entry for a named profile without omitting
    it. A failed log insert refuses the read. An access-logged entity cannot
    grant an anonymous profile any read. The log is stored apart from the
    operational audit. See
    subject-facing access logs.
  • Automatic review executors can renew credentials with privateKeyJwt.
    bregctl review-recovery retry-application requeues an executor-denied
    job after credentials or grants are corrected, keeping its exact current
    approved proposal and idempotency key. Application conflicts and
    precondition refusals retry with a delay of 5 seconds up to 5 minutes.
  • Dead letters retain a closed, value-free failure reason for operator
    inspection. bregctl webhook list stays available when retained work names
    a superseded binding, and the audited, generation-bound
    bregctl webhook discard closes eligible work without replaying it under
    the replacement binding.
  • bregctl dev accepts explicit service-client reviewExecutors bindings
    for automatically applied requests and uses renewing local issuer
    credentials.
  • bregctl dev clients may declare registry_purpose as a list of the
    purposes one client may use. Each authenticated journey step names an exact
    scope subset and, for a multi-purpose client, one declared purpose, and
    gets its own short-lived token. Dev refuses multi-purpose clients whose
    distinct token claims together exceed 16.
  • bregctl dev seeds and schema test journeys can load rows through an
    import route with operation: import, driving the production ingestion run
    under an exact one-item import authority that dev opens and closes.

BReg citizen MCP gateway and review page

  • breg-mcp is an MCP gateway a chat host uses to act for one verified
    citizen. It reads the citizen's own record and creates or patches
    change-request drafts for it, and has no code path to submit, revise,
    cancel, or apply one. For every tool call it exchanges the chat host's
    token for a registry token with the gateway as actor, so the chat host's
    token never reaches BReg, and it takes a draft's target from the citizen's
    own linked record, never from a tool argument.
  • breg-review is the server-rendered page where the citizen signs in,
    reads the draft BReg holds under their own token, and submits it. The page
    holds no authority of its own.
  • Both services ship as release binaries and images from this release. See
    the citizen MCP gateway.

Registry Messaging

  • Registry Messaging sends one message to one destination over one channel
    for an authorized caller, rendered from a reviewed template through an
    operator-configured SMTP or HTTP provider, and reports what is known about
    delivery. It owns its dispatch queue, provider calls, receipts, attempt
    history, payload retention, and audit journal; why, when, and to whom to
    send stay with the caller's source of record.
  • This is its first release. The messaging runtime and messagingctl
    operator tool ship as Linux amd64 binaries and in the
    ghcr.io/registrystack/messaging image, and the HTTP contract is pre-1.0.
    See the
    Messaging changelog
    for the full surface.

Registry Render

  • Registry Render produces governed, byte-stable PDF documents from registry
    data with Typst, as an offline CLI, an HTTP service, or a Rust library. This
    release publishes the registry-render Linux amd64 binary and the
    ghcr.io/registrystack/registry-render image, which keeps the template
    package outside the image.

Registry Casework

  • caseworkctl source add keeps an automatic executor's service apply
    profile separate from human source-context profiles, so staff and
    supervisors receive no executor scopes. check and fixture test report
    each request's application mode from its imported source description.
  • Activation shares its ledger and runtime privilege checks with Scheduling
    through registry-platform-activation, and detects the loss of any
    required table privilege, including when other required privileges remain
    granted.

Registry Scheduling

  • GET /v1/appointments lists the caller's own appointments carrying one
    exact external reference, named by the required
    externalReferenceProduct, externalReferenceRecordType, and
    externalReferenceIdentifier query parameters. Pages hold 1 to 200 items,
    50 by default, and the cursor is bound to both the caller and the filter.
    A reference is an identifier only: it confers no authority and Scheduling
    never calls another product with it.
  • The Rust Scheduling client sends external references and lists
    appointments by reference.
  • Activation shares its ledger and runtime privilege checks with Casework
    and detects the loss of any required table privilege.

Evidence, Relay, Discovery, and Registry Manifest

  • An http-json source may declare evidence to read one predefined
    assertion from another Evidence deployment. The block pins one reviewed
    audience-scoped definition that supports signed-jws, its independently
    accepted keys in trustedJwks, optional revokedKeyIds,
    maximumAssertionLifetimeSeconds, and clockSkewSeconds. Rust draws a
    fresh nonce for every acquisition, sends the request with the ordinary
    source credential, and verifies the signed answer before projection. The
    source needs a fixed POST path ending in /v1/evidence,
    query: forbidden, and jsonBody: required; it cannot declare batch,
    unresolvedProblem, or forwardAccessAttribution: true, and every
    selector in the pinned definition must use valueOrigin: request.
  • An http-json source may set forwardAccessAttribution: true to send the
    verified requester and authorized purpose in the reserved
    Registry-Access-Requester and Registry-Access-Purpose headers. The
    headers grant no source authority; the source must trust this Evidence
    service as an intermediary on its own terms. A BReg source exported for an
    access-logged entity sets it, and its connection client must be listed in
    that entity's trustedIntermediaries.
  • evidence-oid4vci checks each offered selector against the published field
    set, types, and bounds before an offer secret or exchange state exists, so
    an unusable request is refused before a wallet spends its single-use code.
    CredentialCatalog::derive returns a Result.
  • evidence-oid4vci omits response_types_supported from its authorization
    server metadata, as OpenID4VCI 1.0 Final permits for a server that supports
    only the Pre-Authorized Code Grant, instead of publishing an empty array.
  • BREAKING: an evidence-oid4vci inline proof jwk accepts only the
    kty, crv, x, y, alg, kid, and use members, with use only
    as sig, the same closed set a
    did:jwk proof already had. A key carrying any other member is refused
    instead of having the member dropped.
  • registry-evidence-client refuses a holder-bound batch answer whose
    credential count differs from the number of presented holder keys, as the
    same protocol refusal as an unparseable body. It also publishes its offline
    request contract for an integrator that owns its HTTP transport:
    EvidenceDefinitionsDocument::validate_for_request,
    DefinitionSelector::accepts_request_values,
    PreparedEvidenceRequest::prepare,
    PreparedEvidenceRequest::claim_request_json, and
    RetainedEvidenceVerification::from_prepared. None of them performs I/O.
  • Relay, Discovery, and Registry Manifest have no user-visible runtime
    changes in this release. discoveryctl ships as a Linux amd64 release
    binary.

Shared platform and clients

  • registry-platform-activation is a new shared crate: the PostgreSQL
    activation ledger, database identity, and runtime privilege checks Casework
    and Scheduling use. Products keep their transactions, migrations, audit,
    and package-specific activation hooks.
  • registry-platform-httputil refuses localhost and every *.localhost
    name for a productionHttps or privateServiceHttp data destination when
    the binding is constructed, whatever private ranges are allowed.
  • registry-platform-hooks records a closed dead-letter reason and can
    discard pending work, a dead letter, or an expired lease under its exact
    generation, without rebinding or sending it.
  • registry-platform-sdjwt closes the inline proof key member set described
    above.
  • The unified Node.js and Python clients add a messaging namespace over the
    Rust Messaging client, to submit, inspect, cancel, and preview messages.

Editors

  • The VS Code and Zed integrations cover BReg, Casework, Scheduling,
    Messaging, Discovery, Registry Manifest, Registry Render, and Evidence
    OID4VCI projects beside Relay and Evidence, with product-scoped
    definitions, references, symbols, completion, hover, and local reference
    diagnostics. They remain source-installed beta integrations; build the
    hosted CLI from the same checkout.
  • The language server reads only .yaml, .yml, and .json product
    documents. A document reference that names any other file, such as a
    private key, stays a navigation target and is never opened.

Release process

  • Every runtime image overlays the fixed Debian libssl3t64 3.5.7-1~deb13u3
    from DSA-6531-1 on its Distroless base, beside the fixed libc6 it already
    carried, and the Debian 13 image gate refuses an image without it. No
    Registry Stack binary links or loads OpenSSL; the overlay keeps the shipped
    library and the image scan current.
  • The release roster admits the discoveryctl Linux amd64 binary, the
    standalone Scheduling Linux amd64 runtime binary, the Messaging, Render,
    breg-mcp, and breg-review binaries, and the breg-mcp, breg-review,
    messaging, registry-render, and evidence-oid4vci images from v0.38.0,
    through the same build, checksum, smoke, advisory, repeatability, and
    verification steps as every other artifact. Each new image carries a
    reviewed advisory baseline, and its private candidate package joins
    scheduled candidate cleanup.
  • registry-release prepare checks that the VS Code and Zed extension
    manifests and lockfiles carry the release version, and that the excluded
    Evidence fuzz lockfile uses the release path-package graph.
  • Four Evidence fuzz targets cover the verifier's flattened-JWS and SD-JWT VC
    paths and the authoring readers for OpenAPI descriptions and project
    documents. They run as a smoke in the merge queue when a change reaches
    their crates and in the nightly sweep. The verifier's fixtures feature,
    off by default, supports them, and a workspace package that enables it is
    refused. The threat model and hardening checklist gain sections on the
    automated adversary.

Known limitation

bregctl refuses a package with a change-request planner as a predecessor:
the package records the planner's declaringOrigin, which the predecessor
loader does not accept. A database activated with such a package therefore
cannot plan or apply a successor, and bregctl test or bregctl package with
--baseline-package naming it is refused. Initial activation and runtime
startup are unaffected. A project that also declares rowBoundaries must
rebuild and apply its package to run v0.38.0, so it cannot upgrade until the
fix ships. This limitation predates this release; the fix is tracked in
#1814.

Changes since v0.37.0.
This remains a pre-1.0 Beta release for self-hosted institutional pilots.