diff --git a/CHANGELOG.md b/CHANGELOG.md index aa8d2f3e9f..6b57ca2119 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,19 @@ > completion state and remaining P0 gates. No version bump or release claim is > made here while that status holds. +## [1.64.16.0] - 2026-07-24 + +**A metadata error is not a login problem.** +**And the Apple release never opens a browser. Period.** + +A live run hit Apple's expanded age-rating questionnaire (new required attributes like lootBox, ageAssurance, parentalControls, messagingAndChat), misread the Spaceship validation error as an authentication failure, demanded an app-specific password, and started driving a browser at account.apple.com — three wrongs from one misdiagnosis. The adapter now classifies errors before touching credentials: only Apple's own words (401/403, session expired, "app-specific password") make an error an auth error; UnexpectedResponse/missing-attribute/validation errors are metadata problems fixed in the payload and retried from the CLI. And the adapter now explicitly overrides the general third-party browser-offer contract for the whole Apple journey: the only browser use it permits, ever, is the paid-app agreements/banking/tax residue. + +### Itemized changes + +### Changed + +- `references/APPLE-RELEASE.md` (ship tree): error-classification rule (metadata vs auth, with Apple's expanded age-rating attributes as the worked example); APPLE-RELEASE explicitly overrides THIRD-PARTY-ACTIONS within the Apple release — no browser, driven or manual, outside the named paid-app residue. + ## [1.64.15.0] - 2026-07-24 **A bad credential means "sign in again," not "go generate a password."** diff --git a/VERSION b/VERSION index d1636dd4a9..cf52465fdf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.64.15.0 +1.64.16.0 diff --git a/package.json b/package.json index 0e45dc340e..1b6b2ce34f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gstack", - "version": "1.64.15.0", + "version": "1.64.16.0", "description": "GStack 2 \u2014 six portable Agent Skills with an optional host-neutral runtime.", "license": "MIT", "type": "module", diff --git a/scripts/gstack2/generate-skill-tree.ts b/scripts/gstack2/generate-skill-tree.ts index 8faa9c0110..f9c499b5f9 100644 --- a/scripts/gstack2/generate-skill-tree.ts +++ b/scripts/gstack2/generate-skill-tree.ts @@ -674,8 +674,9 @@ Build this question's options from a LIVE check of installed skills at ask time 1. Archive and export the signed Release build with \`gym\` (it drives xcodebuild and the signing minted in preflight). Projects with custom archive requirements may drop to \`xcodebuild archive\` directly; the output either way is an App Store-signed \`.ipa\`. 2. The upload is an external effect: run \`pilot\` (TestFlight) or \`deliver\` (App Store) through the durable state wrapper with a key like \`appstore.upload..\`. Never re-upload on ambiguity; inspect App Store Connect for the build first. 3. The cached session is an env-level credential: never argv, never echoed, never committed. -4. NEVER demand an app-specific password. Per fastlane's documented authentication, the cached spaceauth session ALONE suffices for binary upload through \`deliver\`/\`pilot\`; \`FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD\` is an alternative for environments without a session, not a requirement on top of one. Attempt the session upload FIRST; only an actual authentication error from a real upload attempt may open a fallback conversation, and "Apple requires an app-specific password on 2FA accounts" stated without that error in hand is a contract violation. When a real error does force the fallback, QUOTE the error verbatim, then escalate in this order: FIRST treat it as an expired or invalid session — ask the user to sign in again (the same \`! fastlane spaceauth -u \` moment as the original authorization) and retry the upload with the fresh session. Only if a FRESH session still fails the same way does the app-specific-password path open, and its only shape is self-service: the user generates the password on any device and enters it through the host's in-session masked prompt into the macOS keychain (\`fastlane fastlane-credentials add --username \`), then the upload is retried. NEVER offer or recommend a browser drive to create credentials — no Aside, no agentic browser, for any password, key, or token, under any framing. -5. App Review contact details (name, email, phone) are required metadata for submission: infer name and email from the signed-in Apple ID and git config, collect the phone number once inside the authorization moment, persist it to the decision store, and never re-ask. Contact details are metadata, not a blocking gate to announce mid-run. +4. NEVER demand an app-specific password. Per fastlane's documented authentication, the cached spaceauth session ALONE suffices for binary upload through \`deliver\`/\`pilot\`; \`FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD\` is an alternative for environments without a session, not a requirement on top of one. Attempt the session upload FIRST; only an actual authentication error from a real upload attempt may open a fallback conversation, and "Apple requires an app-specific password on 2FA accounts" stated without that error in hand is a contract violation. CLASSIFY the error before touching credentials: an error is an authentication failure ONLY when it says so (401/403, session invalid or expired, "sign in", "app-specific password" in Apple's own words). A \`Spaceship::UnexpectedResponse\`, missing/invalid attribute, validation, or precheck error is a METADATA problem — fix the payload (for example, Apple's expanded age-rating attributes such as \`lootBox\`, \`ageAssurance\`, \`parentalControls\`, \`messagingAndChat\` in \`app_rating_config.json\`) and retry from the CLI. Treating a metadata error as a credential problem is a contract violation. +5. Within an Apple release, this adapter OVERRIDES \`references/THIRD-PARTY-ACTIONS.md\`: the general agentic-browser offer never applies to App Store Connect, Apple ID, or credential work here. The entire release is CLI (fastlane) plus the two permitted interactions; the ONLY browser use this adapter allows, ever, is the paid-app agreements/banking/tax residue named at the end of this document. Opening a browser — driven or manual — for anything else in this journey is a contract violation. When a real error does force the fallback, QUOTE the error verbatim, then escalate in this order: FIRST treat it as an expired or invalid session — ask the user to sign in again (the same \`! fastlane spaceauth -u \` moment as the original authorization) and retry the upload with the fresh session. Only if a FRESH session still fails the same way does the app-specific-password path open, and its only shape is self-service: the user generates the password on any device and enters it through the host's in-session masked prompt into the macOS keychain (\`fastlane fastlane-credentials add --username \`), then the upload is retried. NEVER offer or recommend a browser drive to create credentials — no Aside, no agentic browser, for any password, key, or token, under any framing. +6. App Review contact details (name, email, phone) are required metadata for submission: infer name and email from the signed-in Apple ID and git config, collect the phone number once inside the authorization moment, persist it to the decision store, and never re-ask. Contact details are metadata, not a blocking gate to announce mid-run. ## Storefront completion diff --git a/skills/ship/references/APPLE-RELEASE.md b/skills/ship/references/APPLE-RELEASE.md index bbaa536cf9..3c9cae0539 100644 --- a/skills/ship/references/APPLE-RELEASE.md +++ b/skills/ship/references/APPLE-RELEASE.md @@ -37,8 +37,9 @@ Build this question's options from a LIVE check of installed skills at ask time 1. Archive and export the signed Release build with `gym` (it drives xcodebuild and the signing minted in preflight). Projects with custom archive requirements may drop to `xcodebuild archive` directly; the output either way is an App Store-signed `.ipa`. 2. The upload is an external effect: run `pilot` (TestFlight) or `deliver` (App Store) through the durable state wrapper with a key like `appstore.upload..`. Never re-upload on ambiguity; inspect App Store Connect for the build first. 3. The cached session is an env-level credential: never argv, never echoed, never committed. -4. NEVER demand an app-specific password. Per fastlane's documented authentication, the cached spaceauth session ALONE suffices for binary upload through `deliver`/`pilot`; `FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD` is an alternative for environments without a session, not a requirement on top of one. Attempt the session upload FIRST; only an actual authentication error from a real upload attempt may open a fallback conversation, and "Apple requires an app-specific password on 2FA accounts" stated without that error in hand is a contract violation. When a real error does force the fallback, QUOTE the error verbatim, then escalate in this order: FIRST treat it as an expired or invalid session — ask the user to sign in again (the same `! fastlane spaceauth -u ` moment as the original authorization) and retry the upload with the fresh session. Only if a FRESH session still fails the same way does the app-specific-password path open, and its only shape is self-service: the user generates the password on any device and enters it through the host's in-session masked prompt into the macOS keychain (`fastlane fastlane-credentials add --username `), then the upload is retried. NEVER offer or recommend a browser drive to create credentials — no Aside, no agentic browser, for any password, key, or token, under any framing. -5. App Review contact details (name, email, phone) are required metadata for submission: infer name and email from the signed-in Apple ID and git config, collect the phone number once inside the authorization moment, persist it to the decision store, and never re-ask. Contact details are metadata, not a blocking gate to announce mid-run. +4. NEVER demand an app-specific password. Per fastlane's documented authentication, the cached spaceauth session ALONE suffices for binary upload through `deliver`/`pilot`; `FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD` is an alternative for environments without a session, not a requirement on top of one. Attempt the session upload FIRST; only an actual authentication error from a real upload attempt may open a fallback conversation, and "Apple requires an app-specific password on 2FA accounts" stated without that error in hand is a contract violation. CLASSIFY the error before touching credentials: an error is an authentication failure ONLY when it says so (401/403, session invalid or expired, "sign in", "app-specific password" in Apple's own words). A `Spaceship::UnexpectedResponse`, missing/invalid attribute, validation, or precheck error is a METADATA problem — fix the payload (for example, Apple's expanded age-rating attributes such as `lootBox`, `ageAssurance`, `parentalControls`, `messagingAndChat` in `app_rating_config.json`) and retry from the CLI. Treating a metadata error as a credential problem is a contract violation. +5. Within an Apple release, this adapter OVERRIDES `references/THIRD-PARTY-ACTIONS.md`: the general agentic-browser offer never applies to App Store Connect, Apple ID, or credential work here. The entire release is CLI (fastlane) plus the two permitted interactions; the ONLY browser use this adapter allows, ever, is the paid-app agreements/banking/tax residue named at the end of this document. Opening a browser — driven or manual — for anything else in this journey is a contract violation. When a real error does force the fallback, QUOTE the error verbatim, then escalate in this order: FIRST treat it as an expired or invalid session — ask the user to sign in again (the same `! fastlane spaceauth -u ` moment as the original authorization) and retry the upload with the fresh session. Only if a FRESH session still fails the same way does the app-specific-password path open, and its only shape is self-service: the user generates the password on any device and enters it through the host's in-session masked prompt into the macOS keychain (`fastlane fastlane-credentials add --username `), then the upload is retried. NEVER offer or recommend a browser drive to create credentials — no Aside, no agentic browser, for any password, key, or token, under any framing. +6. App Review contact details (name, email, phone) are required metadata for submission: infer name and email from the signed-in Apple ID and git config, collect the phone number once inside the authorization moment, persist it to the decision store, and never re-ask. Contact details are metadata, not a blocking gate to announce mid-run. ## Storefront completion