mirror of
https://github.com/ruvnet/RuView
synced 2026-07-23 17:33:20 +00:00
bb154d4e78
Closes the cryptographic-attestation gap in ADR-116 §2.2: every
witness event can now be signed by the Seed's Ed25519 key, with
verify available to any auditor holding the public key.
Module shape (`src/witness_signing.rs`, kept separate from
`witness::` so the hash chain stays usable without dalek linked
in — important for the wasm32 audit-verifier variant we'll ship
later):
* sign_event(event, &SigningKey) -> Signature
* verify_signature(event, &Signature, &VerifyingKey)
-> Result<(), SignatureVerifyError>
* signature_to_hex / signature_from_hex (128-char lowercase,
matches the witness hex convention)
* SignatureVerifyError::Invalid
* SignatureParseError::{Length, Hex}
Key design point: signature covers the SAME canonical bytes
witness::hash_event hashes. That means:
1. A signed event commits to the entire event content (kind,
payload, timestamp, seq, prev_hash) — no field can be
retroactively changed without invalidating both the hash AND
the signature.
2. The signature implicitly commits to the event's *chain
position* via prev_hash — splicing a signed event into a
different chain breaks verification.
Adds `ed25519-dalek = "2.1"` to cog-ha-matter (already in
workspace via ruv-neural, version kept aligned).
9 new tests:
* sign_and_verify_round_trip
* verify_rejects_signature_under_wrong_key
* verify_rejects_tampered_event (mutate payload after sign)
* verify_rejects_event_with_wrong_prev_hash (splice attack)
* signature_hex_round_trip
* signature_from_hex_rejects_wrong_length
* signature_from_hex_rejects_non_hex
* signature_is_deterministic_for_same_event_and_key
(locks Ed25519's determinism — catches future accidental
swap to a randomized scheme)
* different_events_produce_different_signatures
60/60 cog tests green (51 → 60). Key management is intentionally
out of scope here — the cog runtime reads the Seed's key from the
Cognitum control plane's secure store (separate concern).
ADR-116 P4 now ⁵⁄₆: ✅ mDNS record, ✅ chain, ✅ JSONL, ✅ file
persistence, ✅ Ed25519 signing; ⏳ responder + embedded broker.
Co-Authored-By: claude-flow <ruv@ruv.net>
47 lines
2.1 KiB
Rust
47 lines
2.1 KiB
Rust
//! ADR-116 — Home Assistant + Matter Cognitum Seed cog.
|
|
//!
|
|
//! This crate is the Seed-installable wrapper around ADR-115's
|
|
//! `wifi-densepose-sensing-server::mqtt` publisher. It adds the
|
|
//! Seed-native surfaces ADR-115's `--mqtt` flag can't easily reach:
|
|
//!
|
|
//! 1. **mDNS service advertisement** — `_ruview-ha._tcp` so HA discovers
|
|
//! the cog automatically (no manual broker host/port config).
|
|
//! 2. **Optional embedded MQTT broker** — for Seeds running without an
|
|
//! external mosquitto. Defaults to off; the cog can either embed
|
|
//! rumqttd or connect to a user-provided broker.
|
|
//! 3. **RuVector-backed semantic-primitive thresholds** — replaces
|
|
//! static `semantic-thresholds.yaml` with a SONA-adapted RuVector
|
|
//! inference. Per-home thresholds learned from the Seed's own
|
|
//! long-term observation stream.
|
|
//! 4. **Ed25519 witness chain** — every state transition signed so
|
|
//! regulated deployments (healthcare, education, shared housing)
|
|
//! have a tamper-evident audit log.
|
|
//! 5. **Multi-Seed federation** — peer discovery via mDNS + cross-Seed
|
|
//! event deduplication keyed on ADR-110's ≤100 µs mesh-aligned
|
|
//! timestamps. One fall in a shared room emits one alert, not N.
|
|
//! 6. **OTA firmware coordination** — the cog manages C6 firmware
|
|
//! rollouts for ESP32-C6 nodes in the local mesh.
|
|
//!
|
|
//! The cog binary entrypoint is in `bin/main.rs`. Library modules
|
|
//! below are intentionally small and testable per the /loop-worker
|
|
//! discipline rules (see `docs/ADR-110-BRANCH-STATE.md`).
|
|
|
|
pub mod manifest;
|
|
pub mod mdns;
|
|
pub mod runtime;
|
|
pub mod witness;
|
|
pub mod witness_signing;
|
|
|
|
/// Cog identifier used in Seed's app-registry.json + the manifest.
|
|
pub const COG_ID: &str = "ha-matter";
|
|
|
|
/// mDNS service type advertised when the cog starts.
|
|
pub const MDNS_SERVICE_TYPE: &str = "_ruview-ha._tcp";
|
|
|
|
/// Default port for the cog's local HTTP control surface (`/health`,
|
|
/// `/api/v1/cog/status`). Distinct from the MQTT broker port.
|
|
pub const DEFAULT_CONTROL_PORT: u16 = 9180;
|
|
|
|
/// Default port for the embedded MQTT broker, when enabled.
|
|
pub const DEFAULT_EMBEDDED_BROKER_PORT: u16 = 1883;
|