agent rules: first rule "Do it, don't ask" (agents-core and every adapter, README, store-pitfalls lead, first-release, declarations and console skills); the agent runs the real command after the dry run, the owner presses only final public or irreversible buttons and answers compliance facts in one batch; handoff text removed from skills; tests/do-it-dont-ask.test.ts. Pitfall 26

This commit is contained in:
CRTkafa 2026-10-12 09:28:45 +08:00
parent fc524cd2d4
commit dfc28c15f8
22 changed files with 393 additions and 105 deletions

View file

@ -2,16 +2,43 @@
These rules apply to every AI tool that uses storebound (skills, MCP server or the CLI in a terminal).
## First rule: do it, don't ask
storebound plus you, the AI agent, do the work. The owner is not your pair of hands.
1. **You do everything yourself:** API calls, uploads, builds, template and CSV downloads and exports, every console
navigation (open, Get Started, Edit, Next, Continue, Save draft), console forms, and the verification afterwards.
Never tell the owner "run this yourself" or "click X yourself" for any of these.
2. **The owner keeps only the final public or irreversible buttons:** Submit for review (App Review or Beta App
Review), releasing a version or completing / resuming a production rollout, App Privacy Publish, accepting legal
agreements; plus deleting store data, changing live prices, sending review replies and inviting or removing
testers. (Also the owner's: canceling a submission, starting or stopping a store experiment, a console form's final
Submit / Create that a console plan lists in `buttons.final`, signing in and granting account permissions.) For
these you prepare everything, show the dry run, and the owner presses one button or says yes.
3. **Ask the owner only for facts that no code, config or doc can prove:** compliance answers such as Data safety,
App Privacy, age rating, export compliance, partial data deletion. Collect ALL of them in ONE batch at the start
(`storebound check` and `storebound validate` list them), never one at a time during the run. Reuse answers that
are already in the config.
4. **Default loop:** plan, then you drive (the API first, your browser tool for consoles without an API), then verify
(read it back), then continue. No round trip to the owner in between.
5. **Catch rejections offline.** Before a write, `storebound check` and `--dry` must catch what the store would refuse
(live-shape fixtures, id and pair checks). A failure belongs in the dry run, not in a 400 at write time; when a
store refuses something the dry run passed, fix the check (pitfalls), not just the data.
Every hour of "please click this" is an hour the owner did not want to spend. If you catch yourself writing "you
need to ...", do it instead, unless it is one of the owner steps in point 2.
## The other rules
**Read `skills/store-pitfalls/SKILL.md` before any store task.** It lists the mistakes already made in real releases
(store lists that lag after a create, dry runs without a plan, taken App Store names, byte limits, ...) and what to do.
1. **The owner decides public and irreversible steps.** Submitting for review (App Review or Beta App Review),
releasing a version, resuming or completing a rollout, canceling a submission, deleting products or listings,
accepting agreements, sending review replies, inviting or removing testers, changing prices, starting or stopping
a store experiment: explain what will happen and let the owner do it (or run the command only after a clear yes in
chat). storebound's MCP server does not offer these at all.
2. **Dry run first.** Every write command has `--dry` (MCP: `dry_run`, default true). Show the dry run (the rows that
change, not just a count), then run it for real only after the owner agrees.
1. **The owner presses only the owner steps** (point 2 of the first rule). Prepare them completely, say what will
happen, and let the owner press the button, or run the command only after a clear yes in chat. storebound's MCP
server does not offer these at all. Everything else you run yourself.
2. **Dry run first, then run it yourself.** Every write command has `--dry` (MCP: `dry_run`, default true). Run the
dry run, check and show it (the rows that change, not just a count), then run the real command yourself (`--yes`
where it asks for a confirmation) and read the result back. Wait for the owner's yes only before an owner step.
3. **Read before you write.** `storebound scan` (offline: rejection risks in the project itself), `storebound check`
(offline) and `storebound validate` (read-only, both stores) tell you what is missing and in which order to fix it.
4. **Credentials only from the environment, `.storebound/`** in the project (gitignored) **or a credential profile**
@ -19,7 +46,8 @@ These rules apply to every AI tool that uses storebound (skills, MCP server or t
passwords or tokens in chat, never print them, never write them into the config, docs or commits. The same goes
for the App Review demo account (`reviewDemoAccount` in `.storebound/credentials.json`): the owner puts it there.
5. **Never answer a compliance question you cannot know.** Export compliance, Data safety, App Privacy, age rating,
target audience: ask the owner when the code does not prove the answer. A wrong "no" is worse than a slow "ask".
target audience: ask the owner when the code does not prove the answer, all such questions in one batch at the
start (first rule, point 3), and write the answers into the config. A wrong "no" is worse than a slow "ask".
6. **Pick builds by explicit number.** Use the build number / versionCode you just uploaded, never "the latest".
7. **Long uploads run in the background with a log** (`storebound play images > .storebound/images.log 2>&1 &`) and
you report the progress lines, not guesses.
@ -31,7 +59,7 @@ These rules apply to every AI tool that uses storebound (skills, MCP server or t
10. **Console forms without an API: drive them yourself, agent-first.** `storebound console plan <form> --json` (MCP
`console_plan`) gives the start URL, steps, the answer sheet, the buttons you must never press and the verified UI
facts. Drive the page with your own browser tool, adapt to what it shows, run 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 (Publish,
that writes `window.__log` (one evaluate call times out around 45 s), stop only before the final button (Publish,
Submit, Create, a final Save) and tell the owner exactly what to press, then `storebound console verify <form>`.
Never sign in, accept an agreement or grant a permission (a service account's app access) for the owner.
`storebound console fill` is the optional scripted fast path; it never blocks you.

View file

@ -9,6 +9,7 @@ fails without the fix.
| # | date | lesson | guard |
|---|---|---|---|
| 26 | 2026-10 | An agent using storebound spent hours handing the owner one click, command or answer at a time ("press Next", "download the CSV template", "now run the upload", a compliance question in the middle of a run): skills said "let the owner do it" / "by hand" for navigation, exports and uploads. | The first rule "Do it, don't ask" heads `docs/agents-core.md` (every generated adapter), README and the store-pitfalls skill: the agent does API calls, uploads, builds, exports, console navigation and forms itself; the owner presses only the final public or irreversible buttons and answers the facts no file proves in one batch at the start. `tests/do-it-dont-ask.test.ts` checks the rule is there and fails on skill text that hands navigation, draft saves, exports, uploads or form filling to the owner. |
| 25 | 2026-10 | In a non-interactive shell `play build` stopped in Gradle with "SDK location not found" (no `ANDROID_HOME` there, `local.properties` gitignored) although the SDK was in `~/Library/Android/sdk`; `apple upload --no-wait --yes` sent the IPA for over 10 minutes without a line (progress every 10th part only, no per-part or per-call timeout). | `resolveAndroidSdk` (ANDROID_HOME, ANDROID_SDK_ROOT, `sdk.dir` in local.properties, the Android Studio default folder; only folders with platforms/ or platform-tools/) hands the SDK to Gradle in the environment, never writes local.properties, stops before Gradle with the places checked; `doctor` shows it (`cli/lib/tools.ts`, `cli/play/build.ts`, `cli/doctor.ts`). `apple upload` prints the size, a line per part and a 20 s heartbeat (api, altool, processing wait), per-part and per-call timeouts, `--timeout` exits 7 with the resume hint (`sendParts` in `cli/apple/upload.ts`, `cli/lib/progress.ts`; `tests/tools-path.test.ts`, `tests/build-sign.test.ts`, `tests/upload-progress.test.ts`). |
| 24 | 2026-10 | `flow run release --apply --yes` ran `apple upload --no-wait`, which printed "not a terminal: re-run with --yes to confirm" and declined, yet the flow logged "4/13 upload: ok" and went on to `apple testflight wait` for a build that was never uploaded: a declined confirmation exited 0, and the flow's `--yes` never reached the steps. | `confirm()` (`cli/lib/ctx.ts`): every decline (answered no, not a terminal without `--yes`, under serve) prints `declined: <reason>` and exits 3 (`DECLINED_EXIT`). `flow run` reports "step N declined: <reason>" (status `declined`) and stops; `--apply --yes` adds `--yes` to write steps only (`planStep`, `declinedReason`; `tests/flow.test.ts`). |
| 23 | 2026-10 | Capacitor: native build ships old web assets. `flow run release --apply` went straight into `apple build` (xcodebuild archive) with `ios/App/App/public` and `android/app/src/main/assets/public` 3.5 hours older than the latest source commit: the native projects hold the copy `npx cap sync` made last, and nothing ran the web build + cap sync first, so the old game would have shipped. | New `build.prebuild` (per store `apple.prebuild` / `play.prebuild`): `apple build` / `play build` run it first (printed, streamed, nonzero exit stops; `--dry` only prints; `--no-prebuild`; once per `flow run` through `STOREBOUND_PREBUILD_DONE`). After it, a Capacitor project's copied `public/index.html` must be newer than the last commit outside ios/ android/ node_modules/ store/ .storebound/ and `<webDir>/index.html`, else the build stops ("web assets are older than the source ..."; `--allow-stale-web` overrides). `check` warns when stale without a prebuild; build output and dry plan show the bundle's sha256 + mtime. Monorepo (`apps/native` with its own capacitor.config.ts, android/, ios/; `play build` failed with "no Gradle project ... in android or ."): the one Capacitor project one or two levels down is found and named, several ask for `play.build.dir` / `apple.build.*` (`cli/lib/web-assets.ts`, `tests/web-assets.test.ts`). |