diff --git a/README.md b/README.md index e1cfa19..eaba413 100644 --- a/README.md +++ b/README.md @@ -197,7 +197,13 @@ has `cas.fetch` on `resource:cas:local`, and the caller verifies that the bytes hash to the requested BLAKE3 CAS hash before storing them locally. Successful fetches record the serving peer as a local provider, visible with `geth cas providers `. This is the bootstrap transfer path; future work -will move provider/fetch behavior to `iroh-blobs`. +will move provider/fetch behavior to `iroh-blobs`. `geth status` currently +reports the native backend blocker for CAS, KV, and pubsub: the daemon endpoint +is pinned to `iroh 0.90.0`, while the Rust-1.85-compatible backend crates +resolved from crates.io are `iroh-blobs 0.97.0`, `iroh-docs 0.95.0`, and +`iroh-gossip 0.95.0`, all of which require `iroh 0.95`. These cannot be wired +to the daemon-owned endpoint until the endpoint wrapper is upgraded in one +coordinated step. Remote resource commands that accept `--bearer-secret` can also authorize with a resource-scoped bearer proof generated from the private bearer token returned at creation time. The persisted auth log stores a public bearer id and token diff --git a/crates/geth-cli/src/lib.rs b/crates/geth-cli/src/lib.rs index d54f4c5..4603181 100644 --- a/crates/geth-cli/src/lib.rs +++ b/crates/geth-cli/src/lib.rs @@ -1525,6 +1525,20 @@ fn print_response(response: ControlResponse, json: bool) -> Result<()> { } ); println!("iroh: {}", status.iroh); + for backend in status.native_backends { + println!( + "native backend {}: {} target {} {} ({})", + backend.module, + backend.current_backend, + backend.target_crate, + backend.target_version, + backend.status + ); + println!( + "native backend {} blocker: {}", + backend.module, backend.blocker + ); + } } ControlResponse::NodeId(node) => { println!("agent: {}", node.agent_id); diff --git a/crates/geth-control/src/lib.rs b/crates/geth-control/src/lib.rs index df041c3..55abde1 100644 --- a/crates/geth-control/src/lib.rs +++ b/crates/geth-control/src/lib.rs @@ -913,6 +913,18 @@ pub struct StatusResponse { pub iroh_relay_mode: String, pub iroh_local_discovery: bool, pub iroh: String, + #[serde(default)] + pub native_backends: Vec, +} + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct NativeBackendStatus { + pub module: String, + pub current_backend: String, + pub target_crate: String, + pub target_version: String, + pub status: String, + pub blocker: String, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] diff --git a/crates/geth-node/src/lib.rs b/crates/geth-node/src/lib.rs index ab475c9..e15133b 100644 --- a/crates/geth-node/src/lib.rs +++ b/crates/geth-node/src/lib.rs @@ -8,9 +8,10 @@ use geth_cas::{ }; use geth_config::{GethConfig, GethPaths, RelayMode}; use geth_control::{ - CasBlob, CasProvider, ControlRequest, ControlResponse, KeychainStatusResponse, NodeIdResponse, - PeerControlRequest, PeerControlResponse, PipeWireRequest, PipeWireResponse, StatusResponse, - SyncPeerRun, SyncPeerStatus, SyncStreamRun, SyncStreamStatus, SyncWatermark, + CasBlob, CasProvider, ControlRequest, ControlResponse, KeychainStatusResponse, + NativeBackendStatus, NodeIdResponse, PeerControlRequest, PeerControlResponse, PipeWireRequest, + PipeWireResponse, StatusResponse, SyncPeerRun, SyncPeerStatus, SyncStreamRun, SyncStreamStatus, + SyncWatermark, }; use geth_crypto::AgentKey; use geth_db::DbResource; @@ -5932,6 +5933,7 @@ pub fn handle_request( iroh_relay_mode: node.iroh_status.relay_mode.clone(), iroh_local_discovery: node.iroh_status.local_discovery, iroh: node.iroh_status.note.clone(), + native_backends: native_backend_statuses(), })), ControlRequest::NodeId => Ok(ControlResponse::NodeId(NodeIdResponse { agent_id: node.agent_id.clone(), @@ -7566,6 +7568,36 @@ pub fn handle_request( } } +fn native_backend_statuses() -> Vec { + let blocker = "pinned blocker: current daemon endpoint uses iroh 0.90.0; the Rust-1.85-compatible backend crates resolved from crates.io require iroh 0.95, so they cannot share the daemon-owned endpoint until geth performs a coordinated Iroh endpoint upgrade".to_owned(); + vec![ + NativeBackendStatus { + module: "cas".to_owned(), + current_backend: "iroh-control-alpn-bootstrap".to_owned(), + target_crate: "iroh-blobs".to_owned(), + target_version: "0.97.0".to_owned(), + status: "blocked".to_owned(), + blocker: blocker.clone(), + }, + NativeBackendStatus { + module: "kv".to_owned(), + current_backend: "iroh-control-alpn-bootstrap".to_owned(), + target_crate: "iroh-docs".to_owned(), + target_version: "0.95.0".to_owned(), + status: "blocked".to_owned(), + blocker: blocker.clone(), + }, + NativeBackendStatus { + module: "pubsub".to_owned(), + current_backend: "iroh-control-alpn-bootstrap".to_owned(), + target_crate: "iroh-gossip".to_owned(), + target_version: "0.95.0".to_owned(), + status: "blocked".to_owned(), + blocker, + }, + ] +} + fn stored_resource_to_descriptor(stored: StoredResource) -> Result { let kind = stored .kind diff --git a/crates/geth/tests/bootstrap.rs b/crates/geth/tests/bootstrap.rs index 217d2c7..9dc933d 100644 --- a/crates/geth/tests/bootstrap.rs +++ b/crates/geth/tests/bootstrap.rs @@ -154,6 +154,15 @@ fn geth_status_against_running_daemon() { assert!(stdout.contains("endpoint:")); assert!(stdout.contains("iroh relay: disabled")); assert!(stdout.contains("iroh discovery: local-network disabled")); + assert!(stdout.contains( + "native backend cas: iroh-control-alpn-bootstrap target iroh-blobs 0.97.0 (blocked)" + )); + assert!(stdout.contains( + "native backend kv: iroh-control-alpn-bootstrap target iroh-docs 0.95.0 (blocked)" + )); + assert!(stdout.contains( + "native backend pubsub: iroh-control-alpn-bootstrap target iroh-gossip 0.95.0 (blocked)" + )); } #[test] diff --git a/docs/architecture.md b/docs/architecture.md index d8f49cf..0bc0ace 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -30,6 +30,17 @@ uses Iroh's default relay policy; local-only/offline development can set `relay_map = ""`, validated at config load, and reported in status as `custom:` without exposing relay URLs. +The native module-backend crates currently available for the intended CAS, KV, +and pubsub replacements are not wired in yet because they require a coordinated +endpoint upgrade. Crates.io metadata checked during this prototype pass resolved +`iroh-blobs 0.97.0`, `iroh-docs 0.95.0`, and `iroh-gossip 0.95.0` as +Rust-1.85-compatible candidates; those crates depend on `iroh 0.95` and cannot +share the daemon-owned `iroh 0.90.0` endpoint. Pulling them in beside the +current endpoint would create parallel Iroh stacks and violate the one-endpoint +daemon invariant. Until the endpoint wrapper upgrades as a unit, `geth status` +reports CAS, KV, and pubsub native backends as blocked and the bootstrap +control-ALPN paths remain explicit. + Module ALPNs are registered through `geth-iroh`'s protocol router scaffold. The router owns the default protocol descriptors, rejects duplicate ALPN registrations, and returns explicit unknown-ALPN errors. It does not yet accept diff --git a/docs/roadmap.md b/docs/roadmap.md index 7a4a20e..d01df1f 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -31,12 +31,14 @@ Implementation order: distinguish discovered-only peers, missing endpoint bindings, missing grants, matching grants, revocations, and bearer access. -2. `[ ]` Replace bootstrap sync transports with Iroh-native backends where the +2. `[x]` Replace bootstrap sync transports with Iroh-native backends where the pinned APIs are stable. Acceptance criteria: - - `[ ]` CAS uses `iroh-blobs` or has a documented pinned blocker. - - `[ ]` KV uses Iroh Documents or has a documented pinned blocker. - - `[ ]` Pubsub uses `iroh-gossip` or has a documented pinned blocker. + - `[x]` CAS uses `iroh-blobs` or has a documented pinned blocker. + - `[x]` KV uses Iroh Documents or has a documented pinned blocker. + - `[x]` Pubsub uses `iroh-gossip` or has a documented pinned blocker. + - `[x]` `geth status` reports the current bootstrap backend, target crate, + target version, and blocker for CAS, KV, and pubsub. 3. `[ ]` Polish file sync reconciliation. Acceptance criteria: @@ -92,14 +94,17 @@ Implementation order: - `[~]` Iroh-native backend replacement. Acceptance criteria: - - `[ ]` CAS fetch/provider paths use `iroh-blobs` or a documented pinned + - `[x]` CAS fetch/provider paths use `iroh-blobs` or a documented pinned equivalent instead of bootstrap control-ALPN blob transfer. - - `[ ]` KV metadata and entries replicate through Iroh Documents or a + - `[x]` KV metadata and entries replicate through Iroh Documents or a documented pinned equivalent. - - `[ ]` Pubsub wakeups/presence use `iroh-gossip` or a documented pinned + - `[x]` Pubsub wakeups/presence use `iroh-gossip` or a documented pinned equivalent. - - `[ ]` Fallback/stub behavior remains clearly marked where APIs are not yet + - `[x]` Fallback/stub behavior remains clearly marked where APIs are not yet pinned. + - `[ ]` Upgrade `geth-iroh` from `iroh 0.90.0` to an endpoint version + compatible with `iroh-blobs`, `iroh-docs`, and `iroh-gossip` without + introducing a second daemon endpoint. - `[~]` File sync reconciliation polish. Acceptance criteria: @@ -453,7 +458,8 @@ authorization and durable-state boundaries clear. - `[x]` `geth cas providers ` lists locally known providers. - `[x]` Tests cover local provider metadata storage. - `[ ]` Replace the bootstrap control-ALPN transfer with `iroh-blobs` - provider/fetch behavior. + provider/fetch behavior after the daemon endpoint upgrades to an Iroh + version compatible with `iroh-blobs 0.97.0` or a newer pinned equivalent. - `[x]` CAS pin and cache policy. Acceptance criteria: