Fork Strategy & Upstream Sync
Relevant source files
The following files were used as context for generating this wiki page:
The dash project is a maintained fork of basecamp/kamal. Its primary purpose is to provide features and improvements that are unlikely to be merged into the upstream repository, specifically advanced proxy load balancing, rate limiting, and compression. The project maintains a strict separation between upstream code and fork-specific enhancements to ensure seamless synchronization and long-term maintainability.
The strategy relies on maintaining two primary branches: main (a mirror of upstream) and dash (the fork's development root). By keeping certain files pristine and using unique naming conventions for fork-owned assets, the project avoids merge conflicts and protects the fork's identity.
Sources: CLAUDE.md:1-7, ROADMAP.md:3-8
Branch Management & Repository Structure
The fork follows a "dual-primary" branch strategy to manage the relationship with the upstream repository.
Branch Definitions
main: A fast-forward-only mirror ofbasecamp/kamal. No commits are ever made directly to this branch.dash: The root branch for all fork-specific features and releases.- Feature Branches: These must always be rooted off the
dashbranch. If a feature is intended for upstreaming, a separatemain-rooted branch is created.
Git Workflow Diagram
The following diagram illustrates the flow of code from upstream through the fork branches.
Sources: CLAUDE.md:12-14, CLAUDE.md:27-28, CLAUDE.md:43-48
Synchronization Protocol
Synchronization with upstream is a manual process designed to minimize conflicts by protecting upstream-owned files.
Protection Rules
To prevent sync conflicts, the following files and tags are treated as immutable within the fork context:
kamal.gemspec: Kept pristine to match upstream; the fork usesdash.gemspec.bin/release: Upstream release script; the fork usesbin/release-dash.- Git Tags: The fork avoids
v*tags (owned by upstream) and instead usesdash-v<version>.
Sync Execution
A sync is initiated by fetching from the upstream remote and merging the mirrored main branch into dash.
git fetch upstream --tags --prune
git checkout dash
git merge main
# Post-sync: mirror dependency changes from kamal.gemspec to dash.gemspec
diff kamal.gemspec dash.gemspec
Sources: CLAUDE.md:15-20, CLAUDE.md:32-34, CLAUDE.md:52
Fork Identity and Divergence
The fork maintains its identity by overriding specific configuration defaults and metadata while preserving the core Kamal:: Ruby namespace.
| File Path | Purpose of Divergence |
|---|---|
dash.gemspec | Defines the gem as dash instead of kamal. |
lib/kamal/configuration/proxy/run.rb | Sets MINIMUM_VERSION and default repository to ghcr.io/mhenrixon/kamal-proxy. |
Gemfile | References gemspec name: "dash" to avoid ambiguity. |
.github/workflows/* | Configured for CI on the dash branch and publishing to fork-owned registries. |
Sources: CLAUDE.md:4-6, CLAUDE.md:50-59
Release Strategy
Releases for the dash gem are tightly coupled with the kamal-proxy sibling repository. A gem release is only permitted once the corresponding proxy image exists.
Versioning Logic
The fork uses a four-segment versioning scheme (e.g., v<upstream-base>.<counter>) to ensure it sorts correctly relative to upstream releases:
- Segment 1-3: Matches the current base upstream version (e.g.,
0.9.2). - Segment 4: A fork-specific counter (e.g.,
.1). - Result:
v0.9.2.1is newer than upstreamv0.9.2but older than the future upstreamv0.9.3.
Sequence Diagram: Release Flow
The diagram below shows the required ordering for releasing fork components.
Sources: CLAUDE.md:21-25, CLAUDE.md:61-63, ROADMAP.md:129-131
Summary
The dash fork strategy focuses on non-destructive extension of the kamal project. By mirroring upstream on a protected main branch and rooting all development on a separate dash branch, the project enables high-velocity feature development (e.g., advanced load balancing and security) while maintaining a low-friction path for integrating upstream updates. All releases are synchronized with a customized proxy image and follow a strict four-segment versioning protocol to maintain compatibility and clear provenance.