merge origin/main (cross-store text checker); macOS platform pitfall renumbered to 79
This commit is contained in:
commit
9db7180eb9
35 changed files with 618 additions and 60 deletions
|
|
@ -25,6 +25,9 @@ true; never use competitor or other apps' or games' names, "best / #1", or unrel
|
|||
- **Screenshot captions**: write them with the words people search for ("Budget planner with shared lists", "Match 3 puzzles offline", not "Fun awaits").
|
||||
Claims that Apple reads caption text for search ranking are unverified; good captions help conversion either way.
|
||||
- Changing keywords needs a new version (submitted with it); promotional text (170) changes any time but is not indexed.
|
||||
- **No other platforms (2.3.10)**: no Android, Google Play (Games), Play Store, Galaxy Store, Amazon Appstore, Steam,
|
||||
Microsoft Store, AppGallery (and localized forms such as "Google Play Spiele", "安卓") in any App Store field,
|
||||
What's New included. Every App Store text write refuses them (store-pitfalls 77).
|
||||
|
||||
## Google Play
|
||||
- **Indexed**: title (30), short description (80), full description (4000). There is no keyword field.
|
||||
|
|
@ -33,6 +36,9 @@ true; never use competitor or other apps' or games' names, "best / #1", or unrel
|
|||
- **No stuffing**: a word in more than ~3 % of the full description, keyword lists, ALL CAPS titles, emoji in the
|
||||
title, or "best / top / #1" break the metadata policy. `check --aso` warns on these.
|
||||
- Localize every listing you can; Play machine-translates otherwise, which ranks and converts worse.
|
||||
- **No Apple platforms (Metadata policy)**: no iOS, iPhone, iPad, App Store, Apple Arcade, Game Center or TestFlight in
|
||||
the title, descriptions or release notes; every Play text write refuses them. A real sign-in button name ("Sign in
|
||||
with Apple") stays only through the owner's `listing.allowPlatformMentions` entry.
|
||||
|
||||
## Workflow
|
||||
1. List 20-30 candidate terms with the owner: what people would type to find this app (the job it does, the problem it solves; for a game:
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ presses release; you prepare, dry-run and report. `storebound mcp` deliberately
|
|||
`storebound apple listing --version 1.3.0 --build <that number>`. Never pick "the latest build": a CI or a
|
||||
teammate may have uploaded another one meanwhile.
|
||||
2. `storebound apple release --phased on --dry`, then without `--dry` (works while the version is being prepared).
|
||||
With versions on more than one App Store platform add `--platform ios|macos|tvos|visionos` (pitfall 77).
|
||||
With versions on more than one App Store platform add `--platform ios|macos|tvos|visionos` (pitfall 79).
|
||||
3. Submit (owner, UI). Wait: `storebound apple status --wait-review` (polls with backoff, exit 0 approved, 1 rejected,
|
||||
7 timeout; `--timeout 72h`). Rejected: `review-rejections` skill.
|
||||
4. Approved = PENDING_DEVELOPER_RELEASE. Owner releases: `storebound apple release --manual-release` (asks to confirm)
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ in-app purchases). Resubmit that same submission; never create a second one next
|
|||
3. `storebound apple resubmit --build <n>` (dry run without `--yes`): the plan table shows the build to attach, the
|
||||
submission reused, every item in it already or added, which REJECTED items are marked resolved, and the submit.
|
||||
An app with a macOS (tvOS, visionOS) version too: it picks the platform whose version was rejected, and asks for
|
||||
`--platform ios|macos|...` when both were (pitfall 77).
|
||||
`--platform ios|macos|...` when both were (pitfall 79).
|
||||
4. The owner's yes, then `storebound apple resubmit --build <n> --yes`: build n is attached by its number, missing
|
||||
items go in, the REJECTED version item is marked resolved (`PATCH reviewSubmissionItems/{id}` `resolved: true`),
|
||||
then it submits. Apple answers every submit with "Version is not ready to be submitted yet" (and the console's
|
||||
|
|
@ -89,6 +89,11 @@ Plain, polite, specific; one guideline per paragraph; no blame, no threats, no "
|
|||
- **2.3 Accurate metadata**: screenshots must show the real app (for a game: real gameplay); no prices, no "free"
|
||||
claims for paid items, no other platforms' UI; keywords without competitor names; age rating answers that match
|
||||
the content.
|
||||
- **2.3.10 Accurate Metadata (other platforms)**: "Android", "Google Play", "Google Play Games" or another store in
|
||||
any App Store text, often a What's New copied from notes shared with Play (store-pitfalls 77). Fix: remove the
|
||||
lines (tag shared notes `[play]` / `[apple]`, `storebound whats-new apply`), `storebound check` must show no
|
||||
`other platform` blocker, push with `apple listing --version x.y.z`, reply "removed the references to other
|
||||
platforms" and resubmit. Play's mirror case is the Metadata policy (iOS, App Store, Game Center in Play text).
|
||||
- **2.3.1 Hidden or undocumented features** (Play: Deceptive behavior): remote config, feature flags or a remote
|
||||
paywall the review notes did not mention (`storebound scan` rule `remote-features`, store-pitfalls 74). Fix: say in
|
||||
the notes which SDK changes what remotely; a business-model change needs a new review and a description update.
|
||||
|
|
|
|||
|
|
@ -36,8 +36,10 @@ storebound api apple salesReports_getCollection --param ... --out report.gz #
|
|||
## Write (only the owner sends)
|
||||
1. Run the write without `--yes`: it prints the exact request (method, URL, body; the key is never shown) and sends
|
||||
nothing. Show that to the owner.
|
||||
2. The owner runs it in their own terminal with `--yes`. Outside an interactive terminal, under MCP or in the desktop
|
||||
app, a write is never sent, whatever the flags.
|
||||
2. The owner runs it in their own terminal with `--yes`. Under MCP or in the desktop app a write is never sent,
|
||||
whatever the flags. `--yes` with stdout not a TTY (piped `| tail`, redirected `> out.json`, an agent's shell) is
|
||||
refused: exit 1 and "refused: writes through `storebound api` need an interactive terminal ... Nothing was sent."
|
||||
on stderr (store-pitfalls 78). Never pipe or redirect a write; use the dedicated command the message names.
|
||||
3. Owner-only operations (cli/api/gate.ts: every DELETE, submissions and their cancel, release requests, phased
|
||||
release changes, product page test start / stop, price schedules and price migrations, review replies, tester and
|
||||
user invitations, Play `edits.commit`, product activation, refunds, revokes and cancels, app signing) also ask for
|
||||
|
|
|
|||
|
|
@ -763,7 +763,8 @@ that fails without the fix (see CONTRIBUTING.md).
|
|||
bundleIdCapabilities answers, lag, a write that never sticks).
|
||||
|
||||
## 66. `storebound api apple ... --body f.json --yes` only dry-ran from an agent
|
||||
- **Do:** expected: writes through `storebound api` are sent only from an interactive terminal, by design. Use the
|
||||
- **Do:** expected: writes through `storebound api` are sent only from an interactive terminal, by design (since
|
||||
pitfall 78 it is a loud refusal with exit 1, not a dry run). Use the
|
||||
dedicated command the message names (bundle id capabilities: `apple signing ensure`; IAPs: `apple iap`; listing:
|
||||
`apple listing`, ...), which runs anywhere with its own dry run and read-back.
|
||||
- **Guard:** `dedicatedCommand` (cli/api/gate.ts), `tests/signing-capabilities.test.ts`.
|
||||
|
|
@ -941,7 +942,30 @@ that fails without the fix (see CONTRIBUTING.md).
|
|||
re-run, still processing, rejected / archived files, add-for-review without submitting, verify read-only with the
|
||||
waiting state, a refused live placement, the validate finding).
|
||||
|
||||
## 77. A macOS (tvOS, visionOS) version was invisible next to the iOS one
|
||||
## 77. What's New shared with Play rejected on the App Store (2.3.10)
|
||||
- **Symptom:** a Mac App Store version was rejected under Guideline 2.3.10 (Accurate Metadata): its What's New came
|
||||
from release notes shared with Google Play and had "Google Play Games" and "Android" lines. storebound wrote it
|
||||
without a word (the old check was a warning in the editor only).
|
||||
- **Cause:** one notes source for both stores, no per-store split, and no write that refused other platforms. Google
|
||||
Play's Metadata policy is the mirror case (iOS, iPhone, App Store, Game Center, TestFlight in Play text).
|
||||
- **Do:** tag store-specific lines `[play]` / `[apple]` in shared notes (whats-new skill); `storebound check` must
|
||||
show no `other platform` line. A functional mention (a "Continue with Google" / "Sign in with Apple" button) is the
|
||||
owner's call: `listing.allowPlatformMentions: [{ store, text, reason }]`. Never add an entry yourself.
|
||||
- **Guard:** `cli/lib/cross-store.ts` (term lists, per locale / field / line, the allowlist, `notesForStore`).
|
||||
Refused before anything is sent, dry runs included: `apple listing`, `play listing`, `play release` /
|
||||
`play upload` (release notes), `listing set`, `whats-new check` / `apply`, the desktop editor and `storebound edit`
|
||||
(`appleLocaleIssues` / `playLangIssues` errors). `check` / `validate` blockers (`other-platforms`), `scan` rules
|
||||
`other-platforms` (2.3.10) and `play-other-platforms` (Play: Metadata). `tests/cross-store.test.ts`.
|
||||
|
||||
## 78. `storebound api ... --yes` piped or redirected became a silent dry run
|
||||
- **Symptom:** `storebound api apple <write> --yes | tail` (or `> out.json`) printed a dry run and exited 0; the
|
||||
owner thought it was sent. Happened twice.
|
||||
- **Cause:** writes need an interactive terminal; without one the gate fell back to a dry run.
|
||||
- **Do:** run writes without a pipe or redirect in a terminal, or use the dedicated storebound command.
|
||||
- **Guard:** `decide` in `cli/api/gate.ts` refuses (`NOT_A_TTY`): exit 1, the message on stderr, nothing sent, the
|
||||
dedicated command named. Without `--yes` a write is still a plain dry run. `tests/api.test.ts`.
|
||||
|
||||
## 79. A macOS (tvOS, visionOS) version was invisible next to the iOS one
|
||||
- **Symptom:** `apple resubmit` said "nothing to resubmit" while a macOS version was REJECTED with an
|
||||
UNRESOLVED_ISSUES submission; `apple listing --version 0.8.7` refused because the iOS 0.8.7 was live, although the
|
||||
macOS 0.8.7 was the rejected one to fix; `apple status` listed versions without saying which platform.
|
||||
|
|
@ -954,4 +978,3 @@ that fails without the fix (see CONTRIBUTING.md).
|
|||
every version; validate and release status warn about another platform's editable or rejected version.
|
||||
- **Guard:** `cli/apple/platform.ts` (`pickPlatform`, `parsePlatform`), `tests/apple-platforms.test.ts` (fake App Store
|
||||
Connect: iOS 0.8.7 live, macOS 0.8.7 rejected in UNRESOLVED_ISSUES).
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,20 @@ CI, PR, OTA, fingerprint, bump, deps, ...), version-control words (commit, merge
|
|||
code identifiers (`saveSlot`, `max_lives`). Each warning names the word and a plain alternative. Rewrite the line;
|
||||
when a flagged word is a real player-facing term (a character called "Sentry"), add it to `whatsNew.allowWords`.
|
||||
|
||||
## One source, two stores: tag store-specific lines
|
||||
A notes source shared by both stores must not carry one store's lines into the other: a Mac App Store version was
|
||||
rejected under Guideline 2.3.10 for a What's New with "Google Play Games" and "Android" lines (store-pitfalls 77).
|
||||
- Tag a line for one store: `[play] Achievements on Google Play Games.` or `• [apple] Game Center leaderboards.`
|
||||
(also `[android]` / `[ios]`). A line that is only `[play]` starts a block for that store up to the next blank line.
|
||||
Untagged lines go to both stores; the tag itself is removed.
|
||||
- The draft leaves an untagged line that names the other side's platform out of that store's draft and says so
|
||||
(tag it to make it explicit). `whats-new check` and `apply` refuse notes that still name Android, Google Play,
|
||||
Steam, ... in App Store text or iOS, iPhone, App Store, Game Center, TestFlight in Play text, with language, line
|
||||
and term; `apple listing`, `play listing`, `play release` / `play upload` (release notes), `listing set` and the
|
||||
desktop editor refuse the same, dry runs included.
|
||||
- A functional mention (a "Continue with Google" or "Sign in with Apple" button) is the owner's call: an entry in
|
||||
`listing.allowPlatformMentions` (`{ store, text, reason }`). Never add one yourself to get past the check.
|
||||
|
||||
## Write it for your users
|
||||
1. Run `storebound whats-new --dry`, read the draft with the owner.
|
||||
2. Rewrite:
|
||||
|
|
@ -68,5 +82,5 @@ when a flagged word is a real player-facing term (a character called "Sentry"),
|
|||
|
||||
## Gotchas
|
||||
- Squash-merged repos: the PR titles are the subjects; keep them in conventional form (`feat: ...`) to get clean drafts.
|
||||
- Commits marked `[skip notes]` or `[internal]` are left out.
|
||||
- Commits marked `[skip notes]` or `[internal]` are left out; `feat: [play] ...` subjects go only into the Play draft.
|
||||
- Release notes are public: nothing about cheats, exploits, unreleased content or private names.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue