Releases: jenksed/switchyard
Release list
Switchyard v0.9.0 — v1 release candidate
Switchyard v0.9 — The v1 release candidate
Released 2026-07-24. Application, relay artifact, and unified CLI version
0.9.0; relay protocol remains 1; endpoint configuration document
remains version 2.
v0.9 hardens Switchyard for self-hosted operation: optional multi-node
clustering, forward-only rolling upgrades, three documented deployment
profiles sharing one immutable non-root image, measured performance
boundaries, and a release-candidate freeze that becomes the v1 stability
contract. No user-facing feature was added; every change is operational
hardening behind the same stable API v1, unified CLI, and relay protocol.
v0.9 is the v1 release candidate (PROJECT_PLAN Stop 9). It proves that the
product runs correctly on more than one node, upgrades without down
migrations, deploys through documented profiles, and survives a two-hour
soak while preserving the v0.8 surface exactly. The work is intentionally
invisible to everyday users: endpoints, events, deliveries, routing,
notifications, evidence, and templates behave as they did in v0.8.
User-visible capabilities
There are no new user-visible features in v0.9. The release keeps every
v0.8 capability intact and adds operator-facing hardening:
-
Optional multi-node operation (V09-B, SPEC-044, ADR 051..053).
Clustering is opt-in and fail-closed. Two or more nodes gossip on a
private network withlibclusterusing an encrypted gossip secret and a
separate Erlang distribution cookie; invalid configuration fails startup
rather than falling back to a single-node mode. Relay destination
ownership uses:global.register_name/3with a 5-second fail-closed
registration deadline and:global.notify_all_name/3for graceful
takeover. A node that dies with an in-flight delivery leaves a fenced
claim that the next owner rejects and retries, leaving exactly one
terminalsucceededrow. -
Forward-only rolling upgrades (V09-B, ADR 054). Migrations are
additive and never reversed. The N/N+1 read window means old application
code continues to read the new schema until all nodes are upgraded, then
the new code path becomes active.bin/verify-rolling-upgradeproves the
prior (v0.8.0) → forward (v0.9.0) → back (v0.8.0) cycle with
/healthand/health/readygreen on every boot and no down migration. -
Three deployment profiles (V09-D,
docs/v0.9/PROFILES.md). The same
non-root, read-only, digest-addressed application image serves
single-node development (compose.yaml), single-node team
(compose.team.yamlwith TLS, SMTP, backups, restricted egress), and
multi-node team (compose.cluster.yaml) deployments. Secrets are
mounted as0600files; the image is reused, not rebuilt, across
profiles. -
Measured performance boundaries (V09-C, SPEC-045,
docs/v0.9/TESTED_LIMITS.md). A deterministic harness runs six
scenarios (sustained ingest, remote delivery, relay, concurrent LiveView,
retention under load, JSON/form/binary growth) and a default 7,200-second
soak. The full soak on an Apple M1 Pro/16 GiB RAM/PostgreSQL 17 accepted
142,120 events at 19.74 events/s sustained with zero hard invariant
violations and zero duplicates. These numbers are human-accepted under
SPEC-045 and are cited only with their full hardware, software,
topology, and duration qualifiers — they are not universal capacity
claims. -
Operational runbooks (V09-D). Nine runbooks complete the Stop 9
list: application installation, configuration, upgrade/rollback,
delivery troubleshooting, relay troubleshooting, database maintenance,
retention sizing, security configuration, and known limitations.
bin/verify-runbookschecks every referenced file and every safe
non-destructive command.
Operational changes
-
bin/build-app-imagebuilds the single immutable non-root application
image and writes a manifest attmp/v0.9/application-image-manifest.json.
The image runs as an unprivileged user with a read-only root filesystem
and loads runtime secrets from mounted files. -
compose.cluster.yamland.env.cluster.exampledefine the multi-node
team profile;compose.team.yamland.env.team.exampledefine the
single-node team profile. The development profile remains
compose.yaml. -
bin/verify-v0.9-b-clusterproves the two-node image cluster: relay
ownership handoff on simultaneous join, graceful replacement, abrupt
node loss, partition/heal convergence, and in-flight delivery recovery. -
bin/rehearse-upgrade-rollbackruns the prior → forward → back cycle
against a disposable database, confirming/healthand/health/ready
are200on every boot. -
bin/verify-v0.9-cchains V09-B, builds the released relay escript,
runs the six short harness scenarios and a ten-second soak in a
disposable database, and validates the receipts. -
bin/verify-v0.9-dchains V09-C,bin/verify-runbooks,
bin/verify-backup-restore, andbin/rehearse-upgrade-rollback. -
bin/verify-v0.9is the operator exit gate: it chains V09-D, runs the
live failure walkthrough, and verifies offline artifact signatures. -
bin/sign-artifactsandbin/verify-signaturesmigrated to Cosign
v3.1.2 Sigstore bundles (*.sigstore.json), fully offline, with bundle
names that encode the artifact path to prevent basename collisions. -
bin/verify-signing-flowproves the signing contract with disposable
keys: sign, bundle naming, proxy-blocked offline verify, tampered
artifact / missing bundle / corrupted bundle / wrong-key rejection, and
missing/unsupported cosign errors. -
bin/verify-v0.9-failure-walkthroughprovisions a disposable
deployment, drives the documented CLI-only operator path for an induced
HTTP-500 fixture, asserts timing (112 s of the 180 s bound),
sanitization, and hard=0, and cleans up.
Compatibility
docs/v0.9/compatibility.json records the frozen contracts. API v1,
relay protocol 1, configuration document 2, receipt format 1, and
CLI exit codes 0/2/3/4/5/6/7/8/78 are unchanged. The public surface did
not expand; every v0.8 client, token, script, and relay escript continues
to work against v0.9.0 without modification.
The frozen contracts are listed in docs/v0.9/FREEZE.md and become the
seed of the v1 stability contract. After v0.9.0, only critical
corrections (security vulnerabilities, violated invariants, or
release-blocking defects) may change them, and each requires an
acceptance row, a regression test, and a new ADR entry.
Verification
POSTGRES_PORT=55432 bin/verify-v0.9 is the durable release gate. Exit 0
means the v0.9 release candidate is met. The gate chains:
- The complete v0.8 release gate (
bin/verify-v0.8). - V09-B multi-node correctness (
bin/verify-v0.9-b), including the
two-node image cluster and the rolling-upgrade/rollback matrix. - V09-C tested limits (
bin/verify-v0.9-c), including the harness
contract, the released relay escript, the six short scenarios, and the
soak fencing. - V09-D deployment profiles and operational runbooks
(bin/verify-v0.9-d), including runbook reference checks,
backup/restore, and the upgrade/rollback rehearsal. - V09-E operator exit gate: offline signature verification and the live
failure walkthrough.
The final review also ran 452 focused LiveView/controller tests after the
V09-E-01 accessibility remediation and produced four review reports under
docs/v0.9/reviews/.
Known limits
- Delivery remains at-least-once; SSE delivery is also at-least-once
(clients dedupe by event UUID). - Multi-node clustering is opt-in, requires a private network, and is not
cross-region active/active. - Configuration
applyremains personal-principal only; machine
principals receive a documented 403. - The tested-limit numbers apply only to the named hardware, software,
topology, and duration indocs/v0.9/TESTED_LIMITS.md. - Only macOS arm64 artifacts are verified in this release; Linux
arm64/x86_64, Windows x86_64, and macOS x86_64 have documented local
procedures and honestNot runstatus.
Sign-off
The V09-E human checkpoint accepted the full risk list
(docs/v0.9/RISKS.md), signed the release-candidate freeze
(docs/v0.9/FREEZE.md), and signed the Stop 9 audit
(docs/v0.9/STOP9_AUDIT.md) on 2026-07-23. The operator exit gate
(bin/verify-v0.9) passed, including the live failure walkthrough
(112 s of the 180 s bound). Annotated tag v0.9.0 points to the verified
release commit.
The next stop is v1.0: the stability contract. v1.0 adds no new features
and hardens the v0.9 freeze into the long-term compatibility promise.
Artifact signatures
Release artifacts are signed with Cosign v3.1.2 keyless/Sigstore bundles.
- Public key:
config/signing/keys/switchyard-release.pub - Sigstore bundles: [
artifacts/v0.9/signatures/](https://github.com/jenksed/switchyard/blob/main/artifacts/v0.9/s...