# Central AI Hub — Code Structure Map

> **Writing Style**: ASD-STE100 Simplified Technical English (`ste-writing`).
> **Status**: Hub skeleton built (AUD-49). The three inbound routes answer.

## 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
  routing.md                human-edited routing rules
  Dockerfile                multi-stage build (static binary, distroless)
  docker-compose.yml        one container, port 8788
  .dockerignore             build context filter
  docs/
    hub-architecture.mmd    Mermaid source
    hub-architecture-map.html  Archify map
    diagrams/               rendered images
    archify/                Archify JSON input
    outline/                AI context documents
    ask-contract.md         Hub to project interface
    hub-api.md              frozen inbound API (v1)
    vikunja-tasks.json      human task list
  scripts/
    paperclip-roundtrip.sh  Phase 1 outbound job proof
  src/                      Hub service code (module hub)
    go.mod                  module hub (Go 1.25, standard library only)
    main.go                 HTTP layer: POST /ask, POST /approve, GET /health
    apierr/                 the frozen error envelope
    ids/                    ULID request and approval ids
    config/                 environment and secrets loading
    hear/                   step 1: decode and validate the request
    understand/             step 2: never-route check and the routing LLM
    check/                  step 3: identity and source checks
    route/                  step 4: dispatch to one destination
    answer/                 step 5: reply shaping (text, speech, notify)
    destinations/           one client per destination:
                            project.go   (a data project through /ask)
                            speakers.go  (Jervis house TTS)
                            paperclip.go (file a job after approval)
    logbook/                append-only, size-capped request log
    hub/                    the pipeline that wires the five steps
    tests/fakeproject/      fake /ask project for tests and manual runs
```

## Entry Points

| Entry point | Use | Handler |
|---|---|---|
| `POST /ask` | Send a voice transcript or text. Returns a reply. | `main.go`, `hub.Service.Ask` |
| `POST /approve` | Admin app confirms a Hub-owned action. | `main.go`, `hub.Service.Approve` |
| `GET /health` | Liveness check. No authentication. | `main.go`, `hub.Service.Health` |

The inbound API is frozen. See `docs/hub-api.md`.

## The Five Steps in Code

| Step | Package | Notes |
|---|---|---|
| Hear | `hear` | Decode JSON, validate the frozen shape, make a request id. |
| Understand | `understand` | The never-route check runs first, with no LLM. Then the OmniRoute LLM picks route, fanout, clarify, or no_match. |
| Check | `check` | One identity (Sam) and a source that matches the token. |
| Route | `route` | Dispatch. The action call holds no LLM. |
| Answer | `answer` | Choose the reply shape from `source` and `want`. House TTS is out of band. |

## Primary Dependencies

- HTTP server and client (Go 1.25, standard library `net/http`).
- No third-party module. The binary is static and small.
- OmniRoute, Home Assistant, MQTT, and Paperclip are called over HTTP.

## Destinations

Each destination gets one client under `src/destinations/`. The client calls the
destination API. The client does not hold business logic.

## Tests

```bash
# Unit and round-trip tests. No network, no secrets.
docker run --rm -v "$PWD/src":/src -w /src golang:1.25-alpine go test ./...
```

The fake `/ask` project (`src/tests/fakeproject/`) proves the Hub-to-project
round trip. It has no real data and changes no state.

## Source Control

- Gitea: `sam/central_ai_llm_master`
- Local: `/home/sam/paseo/projects/central_ai_llm_master/`
