cross-store text: other platforms named in App Store text (2.3.10: Android, Google Play, ...) or Play text (Metadata: iOS, App Store, Game Center, ...) are refused by every text write (apple / play listing, play release / upload notes, listing set, whats-new, storebound edit, desktop editor), blockers in check / validate, scan other-platforms / play-other-platforms; listing.allowPlatformMentions for the owner's functional mentions; whats-new splits [apple] / [play] lines per store; storebound api --yes without a TTY is refused (exit 1, stderr) instead of a silent dry run; pitfalls 77, 78
This commit is contained in:
parent
3e4015b686
commit
edabbec874
32 changed files with 613 additions and 53 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:
|
||||
|
|
|
|||
|
|
@ -87,6 +87,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`.
|
||||
|
|
@ -925,3 +926,26 @@ that fails without the fix (see CONTRIBUTING.md).
|
|||
Uploading and selecting are normal steps, not owner buttons; the version's Submit for Review stays the owner's.
|
||||
- **Guard:** `cli/apple/creative-assets.ts`, `tests/creative-assets.test.ts` (fake App Store Connect: dry run, upload,
|
||||
waiting, select, replace on a changed file, nothing on the same file).
|
||||
|
||||
## 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`.
|
||||
|
|
|
|||
|
|
@ -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