How Robo-8 v2 was planned, designed and built
A maker's account of Robo-8 v2: the constraints, the architecture choices, the design direction and how it was verified.
Start with the constraints
I did not begin with features. I began with four things the app had to be true to. It must work without a server. Any cloud use must be optional and free to try. No key may live in the APK or in web storage. And it must run on Android 6 and up. Everything else was allowed to bend around those.
One assumption I could not get around
The original signing material for v1 was not available. That mattered more than it sounds: Android will not update an app signed with a different key. So v2 became a separate package that installs beside v1. I wrote that down as an assumption rather than pretending it was an upgrade.
Architecture: a WebView with a very small native bridge
I weighed three shapes. A hosted page fails the moment you are offline. A full agent-UI runtime brings a paid router and a server, which breaks the free-only rule. The shape I chose bundles the HTML, CSS, JavaScript and fonts inside the app, loaded in a WebView from an app-only origin, with a tiny native layer for two jobs: making the HTTPS call to NVIDIA, and collecting the key. Because the call is native, the browser never sees the key and CORS stops being a problem.
The key never touches the page
The key is typed into a native dialog that blocks screenshots, kept in the process memory for the session, and cleared on disconnect. The WebView cannot read it. A request carries only the message you typed plus a fixed prompt, with a bounded body size, a connect and read deadline, and no redirects followed. There is no chat history to leak because none is kept.
Design: a small living object, not a dashboard
The direction I wrote down was a playful instrument: a phone on a desk in evening light should feel like a small living thing. That meant a deep marine surface, pale mint eyes, one vermilion accent, shell-white type, and one signature shape, asymmetric rounded eyes in a physical face opening. Space Grotesk and IBM Plex Mono are bundled locally. I ruled out gradients, glass, nested cards and decorative loops. Motion exists only to show gaze, blink, touch, thought or breathing, and reduced-motion turns the idle animation off. The robot is the first screen; tools and conversation sit below it.
Original face, borrowed principles only
EMO's public description of expressions, personality and idle behaviour was inspiration. I copied no art, firmware or animation from it. From two MIT-licensed projects I took ideas, not runtime code: an allowlisted way to render generated interface components, and the habit of keeping keys ephemeral. Both are credited in the notices.
Safe by construction where I could make it so
Generated answers cannot run code. The renderer accepts only fixed component schemas and writes text with textContent, so a hostile reply is just text. Network calls have caps. Hidden animations pause. These were failure cases I listed before writing the code, then wrote tests for.
Verification, and what it did not cover
I planned the checks as ways the design could be wrong: render at 320 and 390 pixels, run every interaction offline, mock cloud errors, inspect the APK signature and manifest, install and launch. The record shows 11 engine assertions and 34 browser UI assertions passing, and an install and launch on an Android 6 emulator. The first emulator run exposed a real bug: the bundled WebView was too old for modern JavaScript, so I transpiled the code for an old Chrome and added CSS fallbacks, then reinstalled and checked again. What was not tested: a real phone, newer Android versions, vendor battery behaviour, release signing, and an authenticated NVIDIA completion, because no key was available. I say so on the app page too.
What I would do next
Test on real hardware, run one authenticated cloud session with a trial key, and decide whether v1's camera and speech features deserve to come back behind explicit permission. Until then, v2 is a calm offline companion with an optional brain.
Version 3: sensors, memory and what I could not verify
v3 builds on the v2 design by adding senses. The companion now reacts to being picked up, shaken, spun, tilted and dropped, to light and dark, to claps and to strokes, and it keeps a memory of streaks and milestones across days, with small idle behaviours of its own. The microphone is off by default, because a listening feature should be opt-in. I also gave it a neutral package name, com.jackgross.robo8, so the identifier carries nothing but the project. The build process turned up a real bug: native sensor events were firing before the page JavaScript had loaded, so early reactions were lost. It was fixed, and the version hosted here is the fixed build. What was verified: an install and launch on an Android 6 emulator, live-tested battery, light and dark sleep, face-down, and wake plus idle dance reactions, 97 engine assertions and 27 of 27 browser checks, as reported by the project. What was not: sensors, microphone and vibration on a real phone, and an authenticated NVIDIA reply. Treat the sensor thresholds as unproven until a phone run happens.