Use when releasing, submitting, or verifying a public Hussh One iOS App Store build cut from green main: Apple-managed signing with an Admin ASC API key, a binary whose backend is chosen by `backend_target` (default UAT, or production), per-version "What's New" and build attach via the ASC API, and the two-gate dispatch path (prepare-only default, opt-in irreversible public submit).
Resources
2Install
npx skillscat add hushh-labs/hushh-research/codex-skills-release-ios-appstore Install via the SkillsCat registry.
SKILL.md
Hussh Release iOS to App Store Skill
Purpose and Trigger
- Primary scope:
release-ios-appstore-scope - Trigger on releasing, submitting, or verifying a public iOS App Store build from a green
mainSHA. - Avoid overlap with
uat-scoped-deploy,mobile-native, and broadrepo-operationsintake.
Coverage and Ownership
- Role:
spoke - Owner family:
repo-operations
Owned repo surfaces:
.github/workflows/release-ios-appstore.ymlscripts/release/dispatch-ios-appstore.mjs
Non-owned surfaces:
mobile-nativeuat-scoped-deploysecurity-auditrepo-operations
Do Use
- Cutting a public App Store build from the latest green
main(prepare-only by default). - Setting per-version "What's New", attaching the processed build, and resolving the build number.
- Verifying an App Store Connect upload/version/submission state after a "Release iOS to App Store" run.
Do Not Use
- TestFlight-only distribution — use the
ship-ios-testflightsibling (same UAT-backed binary). - Merging code to
main; this ships what is already onmainand never merges. - Production Cloud Run deploys route to
repo-operations; scoped UAT deploys route touat-scoped-deploy. - Publish-safety clearance or consent-boundary decisions — route to
security-audit.
Read First
.github/workflows/release-ios-appstore.ymldocs/guides/mobile/release-ios-appstore.mdscripts/release/dispatch-ios-appstore.mjsscripts/ci/submit-appstore-version.pyscripts/ci/resolve-ios-build-number.pydeploy/app_store_deployment.md.codex/skills/repo-operations/references/admin-release-sop.md.codex/skills/release-ios-appstore/references/release-proof.md
Workflow
- Confirm the
ghactor is inconfig/ci-governance.json->production.manual_dispatch_users, else STOP (the run is rejected byscripts/ci/assert-governed-actor.pywith--surface production). - Pick SHA = user-provided else latest
origin/main; it must be an ancestor oforigin/main. - Require "Main Post-Merge Smoke Gate" = success on that exact SHA (the workflow re-checks via
scripts/ci/require-deploy-sha-on-main.shand refuses otherwise). - First run after any signing/secret change, dispatch a dry run (
make ios-prod-release-dry): archive + sign, no upload. A dry run does NOT catch a closed marketing-version train. - GATE 1 (every dispatch): restate workflow,
--ref main, short SHA, mode, backend target (uat=hushh-pda-uat, the default;production=hushh-pda/ one.hushh.ai), bundlecom.hushh.app; get an explicit yes, thenmake ios-prod-release ARGS="--sha <sha> --backend <uat|production> --yes --whats-new '<notes>'"(prepare-only default; no--submit). The first production-backed release moves existing App Store users from the UAT database to the production one. Name that in the gate, because their vault and records do not move with them. - If a marketing-version train is closed or its App Store version is locked, select a higher explicit
--marketing-versionto repackage the same deployed source SHA. The workflow verifies the app and extension archive versions and records the selected version in both receipts. A committedMARKETING_VERSIONbump is also supported, but its source must match the selected backend deployment. The build-number resolver never bumps the marketing version. Resolve an approved-but-unreleased Apple version before preparing its successor; publishing or withdrawing it requires its own authorization. - GATE 2 (public submission only): irreversible and publishes to real users; requires a fresh explicit yes and every publish-safety blocker cleared, then
--submit --ack-blockers(workflow inputsubmit_for_review=true). Never dispatch submit from automation or on assumption. - Verify from the ASC API and the run Job summary — uploaded, processed, "What's New" set, build attached, submitted-or-prepared — before reporting done. Never print, paste, or read the ASC
.p8/ Key / Issuer secrets. - A production-backed submit needs the dedicated production reviewer account and its App Review Information, set by hand in App Store Connect (
docs/guides/mobile/release-ios-appstore.md§ App Review sign-in on a production-backed build). Production never advertises or mints review mode (consent-protocol/api/routes/health.py), so do not "enable"APP_REVIEW_MODEthere, and never reuse the production reviewer UID as a UAT or devREVIEWER_UID: the lanes share one Firebase authority and UAT mints with no credential. - Any verify step shared with the TestFlight sibling must bring the same runtime. Run 36358944003 (2026-09-27) died in
verify:one-voiceonModuleNotFoundError: dotenv: the capability-graph generator needs the consent-protocol package, TestFlight got its Python step in 231c6e50f, and this lane did not. Diff both workflows' setup steps whenever a verify step is shared.
Handoff Rules
- If the request is broad or ambiguous, route it back to
repo-operations. - Route iOS native/Capacitor build, entitlement, or plist issues to
mobile-native. - Route production Cloud Run and web deploys to
repo-operations; route scoped UAT deploys touat-scoped-deploy. - Route publish-safety, consent, or secret-boundary findings to
security-audit.
Required Checks
gh run list --workflow release-ios-appstore.yml --limit 5 --json databaseId,status,conclusion,headSha,event,url
gh workflow view release-ios-appstore.yml
python3 .codex/skills/codex-skill-authoring/scripts/skill_lint.py