# aryanil89/smh-hermes architecture

> Architecture diagram of the GitHub repository aryanil89/smh-hermes, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-14). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/aryanil89/smh-hermes
- Repository: https://github.com/aryanil89/smh-hermes

## Overview

#### Purpose and Runtime Topology
Hermes is an on-device AI operations layer for a Snapdragon X Elite laptop. It combines infrastructure telemetry, UNO Q physical sensors, and access state into incident assessments, proactive alerts, and a local operations wall. Core reasoning is Qwen3-4B served by Qualcomm GenieX on the laptop Hexagon NPU; Hermes Agent invokes local MCP servers over stdio. Main operational entry points are `mcp-tools/src/dashboard/server.ts`, MCP server launchers in `mcp-tools/src/servers/`, and the board application at `uno-q/hermes-sensor-logger/python/main.py`.

#### Telemetry and Sensor Ingestion
The UNO Q produces climate ticks, button/ToF events, and board-local SmolLM2 activity inferences. Its app writes events locally and pushes a log to the laptop over WiFi plus Tailscale; USB is provisioning only. The laptop environmental adapter reads that file, applies freshness checks and labeled mock fallback, forming the boundary between physical telemetry and application logic.
Paths: `uno-q/hermes-sensor-logger/python/main.py`, `uno-q/hermes-sensor-logger/push_sensor_log.sh`, `mcp-tools/src/environmental/file-source.ts`, `mcp-tools/src/environmental/unoq-client.ts`.

#### MCP Telemetry and Deterministic Assessment
Five stdio MCP servers expose network, storage, compute, environmental, and a one-call assessment endpoint. Network/storage and most compute data are simulated; host compute can use local OS metrics and preserves `real` versus `mock` provenance. The assessment service collects the telemetry families, computes reproducible risk/confidence, and appends UNO activity only after scoring so it cannot change the verdict.
Paths: `mcp-tools/src/servers/network-server.ts`, `mcp-tools/src/servers/environmental-server.ts`, `mcp-tools/src/servers/assessment-server.ts`, `mcp-tools/src/assess/assess.ts`.

#### Alerting and On-Site Suppression
A persistent watchdog evaluates environmental state every 15 seconds without calling the LLM. It persists alert state, edge-triggers alert/recovery delivery, and routes messages through a Telegram adapter when configured. Suppression is coupled to fresh access state: an expected enrolled responder can defer normal pages, while escalation or stale access state fails open and pages.
Paths: `mcp-tools/src/alert-skill/watch-loop.ts`, `mcp-tools/src/alert-skill/tick.ts`, `mcp-tools/src/alert-skill/suppress.ts`, `mcp-tools/src/common/telegram.ts`.

#### Access-Control Decision Loop
The dashboard server hosts both a read-only wall and the phone approval terminal. Presence events open challenges; captured images go through a pluggable identity ladder, then a decision matrix handles authorization, tailgating, anti-passback, and human approval/denial. Face CPU matching uses external Python/ONNX tooling; unmatched captures remain memory-only, while enrollment stores embeddings/audit state locally.
Paths: `mcp-tools/src/access/sentry.ts`, `mcp-tools/src/access/identify.ts`, `mcp-tools/src/access/decide.ts`, `mcp-tools/src/dashboard/server.ts`.

#### Human Interfaces and Messaging Boundaries
The local dashboard presents shared sensor, infrastructure, access, and alert state, and reads Hermes transcript data read-only. `/phone.html` is the sole human write surface for access decisions. Telegram is the only intentional cloud relay and carries messages, not inference or tool execution. Gateway hooks add early receipts and a degraded failover path when GenieX is unavailable.
Paths: `mcp-tools/public/index.html`, `mcp-tools/public/phone.html`, `hermes-hooks/ack/handler.py`, `hermes-hooks/failover/handler.py`.

