Google's account widget and cookie rotation frames (accounts.google.com /
ogs.google.com) on a signed-in Play Console no longer count as a sign-in
page. Each detection logs its rule and URL; heartbeats name the page; a
copied Chrome session that lands on a sign-in URL is said plainly; the
sign-in wait gets a watchdog dump, and --debug-dump up to 3 dumps.
Fixtures and tests for the chooser and home with the widget frames and a
top-level accounts.google.com page; pitfall 16.
A real run (sanitized debug dump) showed why the walk stopped after Next:
the data types step is the same "Data Collection" dialog (URL unchanged),
and each checkbox's accessible name is its label run together with its
help text ("NameIncluding first or last name"). Some labels also differ
from Apple's help page ("Purchases", "Other Data").
- labelNames: the exact name, then the label as a prefix that ends where
the help text starts (no lowercase letter follows), so "Name" never
matches "Phone Number...", "Head" never "Health...", "Contact" never
"Contacts...". Used for the data types and the purposes.
TYPE_ALIASES maps Purchase History / Other Data Types to the console's
labels.
- Dialog per step: a section's dialog is also found as the one visible
dialog with a heading of that name.
- Every click and check is bounded (ACTION_MS, 10 s; the scan test now
also rejects clicks without a timeout).
- The flow fixture mirrors the real dialog's structure (dialog/h2 title,
group h3s, input name = Apple's enum, <label> with label + help <p>s,
Save disabled until a type is ticked); no data from the dump. A test
checks every Apple type matches exactly one real-style checkbox.
- Pitfall 15.
Publish is still never clicked; unknown steps still get the watchdog dump.
With the copied Chrome profile, `console fill play-app-record` stopped with
"no developer account named "<name>" (play.developerAccount) on the
chooser" although the name was there: the real "Choose developer account"
rows are not plain /developers/<id> text links (nested spans, icon-font
glyphs, role=button rows with the id in a data attribute, an avatar row
whose id only its click reveals).
- readChooser: every visible clickable row in the page content (header
and navigation left out); the name is the first visible line (icon
fonts, images and aria-hidden parts skipped); the id comes from
/developers/<id> in any attribute, else a data-*id attribute, else ''
(the row is then opened through the account-switch gate and the id is
read from the URL). "Create a new developer account" is not an account.
- matchAccount: exact spelling, then spaces and case aside (Turkish I/ı
folded), then a unique prefix. A case pair (ACME / Acme) needs the
exact spelling; otherwise it stops and lists both with their ids.
- One developer account: picked (a different play.developerAccount is
said). Not found: every visible account is listed with its id.
- The resolved developerId is remembered as before.
Fixtures play-chooser-real.html (the owner's chooser shape, placeholder
names) and play-chooser-one.html; tests for exact, case pair, prefix,
single account and not found.
A real `console fill apple-app-privacy` clicked Next onto a console page
the engine did not recognise and logged nothing for 8 hours.
- Step watchdog: after a click, or while the form is expected, no known
page within --step-timeout seconds (default 30) -> "the page after
"Next" is not a page storebound knows ... Buttons there: ...", a debug
dump, and the manual steps. It keeps watching, but 20 min without
progress closes the window and exits 1.
- A heartbeat line every minute while waiting (also during sign-in); the
final review wait is bounded (2 h) with a reminder every 10 min.
- Debug dump (cli/console/debug.ts) in .storebound/console-debug/
<form>-<time>/: page.json (URL without query, headings, dialogs, every
visible control with role and name), page.html (rebuilt from a clone:
no scripts, values, hidden inputs or non-whitelisted attributes) and a
small screenshot. Emails, phone numbers and the header / account area
are replaced; cookies, storage and tokens are never read.
--debug-dump writes one at every step for bug reports.
- Guardrail tests: an unknown-page fixture (dump sanitized, bounded exit)
and a scan of cli/console for while loops without a deadline and
Playwright waits without a timeout (one waitForLoadState fixed).
- Pitfall 14 (docs/pitfalls.md, store-pitfalls skill); the
console-autofill skill says how to send a dump.
App Privacy stopped at "now click Get Started yourself" and every page
asked the owner to click Next. The owner should not click what
storebound can safely do.
- Every button of every console form is classified (navigation,
draft-save, final-submit) in FORM_BUTTONS (cli/lib/console-forms.ts),
citing Apple's and Google's help pages. A scoped flow gate
(flowAllowed) lets navigation through; the generic click gate stays
absolute for field clicks.
- App Privacy: Get Started, Edit next to Data Types (never the Privacy
Policy Edit), each data type / "Set Up <type>", Next, and the Save
inside the questionnaire dialogs (a draft: Apple publishes only after
Publish, per "Manage app privacy"). Each type's dialog may be one page
or purposes > Next > linked > Next > tracking > Save. It ends with
"review the summary, then press Publish yourself". Publish is never
clicked.
- Play content rating and target audience: Next by itself. Save draft,
Submit, the final Save, Create and Create app stay the owner's.
- An uncertain answer stops the walk on its page (outlined, "answer
needed on ...") until the owner has set it; then it goes on.
Fixture apple-app-privacy-flow.html (first time, ?existing=1, decoys);
tests/console-flow.test.ts with the guardrail that no log line asks the
owner to click a navigation control.
`console fill apple-app-privacy` without apple.appId stopped at "the app
in the list" with "more than one app matches: X | X" for an account with
one app: the Apps grid names each app twice (the icon link's aria-label
and the title link), both opening the same /apps/<id>/... page.
- pickApp tells hits apart by the app they open (/apps/<id>, else the
link target), not by name. Two apps of one name with different targets
still stop and are listed.
- Without apple.appId, but with App Store Connect API credentials, the
app id is looked up from apple.bundleId (GET /v1/apps?filter[bundleId],
as `apple status` does), cached in .storebound/console-app-ids.json, and
App Privacy opens by deep link. Without credentials, or when the lookup
fails, the Apps list by name is used, and the log says so.
Fixture asc-apps-card.html (a card with the name in the title and an
aria-label); tests for both paths.
Root cause: the per-character font probes were inline spans side by side, so Chrome shaped f + i into the fi ligature across them and the lone i probe reported no glyph of ours. Each probe is now its own block. The Google Fonts text= subsets keep the GSUB ligatures; regression test with a real Montserrat text= subset.
--help / -h prints the command's usage and exits 0 before any config, render or network; unknown flags exit 2 with the usage (cli/data/flags.json from tools/gen-flags.ts). Command tables moved to cli/commands.ts; ads apple reachable again; shots render --scenes rejects unknown ids at once.
- aso competitors: top apps per keyword from the iTunes Search API (name, developer,
rating count, release / update dates, localized genre), coverage gaps (words of 2+
developers), new entrants vs the last snapshot (.storebound/aso/competitors/)
- aso suggest: candidates from own text, competitor names, localized category names and
Apple Ads keyword suggestions (POST /v1/suggestions/keywords/query, relative 0-100
popularity, only with credentials); 100-byte keyword field per locale as a diff,
--write marks it a draft that check --aso and aso audit report
- aso audit: check --aso, free keyword room, rank trend arrows, gaps, Play short
description / density, App Store conversion, PPO / Play experiment ideas, next 3 actions
- MCP: read-only aso_competitors, aso_suggest, aso_audit; desktop ASO card (visx rank chart)
- docs: README, aso-basics, store-pitfalls (Search API order, no Play search API), CHANGELOG;
demo-app listing files; tests on recorded Search API and mocked Ads answers
Navigation after sign-in (navPlan + navigate): App Store Connect Apps > + > New App
(EN/TR), App Privacy by /apps/<appId>/distribution/privacy or the app list, Play app
list by package name > Policy and programs > App content > Start / Manage. Every
navigation click goes through navClick: the click gate stays absolute, only a link
named exactly Start / Manage / Başla / Yönet passes. Each step is logged; a step not
found in time or two matching apps -> the printed steps and wait (no crash).
The TR gate now refuses "uygula" (apply) but not "uygulama" (app).
Browser (cli/console/session.ts): attach to a Chrome with remote debugging (--cdp or
DevToolsActivePort), else on macOS a temporary profile with only Local State and the
profile's Cookies filtered to the console hosts, opened in real Chrome and deleted at
the end, else storebound's own profile (--fresh-profile). Cookies are never printed.
Desktop: fresh_profile option, the dialog says it uses the Chrome sign-in.
Tests: navigation fixtures (ASC EN/TR, Play list, App content, missing step,
duplicates, deny-listed decoys), session file selection, host filter, cleanup, and a
real-Chrome copy-mode test on a throwaway profile and a local site.
Conflict in cli/lib/config.ts (play section): kept play.build from main and the new targetAges, accountType, accountCreated and billingPrograms. Adapters and API tables regenerated (unchanged).
Play rules verified against the live Policy Center / Play Console Help pages
(checked 2026-10-11, cited in cli/lib/scan/play-rules.ts): restricted
permissions and their declarations (background location, photo / video, All
files access, AccessibilityService, REQUEST_INSTALL_PACKAGES, Health Connect,
full-screen intent, VpnService), prominent disclosure and the in-app privacy
policy, Data safety vs SDK disclosures, Families (certified ad SDKs, AD_ID,
location), AD_ID on targetSdk 33+, 16 KB page sizes (Unity, React Native, NDK,
AGP, prebuilt .so), testing for new personal accounts, Play metadata, ads at
launch, payments outside Play Billing, impersonation. Detection reads manifest
components, accessibility configs, strings.xml, native toolchain versions and a
local build's merged manifest. New fixtures and tests; README table per store.
New cut on the approved storyboard (33.75 s, every cut on the 128 BPM beat): rejection mails in a generic inbox,
storebound scan typed on black with its real output (tests/fixtures/scan/teaser), the re-scan of the fixed copy
(new fixture teaser-fixed) flipping five reds to green, 200 store screenshots, 764 Data safety answers, the desktop
app's Portfolio, release timeline (rollout to 20%) and Checks tab, then the Submit card and the logo.
60 fps capture blended to 30 fps for motion blur, whip / mask / zoom transitions, sound design on every cut,
a 1280x720 web version. tests/teaser.test.ts checks the scan text, beat grid, caption length and holds.
apple signing status|ensure: bundle id capabilities, a distribution certificate from a key made locally (kept in .storebound/signing, never printed), App Store profiles installed for Xcode; Developer ID 403 explained.
apple build / apple upload: xcodebuild archive + export with a generated ExportOptions.plist, next build number, App Store Connect API build upload (or altool), processing wait. Native, Capacitor, React Native, Flutter, Unity projects.
play build / play upload: Gradle bundleRelease with the upload key passed through the environment, next versionCode read back from the AAB, testing tracks only.
originality: offline Guideline 4.3 check (name, listing text, icon and screenshot perceptual hashes, project structure).
New skill build-and-sign; zero new dependencies.
- storebound.workspace.json: app folders (globs), studios with accounts by credential profile, ignore list, the
desktop's pairing overrides; ws init | list | status | check | validate | run | apps import | desktop export/import
- credential profiles in ~/.storebound/credentials/<profile>.json or env, --account <profile> on any command
- release status / release plan <version>, table or --json; MCP workspace_list, workspace_status, release_status,
release_plan (read-only)
- pairing rules (cli/lib/identity.ts), release lanes (cli/lib/train.ts) and the per-app status read
(cli/lib/app-status.ts) shared with the desktop instead of copied
- tests with sanitized fixtures, README, skills, CHANGELOG
Detects the stack (native iOS / Android, React Native, Expo, Capacitor, Cordova,
Flutter, Unity, Godot) and the SDKs from a maintained table with versions,
file:line and each vendor's disclosure page, then reports App Store and Google
Play rejection risks with guideline, evidence, fix, severity and skill: 2.1(a)
demo account and placeholder text, 5.1.1(v) account deletion, 4.8 login
services, 3.1.1 restore and outside payments, 3.1.2 subscription info, 5.1.2(i)
ATT, purpose strings, privacy link, privacy manifest, 2.3.10, 2.3.7, 2.3.8, 4.2
web wrappers, 2.5.1, 2.5.5, ATS, export compliance, 1.3 kids ads, review
prompts, privacy labels vs SDKs; Play target SDK 36, delete-account URL, App
access, foreground services, exact alarms, QUERY_ALL_PACKAGES, SMS / call log,
com.example package name.
Proposes Data safety / App Privacy / ATT / privacy manifest answers (detected
file:line or ask owner) as a diff against the config; --write adds only the
detected ones. scan.ignore records owner-accepted findings. MCP tool scan
(read-only), validate includes open findings, desktop Checks tab shows them.
Fixtures for iOS, Android, Capacitor, Unity, Flutter, clean and teaser.
storebound import fastlane [--dir] [--out] [--profile] [--dry] (MCP import_fastlane, dry run by default) reads
Appfile / Deliverfile plain option lines, deliver and supply metadata and screenshots, and writes
storebound.config.ts, store/appstore.md, store/listing.md, the Play icon and feature graphics, and frames with a
folder capture source. App Store and Play language codes are paired (cli/lib/store-locales.ts). Existing files are
never overwritten (.imported copies with a diff hint); keys, team ids, the review contact and demo account are only
named in the report. Fixture tests/fixtures/fastlane-sample, skill migrate-from-fastlane, README and CHANGELOG.