Files
central_ai_llm_master/README.md
Sam Rolfe 4d87124840 AUD-56: deploy prep - token script, container user fix, runbook
- Add scripts/provision-hub-tokens.sh. It adds the five HUB_TOKEN_* keys to
  ~/.config/environment.d/10-secrets.conf. It is idempotent, keeps mode 600,
  leaves a mode-600 backup, and never prints a value. It uses openssl when
  present and /dev/urandom otherwise (this host has no openssl).
- docker-compose.yml: run the container as the host user. The image's
  distroless nonroot user cannot read the 0600 secrets file. With nonroot the
  Hub read no tokens and every /ask returned 401.
- Document the deploy steps, the finding, and the dry-run evidence in
  docs/outline/04-agent-runbook.md, docs/outline/02-config-and-env.md, README.md.

Dry run on port 18788 with a scratch secrets file: /health ok with
omniroute ok, control action refused, bad token 401. The host secrets file and
the running hub container were not touched.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-10 17:48:22 +11:00

3.9 KiB

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 1.25 service · HTTP JSON API · MQTT · LLM intent routing · OmniRoute gateway · Docker
  • Entry routes: POST /ask · POST /approve · GET /health (frozen in docs/hub-api.md)
  • 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

Run the Hub

# Build and run the container (Docker host 192.168.20.13).
docker compose up -d --build

# Liveness (no token).
curl -s http://192.168.20.13:8788/health

# Ask a question (source esp32 speaks the reply on the house speakers).
curl -s -X POST http://192.168.20.13:8788/ask \
  -H "Authorization: Bearer $HUB_TOKEN_ESP32" \
  -H "Content-Type: application/json" \
  -d '{"text":"what does Harry have on today?","asker":"sam","source":"esp32"}'

The Hub reads HUB_TOKEN_*, OMNIROUTE_API_KEY, and the project tokens from ~/.config/environment.d/10-secrets.conf (mounted read-only, never committed). Add the five Hub client tokens with the idempotent script scripts/provision-hub-tokens.sh; it keeps mode 600 and never prints a value. A new token needs Sam's OK (AGENTS.md "ask first: credentials").

Test without a network

scripts/hub-test.sh

The fake /ask project in src/tests/fakeproject/ proves the round trip.

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.
scripts/paperclip-roundtrip.sh --title "round-trip test"

Full steps: docs/outline/04-agent-runbook.md.

System Architecture

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["Peers and services<br/>(the Hub is not a destination)"]
        HA["Home Assistant"]
        SPK["Speakers<br/>Jervis TTS"]
        NET["Internet control<br/>parental limits"]
        ART["Artemis<br/>phone screen"]
        PC["Paperclip<br/>work bench"]
        WEB["Web search"]
        APP["Apprise / NTFY"]
    end

    PHONE --> HUB
    ESP --> HUB
    DSH --> HUB
    CONSOLE --> HUB
    ADMIN --> HUB
    HUB --> HA
    HUB --> SPK
    HUB --> ART
    HUB --> WEB
    HUB --> APP
    HUB -- "ask only (query)" --> NET
    HUB -- "slow job (approved)" --> PC
    ADMIN -- "control + tap to approve" --> NET
    PC -. result .-> HUB

Interactive architecture map: maps.lab.audasmedia.com.au/central_ai_llm_master

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.
  • Hub is at http://192.168.20.13:8788 (local Docker container).

The design brief is hub_brief.md. Project instructions are AGENTS.md.

The interface between the Hub and every data project is docs/ask-contract.md. The frozen inbound API (ways in to the Hub) is docs/hub-api.md. Every other project is a peer, not a sub-project. A high-consequence control (for example, cutting the kids' internet) does not route through the Hub.