Initial spec: AGENTS.md build spec + archived original notes

This commit is contained in:
2026-10-11 17:24:04 +11:00
commit a3b93f6cf3
4 changed files with 291 additions and 0 deletions

180
AGENTS.md Normal file
View File

@@ -0,0 +1,180 @@
# 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.
## 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.