Initial Central AI Hub docs: brief, rules, README, outline context, architecture

This commit is contained in:
2026-10-10 14:44:54 +11:00
commit b3658132dd
14 changed files with 14404 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.env
*.visual-check.*

91
AGENTS.md Normal file
View File

@@ -0,0 +1,91 @@
# Central AI Hub (`central_ai_llm_master`)
## Mission
Build the **Hub**. The Hub is one small service. Every way in reaches every
ability through it. Build the ability once. All ways in get it.
## Authority
Read `hub_brief.md` in this folder first. It is the agreed design. If this file
and the brief disagree, the brief wins.
- `hub_brief.md` — the agreed brief (source of truth).
- `README.md` — technical readme.
- `docs/outline/` — AI context. Start with `00-index.md`.
## What the Hub does
Five steps, in order:
1. **Hear** — take voice or text from any way in.
2. **Understand** — the LLM works out what was asked.
3. **Check** — is this person allowed to ask for this?
4. **Route** — send it to the right destination.
5. **Answer** — return a short reply in the right shape for the device.
The reply can be text, spoken audio (TTS), Artemis commands, a notification, an
email, or a mix. TTS can play on the house speakers or on the phone.
## The dividing line
> Does this need a decision, or does it need to happen?
- **Happen** — fast and certain. Go straight to the destination. No LLM in the
path of the action.
- **Decision** — slow, multi-step, worth recording. Send to Paperclip.
**Paperclip is the work bench, not the switchboard.**
## Rules
1. All models go through **OmniRoute**. Never call a provider directly.
2. All secrets come from **`environment.d`**. Never hard-code.
3. Own service, own port, own folder.
4. No LLM in the path of a fast or consequential action.
5. Paperclip only for slow, multi-step, recorded work.
6. Replies return to the source and stay short.
7. Restricted actions need **tap-to-approve** on the admin app.
8. Only the admin app changes parental controls.
9. A new ability registers with the Hub. Build it once.
## Build order
1. **Thin slice, end to end.** Issue a Paperclip API key. File one job from a
script. Get the result announced back. Prove the round trip.
2. **Hub skeleton.** Hear → understand → route → answer, with one destination.
3. **Approval flow.** "Did you ask for this?" on the admin app.
4. **Internet control.** Standalone service with a plain API. Device-side
enforcement. Admin-only.
5. **Artemis.** Standalone service with a plain API. Screen control only.
6. **Move Jervis's tools** into the Hub. Jervis becomes voice-only.
7. **Phone Kotlin app.** Wake word, voice to the Hub, replies and approvals.
8. **Email and school pipelines.** Stay independent. Connect when ready.
## Definition of done (phase 1)
- A Paperclip API key exists.
- One job is filed by script and its result is spoken.
- The round trip is recorded in `docs/outline/04-agent-runbook.md`.
## How this project relates to the other projects
This project owns the **shared Hub**. It does not own the destinations.
| Project | Relation |
|---|---|
| Email agent | Own pipeline. Reports through the Hub when ready. |
| Compass / NHS | Own pipeline. Reports through the Hub when ready. |
| Internet use control | Destination. Exposes a plain API. The Hub calls it. |
| Artemis | Destination. Exposes a plain API. The Hub calls it. |
| Jervis | Becomes voice-only. Its tools move here. |
| dsh | Calls the Hub for actions. |
Each project writes its own docs. Do not copy theirs here. Link to them.
## Do not
- Do not build one central brain. No single personality or memory.
- Do not put Paperclip in the path of a fast command.
- Do not duplicate a destination inside the Hub.
- Do not add a spoken keycode as the only lock for restricted actions.

81
README.md Normal file
View File

