mirror of
https://github.com/ruvnet/RuView
synced 2026-06-30 13:43:18 +00:00
20ad75f30c
* 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>
67 lines
3.0 KiB
TOML
67 lines
3.0 KiB
TOML
# HOMECORE-SERVER — the integration binary that ties every HOMECORE
|
|
# crate together into one process.
|
|
#
|
|
# Boots a HomeCore runtime, opens the SQLite recorder, mounts the
|
|
# REST + WS API on :8123, initializes the plugin runtime, spins up
|
|
# the automation engine subscribed to the state machine, and starts
|
|
# the assist pipeline + HAP bridge surface.
|
|
|
|
[package]
|
|
name = "homecore-server"
|
|
version = "0.1.0-alpha.0"
|
|
edition = "2021"
|
|
license = "MIT"
|
|
authors = ["rUv <ruv@ruv.net>", "HOMECORE Contributors"]
|
|
description = "HOMECORE integration server — wires HomeCore + API + Recorder + Plugins + Automation + Assist + HAP into one process"
|
|
repository = "https://github.com/ruvnet/RuView"
|
|
|
|
[[bin]]
|
|
name = "homecore-server"
|
|
path = "src/main.rs"
|
|
|
|
[dependencies]
|
|
# The 8 HOMECORE crates this binary integrates
|
|
homecore = { path = "../homecore", version = "0.1.0-alpha.0" }
|
|
homecore-api = { path = "../homecore-api", version = "0.1.0-alpha.0" }
|
|
homecore-plugins = { path = "../homecore-plugins", version = "0.1.0-alpha.0" }
|
|
homecore-hap = { path = "../homecore-hap", version = "0.1.0-alpha.0" }
|
|
homecore-recorder = { path = "../homecore-recorder", version = "0.1.0-alpha.0" }
|
|
homecore-automation = { path = "../homecore-automation", version = "0.1.0-alpha.0" }
|
|
homecore-assist = { path = "../homecore-assist", version = "0.1.0-alpha.0" }
|
|
# Migration crate is CLI-only; not linked here.
|
|
|
|
tokio = { version = "1", features = ["full"] }
|
|
tracing = "0.1"
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
clap = { version = "4", features = ["derive", "env"] }
|
|
anyhow = "1"
|
|
serde_json = "1"
|
|
axum = { version = "0.7", features = ["macros"] }
|
|
# Static-file serving for the HOMECORE-UI dashboard (ADR-131) mounted at
|
|
# /homecore, request tracing, and the CORS allowlist applied to BOTH the
|
|
# homecore-api routes AND the merged BFF gateway routes (ADR-131 §11).
|
|
tower-http = { version = "0.6", features = ["fs", "trace", "cors"] }
|
|
# BFF gateway (ADR-131 §11): reverse-proxy the calibration API + aggregate
|
|
# upstreams. rustls is requested here, but NOTE this is a WORKSPACE-WIDE
|
|
# concern: cargo feature-unification means a sibling crate that enables
|
|
# reqwest's default `native-tls` re-introduces OpenSSL into the final binary
|
|
# regardless of this opt-out. A real "no OpenSSL on the appliance" guarantee
|
|
# requires every crate that pulls reqwest to align on rustls-only (tracked in
|
|
# CHANGELOG / ADR-131 security note).
|
|
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
|
|
serde = { version = "1", features = ["derive"] }
|
|
# Concurrent fan-out of per-bank RoomState fetches in the gateway (§11 perf).
|
|
futures = "0.3"
|
|
|
|
[dev-dependencies]
|
|
# Drive the assembled router in integration tests via ServiceExt::oneshot.
|
|
tower = { version = "0.5", features = ["util"] }
|
|
http-body-util = "0.1"
|
|
|
|
[features]
|
|
default = []
|
|
# Pull in ruvector-backed semantic memory.
|
|
ruvector = ["homecore-recorder/ruvector"]
|
|
# Pull in real Wasmtime plugin runtime (vs InProcessRuntime).
|
|
wasmtime = ["homecore-plugins/wasmtime"]
|