From 8bf93f372bfc3083b4bf491fe6247fc67463d404 Mon Sep 17 00:00:00 2001 From: jjbrunton Date: Mon, 31 Aug 2026 10:08:03 +0100 Subject: [PATCH] docs(release): authorize scoped store uploads --- .codex/skills/generate-release/SKILL.md | 10 +++-- .codex/skills/release-mobile/SKILL.md | 35 ++++++++---------- docs/releasing.md | 49 +++++++++++++------------ 3 files changed, 48 insertions(+), 46 deletions(-) diff --git a/.codex/skills/generate-release/SKILL.md b/.codex/skills/generate-release/SKILL.md index 25e60da..25a6477 100644 --- a/.codex/skills/generate-release/SKILL.md +++ b/.codex/skills/generate-release/SKILL.md @@ -13,9 +13,13 @@ drafting notes and [references/artifact-verification.md](references/artifact-ver before accepting a build. A request to generate or create a release authorizes the scoped version edits, -release notes, local builds, release commits, and one local annotated tag. It -does not authorize pushing commits or tags, uploading binaries, submitting a -store release, changing signing credentials, or regenerating native projects. +release notes, local builds, release commits, and one local annotated tag. When +the request also specifies a mobile release, upload, or store-submission +workflow, it authorizes the requested store upload within its stated platform +and destination scope after the exact artifact has been verified. It does not +authorize pushing commits or tags, changing signing credentials, regenerating +native projects, a public rollout, App Review submission, or additional +TestFlight distribution unless the request explicitly includes that action. ## Defaults diff --git a/.codex/skills/release-mobile/SKILL.md b/.codex/skills/release-mobile/SKILL.md index ba7e23c..d1ff6be 100644 --- a/.codex/skills/release-mobile/SKILL.md +++ b/.codex/skills/release-mobile/SKILL.md @@ -18,13 +18,13 @@ so routine release builds must package those checked-in sources. Do not run `expo prebuild` first; native regeneration is a separate reviewed change. Use the package scripts in `apps/mobile/package.json`; they create artifacts only. -Never infer upload or submission authority from build authorization. Store upload -uses a separately authorized command. +An explicit request for a mobile release, upload, or store-submission workflow +authorizes the requested store upload within its stated platform and destination +scope. Building an artifact alone does not authorize an upload. -## Upload authorization gate +## Upload execution -After an artifact passes verification, stop immediately before the external -upload and ask the user for confirmation. The request must identify: +Before an external upload, independently verify and report: - the platform, exact artifact path, bundle/package identifier, public version, build number, signature identity, and SHA-256 digest; @@ -33,24 +33,21 @@ upload and ask the user for confirmation. The request must identify: - that the upload does not authorize a public rollout or App Review submission. For iOS, inspect the current App Store Connect automatic-distribution behavior -before asking. If the build would be distributed automatically, name the exact -TestFlight groups or testers in the request and include that effect in the fresh -authorization. If the effect cannot be established, stop; changing an automatic- -distribution setting also requires separate authorization. +before uploading. If the build would be distributed automatically, report the +exact TestFlight groups or testers. If the effect cannot be established, stop; +changing an automatic-distribution setting is a separately authorized action. -Even when the original request includes building, releasing, uploading, or -submitting, require this fresh confirmation once the exact verified artifact and -destination are known. End the request with: `Upload this verified artifact to - now?` A clear affirmative response authorizes one upload of that -artifact to that destination, plus only any automatic TestFlight distribution -explicitly disclosed in the request. Run `eas submit` with the explicit +Once these details match the user's stated scope, upload without requesting a +second confirmation. Run `eas submit` with the explicit `--platform`, `--profile production`, `--path`, and `--wait` arguments; never select `--latest`. If the result is ambiguous, inspect EAS and the store before -doing anything else, do not retry, and ask again before another upload. +doing anything else; do not retry unless the user explicitly authorizes another +upload. -Apply this gate to every upload method, including EAS, Fastlane, Xcode Organizer, -and the store consoles. A later public rollout, App Review submission, or -additional TestFlight distribution requires another fresh authorization. +Apply this policy to every upload method, including EAS, Fastlane, Xcode +Organizer, and the store consoles. A public rollout, App Review submission, or +additional TestFlight distribution requires separate explicit authorization +unless it was expressly included in the original request. Preserve platform signing and local EAS versioning. After a build, verify that tracked changes are limited to the expected version metadata, then independently diff --git a/docs/releasing.md b/docs/releasing.md index 5f9ec96..cec20a2 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -36,7 +36,9 @@ npm run release:ios Output files are placed in the current directory by default. These scripts create signed artifacts only. They do not upload or submit them. -Store mutation always requires a separate, explicitly authorized command. +An explicit request for a mobile release, upload, or store-submission workflow +authorizes the requested store upload within its stated platform and destination +scope. Building an artifact alone does not authorize an upload. ## Submit a local artifact with EAS @@ -56,27 +58,26 @@ eas submit --platform android --profile production --path /absolute/path/to/sauc eas submit --platform ios --profile production --path /absolute/path/to/sauci.ipa --wait ``` -Agents must not upload immediately after building, whether they use EAS, -Fastlane, Xcode Organizer, or a store console. Once the artifact is verified, the -agent must show the user the platform, exact path, bundle/package identifier, -version, build number, signing identity, SHA-256 digest, and destination, then ask -for a fresh confirmation to upload it. This confirmation authorizes one upload -of that exact artifact to that exact destination, even if the earlier request -already said to build, release, upload, or submit. +Agents must not upload an unverified artifact, whether they use EAS, Fastlane, +Xcode Organizer, or a store console. Before upload, they must verify and report +the platform, exact path, bundle/package identifier, version, build number, +signing identity, SHA-256 digest, and destination. Once those details match the +user's stated scope, proceed without asking for a second confirmation. -Before an iOS confirmation, inspect App Store Connect for automatic TestFlight -distribution. If upload will add the build to existing groups or testers, name -them in the confirmation and include that effect in the authorization. If the -effect cannot be established, stop. Changing automatic-distribution settings is -a separate action and requires its own authorization. +Before an iOS upload, inspect App Store Connect for automatic TestFlight +distribution. If upload will add the build to existing groups or testers, report +them before proceeding. If the effect cannot be established, stop. Changing +automatic-distribution settings is a separate action and requires its own +authorization. Do not use `--latest` for a local release. Before upload, verify the artifact's package or bundle identifier, public version, build number, signature, and SHA-256 digest. After upload, read back the same identity and version from Google Play Console or App Store Connect. Public rollout, App Review submission, and additional TestFlight group distribution remain separate, explicitly authorized -actions. If an upload command returns an ambiguous result, inspect EAS and the -store first; do not retry unless the user gives fresh authorization. +actions unless the original request expressly includes them. If an upload command +returns an ambiguous result, inspect EAS and the store first; do not retry unless +the user explicitly authorizes another upload. ### Source integrity @@ -250,9 +251,9 @@ android/app/build/outputs/bundle/release/app-release.aab ### Step 5: Upload to Play Store -Apply the upload authorization gate above before opening or changing the release. -Uploading the AAB and starting any rollout are separate actions; ask again before -the rollout. +Apply the upload execution policy above before opening or changing the release. +Uploading the AAB and starting any rollout are separate actions unless the +original request expressly includes the rollout. 1. Go to [Google Play Console](https://play.google.com/console) 2. Select **Sauci** app @@ -261,8 +262,8 @@ the rollout. 5. Upload the `.aab` file 6. Add release notes, save the release as a draft, and read it back -Do not send the draft for review or start a rollout without the separate fresh -authorization described above. +Do not send the draft for review or start a rollout unless the original request +expressly includes that action. ### Verifying Keystore Fingerprint @@ -300,8 +301,8 @@ cd .. ### Step 4: Upload to App Store -Apply the upload authorization gate above before using Xcode Organizer. Include -any verified automatic TestFlight distribution in the confirmation. +Apply the upload execution policy above before using Xcode Organizer. Report any +verified automatic TestFlight distribution before uploading. 1. In Xcode Organizer (Window → Organizer), select the archive 2. Click **Distribute App** @@ -310,8 +311,8 @@ any verified automatic TestFlight distribution in the confirmation. ### Step 5: Submit in App Store Connect -Submitting for App Review is not authorized by the upload confirmation. Ask the -user for fresh authorization immediately before this step. +Submitting for App Review is not authorized by an upload request unless the +original request expressly includes App Review submission. 1. Go to [App Store Connect](https://appstoreconnect.apple.com) 2. Select **Sauci**