Skip to content

Establish shared-state Stable/Developer channel feeds and release artifacts #148

Open

Description

@NOirBRight

Problem

CodexHub v0.1.5 has one Stable updater path but no typed, user-selectable release channel or Developer prerelease feed. The former Beta design used a second product/runtime home, separate ports, and side-by-side ownership; that model conflicts with the accepted one-installation, shared-state product contract.

The current implementation distinguishes compile-time BuildFlavor (normal/debug) and keeps both flavors on one application identity, but updater selection is still derived from BuildFlavor. Without a separate ReleaseChannel contract and channel-aware signed manifests, later immediate switching would either conflate diagnostics with product cadence or guess artifact identity.

Accepted outcome

Establish the behavior-preserving shared-state release-channel foundation: typed ReleaseChannel values Stable and Developer, persisted independently of BuildFlavor; deterministic signed feed/manifest selection for every ReleaseChannel × BuildFlavor pair; and release automation that can publish complete Developer prereleases or record HOLD.

This foundation must not expose a selectable channel control that only changes the next update feed. The user-facing selector remains disabled or absent until the dependent immediate-transition Issue completes signed install, lower-version Stable rollback, compatibility checks, backups, and restart confirmation.

Scope and invariants

  • Add typed ReleaseChannel values Stable and Developer in the Rust command/state boundary and frontend/shared types where readback is required.
  • Keep ReleaseChannel independent of compile-time BuildFlavor (normal/debug).
  • Persist the effective channel in the existing shared runtime home without changing application identifier, installation path, ports, Gateway owner, Provider/model state, history, settings, or client backups.
  • Define deterministic signed updater endpoint/manifest selection for all four ReleaseChannel × BuildFlavor combinations.
  • Require channel, flavor, version, platform, URL, signature metadata, and artifact identity in the manifest contract so a later transition can fail closed on mismatch.
  • Use SemVer prereleases such as 0.1.6-dev.1 for Developer and normal releases such as 0.1.6 for Stable.
  • Add release-pipeline support for complete Developer candidates and Stable manifests for both BuildFlavors.
  • Treat each working day as a Developer release window, not a mandatory release. When no complete, reversible, green increment exists, record HOLD instead of publishing an empty or partial build.
  • Preserve all current Stable update behavior while the immediate-transition Issue is unfinished.
  • Keep the frontend selector disabled or absent until the dependent immediate-transition Issue atomically enables the full signed transition contract. Internal test/probe controls must not present partial production behavior.
  • Record the accepted ReleaseChannel versus BuildFlavor terminology in the repository domain/decision documentation touched by this work.

Non-goals

  • Installing or restarting into another channel.
  • Lower-version Stable downgrade authorization, custom version comparison, pending-transition completion, shared-data compatibility checks, or pre-install backup; the dependent transition Issue owns them.
  • Side-by-side Stable/Developer applications, separate data homes, separate ports, or concurrent Gateways.
  • Reintroducing Beta as a product, BuildFlavor, or runtime owner.
  • An arbitrary version picker, unsigned installer, or bypass of Tauri updater signature verification.
  • The full revisioned settings patch API or generated cross-language JSON Schema program.
  • Changing Provider routing, model semantics, Responses/Chat conversion, or diagnostic BuildFlavor behavior.
  • Automatically publishing a Developer build every day.

Acceptance criteria

  • ReleaseChannel has exactly Stable and Developer, round-trips through the shared settings/runtime boundary, and is not inferred from or serialized as BuildFlavor.
  • Stable and Developer retain the same application identifier, installation, runtime home, settings, Providers/models, history, client backups, Gateway ports, and Gateway ownership.
  • Signed manifest/feed selection is deterministic for every ReleaseChannel × BuildFlavor pair and rejects channel/flavor/platform/artifact identity mismatches in focused tests.
  • Existing Stable update checks remain behaviorally unchanged when no channel transition is requested.
  • Release automation can build a SemVer Developer prerelease and matching signed manifest for normal/debug without changing the Stable artifact identity.
  • The release workflow can explicitly record HOLD; it does not manufacture an empty or incomplete Developer candidate.
  • No production UI can leave the app in a state where only the future feed changed. The selector remains disabled/absent until the dependent immediate-transition Issue is complete.
  • Repository terminology clearly distinguishes ReleaseChannel from BuildFlavor and removes no existing diagnostic behavior.

Expected hotset

  • src-tauri/src/app_updates.rs
  • src-tauri/src/build_info.rs and/or one focused ReleaseChannel module
  • Shared settings/config persistence only for channel metadata
  • Frontend types/readback and UI-contract tests only as needed to keep the incomplete selector disabled
  • scripts/build-windows-release.ps1, release workflow/contracts, manifest fixtures, and bilingual release documentation

Dependencies and relationships

Blocked by #112 because release/update foundation work must consume the terminal lifecycle boundary rather than create a parallel restart owner. #112 consumes #143, which is blocked by #139.

Blocks the separate immediate signed channel-transition Issue. That Issue owns the selectable UI, signed installation, narrowly scoped lower-version Stable rollback, shared-data compatibility, atomic backup, exact-target confirmation, and legacy Beta-backup compatibility.

Related, not duplicate: #116 owns compile-time normal/debug BuildFlavor and is complete. #135's separate active Beta-home premise remains superseded.

Verification

  • cd src-tauri; cargo test --locked
  • cd src-tauri; cargo clippy --locked --all-targets -- -D warnings
  • cd frontend; npm run build; npm run test:ui-contract
  • Focused signed-manifest identity and release-pipeline contract tests
  • python -m pytest -q when shared release scripts/contracts exercise Python fixtures
  • python scripts/report_quality_gates.py (report-only; non-blocking)

Execution contract

Execution-Contract: v2
Verification-Class: strict
Verification-Commands: cd src-tauri; cargo test --locked; cd src-tauri; cargo clippy --locked --all-targets -- -D warnings; cd frontend; npm run build; npm run test:ui-contract; focused signed-manifest/release-pipeline contract tests; python -m pytest -q when applicable; python scripts/report_quality_gates.py (report-only)
Manual-Evidence: Validate one signed Developer prerelease manifest per BuildFlavor and one explicit HOLD release-window result without installing or changing the running channel.
Architecture-Decision: resolved
Review-Owner: orchestrator

Activity

  1. changed the title [-]Add shared-state Stable/Developer channels with immediate signed Stable rollback[/-] [+]Establish shared-state Stable/Developer channel feeds and release artifacts[/+] on Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestready-for-agentFully specified, ready for an AFK agentwayfinder:taskWayfinder implementation task

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions