Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
plana
PLANA - Protocol for Live Agent Network Automation: a typed application-layer protocol for real-time state synchronization and control between a client shell and a backend service runtime, built on JSON-RPC 2.0 (the way HTTP is built on TCP). Not a general-purpose RPC framework.
The workspace has seven crates without publish = false: the protocol
foundation (plana), the domain profile (plana-celestia-types) and the
service-side crates built on them (plana-rpc-server, plana-rpc-client,
plana-tauri, plana-evernight-client, plana-celestia-config); every other
member is publish = false internal infrastructure. The v* release job in
.github/workflows/publish.yml currently ships five of them: plana,
plana-rpc-server, plana-rpc-client, plana-tauri and
plana-celestia-types.
| Crate | Role in the stack |
|---|---|
plana |
The protocol foundation - the JSON-RPC 2.0 wire layer (plana::jsonrpc) and the generic protocol core (plana::protocol_core) live here directly, plus the server-side axum mounting module behind the rpc-server feature. |
plana-celestia-types |
Celestia domain profile - the celestia-island platform's agent, task, panel, industrial and tool domain messages, built on the generic core. It depends on plana, never the reverse. |
plana-protocol-core |
Re-export shim (publish = false) - a one-line pub use plana::protocol_core::*, kept so git pins naming the former standalone crate keep compiling. |
plana-jsonrpc |
Re-export shim (publish = false) - a one-line pub use plana::jsonrpc::*, same reason. |
Architecture: foundation + domain profiles
PLANA is layered: the foundation crate owns the wire layer and the generic protocol core, and a domain profile is a separate crate that depends on it and plugs its own message vocabulary in.
plana (foundation: plana::jsonrpc + plana::protocol_core)
├── plana-protocol-core / plana-jsonrpc (re-export shims, not published)
├── plana-rpc-server / plana-rpc-client / plana-tauri (service + client frameworks)
├── plana-evernight-client (terminal-route dispatch client)
└── plana-celestia-types (domain profile; depends on plana)
- The generic core -
plana::protocol_coreowns the platform-independent message set: handshake/version/identity negotiation, base protocol messages, health and network descriptors, RBAC, and region policy. It knows nothing about agents, tasks, panels or any specific platform. The generic JSON-RPC 2.0 envelope lives inplana::jsonrpcas the single canonical definition - a former copy in the core drifted and was removed. - Registering a domain - two mechanisms, one for the protocol's own
families and one for third-party profiles:
- Built-in method families declare their namespaces with the
namespace!macro (plana::namespace,#[macro_export]ed at the foundation crate root), which generates the typedMethodvariants whose wire names are derived from the enum path (Sync.Ping,Base.Heartbeat, …). TheMethodcatalog itself is a closed set — extending it is a change to the protocol crate. - Third-party profiles do not fork or patch the protocol: they register
their own method names directly into
plana::jsonrpc::RpcMethodMap(RpcMethodMap::empty().method("my.domain.op", handler), string-keyed dynamic dispatch over HTTP/WS viarpc_axum_router), so any"client shell <-> backend runtime"scenario can speak the same JSON-RPC 2.0 framing without the protocol knowing its methods.
- Built-in method families declare their namespaces with the
- The celestia profile -
plana-celestia-typesis the celestia-island platform's domain profile, built on the generic core ofplana. It is its own crate, not a feature of the foundation: consumers that need the domain vocabulary depend onplana-celestia-typesdirectly. Theplanafeature namedcelestiais a no-op compatibility feature kept only so pins that still declare it keep resolving (see Feature flags). - Shared module names -
httpandenumsexist in both crates, and there is no merged umbrella path between them:plana::http/plana::enumscarry the generic descriptors only, while the domain DTOs (AgentItem,ModelInfo,TierDefinition, …) live underplana_celestia_types::http/plana_celestia_types::enums.plana::http::AgentItemdoes not resolve. - Why it matters - the protocol is usable beyond its origin: any "client shell <-> backend runtime" state-synchronization scenario can implement its own profile crate without forking the protocol.
Usage
Add to your Cargo.toml — either the foundation crate:
[]
= { = "0.2", = ["rpc-server"] }
or the foundation plus the celestia domain profile:
[]
= "0.2"
= "0.1"
plana-jsonrpc and plana-protocol-core are publish = false re-export
shims; do not depend on them by version.
Registering and calling a JSON-RPC method
Built-in method families are declared with the namespace! macro (defined in
plana::jsonrpc::pending) and dispatched through the typed Method
enum. Third-party method names register directly into RpcMethodMap — no
enum extension needed:
use ;
use ;
Using the shared health/network wire types
use ;
Unix-socket transport
use Path;
use ;
let mut transport = connect.await?;
let response = transport.send.await?;
Feature flags
| Feature | Default | What it enables |
|---|---|---|
celestia |
no | No-op compatibility feature. The domain profile is the separate plana-celestia-types crate, which depends on plana (never the reverse), so there is nothing left to gate or re-export. Kept so pins that declare features = ["celestia"] keep resolving; plana::celestia does not exist. |
rpc-server |
no | Server-side SSE event streaming and request network/geo detection (rpc_server::detect_network). Transport sessions for SSE live in plana::jsonrpc::session. |
jsonrpc |
no | No-op compatibility feature — the JSON-RPC layer is an always-on module of this crate now (plana::jsonrpc), so there is nothing to gate. Kept so consumers that declare it keep resolving. |
tracing-helpers |
no | Enables plana::tracing_helpers, the ShortTimer formatting type re-exported from plana::protocol_core::tracing_helpers. |
default = []: no feature is on unless a consumer asks for it.
Consumer migration (post re-pin)
The feature surface of the foundation changed when the generic core was
extracted and again when the celestia facade was removed. Current facts:
celestia— no-op now. It no longer re-exports anything: the domain vocabulary is theplana-celestia-typescrate, so declare that crate directly instead offeatures = ["celestia"].jsonrpc— no-op now (the JSON-RPC layer is always on). A no-op compat feature is kept so existing declarations keep resolving; do not rely on it to disable anything.types— the pre-split name of the domain feature; no such feature exists in any form now. The domain vocabulary is theplana-celestia-typescrate.tracing-helpers— enablesplana::tracing_helpers.
Declarations observed in this workspace (verified against each consumer's
Cargo.toml; keep them in that shape when re-pinning):
| Consumer | Features to declare on plana |
Domain types |
|---|---|---|
| arona | rpc-server |
— |
| shittim-chest | jsonrpc, tracing-helpers |
direct plana-celestia-types dependency |
| evernight | jsonrpc |
— (uses the generic plana::http descriptors) |
| entelecheia | rpc-server |
direct plana-celestia-types dependency |
TypeScript bindings
Generated TS bindings live in two places, both regenerated by
just gen bindings:
packages/plana/bindings/— the generic core types (health, RBAC, handshake, region policy, base messages) and the deferred-operation wire shapes, generated by the foundation crate itself (theplana-protocol-coreshim owns no types). The JSON-RPC request/response envelope is Rust-only; only the error object (JsonRpcError) is generated intobindings/ops.ts.packages/celestia-types/bindings/— the celestia domain profile types (agent, task, industrial, tool, malkuth supervision, …), shipped as the@celestia-island/plana-typesnpm package.
The generic types (e.g. HealthResponse, RbacUser, ConnectionStatus,
BaseHeartbeatParams, RegionPolicy) are generated only into
packages/plana/bindings/; packages/celestia-types/bindings/ additionally
carries two vendored snapshots of the foundation's generated bindings
(protocol-core-httpTypes.ts and ops.ts) so the published npm tarball is
self-contained.
HealthDetailedwas removed in the core split (dead in-repo, unused by in-repo consumers). If you consumed it from the@celestia-island/plana-typesnpm bindings, migrate to the structured health fields (HealthResponse/ServiceStatus/ConnectionStatus).
Stability
Pre-1.0: the API is subject to change. The wire formats (serde layouts, method naming conventions) are treated carefully — changes that affect on-the-wire compatibility are always considered breaking.
Not a general-purpose RPC framework
plana is the scaffold for one specific typed bidirectional sync protocol,
not a general-purpose RPC framework. The wire types and JSON-RPC machinery
are shaped by that protocol's needs; for a generic RPC stack, look at
established frameworks instead.