Skip to main content

Support matrix

Signing status is a known current limitation: macOS and Windows installers are not code-signed, so users must allow them manually the first time they open them; iOS ships unsigned simulator builds only. When no repository key is configured, Android uses a throwaway CI key generated for each release, so candidate versions cannot upgrade in place over one another. Before a release, confirm whether any of this has changed.

Desktop platform boundaries

The authoritative runtime owns Agents, files, Git, PTY, providers, permissions, and persistence. Keep platform differences in apps/desktop/src/platform or a shared facade; do not duplicate business branches in the UI.

Release channels

A channel is a compile-time identity, not a runtime switch: The channel is derived from the tag (*-preview.* / *-rc.* / plain semver). The release process asserts that the versions in the tag, Cargo.toml, package.json, and Packager.<channel>.toml match exactly. Overriding the channel at runtime is rejected (release_channel_override_rejected).

Release workflow

.github/workflows/release.yml runs fully automatically on v* tags, and the desktop matrix covers six platform / architecture combinations: Mobile builds in the same workflow: an Android APK + AAB, and the iOS XCFramework + unsigned simulator app. The release job requires all prerequisite jobs to succeed before it creates a release, so a partial matrix never produces a broken release.
The workflow currently has no macOS notarization or Windows Authenticode step. Until those two steps are added, installers keep carrying the platform warnings.

Android builds

Set VIBEX_MOBILE_ANDROID_TARGETS (space-separated) to override the Debug ABIs; Release builds arm64-v8a only by default. The release workflow calls apps/mobile/scripts/sign-android-release.sh: APKs use zipalign + apksigner, and AABs use jarsigner. RC / Preview generate a throwaway vibex-ci key when no repository key is configured; Stable releases must configure VIBEX_ANDROID_KEYSTORE_BASE64 and VIBEX_ANDROID_KEYSTORE_PASSWORD, plus the optional VIBEX_ANDROID_KEY_PASSWORD and the repository variable VIBEX_ANDROID_KEY_ALIAS (default vibex).
Using a throwaway key means every RC release has a different APK signature, so users cannot upgrade in place and must uninstall before installing again. This is a known tradeoff of the current RC phase.

iOS builds

Builds VibexFFI.xcframework and generates the Xcode project. Signing, the bundle identifier, device / simulator selection, and distribution credentials are all decided by your local Xcode process; do not commit certificates or provisioning profiles to the repository.

Desktop packaging

Linux packages with cargo-packager, and the PDFium runtime ships with the package on linux-x86_64 only. Wayland-related libraries are not bundled (the host ABI boundary); the host provides them.

Automatic updates

crates/app-update implements signed updates:
  • It discovers candidate releases from the GitHub Releases Atom feed and filters them by channel.
  • It verifies the Ed25519 signature of vibex-update.json and the SHA-256 of the artifact, with a URL allowlist limited to release download paths.
  • It checks 30 seconds after launch, then every 2 hours on RC / Preview and every 6 hours on Stable, with jitter and backoff.
  • AppImage replaces itself in place (with .vibex-backup and pending-install.json crash recovery); deb, the macOS app, and NSIS launch the system installer and require a restart.
  • The release pipeline stages docs/operations/release-notes-v<version>.md from the tagged commit as vibex-release-notes.md, and fails the release when the file is missing or carries no ## English section. The desktop fetches it from the verified tag under a bounded size and a shorter timeout, and selects the section by interface language with a fallback to generic Chinese and then English.
Only builds with the public key compiled in check for updates automatically.

Mobile lifecycle

Mobile must handle backgrounding, network switches, disconnects, and reconnects. On recovery, first fetch authoritative sessions and timelines through Remote v2, then subscribe to live events; do not overwrite authoritative state with a stale projection.

Self-hosted deployment

Bind the services to loopback, then publish them through a controlled HTTPS reverse proxy or Tailnet Serve. Host and Origin must be validated independently, and CORS must not use *. The gateway exposes only protocol and health check endpoints; it serves no browser UI and no business API. See Self-hosted headless runtime and Self-hosted Relay for details.