Files
kotlin_phone_app_admin/AGENTS.md

7.8 KiB
Raw Blame History

Kotlin Phone App + Admin

Build spec for Paperclip. Follow the phases in section 11 in order. Do not skip a phase's Definition of Done. When something is unclear, ask Sam — do not guess.


1. Purpose and outcome

Sam's Android app. It is the Hub's way in from the phone, and the trusted admin surface for approvals and parental controls.

Outcome (the single success statement):

Sam talks to the Hub from his phone, hears the answer, and can approve or change anything from the same app.

2. Scope

In scope

  • Capture voice and send it to the Hub.
  • Show the Hub's reply: text, spoken audio, and notifications.
  • Show approval prompts ("Did you ask for this?") and answer them.
  • Admin controls: parental controls, by calling the internet control service.
  • Native phone actions the Hub requests (call, open a link, open an app by deep link).

Out of scope

  • The kids' phone client. That stays under internet_use_control.
  • Artemis (screen control). Separate project.
  • The Hub service itself.
  • Understanding speech. The Hub does that.

Decision to confirm: this is one app with two areas — Hub (voice) and Admin. Not two apps.

3. Users and roles

  • Sam only. This app is not for Jo, Harry, or Finn.
  • The kids' client is a different app, built under internet_use_control.

4. Functional requirements

ID Requirement
FR-1 Capture voice. Start with hold-to-talk; add a wake word later.
FR-2 Send the transcript to the Hub (POST /ask) and show the reply as text.
FR-3 Play the Hub's reply as TTS on the phone, when the reply asks for it.
FR-4 Show approval prompts and return approve or deny to the Hub.
FR-5 Admin: list the kids' devices and their state, and lock, unlock, or grant time.
FR-6 Admin calls the internet use control API directly. The app holds no control logic.
FR-7 Gate admin actions behind a keycode or biometric.
FR-8 Perform native actions the Hub requests: place a call, open a deep link.
FR-9 Show Hub /notify messages as Android notifications.
FR-10 Settings: Hub URL and token. Test the connection.
FR-11 Offline: fail cleanly, and never claim a command succeeded.

5. Screens and UX flow

Screens

  1. Home (Hub) — a large talk button, the last reply, and recent history.
  2. Approvals — pending "Did you ask for this?" items with Approve / Deny.
  3. Admin — the kids' devices, each with its state and quick actions.
  4. Settings — Hub URL, token, keycode, test connection.

Main flow

Sam holds the button and speaks → the Hub replies → the phone speaks it
If the Hub needs approval → a card appears → Sam taps Approve
If Sam opens Admin → he locks a phone → the internet control service applies it

6. Look and feel

Reuse the Family Home Lab design system, adapted to Android.

  • Source: /home/sam/Docker/Containers/family-home-lab/DESIGN.md
  • Tokens: /home/sam/Docker/Containers/family-home-lab/portal/static/tokens.css

Map the tokens to the app theme: canvas #f6f5f4, one action blue #0075de, Inter, 8px spacing, 4px inputs, pill buttons, hairline dividers, dark mode. The login/consent moment is the one dark indigo band.

7. Data model

On the device only. No server database.

Store Holds
Settings Hub URL, Hub token (encrypted), keycode hash
Cache recent replies, pending approvals
Log last actions, for debugging

8. Integrations

System Use
Hub POST /ask, approval callbacks, /notify. Frozen in central_ai_llm_master/docs/hub-api.md.
Internet use control Admin lock, unlock, grant. Direct API call. See internet_use_control/SYSTEM_MAP.md.
Android telephony Native calls and contacts.
Deep links Opening a specific song or place.
Artemis Not called from here. The Hub calls it. Native actions stay in this app.

9. Technology (locked)

Item Value
Language Kotlin (Android)
Voice SpeechRecognizer first; a wake-word engine later
Transport HTTP to the Hub. LAN, or Tailscale when away — decide in Phase 1.
Push FCM, or polling for approvals — decide in Phase 4
Min SDK Decide in Phase 1. Suggest API 29 (Android 10).
Repo sam/kotlin_phone_app_admin

10. Rules and constraints

  1. Admin actions need the keycode or biometric. Never a spoken keycode alone.
  2. The app never holds control logic. It calls the service.
  3. The Hub token lives in encrypted storage. Never in logs.
  4. The app never claims success on a failed call.
  5. Models go through OmniRoute — but this app talks to the Hub, not to models.
  6. Own folder, own repo.

10a. Prerequisites (verify before Phase 1)

Need Status / note
Android toolchain MISSING on .13 — no java/javac, gradle, kotlinc, adb, sdkmanager. Phase 1 cannot start without a JDK + Android SDK + Gradle. Decide: install on .13, or build on .51.
A device to test on sams-pixel-8a is on the tailnet (100.101.49.17).
The Hub Live on .13:8788. Frozen API: central_ai_llm_master/docs/hub-api.md.
Internet use control API Not built yet. Required from Phase 5 (admin lock/unlock). Until then, stop at Phase 4.

Build order note: this project depends on internet_use_control for its admin half. That project is being built first. Phases 1–4 (voice + approvals) do not need it; Phase 5 does.

Task 1 should be: stand up the Android build environment and prove it — JDK, SDK, Gradle, then a hello-world app that calls the Hub's /health and shows the result. No UI, no features. This turns "build an Android app" from an unknown into a known.

11. Build order

Phase 1 — Skeleton and settings Empty app, settings screen, Hub URL + token, test connection. DoD: the app reaches the Hub and shows its health.

Phase 2 — Voice in Hold-to-talk, send to the Hub, show the text reply. DoD: a spoken question returns a Hub answer on screen.

Phase 3 — Voice out Play the reply as TTS on the phone. DoD: the phone speaks the Hub's reply.

Phase 4 — Approvals Fetch pending approvals, show the card, approve or deny. DoD: a real "did you ask for this?" from the Hub is answered from the phone.

Phase 5 — Admin List kids' devices via the internet control API. Lock, unlock, grant. DoD: a real device locks in under one second from the app.

Phase 6 — Security gate Keycode or biometric before admin actions. DoD: admin actions are blocked without the gate.

Phase 7 — Notifications and deep links Hub /notify as notifications. Native actions and deep links. DoD: a Hub notification arrives, and a deep link opens the right song.

Phase 8 — Wake word (optional) Replace hold-to-talk with a wake word. DoD: the wake word starts listening without touching the phone.

Phase 9 — Documentation DoD: project-docs run; docs updated.

12. Acceptance criteria

  • Sam asks a question by voice and hears the answer on the phone.
  • An approval prompt can be answered from the phone.
  • A kids' device can be locked from the app in under one second.
  • Admin actions require the keycode or biometric.
  • A Hub notification arrives on the phone.
  • The app never reports success after a failure.

13. Decisions and remaining questions

Resolved:

  1. One app for Sam (Hub + Admin). The kids' client is under internet_use_control.
  2. Kotlin, Android.
  3. Admin calls the internet control API directly. No Hub in that path.

Remaining:

  1. Hold-to-talk first, wake word later — agree?
  2. How does the app reach the Hub: LAN only, or Tailscale when away?
  3. Approvals by FCM push, or polling?
  4. Locked-screen behaviour: can approvals be answered from the lock screen?
  5. Min SDK version.