wifi-densepose/v2/crates/homecore-server
rUv 20ad75f30c
feat(ADR-131): HOMECORE-UI dashboard + BFF gateway — review-fixed (supersedes #1082) (#1099)
* feat(ADR-131): HOMECORE-UI operational dashboard + BFF gateway

Complete two-tier Cognitum operator dashboard (ADR-131), served by
homecore-server at /homecore, plus the single-origin BFF gateway that
wires it to real backends.

Front-end (zero-dep vanilla TS/JS + CSS, exact Cognitum design tokens):
- All 10 panels (§4.1-4.10): dashboard, SEED fleet + detail, fleet map,
  entities (live WS subscribe_events, never polls), rooms, COGs,
  calibration wizard, events + automation builder, witness/audit, settings.
- §6 UX invariants in code: first-class provenance, prominent stale/veto/
  fragility, null(not-trained) vs withheld vs error, --mono everywhere,
  Hailo vs CPU COG distinction.
- api.js calls the gateway routes in production; mock demoted to a
  dev-only ?demo=1 fixture (no mock in prod); typed error states.
- Tests under plain node: import-graph, boot, render-smoke (22),
  interaction (3), prod-errors (13) — 5 files green; bundle ~137 KB
  (~37x smaller than HA), <2 ms/cold-render.

BFF gateway (homecore-server/src/gateway.rs, compiled + tested on Rust 1.89):
- /api/cal/* reverse-proxy to the calibration API (ADR-151).
- GET /api/homecore/rooms with the RoomState adapter (breathing->breathing_bpm,
  heartbeat:null->heart_bpm:null, injected anomaly.threshold/room_id).
- GET /api/homecore/cogs supervisor over /var/lib/cognitum/apps/.
- GET /api/homecore/appliance from /proc + TCP service probes.
- SEED-device/appliance routes return typed 503 upstream_unavailable.
- cargo test -p homecore-server = 12/12; run live (curl-verified);
  fixed a real double-v1 proxy-URL bug found during live testing.

Honest scope: W1/W2/W4/W6-appliance functional; W3/W5/W6-Hailo/federation
return typed 503 (depend on services/hardware not in this repo).

Co-Authored-By: claude-flow <ruv@ruv.net>

* fix(homecore-ui): resolve code-review findings — SSRF guard, CORS/trace coverage, §6 honesty, crash guards

Addresses the high-effort review of PR #1082:
- SECURITY: cal_proxy rejects path-traversal/confused-deputy SSRF (`.`/`..`
  segments, backslash, %2e%2e/%2f, absolute) on raw+decoded forms → 400,
  before attaching the server-side calibration bearer.
- CORRECTNESS: /api/homecore/* + /api/cal/* now covered by the shared CORS
  allowlist (build_cors_layer, exported from homecore-api) + TraceLayer —
  previously merged outside router()'s layers (no CORS, no tracing).
- §6 HONESTY (no fabricated data): dashboard renders '—' for null metrics
  (not "null%"/"null°C"); cogs Hailo pill reflects the REAL appliance probe
  (not hardcoded "connected"); room anomaly threshold passed through / null,
  not a fabricated 0.5.
- ROBUSTNESS: cogs asArray(hef) guards a non-array manifest field; calibration
  progress guards target<=0 (no NaN%/Infinity%); restart clears the poll timer.
- CLEANUP: mock.js is now a cached DYNAMIC import (demo-only) — never bundled
  in production (§2.2).
- New ui/tests/unit-fixes.mjs pins the above; ADR-131 + CHANGELOG updated.

Co-Authored-By: claude-flow <ruv@ruv.net>

---------

Co-authored-by: Nick Ruest <127058086+nicholas-ruest@users.noreply.github.com>
2026-06-15 11:11:19 -04:00
..
src feat(ADR-131): HOMECORE-UI dashboard + BFF gateway — review-fixed (supersedes #1082) (#1099) 2026-06-15 11:11:19 -04:00
ui feat(ADR-131): HOMECORE-UI dashboard + BFF gateway — review-fixed (supersedes #1082) (#1099) 2026-06-15 11:11:19 -04:00
Cargo.toml feat(ADR-131): HOMECORE-UI dashboard + BFF gateway — review-fixed (supersedes #1082) (#1099) 2026-06-15 11:11:19 -04:00
README.md feat(ADR-131): HOMECORE-UI dashboard + BFF gateway — review-fixed (supersedes #1082) (#1099) 2026-06-15 11:11:19 -04:00

README.md

homecore-server

Integrated HOMECORE server binary that wires state machine, API, recorder, plugins, automations, intent assistant, and HomeKit bridge into one process.

Crates.io License MSRV: 1.89+ ADR-126

The production-ready HOMECORE binary — boots all 7 subsystems (core, API, recorder, plugins, automation, assist, HAP bridge) in a single process listening on :8123.

What this crate does

homecore-server is the integration point for the entire HOMECORE ecosystem. It orchestrates:

  1. HomeCore runtime — state machine, event bus, service registry
  2. REST + WebSocket API — Axum server on :8123 (HA-compatible)
  3. SQLite Recorder — persists all state changes to disk
  4. Plugin Registry — loads and manages integrations (InProcessRuntime by default)
  5. Automation Engine — evaluates triggers, conditions, and actions
  6. Assist Pipeline — intent recognition and execution
  7. HAP Bridge — exposes accessories to HomeKit

All subsystems share the same HomeCore instance, so state changes flow through the event bus and trigger automations, record history, and notify WebSocket subscribers in lockstep.

Features

  • Single unified process — no external microservices; run with cargo run -p homecore-server
  • HA-compatible REST API — drop-in replacement for Home Assistant's /api/ on :8123
  • SQLite state history — persistent recording of all state changes
  • Automation engine — YAML-driven trigger→condition→action execution
  • Intent assistant — regex-based (P1) intent recognition + service calling
  • HomeKit bridge — exposes HOMECORE entities as HomeKit accessories
  • Plugin system — load first-party Rust plugins; Wasmtime WASM plugins (P2, --features wasmtime)
  • Configurable via CLI + env vars — no YAML required; sensible defaults
  • Structured logging — tracing output with RUST_LOG filtering
  • Feature-gated subsystems — disable recorder (--no-recorder), enable ruvector/wasmtime as needed

Subsystems

Subsystem Crate Role Notes
State Machine homecore Core domain model All other subsystems depend on this
REST API homecore-api HTTP boundary Listens on :8123; Axum framework
Recorder homecore-recorder Persistence SQLite; optional --no-recorder
Plugins homecore-plugins Extension system InProcessRuntime default; Wasmtime w/ feature
Automation homecore-automation Trigger execution Subscribes to event bus; YAML-driven
Assist homecore-assist Intent pipeline Regex recognizer (P1); semantic (P2)
HAP Bridge homecore-hap HomeKit export Accessories + characteristics; mDNS (P2)

Usage

Basic startup (in-memory recorder):

cargo build -p homecore-server
./target/debug/homecore-server
# Listens on http://localhost:8123

With persistent SQLite:

./target/debug/homecore-server \
  --bind 0.0.0.0:8123 \
  --db sqlite:~/.homecore/home.db \
  --location-name "My Home"

Full feature build (ruvector semantic search + Wasmtime plugins):

cargo build -p homecore-server --features ruvector,wasmtime --release

Via Docker (Dockerfile planned P2):

docker run -p 8123:8123 \
  -e HOMECORE_DB=sqlite:///data/home.db \
  -v ~/.homecore:/data \
  homecore-server:latest

Test the API:

# List all entities
curl http://localhost:8123/api/states

# Set a light to "on"
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"state":"on","attributes":{"brightness":200}}' \
  http://localhost:8123/api/states/light.kitchen

# WebSocket subscription (real-time state changes)
wscat -c ws://localhost:8123/api/websocket

Configuration via env:

export HOMECORE_BIND="0.0.0.0:8123"
export HOMECORE_DB="sqlite:~/.homecore/home.db"
export HOMECORE_LOCATION="Living Room"
export RUST_LOG="homecore=debug,homecore_api=info"
./target/debug/homecore-server

CLI Options

Flag Env Var Default Description
--bind HOMECORE_BIND 0.0.0.0:8123 REST API listen address
--db HOMECORE_DB sqlite::memory: SQLite path (:memory: for ephemeral)
--location-name HOMECORE_LOCATION Home Friendly name returned by /api/config
--no-recorder off Disable SQLite recorder (low-resource deployments)
--ui-dir HOMECORE_UI_DIR <crate>/ui HOMECORE-UI asset dir served at /homecore (ADR-131); empty disables the mount

HOMECORE-UI dashboard (ADR-131)

This binary also serves the HOMECORE-UI — the complete operational dashboard for the two-tier Cognitum stack (v0 Appliance → SEEDs → ESP32 nodes) — at /homecore, alongside the HA-compat /api surface. It is a zero-dependency, no-build-step vanilla TS/JS + CSS frontend living in ui/:

cargo run -p homecore-server          # then open http://localhost:8123/homecore/

It drives the live /api + /api/websocket (subscribe_events) endpoints; panels backed by services not in this binary (SEED HTTPS API, calibration ADR-151, federation ADR-105) render against a DEMO-flagged contract-conformant mock until those endpoints land (ADR-131 §7.1). Frontend tests + benchmark run under plain node (no npm install):

cd ui && npm test     # import graph + render-smoke + interaction (24 checks)
cd ui && npm run bench # bundle budget (~137 KB, ~37× smaller than HA) + render timing

Comparison to Home Assistant

Aspect Home Assistant homecore-server
Architecture Python asyncio monolith Rust async Tokio + component traits
API protocol /api/ REST (HA wire format) Identical HA wire format
Persistence SQLite + YAML files SQLite (P1); Redis (P2)
Plugins Python integrations in homeassistant/components/ Rust (P1) + WASM (P2)
Automation execution Python asyncio event loop Tokio async tasks + trait-based
HomeKit bridge Via homekit integration Built-in homecore-hap subsystem
CLI hass command with config YAML homecore-server with feature flags
Scalability Single instance (HA Cloud for scale) Can be load-balanced (future)
Binary size ~200 MB (Python + deps) ~50 MB (Rust, release build; 200 MB w/ wasmtime)

Performance Targets (unreleased; TBD)

  • Startup time — < 2s to listen on :8123
  • REST endpoint latency — p50 < 1 ms; p99 < 10 ms
  • Event bus throughput — 10,000+ events/sec
  • Automation evaluation — < 100 μs per trigger
  • Concurrent WebSocket connections — 10,000+
  • Memory footprint — ~100 MB (idle); ~500 MB with 1,000 recorded states

Development

Run tests:

cargo test -p homecore-server

Enable debug logging:

RUST_LOG=debug cargo run -p homecore-server -- --bind 127.0.0.1:8123

Build documentation:

cargo doc -p homecore-server --open

Relation to other HOMECORE crates

homecore-server (orchestration binary)
├── homecore (state machine)
├── homecore-api (REST + WS)
├── homecore-recorder (SQLite persistence)
├── homecore-plugins (extension system)
├── homecore-automation (trigger execution)
├── homecore-assist (intent pipeline)
└── homecore-hap (HomeKit bridge)

References