com.harryaskham.sandbox · Kotlin

Sandbox

One Android app that hosts small experiments, called micro-apps, so a new idea can reach a phone through Play without becoming an app of its own. The home screen lists them; nothing runs until one is opened, and each keeps its own state.

How a micro-app is hosted

What the host gives a micro-app The Sandbox host and one micro-app. Micro-apps are compiled into the app and listed in a fixed registry; nothing is scanned for or downloaded. A micro-app's code only starts when it is opened and is released when it closes. The host gives it its own namespaced files, typed key-value pairs and encrypted secrets, so experiments cannot overwrite each other's state, and a presentation boundary: embedded or fullscreen, a Home affordance, safe-area padding and a shared set of controls. A micro-app declares the capabilities it uses, such as the GPU, the network or audio output. registrycompiled in, fixed order home screensidebar · nothing running micro-appstarts when openedreleased on stop its own statefiles · key-value · secrets presentationembedded or fullscreen declared capabilitiesGPU · network · audio open

A micro-app is a Kotlin or Java module under sandbox/microapps/ with a small microapp.json: its title, a one-line description, its entry point and the capabilities it uses. A script creates new ones, checks them against the registry, and can promote a micro-app that outgrows Sandbox into a standalone app: it copies the source into a new Gradle and Nix project and reports what still depends on the host, leaving the original in place.

The host asks for little: Sandbox requests no storage, microphone, camera, location, overlay, VPN or accessibility permission, and a permission is added only when a shipped micro-app needs it; since the micro-apps share one app, it then applies to all of Sandbox. Micro-apps that need a model use a shared agent runtime with OpenAI-compatible provider profiles, whose keys are stored encrypted.

What is in it

12 micro-apps, read from each module's microapp.json when this page was built
Micro-appIts own descriptionCapabilitiesKind
Accelerator LabCopyable GPU, NPU, and AI diagnosticsGPUmodule
Context LensesLive, session-only dashboards across Sandboxnonemodule
EchoesLiving fiction where abandoned futures remember younetworkmodule
Fluid DrumMulti-touch dye vortices and sample-free percussionaudio out, GPUmodule
Future ArchiveDraw artifacts. Model causes. Exhibit possible worlds.nonemodule
Infinite ComicTake turns drawing with a tool-using agentnetworkmodule
Puzzle ArchitectSketch, wire, and solve agent-built signal contraptionsGPU, networkmodule
Shader GardenStylus performance sketchbook and shader mentorGPU, networkmodule
Signal LabTap, persist, and color a namespaced pulsenonemodule
Spatial ProgrammerLive-reactive agent workflow canvasnetworkmodule
Overlay WMBSP layout and shared control for signed floating windowssee belowbuilt in
Local AI ServerLiteRT-LM models and OpenAI-compatible inferencesee belowbuilt in

The descriptions are the micro-apps' own, so they read more like pitches than the rest of this site. Most are experiments in drawing with a stylus, or in working alongside a model, rather than finished tools.

Overlay WM

The first coordinator for floating windows across this suite's apps. It keeps a BSP tiling layout and focus, and sends windows geometry, hide, minimise, restore and focus commands over Binder, protected by a signature permission so that only apps signed with the same key can join. Flotilla is the later, separate window manager with per-app approvals; each app chooses one of the two as its coordinator. Sandbox ships a widget for Overlay WM's control panel.

Local AI Server

Runs a language model on the phone and serves it with an OpenAI-compatible API, by embedding LiteRT-LM 0.16.1's own Python server through Chaquopy 17 rather than reimplementing the API. The model is Gemma 4 E2B in LiteRT-LM's format; the app tries the GPU first and falls back to the CPU.

It listens on 127.0.0.1:8080 with no token by default. Other addresses, including all interfaces, are allowed, with an optional bearer token. It runs as a foreground service you start yourself, and a widget shows its real state and starts or stops it.

# from Nix-on-Droid on the same phone
curl 127.0.0.1:8080/v1/chat/completions \
  -H 'content-type: application/json' \
  -d '{"model": "gemma-4-e2b",
       "messages": [{"role": "user",
                     "content": "Say hello."}]}'

Limits