Channels & Releases
Relevant source files
The following files were used as context for generating this wiki page:
Crisp utilizes a multi-channel release architecture designed to separate stable production environments from experimental development and integration stages. The system consists of three distinct channels—Stable, Nightly, and Dev—each featuring unique identifiers, application icons, and update behaviors. This structure ensures that new features are rigorously tested in isolation before reaching the end-user.
The release lifecycle is governed by automated promotion scripts and CI/CD pipelines that enforce quality gates, including linting and unit testing, before any code is merged into the stable branch. This page details the technical implementation of these channels, the versioning logic, and the release automation workflow.
Sources: CLAUDE.md:126-150, apps/desktop/build.sh:5-30, README.md:39-43
Release Channels Architecture
Crisp is designed to allow all three channels to be installed side-by-side on a single macOS system. This is achieved through distinct Bundle Identifiers, application names, and data directories defined during the build process.
| Attribute | Stable | Nightly | Dev |
|---|---|---|---|
| App Name | Crisp | Crisp Nightly | Crisp Dev |
| Bundle ID | com.syntaxlabtechnology.crisp | ...crisp.nightly | ...crisp.dev |
| Icon Color | Blue | Amber | Purple |
| Auto-Update | Enabled (GitHub API) | Enabled (Rolling Release) | Disabled (Local Only) |
| Branch | main | nightly | Local/Feature branches |
Sources: CLAUDE.md:131-143, apps/desktop/build.sh:11-30, README.md:39-43
Channel Identification Logic
The channel is determined at runtime via the CrispChannel key in the application's Info.plist. The Swift Channel enum parses this value to drive behavior such as update availability and directory paths for logs and models.
The application uses the Channel enum to manage per-channel data directories (e.g., ~/.crisp*) so that settings and logs do not conflict between versions.
Sources: CLAUDE.md:131-143, apps/desktop/build.sh:32-95
Versioning Scheme
Crisp employs a deterministic versioning system based on the git history of the protected branches.
- Stable Versioning: Calculated as
0.<total commit count on main>. This ensures the version number is monotonic and never moves backward. - Nightly Versioning: Uses the format
0.<count>-nightly, but relies on aCrispBuildNumber(the CI run number) for numerical comparison in the updater. It also bakes inCrispBuildInfocontaining the specificbranch@sha. - Numerical Comparison: The internal updater compares versions numerically to ensure updates are only applied when a higher version number is detected.
Sources: CLAUDE.md:126-130, apps/desktop/build.sh:75-90
Release Automation & Promotion
The promotion of code from development to stable follows a strict hierarchical path: Feature Branch → nightly → main.
The Promotion Script
Code is never manually committed to main. Instead, a promotion script (promote.sh) is triggered every Thursday or via manual dispatch. It performs the following sequence:
- Verification: Runs Swift builds, unit tests, SwiftLint, and Python engine tests.
- Tree Sync: Sets the
mainbranch tree to exactly matchnightly. - Squash Commit: Creates a single squash commit on
main, which triggers the final production release.
Machine Learning Model Channels
The release channel concept extends to the on-device ML models (e.g., Wren). Models are published to Hugging Face with branches mirroring the app's channels:
- Nightly Branch (HF): Staging area for new model versions.
- Main Branch (HF): Stable models promoted after testing.
Promotion is handled via promote_model.py, which copies the model manifest from the nightly branch to the main branch on Hugging Face.
Sources: research/filler_classifier/publish_hf.py:16-25, research/NOTES.md:177-195, apps/desktop/Tests/CrispTests/FillerModelDevFlowTests.swift:14-20
Build Configuration
The build.sh script is the central entry point for generating channel-specific binaries. It handles the injection of environment variables and the signing of bundled binaries.
Key Build Flags
CRISP_CHANNEL: Sets the target channel (stable,nightly,dev).CRISP_VERSION: Overrides the auto-calculated version string.CRISP_LICENSING: Toggles the Polar.sh licensing feature (defaults toNO).CODESIGN_IDENTITY: Specifies the certificate for signing Mach-O binaries and the app bundle.
Sources: apps/desktop/build.sh:5-20, apps/desktop/build.sh:95-115
Binary Signing Architecture
Crisp bundles several sub-components that require individual signing before the main application bundle is sealed. This include the Python runtime, FFmpeg, and the crisp-filler helper.
Sources: apps/desktop/build.sh:160-185
Conclusion
The Crisp release system leverages a robust channel-based architecture to balance rapid iteration with production stability. By isolating build identifiers and utilizing automated promotion scripts, the project ensures that stable users receive thoroughly verified updates while developers and early adopters can test experimental features through the Dev and Nightly channels.
Sources: CLAUDE.md:126-150, README.md:39-43