# Candidate shipping artifacts

The installer adds `mobile-candidate.yml`, which calls the existing mobile workflow for a ready,
same-repository `task/` pull request whose frozen mobile intent changed. iOS and Android binaries
build alongside the repository's ordinary validation. Required source and merge-tree checks retain
their existing names and policies. Drafts and forks do not receive candidate builds or credentials.

Candidate mode reads the intent and store version state, prepares the signed binaries and retains
their symbols. It does not create an upload-owner deployment, create/rename an App Store version,
upload to either store or run Bitrise delivery. The existing upload boundary refuses candidate mode.
Bitrise repositories retain their ordinary main-branch delivery path.

After protected merge, each existing platform job looks for its matching candidate artifact. The
lookup never waits for a build to finish. A missing, expired, failed or mismatched candidate uses
the normal release build. Reads have short timeouts and downloading gets the remainder of a
two-minute lookup budget. Dependency caches are also optional and populate during existing jobs.

Reuse requires the same repository, platform, source/build inputs, current signing/account material,
successful producer job and retained file hashes. A successful platform's earlier artifact survives
rerunning only its failed sibling. Consumed custom workflow variables participate in fingerprints;
unrelated organization variables and the rotating Play edit binding do not. Dynamic whole-object
variable use is conservatively included. No credentials are retained inside the binary artifact.

The iOS action restores the frozen build number, marketing version, metadata and symbols, discovers
the current ASC key, and runs its existing version-slot, upload and metadata operations. A changed
store version cannot silently relabel an existing IPA. Candidate version planning can select the
same automatic floor adjustment as a normal release without writing source or store state; main
persists that version through the existing protected source-maintenance path. Prefer committing
the intended release version with the app change so ordinary updates need one candidate.

Android promotion uses the retained signed AAB with the current Play account and existing owned-edit
readback/upload protocol. It keeps review-pending annotations and version identity. iOS Firebase
symbols travel with the candidate artifact; the shipping run emits the console-upload demand once.

When adopting, review the installer’s replaced-binding receipt and retain app-specific workflow
configuration and validation. Native Xcode validation can use the same `native_cache.py` helper
and pinned cache programs as release builds. Cache Pods and `.factory/toolchain/gems` with the
helper's lockfile/Ruby/Xcode/architecture identity; `pod install --deployment` and committed locks
remain required. No warm-up job, machine affinity, reservation or factory wait protocol is added.
