Eyespie is an offline-first travel spy game built with Kotlin Multiplatform and on-device computer vision.
Core gameplay requires no hosted backend and no hosted account. Game authority, clues, embeddings, matching, and progress are local to the device. Cloud and peer networking are optional future adapters for capabilities that actually need them.
The former Supabase-based application remains recoverable from:
archive/pre-backendless-reboot-2026-08-1550091a631d971c520e48884cfbd15cf15dd7251bThe reboot and closed-alpha release are tracked by issues #156 and #90. The backendless/local-authoritative epoch is called Wayfinder.
The Wayfinder closed-alpha implementation is integrated on main:
PlayerId;ImageCapture boundary;.eyespie v1 export/import with fail-closed hostile-input validation and verified preview before persistence;.eyespie document ingress and the narrow eyespie://game/<GameId> route for already-accepted local games;INTERNET permission.Operational diagnostics are deliberately separate from product analytics: the current diagnostic path is bounded, local/process-lifetime, explicit-export only, and has no remote collector or gameplay authority.
Implementation and simulator/CI qualification are not the same as physical release proof. The current release path is qualification of one exact post-Wayfinder/post-telemetry candidate, not feature expansion.
The latest exact-head protected Android publish=false candidate build has successfully validated the requested source SHA, staged and verified the pinned runtime model, produced signed APK/AAB artifacts, and validated the signed Android artifact. That does not establish iOS signed-distribution or physical-device acceptance by itself; #90 remains the canonical candidate/evidence tracker.
Closed-alpha readiness still requires the evidence owned by:
Do not describe these physical/release gates as complete until their evidence is recorded against the exact accepted candidate. Candidate-changing source changes must re-bind affected evidence rather than carrying it forward implicitly.
The canonical local/CI Android gate is:
mise run ci
That verifies release-candidate identity, Python evidence tooling, Android unit tests, the debug application, and the instrumentation-test APK.
Ordinary build/CI paths intentionally remain network-independent and do not provision the external image-embedding model. To provision the pinned model, verify it, and install a runnable Android debug application on a connected device/emulator, use:
mise run android-runtime
To verify an already-staged Android runtime model without network access or repair, use:
mise run android-runtime-verify
The Gradle application project is named :app even though its source directory is eyespie/. The direct operations are therefore:
./gradlew :app:stageAndroidImageEmbedderModel
./gradlew :app:verifyAndroidRuntime
./gradlew :app:installDebug
After the build or test sequence finishes and its required evidence and artifacts have been retained, run the repository-native Gradle cleanup in the same Git worktree:
./gradlew clean --no-daemon --stacktrace
# Convenience alias when using this repository's task runner:
mise run clean
Run cleanup after failures too, using an EXIT trap, a finally block, or an equivalent CI finalizer. Keep the original build/test result and report a cleanup failure separately. The individual mise run build, mise run test, and mise run ci commands do not automatically invoke cleanup; the workflow owner must finish the lifecycle once evidence consumers are done. In particular, mise run ci inspects the generated debug APK: do not clean before its permission verification completes or before saving any candidate artifacts, test results, and diagnostics needed for release/review.
The ordinary offline-core, hosted-screen, and Wayfinder CI workflows attempt cleanup after their last verification/evidence step. If failure diagnostics cannot be uploaded, they retain the outputs rather than erasing uncollected evidence. Signed internal-distribution workflows retain their separate credential and release-artifact teardown.
Gradle’s native clean task is restricted to build directories in this checkout’s Gradle projects. It does not remove downloaded model data under eyespie/bluebellAssets/, SDKs, checked-out sources, project-local Gradle dependency caches, the shared Gradle user home, or other agents’ worktrees. This command is a local generated-output cleanup, not a release-artifact retention or model-management operation. Do not run it while another process is consuming this worktree’s build outputs.
See docs/development/android-runtime.md for the stage → verify → install contract, failure diagnosis, and shared-automation boundary.
The iOS integration workflow additionally resolves the project-specific MediaPipe CocoaPods graph, compiles the Kotlin/Native simulator target, and builds the real unsigned Xcode simulator application.
Physical/release runbooks live under docs/release/, including candidate identity, Android/iOS embedding calibration, network observation, cross-device smoke testing, and protected internal distribution.
Wayfinder presentation contracts and review evidence live under docs/design/.
See ARCHITECTURE.md for the current architecture and trust boundaries.