Back to blog
2026-07-31 Thijs Creemers

Release: v1.0.0-beta-2 — Wagoe enters beta


Wagoe is now in beta, and this is the first release published under the Wagoe name.

Two things landed together. The framework was renamed from Boundary to Wagoe — new namespaces, new coordinates, new home — and the Framework Quality programme (Phases 0–2) closed out: a wide sweep of security hardening, new production-grade adapters, performance work and architectural cleanup.

1.0.0-beta-1 was tagged under the old name and never shipped as a Wagoe release. If you are coming from the alpha line, this page is the one to read; everything from beta-1 is included below.

Boundary is now Wagoe

Renaming before the first public release rather than after. There are no compatibility shims: nothing had been published under a stable version, so no deprecation window is provided.

Kind Before After

Namespaces

boundary.<seg>.…

wagoe.<seg>.…

Integrant / config keys

:boundary/http-server

:wagoe/http-server

Maven / Clojars coords

org.boundary-app/boundary-<lib>

com.wagoe/wagoe-<lib>

Environment variables

BND_*, BOUNDARY_*

WAG_*

CLI binary

boundary <cmd>

wagoe <cmd>

MCP resource URIs

boundary://…

wagoe://…

Repositories

thijs-creemers/boundary

wagoebv/wagoe

Sites

boundary-app.org

wagoe.org

docs.boundary-app.org is retired and the documentation is folded into wagoe.org/docs. The old domains and repository URLs redirect, so existing links and clones keep working.

Not renamed, on purpose. "Boundary" is also an architecture term here, and those uses are unchanged: the FC/IS boundary rules, the persistence / HTTP / API / DB boundary, boundary conditions and boundary testing. A bb check:no-boundary gate guards the renamed token families and treats the prose word as report-only for exactly this reason.

Security hardening

Security was the primary driver of the quality programme.

  • Authentication (wagoe-user): the JWT algorithm is now pinned and startup fails fast on a weak secret — a JWT_SECRET of at least 32 characters is required, with a separate CSRF secret. MFA TOTP secrets are encrypted at rest and backup codes are hashed. Sessions rotate on password and role change, defeating fixation and stale-privilege reuse.

  • Access control: an IDOR on the user API routes (/users, /users/:id) is closed — a caller can no longer read or modify another user by id. User-management web routes are mounted behind authz guards, and the web user-detail page is admin-only.

  • Error hygiene (wagoe-platform): 5xx responses no longer leak exception internals, and the admin error flash no longer echoes raw exception messages. Security response headers and session-cookie attributes are hardened, backed by a dedicated authz negative-path suite (RBAC / IDOR / cross-tenant) plus brute-force lockout and session-fixation coverage.

  • Jobs (wagoe-jobs): the Redis dequeue is now reliable — jobs are no longer lost when a worker crashes mid-dequeue.

  • Dependencies: a stale root pom.xml carrying a vulnerable PostgreSQL JDBC pin was dropped, and the driver bumped for GHSA-j92g-9f8w-j867. A js-yaml DoS advisory (GHSA-h67p-54hq-rp68) and a brace-expansion advisory were patched on the docs site.

New: observability

A new wagoe-observability library brings first-class metrics and tracing:

  • A Prometheus metrics adapter with a GET /metrics scrape endpoint.

  • A backend-agnostic tracing port (ITracer plus the with-span macro) with no-op and logging adapters.

  • An OpenTelemetry OTLP exporter for both traces and metrics, with automatic per-request HTTP spans and per-job worker spans. One vendor-neutral OTLP/HTTP exporter feeds any OTel backend — SigNoz, Grafana Tempo, Jaeger, or Datadog-via-OTel.

HTTP request metrics (request count, error count, latency histogram) now emit through the real metrics emitter, so they reach any active provider.

New: storage, email, and durable jobs

  • wagoe-storage: a Google Cloud Storage adapter with V4 signed URLs, a :wagoe/storage Integrant key dispatching :local / :s3 / :gcs, and real HMAC-signed, expiring URLs for the local adapter.

  • wagoe-email: an in-memory email queue with bounded retry, :wagoe/email and :wagoe/email-queue Integrant keys, and user welcome mail routed through the email lib.

  • wagoe-jobs: a DB-backed job queue adapter — durable background jobs without Redis — with transactional outbox enqueue. The transactional enqueue contract is now guarded, with the capability moved onto a port.

Deployment

A production Dockerfile, a worker run mode (no HTTP listener), and a production configuration guard make packaging and running Wagoe services straightforward. The uberjar build was repaired and its artifact version pinned to the suite.

A server that started silently without serving is fixed — three separate bugs, now covered by a smoke test that proves the jar actually serves.

Performance

Every hot-path change was benchmarked with criterium before implementation.

  • Malli validators compiled once — validating with a raw schema re-parses it on every call (measured 8.6–9.9× overhead). All 121 static-schema call sites across 43 files now use validators compiled at namespace load; schema-as-argument callers get memoized compilation.

  • Logger dispatch — reflective logger interop on every request enter/leave replaced with protocol calls (~90× per call).

  • DB result conversion — snake→kebab key conversion moved into the next.jdbc builder-fn (converted once per result set, not per row); admin entity/table metadata cached in the long-lived schema repository, eliminating 2×N information_schema queries per page.

  • i18nresolve-markers now shares structure and returns original nodes when nothing changed (82.4µs → 25.0µs on a 50-row table).

  • N+1 writes batched in wagoe-audience and wagoe-user — a 50k-user membership save drops from ~100k statements to ~102.

  • CSRF, correlation ids, JWT secret resolution, and the jobs heartbeat all took targeted fast-path fixes.

Architecture: FC/IS purity and cycle dissolution

  • FC/IS core purity: definition registries and process guards moved out of core/ into the shell — core/ may no longer throw or hold mutable state, now enforced by check:fcis.

  • Dependency cycles dissolved: the platform↔user cycle broken via app-layer wiring; shared Hiccup UI extracted into a new wagoe-shared-ui lib (dissolving admin↔user); tenant HTTP middleware relocated out of platform; parallel search stacks merged into libs/search.

  • Honesty: 15 previously-undeclared deps declared; dead protocols and helpers removed; deploy publish order derived from a topological sort of the dependency graph.

Developer experience

bb test:all runs every test surface in one command. Project creation is now plainly wagoe new — the separate starter-repository concept is gone.

Docs

A runnable in-repo example (examples/todo) with CI smoke, 7 new library READMEs, expanded module AGENTS.md guides, and relocated multi-tenancy usage docs. The getting-started and architecture guides were refreshed for beta.

Version alignment

All 29 libraries are published at v1.0.0-beta-2 under the com.wagoe group, maintaining lockstep versioning — including the two new libraries, wagoe-observability and wagoe-shared-ui.

Upgrade

Re-run the installer to pick up the latest release:

curl -fsSL https://get.wagoe.org | bash

Coming from the alpha line, apply the rename table above — namespaces, config keys, coordinates, environment variables and the CLI binary all move. Then note the intentional behaviour changes: a JWT_SECRET of at least 32 characters is required at startup, and FC/IS core-purity is enforced by check:fcis.