console: agent-first mode (console plan / console verify), verified App Privacy and Play Create app facts

- `storebound console plan <form> [--json] [--lookup]`: read-only plan for an AI agent that drives the browser
  itself: start URL (deep links), ordered steps, answer sheet with the console's exact labels (certain / ask owner,
  curly quotes noted), never-press list, verified UI facts, driving guidance (in-page async loop + window.__log),
  verify instructions. All six forms.
- `storebound console verify <form> [--from-text <file|->]`: App Privacy per-type summaries from page text, Play
  Create app from input states, content rating / target audience summaries, App Store record and age rating from
  the API; exit 1 on a mismatch.
- MCP: console_plan, console_verify (read-only); console fill stays off MCP.
- App Privacy (verified 2026-10-12): two information steps, unlabeled purpose checkboxes (nearest parent text),
  "Definitions and Examples" never pressed; fixture and engine follow.
- Play Create app (verified 2026-10-12): /developers/<id>/create-new-app, App package name + read-only Check
  availability, material-radio inner [role=radio] click, app dashboard URL and play.appId, service account
  "Add app" as an owner step.
- console-autofill skill rewritten agent-first; agents-core rule 10; README; pitfalls 12, 18 (confirmed sign-out),
  19; CHANGELOG; play-first-release.
This commit is contained in:
CRTkafa 2026-10-12 08:22:03 +08:00
parent a9261a8052
commit c9a7f095c4
34 changed files with 1430 additions and 113 deletions

View file

@ -1,6 +1,6 @@
---
name: store-pitfalls
description: Known pitfalls with App Store Connect, Google Play and storebound itself, learned from real releases, and what to do about each - store lists that lag right after a create, dry runs that print a count instead of a plan, App Store names taken on a storefront, keyword limits in bytes, Data safety answers without code evidence, missing font glyphs in screenshots, console sign-in and sessions, Capacitor monorepo plugins, duplicates from retries, re-runs and parallel runs, App Store search ranks that are only a trend, Play without a search API, Play's Create app form (no API, opener and submit share a name, Free is final), App Privacy purposes over-mapped (Play advertising is Third-Party Advertising only), an unknown console page (bounded wait and a debug dump), a signed-in console read as a sign-in page (Google account widget frames). Read it before any store task, and when a store command does something you did not expect.
description: Known pitfalls with App Store Connect, Google Play and storebound itself, learned from real releases, and what to do about each - store lists that lag right after a create, dry runs that print a count instead of a plan, App Store names taken on a storefront, keyword limits in bytes, Data safety answers without code evidence, missing font glyphs in screenshots, console sign-in and sessions, Capacitor monorepo plugins, duplicates from retries, re-runs and parallel runs, App Store search ranks that are only a trend, Play without a search API, Play's Create app form (no API, opener and submit share a name, Free is final), App Privacy purposes over-mapped (Play advertising is Third-Party Advertising only), an unknown console page (bounded wait and a debug dump), a signed-in console read as a sign-in page (Google account widget frames), console forms driven agent-first. Read it before any store task, and when a store command does something you did not expect.
---
# Store pitfalls
@ -103,11 +103,19 @@ Each entry: **symptom** → cause → what to do → what guards it now. The ful
- **Symptom:** an agent cannot create the Play app through the API, or clicks "Create app" without knowing whether it
opens the form or submits it; or an app goes out as Free and the owner later wants it paid.
- **Cause:** the Play Developer API cannot create apps. Play Console's Home has a "Create app" button that opens the
form, and the form's final button has the same words. Free cannot become Paid later on Google Play. The package
name is not in this form: the first AAB upload sets it.
- **Do:** `storebound console fill play-app-record` (pick the account with `play.developerId` or
`play.developerAccount`); tell the owner that Free is final; the owner ticks the declarations and presses Create
app; then `storebound play upload --track internal` (or `flow run release`) sets the package name.
form, and the form's final button has the same words. Free cannot become Paid later on Google Play. The form
(`/console/u/0/developers/<developerId>/create-new-app`, verified 2026-10-12) has an App package name field (max
150) with a read-only "Check availability" button ("Package name available"); the package name is fixed for good.
App or game and Free or paid are `<material-radio>`s: setting the native input leaves the form saying "Select app
or game" until the inner `[role=radio]` is clicked (a JS click works in a background window).
- **Do:** `storebound console plan play-app-record` and drive the form with your browser tool (or the scripted
`console fill play-app-record`); fill the package name and press Check availability; click the inner
`[role=radio]`s and check that no "Select …" hint is left (`console verify play-app-record`); tell the owner that
Free is final; the owner ticks the declarations and presses Create app. Afterwards the app lives at
`/console/u/0/developers/<developerId>/app/<appId>/app-dashboard` (set `play.appId`). The service account's
app-level permissions do NOT cover the new app: the OWNER adds it (Users and permissions > the service account >
Add app > Admin, or the minimal set > Apply > Save changes; never an agent: it is a permission grant), then
`storebound apps check --store play`.
- **Guard:** `createAppAllowed` lets the opener through only on the app list, never inside a form or dialog (English
and Turkish); agreement checkboxes are never ticked; Free or paid is outlined as an owner check.
@ -183,6 +191,8 @@ Each entry: **symptom** → cause → what to do → what guards it now. The ful
opt-in that prints the warning; an agent never adds it. Apple publishes no such binding, but `--use-chrome-session
apple` is opt-in too. If Google says "Couldn't sign you in" in storebound's window, storebound prints "Google refused
sign-in in this window (/signin/rejected)": try again, or sign in at accounts.google.com first in that window.
- **Confirmed (2026-10-12):** the earlier default copy of the Google cookies DID sign the owner out of Play Console
in their real Chrome.
- **Guard:** `browserPlan` / `openConsoleBrowser` in `cli/console/session.ts` (no copy without the flag, the copy keeps
only the form's own provider), Chrome started by storebound without `--enable-automation` and with
`navigator.webdriver` false, `googleRejected`; `tests/console-session.test.ts`.
@ -206,6 +216,20 @@ Each entry: **symptom** → cause → what to do → what guards it now. The ful
`tests/play-post-reads.test.ts` (phone-only fixture: dry plan, info line, exit 0; `tablets: true` without renders is
an error; no tablet DELETE without `--prune`).
## 20. Drive consoles agent-first; the scripted fill is a fast path
- **Symptom:** hours went into fix cycles of the scripted engine's selectors (`console fill`) while the console UI
kept differing from the model (App Privacy's "Set Up" as plain text, unlabeled purpose checkboxes, two information
steps, Play's material radios), each one a stop until a new release.
- **Cause:** a script only knows the page it was written for. An AI agent with a browser tool reads the page as it is
and adapts.
- **Do:** run `storebound console plan <form> --json` and drive the page yourself (Claude in Chrome, a built-in
browser, Playwright) from its answer sheet, never-press list and UI facts; long flows as an in-page async loop that
writes `window.__log` (one evaluate call times out around 45 s); stop before the final button and tell the owner
what to press; then `storebound console verify <form>`. `console fill` is the optional scripted fast path; when it
stalls, switch to the plan instead of waiting for a selector fix.
- **Guard:** `console plan` / `console verify` (CLI and the read-only MCP tools `console_plan`, `console_verify`), the
console-autofill skill puts them first; `tests/console-plan.test.ts`.
## Adding a lesson
Every bug found in real use gets an entry in `docs/pitfalls.md` and here, and, where possible, a check or a test
that fails without the fix (see CONTRIBUTING.md).