#### Compute Tiers and Operations
Laptop inference requires Windows ARM64, Node 22+ for MCP tooling, Hermes Agent, and GenieX’s OpenAI-compatible localhost endpoint. The UNO Q independently runs SmolLM2-135M for pre-correlation. A Galaxy S25 Ultra runs a one-shot ADB-backed Qwen failover, explicitly degraded and tool-less. NPU profiling and serving/energy benchmarks are separate evidence harnesses, not runtime dependencies.
Paths: `scripts/geniex-supervisor.ps1`, `llm-serving-bench/phone/run.sh`, `bench/bench.py`, `llm-serving-bench/bench.py`.

Main entry points: [`mcp-tools/src/dashboard/server.ts`](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/dashboard/server.ts) (Dashboard server), [`mcp-tools/src/environmental/unoq-client.ts`](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/environmental/unoq-client.ts) (UNO Q client), [`mcp-tools/src/servers/environmental-server.ts`](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/servers/environmental-server.ts) (Telemetry MCP servers), [`mcp-tools/src/servers/assessment-server.ts`](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/servers/assessment-server.ts) (Assessment MCP server)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_sensor["UNO Q Edge"]
  node_uno_app["UNO Q sensor app<br/>sensor runtime<br/>[main.py]"]
  node_uno_push["WiFi log push<br/>transport script<br/>[push_sensor_log.sh]"]
  node_uno_smollm{{"SmolLM2 pre-correlation<br/>edge inference"}}
end

subgraph group_mcp["Laptop MCP Layer"]
  node_env_file["Environmental file source<br/>telemetry adapter<br/>[file-source.ts]"]
  node_env_client["UNO Q client<br/>environment adapter<br/>[unoq-client.ts]"]
  node_telemetry_servers["Telemetry MCP servers<br/>stdio MCP servers"]
  node_assessment_server["Assessment MCP server<br/>stdio MCP server"]
  node_assessment_engine["Risk scorer<br/>deterministic assessment<br/>[assess.ts]"]
  node_watchdog["Alert watchdog<br/>persistent loop<br/>[watch-loop.ts]"]
  node_suppression["On-site suppression<br/>alert policy<br/>[suppress.ts]"]
  node_telegram["Telegram relay<br/>cloud messaging adapter<br/>[telegram.ts]"]
end

subgraph group_access["Access &amp; Wall"]
  node_dashboard["Dashboard server<br/>local web server<br/>[server.ts]"]
  node_wall["Operations wall<br/>read-only UI<br/>[index.html]"]
  node_phone["Phone approval terminal<br/>human write UI<br/>[phone.html]"]
  node_sentry["Access sentry<br/>presence challenges<br/>[sentry.ts]"]
  node_identity["Identity ladder<br/>identity matching<br/>[identify.ts]"]
  node_decision["Access decision matrix<br/>authorization policy<br/>[decide.ts]"]
end

subgraph group_inference["Inference Tiers"]
  node_agent["Hermes Agent<br/>local agent runtime"]
  node_geniex{{"GenieX / Qwen3-4B<br/>local NPU inference"}}
  node_hooks["Gateway hooks<br/>receipt and failover hooks<br/>[handler.py]"]
  node_phone_failover{{"Galaxy Qwen failover<br/>degraded phone inference<br/>[run.sh]"}}
end

node_uno_app -->|"activity inputs"| node_uno_smollm
node_uno_app -->|"event log"| node_uno_push
node_uno_push -->|"WiFi/Tailscale"| node_env_file
node_env_file -->|"fresh or mock data"| node_env_client
node_env_client -->|"environmental telemetry"| node_telemetry_servers
node_telemetry_servers -->|"telemetry families"| node_assessment_server
node_assessment_server -->|"assess"| node_assessment_engine
node_uno_smollm -.->|"append after scoring"| node_assessment_engine
node_env_client -->|"environmental state"| node_watchdog
node_watchdog -->|"alert candidate"| node_suppression
node_suppression -->|"edge-triggered page/recovery"| node_telegram
node_dashboard -->|"serves"| node_wall
node_dashboard -->|"serves"| node_phone
node_dashboard -->|"presence event"| node_sentry
node_sentry -->|"capture"| node_identity
node_identity -->|"identity result"| node_decision
node_phone -->|"approval or denial"| node_decision
node_decision -->|"access freshness"| node_suppression
node_agent -->|"stdio tools"| node_telemetry_servers
node_agent -->|"stdio assessment"| node_assessment_server
node_agent -->|"local inference"| node_geniex
node_hooks -.->|"GenieX unavailable"| node_phone_failover

