Sam Rolfe c4e690ebb2 AUD-56: record the live Hub deploy result
- Five HUB_TOKEN_* keys added to the host secrets file (mode 600, backup kept).
- docker compose up -d --build recreated the hub container on :8788 with the
  AUD-49 image (central-ai-hub:local, sha256:f6b773c8a33a), user 1000:100.
- Verified: /health ok with omniroute ok, control action refused, bad token
  401, container healthy.

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

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.

Description
Central AI Hub - one shared service that every way in reaches every ability through.
Readme 969 KiB
Languages
Go 91.1%
Shell 8.5%
Dockerfile 0.4%