Repository navigation
Releases: turlamai/rivet
Release list
Rivet 0.13.0
-
Add an Android selected-device connection coordinator joining live
canonical NSD resolution to one explicit pinned-TLS/RVD1 attempt on a
product-supplied executor. Reject closed pairing windows, stale candidates
and duplicate starts; cancel outstanding resolution and active transports
without a delayed dial or automatic pairing fallback. Deterministic
JVM tests cover selection, successful authenticated handoff, cancellation
before queued work, and stale native callbacks. Product secure storage,
native UI and physical-device evidence remain separate. -
Add the Apple post-RVD1 RVT1 device path: generated Swift APIs can target a
shared RivetRPCClient protocol; a bounded network client correlates RPCs,
forwards cancellation and delivers events, and its lifecycle-aware run()
keeps companion handlers alive until disconnect. A scoped gateway applies
RPC/state/event grants and a backend adapter calls the existing local client.
Tests cover request correlation, cancellation, shutdown, request bounds,
state-grant isolation, event filtering and host argument/result encoding.
Product listener wiring, scope selection, event fan-out, signed apps and
physical-device validation remain outstanding. -
Add an Android Keystore-backed, app-scoped pairing credential store for
the RVD1 persistence gate. Credentials and server SPKI pins are encrypted
together with AES-256-GCM and bound to the application and device ID;
corrupted, restored-without-key, or cross-device records fail closed.
Synchronous SharedPreferences commits and no-replacement policy prevent
a failed credential write from authorizing application traffic. JVM
envelope tests cover tampering, identity binding, and malformed records;
Android SDK compilation covers the KeyStore adapter. This does not provide
a product UI or hardware pairing acceptance. -
Bind Android's RVT1 stream client to the payload and pending-request budgets
negotiated by an accepted RVD1 session. Reject oversized outgoing RPCs
without emitting a frame or poisoning later requests; oversized incoming
frames fail closed. Deterministic JVM tests cover both directions and
malformed acceptance budgets. This is companion transport policy, not a
claim of a complete Android app or physical-device acceptance. -
Add reusable iOS/iPadOS companion orchestration and SwiftUI UI for explicit
Bonjour selection, pinned reconnect, provisional RVD1 pairing, pairing-code
confirmation, Keychain-backed credential persistence, saved-pairing removal,
and session status. Add a watchOS SwiftUI control shell and WatchConnectivity
reachability stream with bounded 64 KiB immediate messages. CI covers Apple
device/simulator SDK builds; signed app packaging and physical-device
acceptance remain outstanding. -
Bridge Android companion TLS streams to the RVD1 client through a
one-shot selected-endpoint session driver. Enforce the stored SPKI pin on
reconnect without implicit pairing fallback, preserve explicit pairing
approval and credential-persistence gating, and lend accepted RVT1 streams
to the product. JVM regressions cover pin mismatch, rejection, success,
cancellation during TLS dialing, and socket cleanup. Product NSD,
secure storage/UI, and physical-device validation remain pending. -
Introduce the Android companion TLS connector for M3: a single-use
JSSE socket with server SPKI SHA-256 pinning for reconnect, explicitly
provisional pairing,rivet-device/1ALPN, TLS 1.2+ forward-secret AEAD
policy, and a cumulative 30-second connection deadline. Deterministic
JVM tests cover the pin and negotiation policy. Android NSD discovery,
RVD1/application binding, and real-device acceptance are not yet delivered. -
Generate an Android
RivetDeviceAPIfrom the same default-deny
device-rpcsallowlist used by Apple companions. The wrapper is emitted
beside the ordinary KotlinRivetAPI, reuses its typed codecs, and contains
only explicitly exported RPC methods, so an authenticated Android session
can bind to the product's generated device surface without hand-written
route strings. Server-side gateway scopes remain authoritative. -
Make verification evidence and orchestration first-class for distributed
agents (issue #287).raco rivet verify-remotedispatches the
per-platform acceptance legs of one commit on GitHub Actions, waits for the
runs, downloads the archivedacceptance --jsonreports, and folds them
into the verification matrix, so an agent edits on one OS and is judged by
the others. Acceptance evidence entries are now classified —
accessibility-snapshot,screenshot,interaction-trace,log, or
generic— and the report pins each declared artifact's kind, presence,
byte size, and SHA-256, while plain string evidence paths stay legal as
generic. The product CI guide archives every leg's report as
acceptance-report-<platform>withif: always(), which is exactly the
convention the new command consumes. -
Add the crash-safe process-external Linux AppImage handoff (issue #290).
AppImageHandoff::LaunchReplacementin the linkedrivet::platformtarget
writes a generated first-party shell script — the counterpart of the
WindowsMsiHandoff— that waits a bounded time for the launching process
to exit, performs the atomic replace with staging, SHA-256 re-check,
schema-1 journal phases, and idempotent rollback, relaunches the
replacement, and commits only after it survives the settle window;
otherwise it restores the previous AppImage (unless the signed manifest
forbids rollback) and records a failure marker forConsumeFailureon the
next launch. A preflight heals attempts that died between the two renames,
so the launch path is never left without an executable, and deb/rpm
installations stay owned by the system package manager.
Rivet 0.12.0
-
Make cross-platform verification first-class.
raco rivet matrix <report.json>... [--json]folds the per-platformacceptance --json
reports for one commit into a single machine-readable verdict: a required
kind/platform cell is proven only by a passing suite on that platform,
missing platforms are never silently green, and the exit code is green only
when every required cell is proven — so an agent editing on one OS can
still be judged by the other platforms' evidence.docs/product-acceptance.md
now defines the guaranteed / conditional / platform-specific capability
classification, and the maintainer contract states that the local
operating system does not reduce the required verification scope. -
Ship the Windows runtime source list as a machine-consumable property
sheet.platform/windows/rivet-runtime-sources.propsis now the single
author of the host library's<ClCompile>set —rivet-host.vcxproj
imports it, and hosts that still compile Rivet sources directly (the
transitional path until #238 ships prebuilt static libraries) import the
same file instead of hand-copying entries that rot: adding a runtime
translation unit previously broke every downstream Windows host at link
time (the podlensvalid_utf8LNK2001). A guard test keeps the props in
step withruntime/CMakeLists.txt, andplatform/windows/README.md
documents both consumption contracts. -
Fix generated C++ bounded-wait RPCs so each promise yields exactly one
future, reused for both the timeout wait and the result read. Void RPCs now
also fulfill their promise after decoding a successful response; previously
non-Void calls threwfuture_already_retrievedand Void calls always timed
out even when the backend had completed. -
Add executable product acceptance contracts.
raco rivet acceptance --jsonvalidatesrivet-acceptance.rktd, rejects missing kind/platform
coverage, launches each current-platform suite as an executable plus argv
without a shell, enforces bounded time and output, and fails on nonzero exits
or missing evidence.inspect --json, generated projects, agent guidance,
and the native UI extension contract now expose the same definition of done,
so a build-only or unrun platform can no longer be described as accepted. -
Set the Windows title-bar icon from the embedded exe resource. WinUI shows a generic placeholder in the title bar unless the window is handed an icon explicitly, so every shipped host ran with a foreign default glyph while taskbar and shortcuts showed the real brand icon — the icon was compiled into the exe (resource ID 1 since #283) but nothing ever loaded it. The host template now loads it with
LoadIconWand hands it toAppWindow.SetIconat construction; projects without awindows-icondeclaration keep the placeholder. Existing products carry the same lines in their ownMainWindowconstructor (podlens landed it first). -
Add the release gate.
raco rivet generate --checkregenerates every client file in memory and fails when the tree differs — the writer and the gate share one regeneration, so a hand-edited version stamp or a forgotten regeneration (four shipped-repo incidents in one week) cannot merge.raco rivet doctor --releasevalidates in one command and one exit code: generated freshness, the committed schema baseline, hand-written host sources callingfetch-update-manifest/select-update/download-update/fetch-sibling-assetonly with keywords the installed rivet accepts (read viaprocedure-keywordsfrom the live functions, closing the payback#:redirectionsclass), and everyrivet.git#...pin being non-empty and consistent with the installed release (the autarx empty-ref incident). The update API keyword contract is a documented, test-guarded stable surface, anddocs/ci.mdwarns about the emptyURL#footgun. -
Own the Linux runtime layout discovery and ship the GTK main-thread bridge.
rivet::linux_runtime::discover_layout()locatesruntime/*.bootplusres/core.zobeside the executable (an explicit-root overload serves tests),layout_error_hint()is the remediation message hosts display, and the host template consumes the library instead of carrying a private copy — the staged-versus-packaged layout is Rivet's contract, so the code that knows it lives with it. The template also shipsrpc_bridge.hpp:unpackflattens a generatedResult<T>(includingResult<void>) into a value-or-error decided on the reader thread, andpost_to_mainruns the closure on the GTK main loop, freeing it there. A new GTK host starts with the correct pattern instead of rediscovering thread affinity the hard way. -
Single-source user-visible strings.
raco rivet i18nverifies the parity contract ofshared/i18n/{zh,en}.json(flat string-to-string maps with identical key sets; violations name the file and key) and regenerates the embedded host tables (GeneratedI18n.hppon Windows and Linux,GeneratedI18n.swifton macOS). The shipped loaders consult the active language, then the other language, then the key, identically across hosts, so a key can never exist in one host's fallback and not another's. The release gate fails when the parity contract breaks or the embedded tables drift from the shared source; projects without ashared/i18nsource skip the check. -
Generate bounded-wait RPC companions for the Windows and Linux C++ clients. Every RPC gains
name_within(arguments, std::chrono::milliseconds): the completion resolves a promise, the call waits up to the timeout, and a miss cancels the pending request through the existing request table — so long-lived polling UIs stop spawning a detached thread per tick. Void RPCs returnbool; other results returnstd::optional<T>; backend errors still throw from the final get. The naming collision check treats_withinas a generated companion, and the fix removes a latent generator defect the new Void fixture exposed: the Void async completion handler assigned intoResult<void>, which has no value member and made every generated header with a Void RPC uncompilable. -
Add
macos-localizationspackaging support. A(macos-localizations "zh-Hans" "en")declaration (BCP 47 identifiers, validated at project load) emitsCFBundleLocalizationsin Info.plist and stages markerContents/Resources/<lang>.lproj/InfoPlist.stringsfiles beforesign-macos!runs, so AppKit renders the system-provided chrome (About/Quit menus, standard alerts) in the user's language instead of the development region's — replacing per-app plutil injection plus manual re-signing. Projects without the declaration build byte-identical bundles to before. -
Add
raco rivet measurefor host apps.measure sizelists everydist/artifact with its byte count and, with--budget <file>(glob rules, first match wins), exits nonzero when any artifact exceeds its budget so a bundle-size regression fails the build instead of shipping.measure startupruns the launch-survival smoke over the packaged artifact and reports the elapsed window. Per-RPC latency deliberately stays with the integration--benchmarkmode, which measures the real embedded runtime end to end;docs/benchmarks.mddocuments the budget format and that boundary. -
Add the updater scaffolding to
rivet/distribution. A runtime binds the
updater config, destination directory, settings bridge, and injectable
transport hooks;updater-runtime-check!fetches, selects, and drives the
download while a phase box (idle/checking/available/downloading/ downloaded/errorwith percent, message, and downloaded path) feeds the
product'supdate-stateevent. The family silent-check throttle stamp is
now owned here: a stamp is written only when a check settles — an answer
or a definitive failure — andsilent-check-due?reads it through the
product's settings adapter, ending the three hand-rolled timestamp
semantics where one offline launch could silence four hours.
The sticky 0-99 rollout bucket resolves through the same adapter
(resolve-rollout-bucket!): drawn once from OS entropy, recovered on later
runs, redrawn on corrupt stored values, degrading to an unpersisted draw when
the store cannot write. -
Let one update feed carry multiple installables per platform. Artifacts
gain an optionalcomponentdiscriminator (app,cli, ortool) that
participates in the manifest's duplicate-identity rule, writers emit the
legacy shape when no component is set, andupdater-configselects by
component; a config without one keeps matching component-less entries
only.raco rivet release --update-payload <installer>:<glob>[:<component>]
(repeatable) expands project-relative globs into component-tagged feed
entries, so products shipping an app and a CLI — or a portable tar.gz
instead of the zip — stop splitting into two feeds. The
updater-configstruct gains the component field as its last argument. -
Add
fetch-sibling-assettorivet/distributionand the
raco rivet sign-manifestsubcommand. The sibling helper checks the HTTP
status before saving, enforces the declared Content-Length against the
byte limit, verifies an optional expected SHA-256, and streams under the
same connect and idle deadlines as the manifest fetch — replacing the
private per-product sidecar downloads that silently accepted 404 pages.
The subcommand builds a manifest from explicitly named artifacts, signs
it with the distribution signer, verifies the written bytes with the
public half before publishing (deleting the output on failure), and
optionally emits.sha256sidecars next to each artifact, so products
keep only their asset-naming conventions. -
Extend the family boundary to Commerce: online payment orchestration and
credential delivery remain optional product/service concerns and never
become Rivet dependencies. -
Bound the updater's network legs.
fetch-update-manifestruns it...
Rivet 0.11.0
- Drop the IsolatedDeinit experimental feature from the released SwiftPM
packages. Released Xcode toolchains reject experimental features outright,
so package consumers could not compile RivetSystem away from trunk
compilers; the clipboard change-observation teardown now uses a plain
deinit over a nonisolated stored Timer, which every toolchain accepts. - Open the Windows taskboard reference window at a size that keeps every
layout region usable. At the WinUI default window size the timing-chart
row squeezed the task list into a virtualizing sliver whose row
containers never realized — invisible in the UI and to UI Automation —
and the native-UI end-to-end wait timed out waiting for the RPC-created
row even though the RPC itself had succeeded. - Make packaging a clean native provenance boundary (#235). Windows package
builds use MSBuildRebuild, macOS recreates the SwiftPM scratch tree, and
Linux already recreates its CMake tree; incremental caches can no longer
produce a valid-looking distributable from older native objects. - Finish the shared host-side update story on Windows and Linux (#237) without
duplicating the engine's security-critical Ed25519/parser/downloader stack.
Signed release feeds now carry portable ZIP plus MSI on Windows and portable
ZIP plus AppImage on Linux;make-updaterselects explicitportable,msi,
orappimageinstall shapes. The released Windows library adds a bounded,
failure-reportingmsiexecquit/install/relaunch handoff with stale-attempt
cleanup and lease release, while the Linux library adds install-shape and
post-commit AppImage relaunch helpers around the existing atomic adapter. - Complete released-package consumption (#238). Generated macOS hosts resolve
Rivet from its tagged root SwiftPM package rather than a checkout path;
Windows and Linux hosts link the released package's platform targets; the
old Linux source fragment is now explicitly private torivet::platform.
Both Windows static-library projects now declare ARM64 configurations. - Preserve the clean release output contract from #236: the unpacked staging
bundle is removed after installers, portable archives, manifests, SBOM, and
notices are produced. The canonical Linux source manifest and anti-drift
guard from #234 remain internal implementation details of the linkable
package rather than an invitation for downstream source compilation. - Fix the linkable Windows and Linux chart packages to carry the shared
chart batch codec/model implementation. The pre-release embedded roundtrip
caught the prior compile-green/link-red package before 0.11.0 shipped. - Isolate NuGet restore state for the sibling Windows host and chart library
projects. Both libraries now participate in the transitive restore graph,
so clean downstream builds receive the WinUI/C++/WinRT projection headers;
canonical directory-valued MSBuild output paths also remove the old MSB8004
warning from referenced-library builds. - Make the Windows host template's CRT selection explicit and consistent.
Self-contained packages use MT/MTd while development builds use MD/MDd,
and the selected mode is applied to the executable and forwarded to every
released static library, preventing clean-package LNK2038 failures. - Make the Windows chart library independent of downstream precompiled
headers by declaring its C++/WinRT dependencies directly, avoiding Win32
macro leakage, and using the correctWindows.UI.Colortype. - Update the Windows reference consumer to use the released
rivet::win_ui
namespace and the chart control's public default-construction contract. - Keep post-release verification compatible with the clean output contract.
When the unpacked staging package is gone,raco rivet verifynow validates
the portable ZIP through an isolated temporary extraction with strict root
layout checks and unconditional cleanup.
Rivet 0.10.0
- Host platforms ship as linkable packages — downstream products never
compile Rivet sources into their own build lists (constraint recorded
in #238). Linux gains arivet::platformstatic library under
platform/linux/that the host template, the integration binary, and
the taskboard exampleadd_subdirectory()and link; the scaffold's
generated CMake does the same. Windows gains
platform/windows/rivet-host.vcxproj(static library) which the host
template references viaProjectReference, with hybrid-CRT hosts
forwarding theirRuntimeLibrarychoice through
RivetRuntimeLibrary. A rootPackage.swiftexposes the macOS
products as a tag-resolvable SwiftPM package
(.package(url: …, from: "0.10.0")) beside the in-repo path package.
The WinUI HWND bridge moves towinui_window.hppso the Windows
library compiles without Windows App SDK include paths.
Rivet 0.9.0
-
Close the last below-floor commercial capability gap with first-party
native file dialogs on every desktop platform. Windows uses Common Item
Dialogs, macOS uses asynchronous AppKit panels, and Linux uses GTK4 native
choosers with portal delegation. The adapters cover open, save, folder
selection, extension filters, cancellation, and open-file multi-selection
without adding file-picker traffic to RVT1. -
Make Linux a first-class product target everywhere users discover Rivet:
the English and Chinese READMEs now include its badge, requirements,
positioning, and comparison stack; the bilingual landing page includes
GTK4 in both the native-UI feature card and comparison table; and the stale
unsupported-host remediation no longer claims only Windows and macOS can
build. Documentation tests pin all three targets to prevent this class of
omission from returning. -
Fix source-package smoke tests under
set -o pipefail. Archive entries are
now read once and checked from a file, sogrep -qcannot close a repeated
unzippipeline early and turn a successful match into spurious exit 141.
Source releases also explicitly omit native build/output trees (the Racket
packager does not read.gitignore), and the isolated install overrides any
maintainer-machine installation-scope link instead of producing a false
“already installed” result. -
Add first-party plain-text clipboard read/write/change observation across
every desktop adapter. macOS usesNSPasteboardwith main-run-loop
changeCountpolling, Windows usesCF_UNICODETEXTplus a message-only
clipboard owner andWM_CLIPBOARDUPDATE, and Linux uses GTK4/GDK with
asynchronous reads suitable for Wayland ownership transfers. Native
observation stays on the platform UI thread and outside RVT1. -
Complete cross-platform global shortcuts. Linux already binds through the
XDG portal; macOS gainsRivetGlobalShortcuts(Carbon
RegisterEventHotKey, main-thread event loop, explicit duplicate-trigger
refusal — RegisterHotKey provides it on Windows, Carbon does not) and
Windows gainsrivet::system::GlobalShortcuts(RegisterHotKeyon a
message-only window withWM_HOTKEYdispatch). The three adapters share
one activation-callback shape (shortcut id, millisecond timestamp,
portal-only activation token) and direct-registration platforms share a
case-insensitive trigger grammar; ANSI virtual-key codes map through
their Carbon constants because the codes follow the physical QWERTY
layout, not the alphabet. macOS parse and lifecycle tests are in the
Swift suite; the Windows adapter is compile-gated by the WinUI CI host
build. -
Add
docs/commercial-parity.md: the honest scorecard against the Tauri 2
and Electron feature floors (above / at / below / roadmap per
capability), with rules of engagement — a product hand-rolling the same
capability twice is a library gap, below-floor rows outrank new surface
area, and the docs suite keeps the scorecard's tracked capability rows
(global shortcuts, clipboard, native file dialogs, mobile hosts) from
silently disappearing. -
Close the scribble coverage gap: the RVT1 framing and value-codec surface
(rivet/protocol— frames, message-type constants, transport limits,
read/write/encode/decode), application resources (rivet/resources),
the diagnostic sink parameter,install-crash-hook!, the version
predicates, the Ed25519 key/digest/base64 primitives, canonical manifest
payload helpers,verify-update-artifact!,make-install-plan,
current-install-kind, and the missingupdater?predicate now have
manual entries. Every public export is covered and the rendered manual
carries no undefined-tag warnings. -
Documentation drift now fails CI instead of rotting silently. The docs
suite derives the current release version frominfo.rktand rejects a
docs/ci*.mdguide pinning any other tag, and it checks scribble
coverage in both directions: a public export without a manual mention
fails, and a manual entry for a binding that is no longer exported fails
(defstruct* forms synthesize their constructor, predicate, structure-type
binding, and accessors, mirroring the rendered output).
Rivet 0.8.1
- Add the macOS
RivetUpdateSwift module: a shared host-side update client
for installed.appbundles, so applications stop hand-rolling the same
security-critical download/verify/swap flow per product. It verifies the
family's signed manifest wrapper (Ed25519 over exact payload bytes before
any JSON parsing), downloads through a delegate-driven session whose
completion callbacks are definitive — byte-iteratingAsyncBytescan park
its continuation forever on a lost end-of-stream flag — enforces signed
size during transfer and on the delivered file, confirms the unpacked
bundle version, and swaps atomically with rollback and relaunch.
Configuration fails closed (HTTPS-only feeds outside loopback drills,
raw-32-byte keys, bare*.appbundle names), task cancellation always
resumes promptly, and progress stays within 0…100. The swap handoff owns
two traps verified on a real stalled OTA: the spawned script keeps the
work directory (cleanupStaleWorkDirectoriessweeps crashed attempts at
startup), and a presented sheet vetoesterminatesilently — the module
ends every sheet, terminates, and stops the run loop if the quit was
deferred.
Rivet 0.8.0
-
Reject self-contradictory signed update manifests before publication or
client acceptance: artifact sets must be non-empty and positive-size,
minimum/previous versions must precede the release, and artifact
platform/architecture/installer identities must be unique. Signed wrappers
and payloads also reject trailing JSON values and fields outside their
versioned schemas. -
Add an opaque managed updater for the check/select/download lifecycle shared
by downstream applications. It copies mutable configuration inputs and
provides deeply immutable, synchronized JSON-safe state,
one background worker, progress, explicit cancellation, monotonic manifest,
stall, and total deadlines, deterministic destinations, and terminal cleanup
while leaving installation and restart with the native host. -
download-updatereports download progress: an optional#:on-progress
callback receives cumulative bytes from zero through the final downloaded
size. Intermediate reports are throttled to about one per percent of the
signed artifact size by default, with an optional byte cadence for activity
watchdogs. In-app updaters can drive progress bars without copying Rivet's
bounded, redirect-aware downloader. Interrupted or cancelled downloads
remove their partial file as reliably as ordinary failures. -
Authenticate signed update-manifest payload bytes before parsing their JSON.
Malformed, unauthenticated payloads now fail at the Ed25519 boundary instead
of entering semantic validation and contradicting the documented trust
order.read-signed-manifestremains an explicitly unauthenticated
inspection API; update clients useverify-signed-manifest. -
Serialize portable update execution and recovery with an installation-scoped
in-process semaphore plus a target-derived operating-system file lock, even
when callers configure different backup paths. A competing updater now fails
before it can remove or rename shared staging, backup, marker, or journal
state; the persistent empty lock file is not a crash marker. The prepared
installation handle is opaque so callers cannot forge its lock identity. -
Make
settings-storean opaque synchronized handle. The pre-1.0 API no
longer exports its constructor, path/lock/data fields, or mutation setters,
which allowed callers to bypass atomic persistence and replace the store's
lock. Transactions refresh under shared in-process and operating-system
locks to prevent stale handles from losing updates; stored JSON trees and
snapshots are deeply immutable. Usemake-settings-storeand the existing
controlled operations;settings-store?remains public. -
Add a Windows
rivet::system::TrayControllerthat owns tray window
subclassing, localized native menu presentation, command dispatch, and
automaticTaskbarCreatedrecovery. The reference Taskboard now exercises
the blessed tray-resident host pattern instead of leaving every application
to rediscoverTrackPopupMenu's foreground-window requirement. -
The Windows tray icon (
rivet::system::TrayIcon) can update its tooltip
(SetTooltip) and re-register itself after an Explorer restart
(Readd, called from the host'sTaskbarCreatedbroadcast handler) —
state-aware tray apps no longer re-allocate the icon to relabel it and no
longer lose it the first time the shell restarts.TrayIconowns an icon
copy so recovery does not impose a new lifetime requirement on callers. -
Document one reproducible downstream install contract: pin Rivet's Git
package source andsetup-embed-racketaction to the same revision, and
install the package only after the minimal embeddable runtime is active. -
Add Wayland-safe Linux global shortcuts through the XDG Desktop Portal,
including asynchronous consent/binding results, compositor activation tokens,
runtime capability discovery, and a hermetic mock-portal integration test.
Rivet deliberately provides no X11XGrabKeyfallback. -
Bound and retry Ubuntu runner package-manager operations so a stalled mirror
cannot consume an entire desktop validation job without a useful failure. -
Removed the misleading
rivet-typeruntime descriptors from the pre-1.0
public surface. Schema type identifiers are declaration grammar, while Keel
is the canonical runtime-inspection model. -
Added an exact public-export contract and a Racket 9.0 CI lane so accidental
API drift and minimum-version regressions fail before merge. -
Make Keel's validated
app-schemathe canonical in-memory input to Swift,
C++, and Kotlin client generation. Rivet now keeps only a fail-closed
Keel-to-RVT1 type adapter instead of reconstructing a parallel codegen schema
model, while preserving generated source and schema snapshot compatibility. -
Synchronize the English and Chinese CI guide with the pinned Ubuntu 24.04
runner and remove a stale comment about the now-opaque State descriptor.
Rivet 0.7.0
- Stage Racket's bundled foreign runtime libraries (
libeay32.dll,
ssleay32.dll,libgmp-10.dll) beside the Windows host executable.
Embedded backends resolve these by bare DLL name through the FFI —
OpenSSL forracket/openssland the libcrypto factory (TLS and update/
license verification), GMP forgmp-libandmath— and a package that
only carried the Racket CS DLL died at startup or first crypto use with
ffi-lib: could not load foreign library. - Pin the MSI's Add/Remove Programs tile to the configured Windows icon
(ARPPRODUCTICON); shortcuts and the executable already inherited it
from the compiled resource. - Adopt Keel as Rivet's transport-neutral schema contract. The new
backend-schema->app-schemaandcurrent-backend-app-schemaadapters project
RPC, Event, State, Record, and Enum declarations into a validated,
deterministic Keelapp-schemawhile RVT1 framing and native renderers stay
Rivet-owned. Align schema placement rules with Keel:Voidis valid only as
a direct RPC result, not inside parameters, containers, Records, Events, or
States. - Split the Linux system adapter into focused single-instance, notification,
tray, autostart, secure-storage, and crash/shutdown implementation units,
with one private XDG/D-Bus support core and no public API change. - Make AppImage the signed Linux update payload when that format is enabled,
emit its SHA-256 sidecar, and add install-kind-aware update selection so
AppImage, portable, and package-manager installations cannot cross streams. - Graduate the Linux package-manager lifecycle gates from a single install to
two-version deb/rpm transactions: corrupt upgrades preserve the working
install, normal upgrades replace both metadata and payload, Debian rejects
implicit downgrade while Fedora verifies explicit local-RPM rollback and
re-upgrade, and uninstall remains complete under native Wayland. - Make embedded diagnostics opt-in across Racket, C++, and Swift. GUI hosts no
longer write to standard error by default, preventing Windows applications
from allocating a black console window on their first diagnostic; explicit
structured-log and stderr sinks remain supported. - Replace the accidental public backend registry structs and mutable State
cell accessors with an opaquestate?handle and a single immutable
backend-schemareflection snapshot. Pre-1.0 tooling that used
registered-*or*-info-*should read the corresponding schema entry;
applications should usestate-refandstate-set!. - Add real Linux installer lifecycle gates: build x64 rpm/AppImage artifacts,
install and launch the rpm on Fedora 44 under native Wayland, launch the
AppImage outside the build tree on Ubuntu 24.04, uninstall the rpm, and
retain package/compositor/application diagnostics as CI artifacts. - Add first-party portable update installation for Windows, macOS, and Linux:
verified ZIP/AppImage payloads are staged, platform-signature checked,
atomically replaced, health-gated, durably committed, and recoverable after
interruption. Native MSI/MSIX/DMG/PKG/deb/rpm artifacts remain explicitly
owned by their system installer or package manager. - Adopt a Wayland-first Linux display policy, document X11/XWayland as
best-effort GTK compatibility, and launch the packaged GTK4 host through a
headless native Wayland compositor in CI.
Rivet 0.6.1
- Fix the 0.6.0 family-release path:
manifest-compose --outputno longer
treats the destination as another input, every release leg's Ed25519
signature and key ID are verified before aggregation, and the command is
listed inraco rivet help. - Make portable update archives honor the documented
<name>-<version>-<os>-<arch>.zipconvention and point per-platform update
manifests at those archives instead of the separately published installer. - Carry
linux-binary-namethrough deb/rpm desktop entries, AppImage staging
andAppRun, dependency collection, and production verification. Native
Linux formats now work with product executables instead of assuming
RivetHost. - Make AppImage command capture check exit status and collect stderr without
the serial-pipe deadlock risk of the previousprocess*implementation. - Keep the source-package release smoke test self-contained by validating its
JSON contract with Racket instead of an incidental Python dependency. - Refresh the English and Chinese Linux capability summaries to reflect the
shipped native installers and StatusNotifierItem tray implementation.
Rivet 0.6.0
-
Add
raco rivet manifest-compose: folds the per-platform signed
update manifests from a multi-platform release into ONE family-wide
signed manifest (one artifact per platform/architecture, identity
fields verified identical across legs, Ed25519 wrapper unchanged) —
replacing the per-product hand-rolled merge scripts. Fixes #175. -
raco rivet releasenow emits a portable zip beside every installer
(family naming, sha256 alongside) — the family update feed and
locked-down machines consume it directly. -
Document the multi-platform release matrix convention (runner labels,
per-arch Racket installs, family artifact naming, the compose step) in
docs/release-and-updates.md. -
Windows and macOS hosts now shut the embedded backend down orderly on
session end. The Windows system adapter gains InstallShutdownHook
(SetConsoleCtrlHandler: CTRL_C/CLOSE/LOGOFF/SHUTDOWN) and the scaffold
wires it plus the window-close path to a thread-safe backend stop; the
macOS scaffold installs an NSApplicationDelegate whose
applicationShouldTerminate stops the backend for Cmd-Q, logout, and OS
shutdown. Mirrors the Linux InstallShutdownHook shipped by #128 and
wired into the scaffold by #168. Fixes #120. -
Document the large-payload conventions (docs/large-payloads.md): cursor
pagination with fail-closed limit caps for report-shaped RPCs, stable-id
tree nodes with windowed children for virtualized trees, and typed
progress records instead of stringly-typed events, including the current
scope of cancellation. Fixes #133; covers the convention layer of #131
and #132. -
Add rivet/testing: an ephemeral-port HTTP listener (racket/tcp cannot
report the bound port; this probes once and returns both the port and
the listener) plus a sequential request-capture fake server with
loopback close-race handling. Test suites only; never enters an embedded
payload. Fixes #98. -
Cut ~100 MB (48%) from Windows release payloads. The packaged app no
longer ships MSBuild debug symbols (*.pdb, 60+ MB) or the ONNX and
DirectML inference runtimes (~40 MB) that Windows App SDK
self-contained deployment drags beside every app; Rivet hosts link no
Windows AI APIs, and the exclusion is pinned by an explicit list plus
a launch smoke on every package. Fixes #144. -
Windows hosts now compile a VERSIONINFO resource into the exe. The
generated app-icon.rc always carries the project identity
(ProductName/FileDescription/Company from rivet.rktd, versions as
version.build) so Explorer, Task Manager, and installer UX show the
product instead of a bare framework binary; the icon line still rides
along when windows-icon is declared. The WiX missing-tool hint now
points at dotnet tool install with a 5.x pin (WiX 7 aborts on the
Open Source Maintenance Fee EULA). Closes the identity half of #166. -
Linux hosts now terminate on SIGTERM/SIGINT. The host scaffold and the
Taskboard example install Rivet's shutdown hook so a termination signal
runs the same orderly backend shutdown as the GTK shutdown signal and
then exits; previously the embedded backend died on the signal while the
GTK process stayed up, leaving a window that could not search or run
anything (observed on Fulcrum 0.4.1:killleft a half-dead app that
only SIGKILL would remove). -
Honor
linux-binary-nameinrivet.rktd: the Linux build stage, package
staging, verification, and launch smoke now use the configured executable
name instead of the hardcoded scaffold nameRivetHost(default
unchanged). Apps ship as their product name —fulcrum, not a generic
host binary — matching what the docs and desktop entries already say.
Partially addresses #169. -
Build native Linux system installers from
raco rivet release: a deb
(dpkg-deb, unprivileged, installs under /opt with a desktop entry and
pixmaps icon), an rpm (rpmbuild BUILDROOT, no distro-specific macros), and
an AppImage carrying the GTK4 dependency closure with compiled GSettings
schemas and pixbuf loaders so one file runs on older distributions. The
set is selectable vialinux-formats; the signed tar.gz update payload
remains unchanged. Production verification validates each format with
its own tooling (dpkg-deb -x, rpm -qpl, --appimage-extract), and the
Linux CI matrix smoke-builds and verifies all three end to end. -
Add a supported WinUI 3-to-
HWNDbridge. Generated Windows hosts expose
WindowHandle()through the first-party system adapter, centralizing the
Windows App SDKIWindowNativeABI and removing the need for title-based
FindWindowWworkarounds. -
Load
raco rivetsubcommand modules lazily. A stale bytecode cache in a
linked checkout now fails inside the command entry point, which detects the
instantiate-linkletmismatch and prints the working remedy (clear
compiled/+raco setup rivet) instead of crashing raco dispatch with a
raw linklet dump. Partially addresses #145. -
Align Swift and Kotlin state accessors with the generated RPC naming: they
are nowget_<state>/set_<state>instead of a camelCase prefix glued to a
snake body (getRepo_root). This is a breaking rename for Swift/Kotlin call
sites; C++ was already snake_case and is unchanged. -
Scope generated Swift Records and Enums under
RivetTypes. Common domain
names such asTaskandResultno longer shadow Swift concurrency or
standard-library types across the application module; native Swift call
sites now useRivetTypes.<SchemaName>. -
Add a reusable checksum-pinned Linux embeddable-Racket setup action and a
bilingual native-host CI guide. The guide requires WinUI, SwiftUI/AppKit,
and GTK4 hosts to compile before release on matching runner image classes,
and the resource guide now shows the verified cross-platformapp/layout
for shared product data.- Add a first-party plain-GTK4 theme resolver. Linux hosts now reconcile the
desktop color-scheme signal with the effectivegtk-theme-namevariant
before creating widgets, preventing application CSS and native controls from
landing on opposite light/dark palettes; pure resolution cases run in CI. -
Add
raco rivet release --without-updatesfor products that deliberately
ship without an online update channel. The release still produces and
verifies its platform installer, SBOM, and third-party notices while update
credentials and the signed channel manifest are omitted explicitly. -
Follow HTTP redirections (10 hops) in
fetch-update-manifestand
download-update. GitHub release assets — the dominant update origin —
answer with a 302 to their CDN, so an updater pointing at
releases/latest/download/…previously verified an empty body and every
check failed. -
Ensure isolated RPCs sent after an idle interval run immediately in embedded
Racket CS hosts instead of waiting for a later frame to wake request dispatch. -
Prefer native 64-bit MSBuild when discovering Visual Studio, preventing the
32-bit host compiler from exhausting its address space on WinUI ARM64 builds. -
Add an opt-in Linux
InstallShutdownHookfor SIGTERM/SIGINT. Its
async-signal-safe self-pipe hands graceful state flushing to a normal watcher
thread, while a repeated signal still terminates a stuck shutdown. -
Compile the Racket backend dependency graph with
raco makebefore creating
core.zo, so a same-length edit to a transitive source module cannot leave
stale bytecode in a successful native build. -
Add the Linux tray contract:
rivet::system::TrayIconhosts an
org.kde.StatusNotifierItem with a com.canonical.dbusmenu menu over the
session bus (GDBus), the pairing every desktop watcher serves (GNOME via
the AppIndicator extension, KDE natively). The opt-in stays an application
decision —TrayIcon::available()and thetraycapability report a
reachable watcher; the icon, tooltip, and flat menu update in place, and
the watcher is re-registered automatically when GNOME Shell or the
extension reloads. Verified end to end against the real desktop watcher
(registration, property reads, menu layout, click dispatch) plus the
graceful no-watcher path in an isolated D-Bus session. -
Add optional human-readable
publisherproject metadata and use it for the
Windows MSIManufacturer/Apps & Features Publisher value. Legacy projects
fall back todisplay-nameinstead of exposing a reverse-DNS identifier. -
Keep macOS development and test executables outside an
.appbundle from
enteringUNUserNotificationCenter, whose missing bundle identity otherwise
raises an uncatchable Objective-C exception. Notification availability is now
explicit; authorization returnsfalseand delivery throws a catchable error. -
Normalize Swift declaration keywords such as
initandpublicbefore
emitting client APIs, and put both source declarations plus the generated
identifier in the first line of native-name collision errors. -
Add provider-neutral, layer-attributed JSONL diagnostics across the Racket
backend, C++/Swift native clients, transports, and embedding bridges. Records
identify lifecycle/RPC boundaries, status, last RVT1 event, and request id;
stderr defaults and injectable sinks keep logging dependencies out of the
runtime and leave the RVT1 wire contract unchanged. -
Launch packaged GUI artifacts as the final verification gate when a graphical
session is available. The executable starts from an unrelated temporary
directory, must remain alive for five seconds, and is then terminated;
premature exit reports bounded stdout/stderr. Headless environments report
an explicit skip, andpackage/verify --skip-launch-smokeprovide an
intentional override without disabling structural or signature checks. -
Generate application identity from
rivet.rktdfor every native client and
stage the same values for Racket throughrivet/app-info. Swift, C++, and
Kotlin now receive display name, version, build, ident...