click node_uno_app "https://github.com/aryanil89/smh-hermes/blob/main/uno-q/hermes-sensor-logger/python/main.py"
click node_uno_push "https://github.com/aryanil89/smh-hermes/blob/main/uno-q/hermes-sensor-logger/push_sensor_log.sh"
click node_env_file "https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/environmental/file-source.ts"
click node_env_client "https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/environmental/unoq-client.ts"
click node_telemetry_servers "https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/servers/environmental-server.ts"
click node_assessment_server "https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/servers/assessment-server.ts"
click node_assessment_engine "https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/assess/assess.ts"
click node_watchdog "https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/alert-skill/watch-loop.ts"
click node_suppression "https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/alert-skill/suppress.ts"
click node_telegram "https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/common/telegram.ts"
click node_dashboard "https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/dashboard/server.ts"
click node_wall "https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/public/index.html"
click node_phone "https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/public/phone.html"
click node_sentry "https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/access/sentry.ts"
click node_identity "https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/access/identify.ts"
click node_decision "https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/access/decide.ts"
click node_geniex "https://github.com/aryanil89/smh-hermes/blob/main/scripts/geniex-supervisor.ps1"
click node_hooks "https://github.com/aryanil89/smh-hermes/blob/main/hermes-hooks/failover/handler.py"
click node_phone_failover "https://github.com/aryanil89/smh-hermes/blob/main/llm-serving-bench/phone/run.sh"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_uno_app,node_uno_push,node_uno_smollm toneBlue
class node_env_file,node_env_client,node_telemetry_servers,node_assessment_server,node_assessment_engine,node_watchdog,node_suppression,node_telegram toneAmber
class node_dashboard,node_wall,node_phone,node_sentry,node_identity,node_decision toneMint
class node_agent,node_geniex,node_hooks,node_phone_failover toneRose
```

## Components

### UNO Q Edge

Physical sensing and local pre-correlation.

- [UNO Q sensor app](https://github.com/aryanil89/smh-hermes/blob/main/uno-q/hermes-sensor-logger/python/main.py): sensor runtime · Produces climate, presence, and local activity events. · `uno-q/hermes-sensor-logger/python/main.py`
- [WiFi log push](https://github.com/aryanil89/smh-hermes/blob/main/uno-q/hermes-sensor-logger/push_sensor_log.sh): transport script · Pushes the board event log to the laptop. · `uno-q/hermes-sensor-logger/push_sensor_log.sh`
- **SmolLM2 pre-correlation**: edge inference · Board-local activity inference.

### Laptop MCP Layer

stdio tools, assessment, and alerting.

- [Environmental file source](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/environmental/file-source.ts): telemetry adapter · Reads pushed logs with freshness and mock fallback. · `mcp-tools/src/environmental/file-source.ts`
- [UNO Q client](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/environmental/unoq-client.ts): environment adapter · `mcp-tools/src/environmental/unoq-client.ts`
- [Telemetry MCP servers](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/servers/environmental-server.ts): stdio MCP servers · Network, storage, compute, and environmental telemetry with provenance. · `mcp-tools/src/servers/environmental-server.ts`
- [Assessment MCP server](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/servers/assessment-server.ts): stdio MCP server · Exposes one-call deterministic assessment. · `mcp-tools/src/servers/assessment-server.ts`
- [Risk scorer](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/assess/assess.ts): deterministic assessment · Scores telemetry before appending UNO activity. · `mcp-tools/src/assess/assess.ts`
- [Alert watchdog](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/alert-skill/watch-loop.ts): persistent loop · Evaluates environmental state every 15 seconds without an LLM. · `mcp-tools/src/alert-skill/watch-loop.ts`
- [On-site suppression](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/alert-skill/suppress.ts): alert policy · Fresh expected presence can defer normal pages; stale state fails open. · `mcp-tools/src/alert-skill/suppress.ts`
- [Telegram relay](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/common/telegram.ts): cloud messaging adapter · Only intentional cloud relay; carries messages only. · `mcp-tools/src/common/telegram.ts`

### Access & Wall

Local dashboard and access-control loop.

- [Dashboard server](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/dashboard/server.ts): local web server · Hosts the read-only wall and phone approval terminal. · `mcp-tools/src/dashboard/server.ts`
- [Operations wall](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/public/index.html): read-only UI · Shows sensor, infrastructure, access, alert, and transcript state. · `mcp-tools/public/index.html`
- [Phone approval terminal](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/public/phone.html): human write UI · Sole human write surface for access decisions. · `mcp-tools/public/phone.html`
- [Access sentry](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/access/sentry.ts): presence challenges · Opens access challenges from presence events. · `mcp-tools/src/access/sentry.ts`
- [Identity ladder](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/access/identify.ts): identity matching · Uses pluggable matching; unmatched captures stay memory-only. · `mcp-tools/src/access/identify.ts`
- [Access decision matrix](https://github.com/aryanil89/smh-hermes/blob/main/mcp-tools/src/access/decide.ts): authorization policy · Handles authorization, tailgating, anti-passback, and approval. · `mcp-tools/src/access/decide.ts`

### Inference Tiers

Local NPU reasoning with degraded phone fallback.

- **Hermes Agent**: local agent runtime · Invokes local MCP servers over stdio.
- [GenieX / Qwen3-4B](https://github.com/aryanil89/smh-hermes/blob/main/scripts/geniex-supervisor.ps1): local NPU inference · OpenAI-compatible localhost inference on Hexagon NPU. · `scripts/geniex-supervisor.ps1`
- [Gateway hooks](https://github.com/aryanil89/smh-hermes/blob/main/hermes-hooks/failover/handler.py): receipt and failover hooks · Add early receipts and degraded inference failover. · `hermes-hooks/failover/handler.py`
- [Galaxy Qwen failover](https://github.com/aryanil89/smh-hermes/blob/main/llm-serving-bench/phone/run.sh): degraded phone inference · One-shot ADB-backed and tool-less. · `llm-serving-bench/phone/run.sh`

## Connections

- UNO Q sensor app → SmolLM2 pre-correlation: activity inputs
- UNO Q sensor app → WiFi log push: event log
- WiFi log push → Environmental file source: WiFi/Tailscale
- Environmental file source → UNO Q client: fresh or mock data
- UNO Q client → Telemetry MCP servers: environmental telemetry
- Telemetry MCP servers → Assessment MCP server: telemetry families
- Assessment MCP server → Risk scorer: assess
- SmolLM2 pre-correlation → Risk scorer: append after scoring
- UNO Q client → Alert watchdog: environmental state
- Alert watchdog → On-site suppression: alert candidate
- On-site suppression → Telegram relay: edge-triggered page/recovery
- Dashboard server → Operations wall: serves
- Dashboard server → Phone approval terminal: serves
- Dashboard server → Access sentry: presence event
- Access sentry → Identity ladder: capture
- Identity ladder → Access decision matrix: identity result
- Phone approval terminal → Access decision matrix: approval or denial
- Access decision matrix → On-site suppression: access freshness
- Hermes Agent → Telemetry MCP servers: stdio tools
- Hermes Agent → Assessment MCP server: stdio assessment
- Hermes Agent → GenieX / Qwen3-4B: local inference
- Gateway hooks → Galaxy Qwen failover: GenieX unavailable
