# AGENTS.md — vela-snake Guidance for AI agents working on this repo. Humans can read it too. ## What this is Textured Snake for the Xiaomi Watch S4 (round 466px screen, Vela quickapp). Package `com.ilias.snake`. Source of truth for releases: https://gitea.oimcloud.myaddr.tools/oiwmiodev/vela-snake (Big Intelligence group). Upstream codex-bot/vela-snake is read-only for this account (no write permission). ## Hard rules - Never commit `sign/*.pem` (gitignored on purpose). Builds currently use the toolkit's default debug keys; if real keys are added, keep them out of git. - Never edit files under `node_modules/`. The toolkit is locked at aiot-toolkit 2.0.5; do not upgrade it casually (release uses plain JS, not JSC/protobuf). - Tests must pass before any commit: `npm test` (pure Node, no watch needed). - Bump `versionName`/`versionCode` in `src/manifest.json` for any release. Hotfixes: `0.9-Hotfix.1` style, versionCode still increments (integer only). - No em dashes in docs, commits or comments. ## Crown control (the fragile part) The Vela firmware does NOT expose crown events to quickapps (verified by firmware string analysis, see docs/CROWN.md). Crown rotation arrives only as scroll deltas on the focused scroll container. The page is a full-screen vertical `scroll` with the dial centered; `onscroll` converts accumulated deltas into queued 90-degree turns (`CROWN_STEP_PX`, 40px per turn) and snaps the scroller back to center (`scrollTo({top: 233})`). Known failure mode (issue oiwmiodev/vela-snake#1): the game can still scroll away, likely because momentum scrolling outlives the snap-back or onShow's scrollTo runs before layout. Any fix must keep: swipe steering working, the dial visually pinned, reversals impossible. If scroll-delta extraction proves unreliable on hardware, the fallback is accepting codex-bot issue #2's conclusion (swipe-only input) and removing the scroll wrapper. Crown work happens on the `crown-experimental` branch; `main` tracks the released state. ## Layout invariants - Dial/board: 466px screen, board at 49px offset, 368px circle, 32px cells, 11x11 grid, 89 legal cells (circular mask, see src/common/snake.js ARENA). - Scroll content height = 932px (233px padding each side), center offset 233. - Overlays fit the watch chord; no legal cell is ever covered by HUD/footer. - No CSS transforms anywhere (tests assert this); tiles are positioned with left/top only. ## Testing `npm test` runs snake logic, piece classification, page wiring (including the crown scroll path), upgrade regressions, numeric layout, randomized property tests and art checks. When fixing a bug, add a failing test first, then fix. Node tests are not device tests: behavior on the actual watch is the only final proof, and whoever has the watch does that testing. ## Release checklist 1. All tests green. 2. `src/manifest.json` version bumped. 3. `npm run release`, verify dist/com.ilias.snake.release..rpk exists. 4. Commit + push to origin (oiwmiodev/vela-snake). 5. Create the release with `tea releases create --repo oiwmiodev/vela-snake --tag v` and attach the rpk with `tea releases assets create`. Download the asset back and byte-compare before claiming success. 6. Release notes: real changelog, never "see commit history". ## Git Git identity is not globally configured; commits must set the repo persona (the "big pc republic" identity used across this Gitea, see prior commits) via `git -c user.name=... -c user.email=...` or local config. Pushes go to origin (the org repo). Auth uses the `oimcloud` tea login.