Skip to main content

Channels (Tracks) and Zero-Recompile Promotion

The /apps/[appId]/tracks page (src/app/apps/[appId]/tracks/page.tsx) isolates OTA patch validation across deployment environments (Tracks / Channels) and lets operators promote a certified binary from one channel to another without ever recompiling Dart source code.


1. Standard and Custom Channels​

By default, every application includes three standard tracks, and operators can create custom tracks at any time:

ChannelRecommended UsageTypical Behavior
devInternal development and integration testingFast auto-approval when Four-Eyes is disabled; tested on emulators or developer devices
stagingQA acceptance testing, pre-production, and UATGuarded by the QA Device Whitelist (allowedClientIds) to prevent leaks outside the testing team
stableProduction fleet (end users)Protected by the IN_STORE_REVIEW shield, Four-Eyes approval (APPROVED_AND_SIGNED), and progressive Canary rollout
Custom ChannelsDedicated tracks (e.g., beta-vip, branch-pilot, internal-canary)Created via the New Track button on /apps/[appId]/tracks and persisted in localStorage under tks_custom_channels_<appId> (automatically merged with any channel returned by the backend)

2. Why Zero-Recompile Promotion Matters​

In traditional mobile CI/CD pipelines, recompiling an application between staging and stable introduces two major risks:

  1. Non-deterministic Binary Drift: Build timestamps, transitive dependency changes, or environment flags shifting between the QA build and the production build.
  2. Invalidated QA Sign-off: The binary delivered to production users on stable is no longer mathematically identical to the binary certified by QA on staging.

With TkushPatch's 1-Click Promotion (TkushPatch Server), the server reuses the exact same physical .vmcode artifact (diffArtifactPath), the exact same targetSha256Hash, and the exact same .symbols file.

Track Promotion Workflow
  1. Pre-Production Testing: Patch is thoroughly tested on staging with registered QA test devices.
  2. Promotion Action: Once certified, authorized manager clicks Promote to Stable in the Web Console.
  3. Production Sealing: The patch is signed with production credentials and general distribution begins.

3. How Promotion Works Under the Hood (POST /api/admin/v1/patches/{id}/promote)​

When an authorized operator (ROLE_ADMIN or ROLE_SECURITY_OFFICER, holding the PROMOTE_PATCH permission) clicks Promote from /apps/[appId]/tracks, /releases, or /rollout:

  1. HTTP Request:
    POST /api/admin/v1/patches/{patchId}/promote
    Content-Type: application/json

    {
    "target_channel": "stable",
    "promoted_by": "ciso@company.com",
    "tenant_id": "sara-money"
    }
  2. Server-Side Security Checks (TkushPatch Server):
    • Verifies multi-tenant isolation (assertReleaseBelongsToTenant).
    • Strict Status Check: Only a patch in the APPROVED_AND_SIGNED state can be promoted (sourcePatch.status() == PatchStatus.APPROVED_AND_SIGNED). Any STAGED or ROLLED_BACK patch is rejected.
    • Channel Check: Prevents promoting a patch onto its own source channel (cleanTargetChannel.equalsIgnoreCase(sourcePatch.channel())).
  3. Per-Channel Sequential Numbering:
    • The server computes the next sequential patch number on the target channel for that release: nextPatchNumber = patchRepository.findMaxPatchNumberForReleaseAndChannel(releaseId, cleanTargetChannel) + 1.
  4. Per-Environment Cryptographic Re-signing (When Key Isolation is Enabled):
    • When ota.crypto.per-environment-keys-enabled=true, cryptoSigner.signPatchHash(tenantId, appId, cleanTargetChannel, targetSha256Hash) signs the target SHA-256 hash using the target channel's isolated RSA key (prod vs nonprod). Otherwise, the certified signature is preserved.
  5. Audit Trail and Cache Eviction:
    • The promoted patch is saved with approvedBy = "PROMOTED_FROM_<SOURCE_CHANNEL>:<promotedBy>", the L1/L2 cache for the release is immediately evicted, and a PATCH_PROMOTED audit log entry is recorded with sourcePatchId, sourceChannel, targetChannel, and patchNumber.