Maintainer hardware records
Current compact pilot platform
The current maintenance bill of materials uses RUBIK Pi 3 / Qualcomm QCS6490 hardware with 8 GB RAM and 128 GB storage. Its working target is two concurrent remote handset slots. Until that exact image passes the acceptance test below, record it as a target rather than guaranteed capacity. A later validated platform may replace it without changing the customer-facing product.
Larger managed deployments
Larger deployments are designed for the site. The maintenance record captures concurrent slot count, runtime nodes, failure domains, isolation mechanism, network path, recovery objective, patch owner, replacement parts, and support boundary.
Slot acceptance test
- Boot every promised Android slot concurrently on the shipping image.
- Authenticate two distinct test identities through the public gateway.
- Open simultaneous WebRTC sessions and exercise touch, keyboard, rotation, audio, lock, stop, and restart.
- Confirm each identity sees only its own phone lifecycle records, tickets, and audit events.
- Run the workload soak agreed for the order and record CPU, memory, thermal throttling, reconnects, and stream latency.
- Power-cycle the host, restore service, and verify the documented recovery procedure.
Android image compatibility
Each runtime advertises supported_android_os. Phone creation fails when the requested image is not in that list.
- AOSP: the default reference path and the only fallback for older runtime agents.
- LineageOS: enabled only on a node with a built and verified compatible image. Do not infer support from processor architecture alone.
- GrapheneOS: routed only to officially supported devices. GrapheneOS explicitly does not support use as a Generic System Image, so generic virtual or board configurations must never advertise it.
Branded Android client
Launcher name and icon are part of a signed APK. Build a customer-specific founding-access client with scripts/build-branded-android.ps1, or run the branded Android workflow. The inputs set the launcher name, icon, tap destination, and hold destination.
.\scripts\build-branded-android.ps1 `
-BrandName "Field Notes" `
-BrandIcon "C:\assets\field-notes.png" `
-PublicUrl "https://ephemeralphone.org/public/" `
-PrivateUrl "https://ephemeralphone.org/console/"The debug-signed workflow artifact is for founding-access evaluation. Customer distribution requires a dedicated signing key, protected signing process, stable application ID, update policy, and revocation plan.
Designate a shared handset
The tap route opens /public/. Its server gateway exposes only a single phone ID configured by the operator, and only after that phone has the exact metadata marker "ephemeral.public": "true". It does not expose create, start, stop, delete, snapshot, audit, or runtime APIs.
curl -X POST https://CONTROL_PLANE/api/v1/phones \
-H "Authorization: Bearer $EPHEMERAL_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"community","mode":"disposable","android_os":"aosp","runtime_id":"community-node","metadata":{"ephemeral.public":"true"}}'
# Vercel environment after the phone is created and started
PUBLIC_PHONE_ID=phone_returned_by_createOrdering configuration
The public page enables Order an Ephemeral Box only when Stripe secret, Price ID, and shipping countries are configured. Checkout collects billing, delivery address, and phone number; Stripe holds the payment record. The signature-verified webhook can forward paid orders to an HTTPS fulfilment system.
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_BOX_2_PRICE_ID=price_...
STRIPE_SHIPPING_COUNTRIES=IE,GB
STRIPE_AUTOMATIC_TAX=true
ORDER_FULFILLMENT_WEBHOOK_URL=https://orders.example/stripe
ORDER_FULFILLMENT_WEBHOOK_SECRET=...Register https://ephemeralphone.org/api/stripe-webhook for checkout.session.completed and checkout.session.async_payment_succeeded. Do not open ordering until price, tax registration, shipping regions, returns, warranty, inventory, and fulfilment ownership are decided.