guanghu/docs/adr/canary-release-channel-and-local-feature-flags.md
Guanghu Domestic Migration 9b41d51231
Some checks are pending
Auto-update PR branches / Update open PR branches (push) Waiting to run
CI / Frontend Static Quality Checks (push) Waiting to run
CI / Frontend Tests & Coverage (push) Waiting to run
CI / Rust Tests & Quality Checks (push) Waiting to run
CI / Linux build verification (push) Waiting to run
Deploy docs / Build VitePress site (push) Waiting to run
Deploy docs / Deploy to GitHub Pages (push) Blocked by required conditions
Release (Alpha) / Compute alpha version (push) Waiting to run
Release (Alpha) / Build release artifacts (push) Blocked by required conditions
Release (Alpha) / GitHub Release (alpha) (push) Blocked by required conditions
Release (Alpha) / Update docs and release pages (push) Blocked by required conditions
chore: import sanitized domestic snapshot for REPO-004
Source snapshot: 514ab1975951d94342ea38e64101d5a0f1c51c77
2026-07-17 15:55:28 +08:00

1.7 KiB

type, id, title, status, date
type id title status date
ADR 0017 Canary release channel and local feature flags active 2026-03-25

Context

Shipping new features directly to all users is risky. A mechanism was needed to let early adopters test pre-release builds and to gate experimental features behind flags that can be toggled without a new release.

Keyboard-first design principle

Decision

Add a canary release channel alongside stable, with builds from the canary branch. Feature flags are localStorage-based (ff_<name>) with compile-time defaults, checked via useFeatureFlag(flag) hook. The update channel is configurable in Settings.

Options considered

  • Option A (chosen): Canary branch + localStorage feature flags — simple, no server infrastructure, users opt in via Settings. Downside: no remote flag management, no gradual rollout percentages.
  • Option B: Server-side feature flags (LaunchDarkly, Unleash) — gradual rollouts, A/B testing. Downside: external dependency, requires server infrastructure, adds latency.
  • Option C: Single release channel with only feature flags — simpler CI. Downside: no way to test full pre-release builds.

Consequences

  • release.yml builds stable from main; release-canary.yml builds canary from canary branch.
  • Canary releases produce latest-canary.json on GitHub Pages, marked as prerelease.
  • useUpdater(channel) checks the appropriate update manifest.
  • useFeatureFlag(flag) checks localStorage override, then compile-time default. Type-safe via FeatureFlagName union.
  • update_channel stored in Settings as "stable" or "canary".
  • Re-evaluation trigger: if user base grows enough to warrant server-side gradual rollouts.