docs/pitfalls.md: rows 64-67 (the skill had them)

This commit is contained in:
CRTkafa 2026-10-15 01:21:13 +08:00
parent 6873f2cc68
commit 4c7ff89950

View file

@ -10,6 +10,10 @@ fails without the fix.
| # | date | lesson | guard |
|---|---|---|---|
| 68 | 2026-10 | A headless Chrome started by storebound's console automation (a test run's `--user-data-dir=$TMPDIR/storebound-profile-apple-…`, `--remote-debugging-port=0 --headless=new`) outlived its parent for ~20 hours as an orphan (parent PID 1). macOS LaunchServices took it for the running "Google Chrome", so the Dock's Chrome only activated the windowless instance and the owner's own Chrome would not open. A Chrome started with a DevTools port does not notice its parent dying. | `cli/console/chrome-guard.ts`: every Chrome storebound starts itself is ended on process exit, closed gracefully on SIGINT / SIGTERM / SIGHUP, and ended by a detached watchdog when the parent dies (SIGKILL included; a reused pid is never killed); every start first ends headless orphans on storebound's profiles and names orphaned windows; headless runs on macOS prefer Chromium / Chrome for Testing over Google Chrome.app; `console fill` closes the window on an error too (`tests/chrome-guard.test.ts`). |
| 67 | 2026-10 | A checkout without `.entitlements` was reported as "builds ship without push / Game Center" while the uploaded build had both (native changes lived on a release branch). | The comparison warns only about this checkout ("built from another branch?") and names the branches / worktrees that have an `.entitlements` file; with a built IPA it reads that build's real entitlements ("uploaded build N"); without one it says the App Store Connect API does not expose them. `checkoutInfo`, `builtIpaEntitlements` (cli/apple/signing.ts), `machoEntitlements`, `compareCapabilities` (cli/lib/signing.ts), tests/signing-capabilities.test.ts. |
| 66 | 2026-10 | `storebound api apple ... --body f.json --yes` only dry-ran from an agent. | By design writes through `storebound api` need an interactive terminal; the message names the dedicated command (`apple signing ensure`, `apple iap`, `apple listing`, ...), which runs anywhere with its own dry run and read-back. `dedicatedCommand` (cli/api/gate.ts), tests/signing-capabilities.test.ts. |
| 65 | 2026-10 | A capability add "succeeded" from the POST answer, but the App ID kept only IN_APP_PURCHASE. | `signing ensure` reads the App ID back after every capability write (retries, about 45 s at most) and fails with the API's answers; `apple status`, `signing status` and `validate` compare the App ID, `apple.signing.capabilities` and the project's entitlements. `verifyCapabilities`, `compareCapabilities` (cli/lib/signing.ts), `checkCapabilitiesStuck` (cli/apple/signing.ts), tests/signing-capabilities.test.ts. |
| 64 | 2026-10 | `apple signing ensure` made a manual App Store profile for an app with automatic signing. | With `signing.style: automatic` it only keeps the App ID's capabilities in step (Xcode owns certificates and profiles; the dry run says so); unused storebound profiles are listed with the exact delete command, never run. `ensureScope`, `unusedStoreboundProfiles` (cli/lib/signing.ts), tests/signing-capabilities.test.ts. |
| 63 | 2026-10 | STAR DASH: re-running `play products` / `prices import` to create 8 new IAPs also changed the live prices of existing products; `--only` was needed. In a terminal (no `--yes`) the one confirmation covered price changes too. | Price changes of existing products need `--allow-price-changes`, TTY or not; the terminal question covers creates and other updates only; with the flag a second question lists each old -> new (asked in a terminal even with `--yes`); dry runs show a "price changes on existing products (held)" section (`allowPriceChanges`, `heldSection` in `cli/lib/price-gate.ts`; `play products`, `prices import`, `play subscriptions`, `apple subscriptions`). `tests/price-gate.test.ts` (TTY and non-TTY). |
| 62 | 2026-10 | STAR DASH: `prices ppp` cut high-income markets (Germany EUR 3.59 instead of 5.99 for USD 4.99; UK, France, Japan cut too): it set base x PPP level x exchange rate, a net price, against VAT-inclusive store prices, and cut every region. | Par = the store's own conversion of the US price (Play convertRegionPrices, Apple equalizations; offline base x fx x (1 + VAT) rounded up); share = clamp(PPP level, 0.3, 1); defaults: only decreases, PPP only where the level is <= 0.5, World Bank high-income economies and CN at par, Play skips CN, top-10 revenue market drops > 20 % warned (from `.storebound/reports/` sales reports, else a static list); unchanged regions are left out of the sheet (`shareOf`, `offlinePar`, `planRows`, `topMarketDrops`, `topMarketsFromReports` in `cli/lib/ppp.ts`). `tests/ppp.test.ts`. |
| 61 | 2026-10 | STAR DASH: `prices ppp --json` printed log lines on stdout before the JSON, so parsing stdout failed. | `withJsonOutput` (`cli/lib/log.ts`) wraps every `--json` run in `cli/index.ts`: console.log / info go to stderr, `printJson` writes stdout, prompts use `promptOut()`; commands that printed JSON with console.log use `printJson`. `tests/json-stdout.test.ts` runs every command that reads `--json` against the fake stores and parses stdout. |