Problem:
The stable helper could consume immutable version tags if main-v2 advanced while exact-SHA CI or the protected relay was starting. Manual CLI and Desktop recovery also still accepted RC tags despite the official-only release contract.
Root cause:
The helper sampled main-v2 once, pushed only tag refs, and the orchestrator required the tags to equal the later branch tip. The candidate was not proven to be the commit that changed the target reviewed Notes record.
Fix:
Bind normal candidates to their reviewed Notes change, revalidate exact push CI from the protected control plane, include main-v2 as a guarded ref in the atomic tag transaction, and accept the immutable candidate after later protected branch advances. Restrict manual CLI and Desktop recovery to official versions while retaining historical reusable-workflow parsing.
Verification:
- bash scripts/release-stable.test.sh
- bash scripts/release-workflows.test.sh
- node --test scripts/release-notes.test.mjs
- actionlint on all active release workflows
- site contract tests, SignPath contract tests, Desktop control-plane test, cache guard, and git diff --check
Problem:
- Preview events for different versions could overlap and let an older npm canary publish last.
- CLI, Desktop, and npm child workflows still exposed standalone public Preview paths that bypassed the all-surface release marker.
Root cause:
- The Preview concurrency key included the version tag, while npm had no channel-level serialization.
- Child workflow dispatch inputs and resolvers treated Preview publication as independently recoverable.
Fix:
- Serialize every Preview event and npm dist-tag publisher, and require public CLI, Desktop, and npm Preview releases to come from release-preview.yml.
- Keep Stable/RC recovery and non-publishing Desktop signing checks available, document unified Preview recovery, and add regression coverage.
Verification:
- bash scripts/release-workflows.test.sh
- actionlint v1.7.7 on all release workflows
- git diff --check
Problem:
- Existing CLI and Desktop manifests predate exact release-note URLs, RC notes had no supported catalog path, and unpublished exact routes could 404.
- The Preview SignPath call-graph test also retained the old allowlist.
Root cause:
- New manifest validation and byte comparisons did not distinguish legacy persisted objects from newly generated candidates.
- Standalone RCs were treated as public changelog identities, and version routes were generated only after publication markers.
Fix:
- Add strict and legacy validation plus semantic comparators that normalize only the missing release-notes field and preserve immutable Desktop manifests.
- Reuse Stable notes for standalone RCs, generate safe unpublished redirects, and update the SignPath contract test.
- Add focused workflow, manifest, route, and RC regression coverage.
Verification:
- bash scripts/release-workflows.test.sh
- go test ./... and go vet ./...
- desktop go test ./... and go vet ./...
- site npm test and npm run build
- node --test scripts/release-notes.test.mjs
- actionlint with the repository CI allowlist
- live v1.18.0 CLI and Desktop manifest compatibility checks
Context: Stable and Preview need independent reviewed identities while CLI, Desktop, npm, and changelog publication remain one protected release event.
Changes:
- Add a protected Preview orchestrator with a shared ordinal and SignPath preflight.
- Bind reviewed release notes to immutable all-surface publication markers.
- Route downloads and changelog archives by channel with accessible theme-aware navigation.
- Harden release authorization, manifests, tests, and operator documentation.
Compatibility:
- Legacy catalog entries without managed status remain readable and public.
- Existing Stable pointers remain unchanged, and Preview continues mirroring the legacy canary pointer for older Desktop clients.
- No persisted user state or Wails JSON contract changes.
Verification:
- bash scripts/release-workflows.test.sh
- node --test scripts/release-notes.test.mjs
- cd desktop && go test ./cmd/sign ./internal/update
- cd site && npm test
- cd site && npm run build
- actionlint for all release workflows
Context:
Reasonix needed one public Stable/Preview contract across native CLI archives and Desktop updates while keeping npm prerelease tags independent.
Changes:
- Add protected native CLI Preview prereleases without moving Homebrew or GitHub Latest.
- Add persistent Desktop Stable/Preview selection, channel-aware update state, R2 pointers, and legacy Canary compatibility.
- Preserve the complete production Windows payload and installer signing chain and fail closed when signing or Preview R2 prerequisites are unavailable.
- Add release gateway routing, workflow contracts, compatibility coverage, and bilingual settings copy.
Compatibility:
Missing and unknown Desktop channel settings remain Stable. Legacy canary, beta, and next settings normalize to Preview. New Preview clients reject stale test-signed Canary manifests while older clients retain the mirrored canary pointer.
Verification:
Root and Desktop Go suites, frontend test:all and production build, crash-report Worker typecheck and 45 tests, release workflow contracts, cache guard, release notes tests, six native CLI target builds, CodeQL, race, and Windows NSIS/portable CI all pass on head 97623c982.