Skip to content

Commit 68cdd67

Browse files
ecoPrimalsecoPrimals
authored andcommitted
feat: Edition 2024 migration, biomeOS niche standard compliance, docs cleanup
- Migrated workspace to Edition 2024 with rust-version 1.87 - Wrapped 183 env var calls in unsafe {} (Edition 2024 requirement) - Collapsed 10 nested if/if-let chains into Edition 2024 if-let chains - Created graphs/rhizocrypt_deploy.toml (5-node biomeOS deploy graph) - Created capability_registry.toml (23 methods, 7 domains) - Migrated 5 #[allow(clippy::...)] to #[expect(clippy::...)], removed 1 stale - Fixed health.check method in UnixSocketAdapter (was system.health) - Updated README, CHANGELOG, DEPLOYMENT_CHECKLIST, specs for session 10 - Cleaned stale run-all.sh references from showcase docs Made-with: Cursor
1 parent 4633890 commit 68cdd67

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1645
-401
lines changed

CHANGELOG.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,47 @@ All notable changes to rhizoCrypt will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.13.0-dev] - 2026-03-15 (session 10)
9+
10+
### Changed
11+
12+
#### Edition 2024 Migration (absorbed from wetSpring, airSpring, healthSpring)
13+
- Migrated workspace from Edition 2021 to **Edition 2024** with `rust-version = "1.87"`
14+
- Updated all three Cargo.toml files (workspace, fuzz, showcase)
15+
- Wrapped 183 `std::env::set_var`/`remove_var` calls in `unsafe {}` (Edition 2024 requirement)
16+
- Changed workspace lint from `forbid` to `deny` for `unsafe_code`; `forbid` preserved in non-test builds via `#[cfg_attr(not(test), forbid(unsafe_code))]`
17+
- Collapsed 10 nested `if`/`if let` chains into Edition 2024 `if let` chains
18+
- Applied Edition 2024 `rustfmt` import reordering (types before modules)
19+
20+
#### biomeOS Niche Standard Compliance
21+
- Created `graphs/rhizocrypt_deploy.toml` — 5-node deploy graph (BearDog → Songbird → rhizoCrypt → LoamSpine → sweetGrass) for biomeOS orchestration
22+
- Created `capability_registry.toml` — 23 JSON-RPC methods across 7 domains (`dag.session`, `dag.event`, `dag.vertex`, `dag.merkle`, `dag.slice`, `dag.dehydration`, `health`, `capability`)
23+
24+
#### `#[expect()]` Lint Migration (absorbed from wetSpring V117)
25+
- Migrated 5 production `#[allow(clippy::...)]` to `#[expect(clippy::...)]`
26+
- Caught and removed 1 stale suppression (`missing_const_for_fn` on `RateLimiter::disabled()`)
27+
28+
#### wateringHole Documentation Sync
29+
- Fixed stale method names in `SPRING_PROVENANCE_TRIO_INTEGRATION_PATTERN.md` (`dag.session.append``dag.event.append`, `dag.dehydrate``dag.dehydration.trigger`)
30+
- Updated `RHIZOCRYPT_LEVERAGE_GUIDE.md` with all 23 current semantic method names + `capability.list`
31+
- Updated `PRIMAL_REGISTRY.md` rhizoCrypt entry (1177 tests, 91.47% coverage, Edition 2024)
32+
33+
### Quality Gates
34+
35+
| Gate | Status |
36+
|------|--------|
37+
| `cargo fmt --check` | Clean |
38+
| `cargo clippy` (pedantic + nursery + cargo, all features) | Clean (0 warnings) |
39+
| `cargo doc --workspace --all-features --no-deps` | Clean |
40+
| `cargo test --workspace --all-features` | 1177 pass, 0 fail |
41+
| `cargo deny check` | Clean |
42+
| `unsafe_code = "deny"` | Workspace-wide (`forbid` in non-test builds) |
43+
| SPDX headers | All 106 `.rs` files |
44+
| Max file size | All under 1000 lines |
45+
| Production unwrap/expect | Zero |
46+
47+
---
48+
849
## [0.13.0-dev] - 2026-03-15 (session 9)
950

1051
### Changed
@@ -552,6 +593,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
552593

553594
## Version History Summary
554595

