Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
806aac1
feat(rumycelium): ADR-264 + core domain model + versioned C ABI boundary
claude Aug 2, 2026
30636ff
feat(rumycelium): ingest, calibration, worldgraph crates + biome simu…
claude Aug 2, 2026
c378215
feat(rumycelium): governed control path + biome federation crates
claude Aug 2, 2026
d1eab5d
feat(rucelium): rename to RuCelium, biome acceptance benchmark, npm D…
claude Aug 2, 2026
4907b2a
feat(rucelium): ADR-265 runtime layer — scaffolding, docs, README (WIP)
claude Aug 2, 2026
8d3f722
feat(rucelium): durable store, constrained transport, no_std ABI (ADR…
claude Aug 2, 2026
77beba5
feat(rucelium): VerifiedEnvSample sealed type + honest reference-mode…
claude Aug 2, 2026
c00391f
feat(rucelium): cryptographically verified calibration authorities
claude Aug 2, 2026
1b47c51
feat(rucelium): durable store hardening, restart-safe control path, A…
claude Aug 2, 2026
2655940
feat(rucelium-gateway): rhizome daemon — UDP ingest, SensorThings API…
claude Aug 2, 2026
0fd4dec
feat(rucelium): federation identity binding + sealed-sample admission
claude Aug 2, 2026
27d2866
feat(examples): shared scenario toolkit for worked applications
claude Aug 2, 2026
97e0ca4
refactor(rucelium-bench): migrate to hardened APIs
claude Aug 2, 2026
224c3a8
wip(rucelium-gateway): mid-migration snapshot — does not compile
claude Aug 2, 2026
bf16171
docs(rucelium): ADR-267 long-term provenance — Merkle notarization, P…
claude Aug 2, 2026
5014654
feat(rucelium-gateway): restart-safe runtime + reviewer acceptance te…
claude Aug 2, 2026
7a7dad4
docs(rucelium): ADR-268 — integrate with the ruvnet stack, don't rein…
claude Aug 2, 2026
bd70c28
feat(examples): six worked applications green; notary WIP snapshot
claude Aug 2, 2026
179a864
feat(examples): wildfire-risk + pollinator-hive green (8 of 10)
claude Aug 2, 2026
bde7b6d
docs(rucelium): ADR-269 — push federation, and why QUIC belongs at on…
claude Aug 2, 2026
cfcea68
fix(rucelium): exact float parsing — signed JSON must survive the wire
claude Aug 2, 2026
cba0e3b
feat(rucelium-core): bind evidence CONTENT into event signatures
claude Aug 2, 2026
20442c9
wip(rucelium-gateway): ADR-269 push federation mid-implementation
claude Aug 2, 2026
267cd4b
feat(rucelium-gateway): push federation (ADR-269 §3) — 466 tests green
claude Aug 2, 2026
f09713a
feat(rucelium-gateway): QUIC federation with RFC 7250 raw-public-key …
claude Aug 2, 2026
0d812ae
fix(rucelium-federation): close key-succession identity takeover (ADR…
claude Aug 2, 2026
b6001a5
fix(rucelium-federation): sign only what survives its own wire format
claude Aug 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@
Cargo.lock.bak
*.pdb
.claude-flow/

# RuCelium metaharness generation ledger (commit deliberately if you want shared lineage)
.rucelium/
harness/node_modules/
157 changes: 157 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 42 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ members = [
"crates/rufield-fusion",
"crates/rufield-bench",
"crates/rufield-viewer",
"crates/rucelium-core",
"crates/rucelium-abi",
"crates/rucelium-ingest",
"crates/rucelium-calibration",
"crates/rucelium-worldgraph",
"crates/rucelium-policy",
"crates/rucelium-federation",
"crates/rucelium-bench",
"crates/rucelium-store",
"crates/rucelium-transport",
"crates/rucelium-gateway",
"crates/rucelium-notary",
"examples",
]

[workspace.package]
Expand All @@ -20,7 +33,12 @@ repository = "https://github.com/ruvnet/rufield"
[workspace.dependencies]
# Serialization
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
# `float_roundtrip` is LOAD-BEARING, not a nicety: every signature in this
# workspace is computed over canonical JSON, and a peer verifies by
# re-serializing what it parsed. Without exact float parsing, ~9% of realistic
# sensor values come back one ULP off, so a genuine signed summary or event
# fails verification after a wire round-trip. Do not remove.
serde_json = { version = "1.0", features = ["float_roundtrip"] }
toml = "0.8"

# Provenance: hashing + signatures
Expand All @@ -35,6 +53,19 @@ rufield-adapters = { version = "0.1.0", path = "crates/rufield-adapters" }
rufield-fusion = { version = "0.1.0", path = "crates/rufield-fusion" }
rufield-bench = { version = "0.1.0", path = "crates/rufield-bench" }
rufield-viewer = { version = "0.1.0", path = "crates/rufield-viewer" }
rucelium-core = { version = "0.1.0", path = "crates/rucelium-core" }
rucelium-abi = { version = "0.1.0", path = "crates/rucelium-abi" }
rucelium-ingest = { version = "0.1.0", path = "crates/rucelium-ingest" }
rucelium-calibration = { version = "0.1.0", path = "crates/rucelium-calibration" }
rucelium-worldgraph = { version = "0.1.0", path = "crates/rucelium-worldgraph" }
rucelium-policy = { version = "0.1.0", path = "crates/rucelium-policy" }
rucelium-federation = { version = "0.1.0", path = "crates/rucelium-federation" }
rucelium-bench = { version = "0.1.0", path = "crates/rucelium-bench" }
rucelium-store = { version = "0.1.0", path = "crates/rucelium-store" }
rucelium-transport = { version = "0.1.0", path = "crates/rucelium-transport" }
rucelium-gateway = { version = "0.1.0", path = "crates/rucelium-gateway" }
rucelium-notary = { version = "0.1.0", path = "crates/rucelium-notary" }
rucelium-examples = { version = "0.1.0", path = "examples" }

[workspace.lints.rust]
unsafe_code = "forbid"
Expand All @@ -57,3 +88,13 @@ uninlined_format_args = "allow"
[profile.release]
opt-level = 3
lto = true

# The RuCelium biome benchmark signs/verifies ~10^5 ed25519 envelopes per
# run; unoptimized curve arithmetic makes debug `cargo test` minutes-slow.
# Optimize just the crypto dependencies in dev builds.
[profile.dev.package.curve25519-dalek]
opt-level = 3
[profile.dev.package.ed25519-dalek]
opt-level = 3
[profile.dev.package.sha2]
opt-level = 3
93 changes: 93 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,99 @@ The full specification of record is
| [`rufield-bench`](crates/rufield-bench) | Deterministic benchmark runner: F1 per task (SYNTHETIC), p95 latency, provenance coverage, privacy violations, and the ADR-260 §31 acceptance test. |
| [`rufield-viewer`](crates/rufield-viewer) | Read-only web dashboard (Axum + vanilla JS, no build step): room state, event log with privacy badges, fusion graph, signed-receipt viewer. **Two sources** — `--source synthetic` (default) replays `SyntheticSim → RuFieldFusion`; `--source live --upstream <URL>` ingests **real** `FieldEvent`s from a RuField upstream (RuView `/ws/field` / `/api/field`, ADR-262 P3), verifying each receipt on ingest. Honest, mutually-exclusive `SYNTHETIC` / `LIVE` / `DISCONNECTED` banner. Not a device-management console. |

## RuCelium — federated environmental intelligence fabric

[ADR-264](./docs/ADR-264-rucelium-federated-fabric.md) extends the stack
from room-scale field sensing to planetary environmental sensing — **not** as
a flat global peer mesh (which fails on battery, bandwidth, routing,
calibration, sovereignty, and compromised nodes) but as a **federated fabric**
with four layers:

```text
Layer 4 Planetary federation discovery + aggregates (OGC SensorThings), no ownership
Layer 3 Biome regions sovereign owners of data, models, actuators
Layer 2 Rhizome gateways Rust: verify, normalize, calibrate, fuse, buffer, govern
Layer 1 Spore nodes C: sense, fixed-point calibrate, sign, transmit
```

C stays confined to the sensor boundary (drivers, fixed-point DSP,
serialization, transport — see
[`rucelium_env.h`](crates/rucelium-abi/include/rucelium_env.h));
everything above it is safe Rust. RuView RF joins as a **contextual modality**
— supporting evidence with a hard `Advisory` severity cap, never ground truth.

| Crate | Description |
|-------|-------------|
| [`rucelium-core`](crates/rucelium-core) | Domain model: `EnvSample` (twelve mandatory attributes), `EnvFrame`, `CalibrationRecord` (Q16.16, lineage-chained), `EnvironmentalEvent`, `SensorModality` (10), `GeoPoint` with exact privacy coarsening, three-tier `DataClass` residency. |
| [`rucelium-abi`](crates/rucelium-abi) | The versioned C ABI: packed 48-byte `rv_env_sample_v1`, bounds-checked allocation-free parse (no `unsafe`), deterministic CBOR (canonical heads enforced), COSE-inspired signed envelope, ed25519 device keys. |
| [`rucelium-ingest`](crates/rucelium-ingest) | Gateway ingest: envelope decode → registry/revocation → signature verify → anti-replay window → normalized `EnvSample`. Forged packets can't burn sequence numbers. |
| [`rucelium-calibration`](crates/rucelium-calibration) | Calibration lineage (anchor-rooted chains), affine application with stated uncertainty, EWMA drift detection, **quarantine — never silent correction**. |
| [`rucelium-worldgraph`](crates/rucelium-worldgraph) | Environmental WorldGraph: typed sensor/ecosystem/region/anchor nodes, geospatial queries, evidence + contradiction edges, RuView `FieldEvent` RF-context bridge (weight-capped). |
| [`rucelium-policy`](crates/rucelium-policy) | The ADR-264 §9 governed control path — proposal → policy → safety sim → authority → signed command → gateway validation → receipt — typed so **no stage can be skipped**. |
| [`rucelium-federation`](crates/rucelium-federation) | Biome sovereignty: outage buffer with duplicate-free replay, signed regional summaries, device revocation, disclosure coarsening + delay, OGC SensorThings 1.1 projection. |
| [`rucelium-bench`](crates/rucelium-bench) | Deterministic **SYNTHETIC** 64-node biome benchmark: 30 simulated days, 7-day offline partition, tamper/replay attack rejection, mid-run revocation — the ADR-264 §14 **fabric reference-model** acceptance test (in-memory library components; the runtime path — store/transport/gateway — is covered by `rucelium-gateway`'s own e2e and restart-attack tests). |

Run the biome acceptance benchmark:

```bash
cargo run -p rucelium-bench # default seed
cargo run -p rucelium-bench -- 2026 # custom seed
cargo run -p rucelium-bench -- 2026 --json
```

> **Honesty note:** like the RuField numbers, the RuCelium scorecard is
> produced by a deterministic synthetic biome simulator and labelled
> **SYNTHETIC** — it proves the fabric's mechanics (signatures, replay
> windows, dedup, quarantine, revocation, projection) against known ground
> truth. It is not a field deployment.

### Runtime — run a gateway (ADR-265)

The fabric is not only libraries — it runs. [ADR-265](./docs/ADR-265-rucelium-runtime.md)
adds the runtime layer:

| Crate | Description |
|-------|-------------|
| [`rucelium-store`](crates/rucelium-store) | Durable append-only segmented store: dedup index rebuilt on open, torn-tail crash recovery, deterministic replay, per-DataClass retention that deletes whole expired segments. |
| [`rucelium-transport`](crates/rucelium-transport) | Constrained-link transport: compact **114-byte envelope v2** (pubkey by reference — v1's ~150 bytes doesn't fit LoRaWAN DR0's 51-byte cap) + MTU fragmentation/reassembly (exactly 3 DR0 datagrams per envelope, loss/duplication/reorder tolerant). |
| [`rucelium-gateway`](crates/rucelium-gateway) | The rhizome daemon: UDP envelope ingestion (v1/v2/fragments) → signature + anti-replay → calibration + quarantine → disk → WorldGraph → local alerts, an OGC SensorThings HTTP API, and **federation sync** — peers exchange only signed summaries and revocations, verified before use. |

```bash
# Start a gateway with a built-in synthetic spore swarm (no hardware, SYNTHETIC):
cargo run -p rucelium-gateway -- --simulate 16

# Then:
curl -s localhost:7465/api/stats | jq
curl -s localhost:7465/api/sensorthings/Observations | jq '.value[0]'

# Two-biome federation on one machine:
cargo run -p rucelium-gateway -- --biome-id biome/a --udp 7464 --http 7465
cargo run -p rucelium-gateway -- --biome-id biome/b --udp 7474 --http 7475 \
--peer http://127.0.0.1:7465
```

`rucelium-abi` also gains a `std` default feature: with
`--no-default-features --features alloc` the wire format + deterministic CBOR
compile for `no_std` targets, so Rust-based spore nodes can share the encoder.

### Metaharness — the Darwin flywheel

[`harness/`](harness) ships **`rucelium-harness`**, a zero-dependency npm
CLI that turns the implementation process itself into a selection loop
(vary → evaluate → select → retain). Fitness is derived from the same
commands CI runs — workspace tests, clippy, and the ADR-264 §14 acceptance
benchmark — and surviving generations are retained in an append-only ledger:

```bash
node harness/bin/rucelium.js fitness # score the working tree (0..100)
node harness/bin/rucelium.js evolve -m "message" # select vs the ledger head
node harness/bin/rucelium.js ledger # lineage of surviving generations
node harness/bin/rucelium.js gate # strict §14 acceptance gate (CI)
```

A change that lowers fitness is **rejected** (not recorded) unless the
regression is recorded deliberately — see [`harness/README.md`](harness/README.md).

## Install / Quickstart

This repository is a standalone Cargo workspace. The fastest way to see it
Expand Down
28 changes: 28 additions & 0 deletions crates/rucelium-abi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "rucelium-abi"
version.workspace = true
edition.workspace = true
description = "RuCelium versioned C ABI boundary: rv_env_sample_v1 wire format (bounds-checked, allocation-free parse), deterministic CBOR, ed25519 signed record envelope (ADR-264 §11)"
license.workspace = true
authors.workspace = true
repository.workspace = true
keywords = ["environmental", "ffi", "cbor", "wire", "iot"]
categories = ["science", "embedded"]

[features]
# std (default): full surface — domain conversion into rucelium-core and the
# ed25519 signing module.
# --no-default-features --features alloc: the no_std surface for Rust-based
# spore nodes — wire format (parse/encode/validate) + deterministic CBOR
# (ADR-265 §5).
default = ["std"]
std = ["alloc", "dep:rucelium-core", "dep:ed25519-dalek", "dep:sha2"]
alloc = []

[dependencies]
rucelium-core = { workspace = true, optional = true }
ed25519-dalek = { workspace = true, optional = true }
sha2 = { workspace = true, optional = true }

[lints]
workspace = true
Loading
Loading