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

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 }
]
}