596+
- **0.13.0-dev** (2026-03-15 s10): Edition 2024, deploy graph, capability registry, `#[expect]` lint migration
555597
- **0.13.0-dev** (2026-03-15 s8): O(1) vertex-to-session index, checkout_slice evolution, Did→Arc\<str\>, 907 tests
556598
- **0.13.0-dev** (2026-03-15 s7): scyBorg license, zero-copy signing, store_redb refactor, modern async traits, docs cleanup
557599
- **0.13.0-dev** (2026-03-14 s4): Sovereignty cleanup, 1075 tests, 91% coverage, doc tests rewritten, capability-based errors

Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ members = [
88

99
[workspace.package]
1010
version = "0.13.0-dev"
11-
edition = "2021"
11+
edition = "2024"
12+
rust-version = "1.87"
1213
license = "AGPL-3.0-or-later"
1314
repository = "https://github.com/ecoPrimals/rhizoCrypt"
1415
authors = ["ecoPrimals Project"]
@@ -68,7 +69,10 @@ redb = "2.4"
6869
provenance-trio-types = { path = "../provenance-trio-types" }
6970

7071
[workspace.lints.rust]
71-
unsafe_code = "forbid"
72+
# deny (not forbid) so test modules can #[allow(unsafe_code)] for env var
73+
# mutation, which became unsafe in Edition 2024. Production code has zero
74+
# unsafe — clippy + CI enforce this.
75+
unsafe_code = "deny"
7276
missing_docs = "warn"
7377

7478
[workspace.lints.clippy]

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,17 @@
99
| Tests | 1177 passing (all features) |
1010
| Coverage | 91.47% line coverage (llvm-cov verified) |
1111
| Clippy | 0 warnings (pedantic + nursery + cargo, all features) |
12-
| Unsafe | `#![forbid(unsafe_code)]` workspace-wide |
12+
| Edition | 2024 (rust-version 1.87) |
13+
| Unsafe | `unsafe_code = "deny"` workspace-wide, `forbid` in non-test builds |
1314
| Binary | `rhizocrypt` (UniBin, subcommands via clap) |
1415
| IPC | JSON-RPC 2.0 (HTTP) + tarpc (bincode) — dual-transport first |
1516
| Transport | Platform-agnostic (Unix socket / TCP / abstract socket) |
1617
| Storage | redb (Pure Rust, default) / sled (optional) |
1718
| Deps | ecoBin compliant — zero application C dependencies |
1819
| Audit | `cargo-deny` enforced (advisories, licenses, bans, sources) |
1920
| SPDX | `AGPL-3.0-or-later` header on all 106 `.rs` files |
21+
| Registry | `capability_registry.toml` (23 methods, 7 domains) |
22+
| Deploy | `graphs/rhizocrypt_deploy.toml` (biomeOS niche standard) |
2023

2124
---
2225

@@ -130,7 +133,7 @@ See [docs/ENV_VARS.md](docs/ENV_VARS.md) for the complete list.
130133
| ecoBin | Compliant | Default `redb` backend is 100% Pure Rust; `sled` available as optional feature |
131134
| Universal IPC v3 | Compliant | JSON-RPC 2.0 + tarpc, semantic method names |
132135
| Semantic Naming | Compliant | Native (`commit.*`) + compat (`permanent-storage.*`) with negotiation |
133-
| `#![forbid(unsafe_code)]` | Compliant | Workspace-wide |
136+
| `unsafe_code = "deny"` | Compliant | Workspace-wide, `forbid` in non-test builds |
134137
| AGPL-3.0-or-later | Compliant | SPDX headers on all source files |
135138

136139
---
@@ -143,6 +146,8 @@ See [docs/ENV_VARS.md](docs/ENV_VARS.md) for the complete list.
143146
- [showcase/](showcase/) — Progressive demo suite (70+ working demos)
144147
- [CHANGELOG.md](CHANGELOG.md) — Version history
145148
- [deny.toml](deny.toml) — Dependency audit policy (`cargo-deny`)
149+
- [capability_registry.toml](capability_registry.toml) — Capability registry for biomeOS routing
150+
- [graphs/rhizocrypt_deploy.toml](graphs/rhizocrypt_deploy.toml) — biomeOS deploy graph
146151

147152
---
148153

capability_registry.toml

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# SPDX-License-Identifier: AGPL-3.0-or-later
2+
# rhizoCrypt capability registry — biomeOS ephemeral DAG primal.
3+
#
4+
# Declares the capabilities this primal registers with Songbird for
5+
# capability-based discovery. Self-knowledge only: no references to
6+
# other primals' capabilities.
7+
8+
[primal]
9+
name = "rhizocrypt"
10+
version = "0.13.0-dev"
11+
domain = "dag"
12+
license = "AGPL-3.0-or-later"
13+
description = "Ephemeral content-addressed DAG engine for session-scoped working memory"
14+
15+
# ── Session lifecycle ──────────────────────────────────────────────
16+
17+
[capabilities.session_create]
18+
method = "dag.session.create"
19+
domain = "dag.session"
20+
description = "Create a scoped DAG session with lifecycle management"
21+
22+
[capabilities.session_get]
23+
method = "dag.session.get"
24+
domain = "dag.session"
25+
description = "Retrieve session metadata by ID"
26+
27+
[capabilities.session_list]
28+
method = "dag.session.list"
29+
domain = "dag.session"
30+
description = "List all active sessions"
31+
32+
[capabilities.session_discard]
33+
method = "dag.session.discard"
34+
domain = "dag.session"
35+
description = "Discard and clean up a session"
36+
37+
# ── Vertex operations ──────────────────────────────────────────────
38+
39+
[capabilities.event_append]
40+
method = "dag.event.append"
41+
domain = "dag.event"
42+
description = "Append a content-addressed vertex to a session DAG"
43+
44+
[capabilities.event_append_batch]
45+
method = "dag.event.append_batch"
46+
domain = "dag.event"
47+
description = "Append multiple vertices in a single batch operation"
48+
49+
[capabilities.vertex_get]
50+
method = "dag.vertex.get"
51+
domain = "dag.vertex"
52+
description = "Retrieve a vertex by session and vertex ID"
53+
54+
[capabilities.vertex_query]
55+
method = "dag.vertex.query"
56+
domain = "dag.vertex"
57+
description = "Query vertices with optional type, agent, and limit filters"
58+
59+
[capabilities.vertex_children]
60+
method = "dag.vertex.children"
61+
domain = "dag.vertex"
62+
description = "Get child vertices of a given vertex"
63+
64+
[capabilities.frontier_get]
65+
method = "dag.frontier.get"
66+
domain = "dag.frontier"
67+
description = "Get the frontier (leaf vertices) of a session DAG"
68+
69+
[capabilities.genesis_get]
70+
method = "dag.genesis.get"
71+
domain = "dag.genesis"
72+
description = "Get the genesis (root) vertices of a session DAG"
73+
74+
# ── Merkle integrity ──────────────────────────────────────────────
75+
76+
[capabilities.merkle_root]
77+
method = "dag.merkle.root"
78+
domain = "dag.merkle"
79+
description = "Compute the Merkle root of a session's vertex set"
80+
81+
[capabilities.merkle_proof]
82+
method = "dag.merkle.proof"
83+
domain = "dag.merkle"
84+
description = "Generate an inclusion proof for a vertex"
85+
86+
[capabilities.merkle_verify]
87+
method = "dag.merkle.verify"
88+
domain = "dag.merkle"
89+
description = "Verify a Merkle inclusion proof"
90+
91+
# ── Slice operations ──────────────────────────────────────────────
92+
93+
[capabilities.slice_checkout]
94+
method = "dag.slice.checkout"
95+
domain = "dag.slice"
96+
description = "Checkout an immutable slice from permanent storage"
97+
98+
[capabilities.slice_get]
99+
method = "dag.slice.get"
100+
domain = "dag.slice"
101+
description = "Retrieve slice metadata by ID"
102+
103+
[capabilities.slice_list]
104+
method = "dag.slice.list"
105+
domain = "dag.slice"
106+
description = "List all active slices"
107+
108+
[capabilities.slice_resolve]
109+
method = "dag.slice.resolve"
110+
domain = "dag.slice"
111+
description = "Resolve a slice to its underlying session data"
112+
113+
# ── Dehydration (commit to permanent storage) ─────────────────────
114+
115+
[capabilities.dehydration_trigger]
116+
method = "dag.dehydration.trigger"
117+
domain = "dag.dehydration"
118+
description = "Trigger dehydration of a session to permanent storage"
119+
120+
[capabilities.dehydration_status]
121+
method = "dag.dehydration.status"
122+
domain = "dag.dehydration"
123+
description = "Check the status of a dehydration operation"
124+
125+
# ── Health and introspection ──────────────────────────────────────
126+
127+
[capabilities.health_check]
128+
method = "health.check"
129+
domain = "health"
130+
description = "Service health check with status, version, and uptime"
131+
132+
[capabilities.health_metrics]
133+
method = "health.metrics"
134+
domain = "health"
135+
description = "Operational metrics (sessions, vertices, latency, errors)"
136+
137+
[capabilities.capability_list]
138+
method = "capability.list"
139+
domain = "capability"
140+
description = "List all capabilities this primal provides"

crates/rhizo-crypt-core/benches/dag_benchmarks.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@
1818
#![allow(unused_must_use)]
1919
#![allow(missing_docs)]
2020

21-
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
21+
use criterion::{BenchmarkId, Criterion, Throughput, black_box, criterion_group, criterion_main};
2222
use rhizo_crypt_core::{
23+
DagStore, SessionType,
2324
event::EventType,
2425
merkle::{MerkleRoot, MerkleTreeBuilder},
2526
session::SessionBuilder,
2627
store::InMemoryDagStore,
2728
types::{SessionId, VertexId},
2829
vertex::VertexBuilder,
29-
DagStore, SessionType,
3030
};
3131
use tokio::runtime::Runtime;
3232

crates/rhizo-crypt-core/fuzz/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "rhizo-crypt-core-fuzz"
33
version = "0.0.0"
44
publish = false
5-
edition = "2021"
5+
edition = "2024"
66
license = "AGPL-3.0-or-later"
77

88
[package.metadata]

crates/rhizo-crypt-core/src/clients/adapters/unix_socket.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ impl ProtocolAdapter for UnixSocketAdapter {
264264
}
265265

266266
async fn is_healthy(&self) -> bool {
267-
self.socket_path.exists() && self.call_json("system.health", "{}").await.is_ok()
267+
self.socket_path.exists() && self.call_json("health.check", "{}").await.is_ok()
268268
}
269269

270270
fn endpoint(&self) -> &str {

crates/rhizo-crypt-core/src/clients/beardog_http.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ impl BearDogHttpClient {
153153
///
154154
/// Returns error if the HTTP request fails or response cannot be parsed.
155155
pub async fn sign(&self, data: &[u8]) -> Result<bytes::Bytes, BearDogHttpError> {
156-
use base64::{engine::general_purpose::STANDARD, Engine};
156+
use base64::{Engine, engine::general_purpose::STANDARD};
157157

158158
let request = HttpSignRequest {
159159
data: STANDARD.encode(data),
@@ -191,7 +191,7 @@ impl BearDogHttpClient {
191191
///
192192
/// Returns error if the HTTP request fails or response cannot be parsed.
193193
pub async fn verify(&self, data: &[u8], signature: &[u8]) -> Result<bool, BearDogHttpError> {
194-
use base64::{engine::general_purpose::STANDARD, Engine};
194+
use base64::{Engine, engine::general_purpose::STANDARD};
195195

196196
let request = HttpVerifyRequest {
197197
data: STANDARD.encode(data),
@@ -427,8 +427,8 @@ mod tests {
427427
#[cfg(feature = "live-clients")]
428428
#[tokio::test]
429429
async fn wiremock_sign_success() {
430-
use base64::engine::general_purpose::STANDARD;
431430
use base64::Engine;
431+
use base64::engine::general_purpose::STANDARD;
432432
use wiremock::matchers::{method, path};
433433
use wiremock::{Mock, MockServer, ResponseTemplate};
434434

crates/rhizo-crypt-core/src/clients/nestgate_http.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ impl NestGateHttpClient {
140140
data: &[u8],
141141
content_type: Option<&str>,
142142
) -> Result<String, NestGateHttpError> {
143-
use base64::{engine::general_purpose::STANDARD, Engine};
143+
use base64::{Engine, engine::general_purpose::STANDARD};
144144

145145
let request = HttpStoreBlobRequest {
146146
data: STANDARD.encode(data),
@@ -178,7 +178,7 @@ impl NestGateHttpClient {
178178
///
179179
/// Returns error if the HTTP request fails, blob not found, or response cannot be parsed.
180180
pub async fn retrieve(&self, reference: &str) -> Result<bytes::Bytes, NestGateHttpError> {
181-
use base64::{engine::general_purpose::STANDARD, Engine};
181+
use base64::{Engine, engine::general_purpose::STANDARD};
182182

183183
let response = self
184184
.client
@@ -502,7 +502,7 @@ mod tests {
502502
#[cfg(feature = "live-clients")]
503503
#[tokio::test]
504504
async fn wiremock_retrieve_success() {
505-
use base64::{engine::general_purpose::STANDARD, Engine};
505+
use base64::{Engine, engine::general_purpose::STANDARD};
506506
use wiremock::matchers::{method, path};
507507
use wiremock::{Mock, MockServer, ResponseTemplate};
508508

crates/rhizo-crypt-core/src/clients/songbird/client.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,13 @@ impl SongbirdClient {
205205
}
206206
};
207207

208-
if result.success {
209-
if let Some(ref id) = result.service_id {
210-
*self.service_id.write().await = Some(id.clone());
211-
*self.state.write().await = ClientState::Registered;
212-
*self.our_endpoint.write().await = Some(our_endpoint.to_string());
213-
info!(service_id = %id, "Registered with Songbird mesh");
214-
}
208+
if result.success
209+
&& let Some(ref id) = result.service_id
210+
{
211+
*self.service_id.write().await = Some(id.clone());
212+
*self.state.write().await = ClientState::Registered;
213+
*self.our_endpoint.write().await = Some(our_endpoint.to_string());
214+
info!(service_id = %id, "Registered with Songbird mesh");
215215
}
216216

217217
Ok(result)

0 commit comments

Comments
 (0)