@@ -0,0 +1,81 @@
# Central AI Hub
One small service that every way in reaches every ability through. Built once,
shared by the phone app, the house voice, chat, and the admin app.
## Demonstrated Skills & Tech Stack
- **Core Technologies**: Go or Python service · HTTP JSON API · MQTT · LLM
intent routing · OmniRoute gateway · Docker
- **Key Tools**: Jervis (voice) · Home Assistant · Paperclip · Artemis ·
internet use control · Apprise / NTFY · OmniRoute
- **Engineering Capabilities**: service design · intent routing · authorization
and approval flows · event-driven integration · deterministic safety for
high-consequence actions
## Quick Start
```bash
# Phase 1 — prove the Paperclip round trip
# 1. Create an agent API key in Paperclip.
# 2. Export it for the test only.
export PAPERCLIP_API_KEY=<redacted>
# 3. File one job.
curl -s -X POST http://192.168.20.13:3100/api/issues \
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"round-trip test","description":"prove the return path"}'
```
Full steps: `docs/outline/04-agent-runbook.md`.
## System Architecture
```mermaid
flowchart LR
subgraph IN["Ways in"]
PHONE["Phone app<br/>wake word + voice"]
ADMIN["Admin app<br/>restricted actions"]
ESP["ESP32 voice<br/>Hey Jervis"]
DSH["dsh chat"]
CONSOLE["Console portal"]
end
HUB{{"HUB<br/>hear - understand - check - route - answer"}}
subgraph OUT["Destinations"]
HA["Home Assistant"]
SPK["Speakers<br/>Jervis TTS"]
NET["Internet control"]
ART["Artemis<br/>phone screen"]
PC["Paperclip<br/>slow jobs"]
WEB["Web search"]
APP["Apprise / NTFY"]
end
PHONE --> HUB
ESP --> HUB
DSH --> HUB
CONSOLE --> HUB
ADMIN --> HUB
HUB --> HA
HUB --> SPK
HUB --> NET
HUB --> ART
HUB --> PC
HUB --> WEB
HUB --> APP
PC -. result .-> HUB
```
*Interactive architecture map:* [maps.lab.audasmedia.com.au/central_ai_llm_master](https://maps.lab.audasmedia.com.au/central_ai_llm_master/docs/)
## Usage & Configuration
- **Model calls** go through OmniRoute at `http://192.168.20.13:20129/v1`.
- **Secrets** come from `~/.config/environment.d/10-secrets.conf`.
- **Paperclip** is at `http://192.168.20.13:3100`. An API key is required.
- **Home Assistant** is at `http://192.168.20.30:8123`.
- **Jervis** (voice) is at `http://192.168.20.13:8501`.
The design brief is `hub_brief.md`. Project instructions are `AGENTS.md`.

View File

@@ -0,0 +1,61 @@
{
"schema_version": 1,
"diagram_type": "architecture",
"meta": {
"title": "Central AI Hub",
"output": "docs/hub-architecture-map.html",
"quality_profile": "showcase",
"views": [
{
"id": "fast-command",
"label": "Fast command",
"focus": ["esp32", "hub", "ha", "spk"],
"note": "A fast command goes straight to the destination. No LLM waits in the action path."
},
{
"id": "slow-job",
"label": "Slow job",
"focus": ["phone", "hub", "pc"],
"note": "A slow job goes to Paperclip. The result returns to the Hub later."
},
{
"id": "restricted",
"label": "Restricted action",
"focus": ["admin", "hub", "net"],
"note": "Only the admin app can change parental controls. Voice may ask; the app confirms."
}
]
},
"components": [
{ "id": "phone", "type": "frontend", "label": "Phone app", "sublabel": "wake word + voice", "pos": [40, 80], "size": [150, 64] },
{ "id": "admin", "type": "security", "label": "Admin app", "sublabel": "restricted actions", "pos": [40, 200], "size": [150, 64] },
{ "id": "esp32", "type": "external", "label": "ESP32 voice", "sublabel": "Hey Jervis", "pos": [40, 320], "size": [150, 64] },
{ "id": "dsh", "type": "frontend", "label": "dsh chat", "sublabel": "per person", "pos": [40, 440], "size": [150, 64] },
{ "id": "hub", "type": "backend", "label": "Hub", "sublabel": "hear - understand - check - route - answer", "pos": [390, 260], "size": [190, 80], "tag": "one shared service" },
{ "id": "ha", "type": "external", "label": "Home Assistant", "sublabel": "devices, timers", "pos": [790, 40], "size": [160, 64] },
{ "id": "spk", "type": "external", "label": "Speakers", "sublabel": "Jervis TTS", "pos": [790, 150], "size": [160, 64] },
{ "id": "net", "type": "backend", "label": "Internet control", "sublabel": "parental limits", "pos": [790, 260], "size": [160, 64] },
{ "id": "art", "type": "backend", "label": "Artemis", "sublabel": "phone screen", "pos": [790, 370], "size": [160, 64] },
{ "id": "pc", "type": "backend", "label": "Paperclip", "sublabel": "slow jobs", "pos": [790, 480], "size": [160, 64] },
{ "id": "web", "type": "cloud", "label": "Web search", "sublabel": "Tavily", "pos": [790, 590], "size": [160, 64] },
{ "id": "app", "type": "backend", "label": "Apprise / NTFY", "sublabel": "notify + email", "pos": [790, 700], "size": [160, 64] }
],
"boundaries": [
{ "kind": "region", "label": "Ways in", "wraps": ["phone", "admin", "esp32", "dsh"], "pad": 26 },
{ "kind": "region", "label": "Destinations", "wraps": ["ha", "spk", "net", "art", "pc", "web", "app"], "pad": 26 }
],
"connections": [
{ "id": "phone-in", "from": "phone", "to": "hub", "label": "voice or text" },
{ "id": "admin-in", "from": "admin", "to": "hub", "label": "restricted" },
{ "id": "esp-in", "from": "esp32", "to": "hub", "label": "command" },
{ "id": "dsh-in", "from": "dsh", "to": "hub", "label": "action request" },
{ "id": "to-ha", "from": "hub", "to": "ha", "label": "do it" },
{ "id": "to-spk", "from": "hub", "to": "spk", "label": "speak" },
{ "id": "to-net", "from": "hub", "to": "net", "label": "confirm" },
{ "id": "to-art", "from": "hub", "to": "art", "label": "screen control" },
{ "id": "to-pc", "from": "hub", "to": "pc", "label": "file job" },
{ "id": "to-web", "from": "hub", "to": "web", "label": "search" },
{ "id": "to-app", "from": "hub", "to": "app", "label": "notify" },
{ "id": "pc-back", "from": "pc", "to": "hub", "label": "result", "variant": "dashed" }
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

13716
docs/hub-architecture-map.html Normal file

File diff suppressed because it is too large Load Diff

36
docs/hub-architecture.mmd Normal file
View File

@@ -0,0 +1,36 @@
flowchart LR
subgraph IN["Ways in"]
PHONE["Phone app<br/>wake word + voice"]
ADMIN["Admin app<br/>restricted actions"]
ESP["ESP32 voice<br/>Hey Jervis"]
DSH["dsh chat"]
CONSOLE["Console portal"]
end
HUB{{"HUB<br/>hear - understand - check - route - answer"}}
subgraph OUT["Destinations"]
HA["Home Assistant"]
SPK["Speakers<br/>Jervis TTS"]
NET["Internet control"]
ART["Artemis<br/>phone screen"]
PC["Paperclip<br/>slow jobs"]
WEB["Web search"]
APP["Apprise / NTFY"]
end
PHONE --> HUB
ESP --> HUB
DSH --> HUB
CONSOLE --> HUB
ADMIN --> HUB
HUB --> HA
HUB --> SPK
HUB --> NET
HUB --> ART
HUB --> PC
HUB --> WEB
HUB --> APP
PC -. result .-> HUB
click HUB "https://maps.lab.audasmedia.com.au/central_ai_llm_master/docs/" "View Archify Map"

38
docs/outline/00-index.md Normal file
View File

@@ -0,0 +1,38 @@
# Central AI Hub — AI Document Index
> **Target**: AI Agents
> **Writing Style**: ASD-STE100 Simplified Technical English (`ste-writing`).
## Document Catalog (Inject Specific Document)
Read this index to inject the exact file you need. Do not search all files.
| Document Title | Path | Scope / Description |
| :--- | :--- | :--- |
| **System Overview** | `docs/outline/01-system-overview.md` | Explains the Hub purpose, its five steps, and the destinations. |
| **Configuration & Env** | `docs/outline/02-config-and-env.md` | Lists services, ports, env vars, and secret paths. |
| **Code Structure Map** | `docs/outline/03-code-map.md` | Shows the planned folder layout and entry points. |
| **AI Agent Runbook** | `docs/outline/04-agent-runbook.md` | Gives steps to build, test, and restart Hub work. |
| **Design Brief** | `hub_brief.md` | The agreed design. This file is the source of truth. |
| **Project Rules** | `AGENTS.md` | Mission, rules, build order, and project relations. |
---
## System Summary
The Hub is one service. Every way in reaches every ability through it. The Hub
does five steps: hear, understand, check, route, and answer. The Hub does not
hold a personality or a memory. The Hub does not do the destination work.
## Core Configuration
- **Env File**: `~/.config/environment.d/10-secrets.conf`
- **Config Directory**: `docs/`
- **Active Ports**: Hub port not allocated yet.
## Agent Restart Steps
1. Read the Document Catalog above. Inject only required files.
2. Read `hub_brief.md`.
3. Check git status: `git status`.
4. Check recent commits: `git log -n 5 --oneline`.

View File

@@ -0,0 +1,59 @@
# Central AI Hub — System Overview
> **Writing Style**: ASD-STE100 Simplified Technical English (`ste-writing`).
## Purpose
The Hub is one service. Every way in reaches every ability through the Hub. Build
each ability once. All ways in get it.
Today, Jervis (voice) and dsh (chat) each understand the user and act. A third
way in, the phone app, would repeat the same work. The Hub stops this repeat.
## The Five Steps
1. **Hear** — take voice or text from any way in.
2. **Understand** — the LLM works out what the user asked.
3. **Check** — test whether the user may ask for this.
4. **Route** — send the request to one destination.
5. **Answer** — return a short reply in the right shape.
## Ways In
- Phone app (Kotlin) — wake word, voice, controls.
- Admin app (Kotlin) — restricted actions only.
- ESP32 voice — "Hey Jervis".
- dsh chat — per-person chat.
- Console portal — web dashboard.
## Destinations
| Destination | Job |
|---|---|
| Home Assistant | Lights, switches, timers, calendar. |
| Speakers (Jervis) | Speak and announce. |
| Internet control | Parental limits on kids' devices. |
| Artemis | Operate the phone screen. |
| Paperclip | Slow, multi-step, recorded work. |
| Web search | Tavily search. |
| Apprise / NTFY | Notifications and email. |
## Reply Shapes
The Hub returns one reply. The reply can hold text, spoken audio (TTS), Artemis
commands, a notification, or an email. TTS can play on the house speakers or on
the phone. The Hub returns the reply to the source.
## The Dividing Line
The Hub asks one question: does this need a decision, or does it need to happen?
- **Happen** — fast and certain. Go straight to the destination. No LLM in the
path of the action.
- **Decision** — slow, multi-step, worth recording. Send to Paperclip.
## What the Hub Is Not
- Not a central brain. No single personality or memory.
- Not Paperclip. The Hub does not wait minutes for an answer.
- Not a destination. The Hub does not turn off the internet itself.

View File

@@ -0,0 +1,43 @@
# Central AI Hub — Configuration & Environment
> **Writing Style**: ASD-STE100 Simplified Technical English (`ste-writing`).
## Secrets
All secrets come from `~/.config/environment.d/10-secrets.conf` on each machine.
Never hard-code a secret. Never commit a secret.
Relevant keys:
| Key | Use |
|---|---|
| `OMNIROUTE_API_KEY` | Model calls through OmniRoute. |
| `PAPERCLIP_API_KEY` | File jobs to Paperclip. Does not exist yet. |
| `TAVILY_API_KEY` | Web search. |
| `OL_API_KEY` | Outline docs. |
| `VIKUNJA_TOKEN` | Vikunja tasks. |
| `GITEA_TOKEN` | Gitea repository. |
## Services and Ports
| Service | Host | Port | Use |
|---|---|---|---|
| OmniRoute | 192.168.20.13 | 20129 | Model gateway. |
| Paperclip | 192.168.20.13 | 3100 | Job orchestration. |
| Jervis (voice) | 192.168.20.13 | 8501 | Speak and announce. |
| Home Assistant | 192.168.20.30 | 8123 | Devices and timers. |
| MQTT | 192.168.20.13 | 1883 | Voice topics. |
| Apprise | 192.168.20.35 | 8210 | Notifications. |
| Hub | not allocated | — | This service. |
## Config Paths
- Brief: `hub_brief.md`
- Rules: `AGENTS.md`
- Docs: `docs/`
- Outline context: `docs/outline/`
## Rule
A new project gets its own service, its own port, and its own folder. Do not
merge a destination into the Hub.

View File

@@ -0,0 +1,56 @@
# Central AI Hub — Code Structure Map
> **Writing Style**: ASD-STE100 Simplified Technical English (`ste-writing`).
> **Status**: Planned. The Hub is not built yet.
## Planned Folder Layout
```text
central_ai_llm_master/
AGENTS.md project rules for agents
hub_brief.md agreed design (source of truth)
README.md technical readme
docs/
hub-architecture.mmd Mermaid source
hub-architecture-map.html Archify map
diagrams/ rendered images
archify/ Archify JSON input
outline/ AI context documents
vikunja-tasks.json human task list
src/ Hub service code (to build)
main.* HTTP entry point
hear/ takes voice or text
understand/ LLM intent routing
check/ authorization and approval
route/ dispatch to a destination
answer/ reply shaping (text, TTS, notify)
destinations/ one client per destination
tests/ unit and round-trip tests
```
## Entry Points
| Entry point | Use |
|---|---|
| `POST /ask` | Send a voice transcript or text. Returns a reply. |
| `POST /approve` | Admin app confirms a restricted action. |
| `GET /health` | Liveness check. |
The API contract is not final. See `hub_brief.md`.
## Primary Dependencies
- HTTP server (Go or Python — decide before build).
- HTTP client for OmniRoute, Home Assistant, Paperclip.
- MQTT client for voice topics.
- Tavily API client for web search.
## Destinations
Each destination gets one client under `src/destinations/`. The client calls the
destination API. The client does not hold business logic.
## Source Control
- Gitea: `sam/central_ai_llm_master`
- Local: `/home/sam/paseo/projects/central_ai_llm_master/`

View File

@@ -0,0 +1,55 @@
# Central AI Hub — AI Agent Runbook
> **Writing Style**: ASD-STE100 Simplified Technical English (`ste-writing`).
## Phase 1 — Prove the Paperclip Round Trip
This phase has no Hub code. It proves the missing link: a job that leaves and a
result that returns.
### Steps
1. Create a Paperclip agent API key for this project.
- Paperclip board: `http://192.168.20.13:3100`.
- Store the key in `~/.config/environment.d/10-secrets.conf` as
`PAPERCLIP_API_KEY`. Never commit it.
2. File one job with `curl`. Use the issue-create endpoint.
3. Confirm the job appears in the Paperclip board.
4. Wait for the agent to close the job.
5. Send the result to Jervis `POST /announce` so the house speaks it.
6. Record the result in this file.
### Commands
```bash
export PAPERCLIP_API_KEY=<from secrets>
curl -s -X POST http://192.168.20.13:3100/api/issues \
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"round-trip test","description":"prove the return path"}'
# Speak the result.
curl -s -X POST http://192.168.20.13:8501/announce \
-H "Content-Type: application/json" \
-d '{"text":"Round trip works."}'
```
### Definition of Done
- The job appears in Paperclip.
- The job closes.
- The house speaks the result.
- This file records the result.
## After Phase 1
Follow the build order in `AGENTS.md`. Do not start a destination before the
round trip works.
## Health Checks
```bash
curl -s http://192.168.20.13:3100/health # Paperclip
curl -s http://192.168.20.13:8501/health # Jervis
curl -s -o /dev/null -w '%{http_code}\n' http://192.168.20.30:8123/ # HA
```

16
docs/vikunja-tasks.json Normal file
View File

@@ -0,0 +1,16 @@
{
"title": "Central AI Hub - Human Task Overview",
"description": "High-level task checklist for human team members.",
"tasks": [
{ "title": "Create Paperclip agent API key and store in secrets", "done": false },
{ "title": "Prove the Paperclip round trip (file job, speak result)", "done": false },
{ "title": "Decide the Hub language and port", "done": false },
{ "title": "Build the Hub skeleton (hear, understand, route, answer)", "done": false },
{ "title": "Add the tap-to-approve flow on the admin app", "done": false },
{ "title": "Build the internet control destination service", "done": false },
{ "title": "Build the Artemis destination service", "done": false },
{ "title": "Move Jervis action tools into the Hub", "done": false },
{ "title": "Build the phone Kotlin app", "done": false },
{ "title": "Connect the email and school pipelines", "done": false }
]
}

150
hub_brief.md Normal file
View File

@@ -0,0 +1,150 @@
# The Hub — a short brief
**Purpose:** tell every project where it fits and the rules it must follow.
**Written:** 2026-10-10
**Status:** agreed direction, not a build order.
---
## The idea in one line
**Share the plumbing. Keep the brains separate. Put one small hub in the middle.**
Every way in (phone, house voice, chat) reaches every ability (lights, internet,
Artemis, Paperclip) through one place — built once, not repeated.
---
## What already works (do not rebuild)
| System | What it is |
|---|---|
| **Jervis** | The house voice. ESP32 "Hey Jervis" → STT → agent → TTS → speakers. Controls HA, timers, reminders, shopping, calendar, music, weather, web search, family messages. |
| **dsh** | Per-person chat (sam / jo / harry / finn). Memory, images, video, documents. |
| **Console portal** | Logins and dashboard for the family. |
| **Front Door Cam** | Its own separate ESP32. Visitor detection, Gemini sees the person, voice asks them to speak. |
| **OmniRoute** | The model gateway. All models go through here. |
| **Home Assistant** | Devices, timers, calendar, notifications. |
| **Shared** | Apprise, Snapcast, STT/TTS, n8n, secrets in `environment.d`. |
These stay. The hub is added, not a replacement.
---
## What is new
- The **Hub** (this brief).
- **Email agent** — its own pipeline.
- **School (Compass / Teams)** — its own pipeline.
- **Internet use control** — a destination the hub calls.
- **Artemis** — a destination the hub calls.
- **Kotlin phone app** — a new way in (wake word, voice, controls).
- **Admin app + kids app** — parental control, admin only.
---
## What the Hub is
One service that does five steps:
1. **Hear** — takes voice or text from any way in.
2. **Understand** — the LLM works out what was asked.
3. **Check** — is this person allowed to ask for this?
4. **Route** — sends it to the right destination.
5. **Answer** — returns a short reply in the right shape for the device.
The reply can be **text**, **spoken audio (TTS)**, **Artemis commands**, **a phone
notification**, **an email**, or a mix. TTS can play on the **house speakers** or
on the **phone**.
### What the Hub is NOT
- **Not a central brain.** It does not hold one personality or one memory.
- **Not Paperclip.** It never waits minutes for an answer.
- **Not a destination.** It does not turn off the internet itself. It sends the
request to the service that does.
### The dividing line
One question sorts every request:
> **Does this need a decision, or does it need to happen?**
- **Happen** (fast, certain) → straight to the destination: HA, internet control,
Artemis, speakers. No LLM in the path of the action.
- **Decision** (slow, multi-step, worth recording) → Paperclip.
**Paperclip is the work bench, not the switchboard.** It is never in the path of
a fast or high-consequence command.
---
## Where each system fits
| System | Role | With the Hub |
|---|---|---|
| **Jervis** | House voice | Becomes the **voice** (speak / announce), not a list of tools. Its action tools move into the Hub over time. |
| **dsh** | Chat | Calls the Hub for actions instead of keeping its own copies. |
| **Console portal** | Login + dashboard | Unchanged. May show Hub status and approvals. |
| **Front Door Cam** | Visitor intercom | Stays separate. May use the Hub only to speak. |
| **Email agent** | Own pipeline (n8n) | Standalone. May report results through the Hub. |
| **School agent** | Own pipeline (n8n) | Standalone. May report results through the Hub. |
| **Internet control** | Destination | The Hub calls its API. Enforcement happens on the kids' devices. |
| **Artemis** | Destination | The Hub calls its API. Artemis touches the phone screen. |
| **Paperclip** | Work bench | The Hub files jobs and hears the answer back. |
| **Phone app** | Way in | Sends voice to the Hub. Shows replies, notifications, approvals. |
---
## Rules every project follows
1. **All models go through OmniRoute.** Never call a provider directly.
2. **All secrets come from `environment.d`.** Never hard-code.
3. **Own service, own port, own folder.** Do not merge into another project.
4. **No LLM in the path of a fast or consequential action.** Deterministic calls
for anything that turns something off.
5. **Paperclip only for slow, multi-step, recorded work.** Never make a person
wait on it.
6. **Replies return to the source, and stay short.** Speaker → one line. Phone →
notification. Chat → text. No long-winded answers.
7. **Restricted commands need tap-to-approve** on the admin app. This includes
parental controls and any job filed to Paperclip.
8. **Only the admin app can change parental controls.** Kids' apps and desktop
exes may only obey and report.
9. **New work registers with the Hub.** A capability is added once, and every way
in gets it.
---
## Safety
- **Voice is shared and unauthenticated.** Anyone in the house can speak.
- **The admin app is the only trusted door** for restricted actions.
- **A spoken keycode is not the lock.** It can be overheard and misheard. Voice
may *ask*; the admin app **confirms** with "Did you ask for this?".
- **Approval is required** for parental controls and Paperclip jobs.
---
## Build order
1. **Thin slice, end to end.** Issue a Paperclip API key, file one job from a
script, and get the result announced back. Proves the round trip.
2. **Hub skeleton.** Hear → understand → route → answer, with one destination
(HA or speakers) working.
3. **Approval flow.** "Did you ask for this?" on the admin app.
4. **Internet control.** Standalone service with a plain API. Device-side
enforcement. Admin-only.
5. **Artemis.** Standalone service with a plain API. Screen control only.
6. **Move Jervis's tools** into the Hub. Jervis becomes voice-only.
7. **Phone Kotlin app.** Wake word, voice to the Hub, replies and approvals.
8. **Email and school pipelines** stay independent and connect when ready.
---
## What is still open
- Exact API contract for a job (title, brief, project, agent).
- How Artemis receives voice (stream vs file) and when phone TTS is used.
- Which Paperclip company / projects to use.
- Identity: how the Hub knows which family member is speaking.