Technician reference · maintenance

Size the runtime. Verify every slot.

This page records internal installation and acceptance details for maintainers and fulfilment technicians. Customer-facing product pages describe supported outcomes rather than boards, chipsets, or unverified benchmark capacity.

Maintainer hardware records

Internal product detail: use this information for sourcing, imaging, maintenance, and acceptance. Do not make the chipset or board the core customer proposition; the order is for an accepted deployment capability.

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

  1. Boot every promised Android slot concurrently on the shipping image.
  2. Authenticate two distinct test identities through the public gateway.
  3. Open simultaneous WebRTC sessions and exercise touch, keyboard, rotation, audio, lock, stop, and restart.
  4. Confirm each identity sees only its own phone lifecycle records, tickets, and audit events.
  5. Run the workload soak agreed for the order and record CPU, memory, thermal throttling, reconnects, and stream latency.
  6. Power-cycle the host, restore service, and verify the documented recovery procedure.
A Cuttlefish launch can create several guests, but Android’s documentation notes that guests from one multi-tenant invocation stop together. An appliance adapter must account for that lifecycle coupling instead of promising independent stop semantics it does not have.

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_create
Shared means shared. Visitors can observe or change one another’s screen. Do not preinstall personal accounts or permit passwords, payments, private messages, recovery codes, or identity documents. Use a dedicated runtime and an operator-defined reset schedule.

Ordering 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.