Phase 0a — ADRs (9 new): - ADR-026: Transport/interface separation (three-layer model) - ADR-027: Crate decomposition (core, secret, storage, flowgraph, napi, CLI) - ADR-028: Auth as irpc service (AuthProtocol behind feature flag) - ADR-029: Identity as core type (Identity + IdentityProvider in alknet-core) - ADR-030: Static/dynamic config split (ArcSwap, ConfigReloadHandle) - ADR-031: Forwarding policy (rule-based allow/deny, TransportKind-aware) - ADR-032: Event boundary discipline (domain, irpc, call protocol boundaries) - ADR-033: OperationEnv universal composition (three dispatch paths) - ADR-034: Head/worker terminology (replace hub/spoke) Phase 0b — New spec documents (7): - identity.md, services.md, interface.md, configuration.md, storage.md, flowgraph.md, secret-service.md Updated existing docs: - auth.md: reference identity.md for canonical definitions, add AuthProtocol - open-questions.md: resolve OQ-12, OQ-16, OQ-18, OQ-22, OQ-23-25 - README.md: add all new docs, ADRs 026-034 Marked 19 architecture tasks as completed.
6.6 KiB
ADR-027: Crate Decomposition
Status
Accepted
Context
alknet-core currently contains everything: transport, SSH, auth, config, the call protocol handler, and the server accept loop. As the project grows to include SQLite-backed identity, HD key derivation, and metagraph storage, core would need to depend on rusqlite, bip39, petgraph, and other heavy dependencies — unacceptable for a library crate that CLI users embed.
Different deployment topologies need different subsets:
- A minimal CLI tunnel only needs core, transport, and auth types
- A head node needs SQLite-backed identity and the secret service
- A flowgraph visualization tool only needs petgraph operations
Circular dependencies must be avoided. alknet-storage implements
alknet-core's IdentityProvider trait, so alknet-core cannot depend on
alknet-storage. alknet-storage references alknet-secret's EncryptedData wire
format, but not as a crate dependency.
Decision
Decompose the project into six crates with a strict acyclic dependency graph.
Crate Structure
-
alknet-core — Transport, SSH, call protocol, config, auth types, identity,
OperationSpec,Interfacetrait. The foundational crate that everything else depends on (by type, not by crate dep in some cases).- Depends on: russh, tokio, irpc (feature-gated), serde, arc-swap
- Does NOT depend on: alknet-secret, alknet-storage, alknet-flowgraph
-
alknet-secret — BIP39 mnemonic generation, SLIP-0010 Ed25519 HD key derivation, AES-256-GCM encryption,
SecretProtocolirpc service.- Depends on: bip39, ed25519-bip32 (or rust-bip32-ed25519), aes-gcm, sha2, irpc
- Does NOT depend on: alknet-core, alknet-storage
-
alknet-storage — SQLite-backed metagraph, identity tables, ACL graph, honker integration,
StorageProtocolirpc service.- Depends on: rusqlite (via honker), honker, petgraph, jsonschema, irpc
- Does NOT depend on alknet-core (but implements alknet-core's
IdentityProvidertrait via the trait, not a crate dep) - Does NOT depend on alknet-secret (but references
EncryptedDatatype format for wire compatibility)
-
alknet-flowgraph —
FlowGraph<N,E>over petgraph, operation graph, call graph, type compatibility checking.- Depends on: petgraph, serde, jsonschema, thiserror
- Does NOT depend on: alknet-core, alknet-storage, alknet-secret
-
alknet-napi — Node.js native addon. Exposes alknet-core to Node.js.
- Depends on: alknet-core
- Does NOT depend on: alknet-secret, alknet-storage, alknet-flowgraph
-
alknet (CLI binary) — Assembles everything.
- Depends on: alknet-core, alknet-secret (feature), alknet-storage (feature), alknet-flowgraph (feature), toml
Dependency Graph
alknet-secret
/ \
/ \
alknet-core ←──── ←── alknet-storage
↑ \ /
│ alknet-flowgraph
│
alknet-napi
alknet (CLI binary — assembles everything)
Narrow Interface Points
Three types serve as the narrow interface points between crates:
-
Identity— Defined inalknet_core::auth. Used by auth handler, forwarding policy, and call protocol. alknet-storage implementsIdentityProviderto produce instances. -
IdentityProvider— Trait defined inalknet_core::auth. Implemented byConfigIdentityProvider(in core) andStorageIdentityProvider(in alknet-storage). The CLI/NAPI layer wires the concrete implementation. -
OperationSpec— Defined inalknet_core::call. Used by the operation registry and by alknet-flowgraph for type compatibility checking. The bridge is serialization — flowgraph serializes to JSON, storage persists it.
irpc Feature Flag
irpc is a feature flag in alknet-core. When disabled, auth and config go through
IdentityProvider and ConfigReloadHandle directly — no irpc overhead. Nodes
that only do SSH tunneling don't need the service layer.
In alknet-secret and alknet-storage, irpc is an independent dependency, not feature-gated. These crates always define irpc service protocols because they are used in production deployments where the service layer is active.
alknet-storage's Relationship to alknet-core
alknet-storage does NOT depend on alknet-core as a crate. Instead:
- alknet-storage defines its own
IdentityProviderimpl that matches alknet-core's trait signature. The trait is re-exported or defined locally with#[cfg(feature = "alknet-core")]interop. - In practice, the CLI binary crate depends on both and wires them together.
alknet-storage provides
StorageIdentityProvider; alknet-core takesimpl IdentityProvider.
alknet-storage's Relationship to alknet-secret
alknet-storage does NOT depend on alknet-secret as a crate. Instead:
- alknet-storage and alknet-secret share the
EncryptedDatawire format (key version, salt, IV, ciphertext). This is a type-level compatibility, not a crate dependency. - alknet-secret encrypts; alknet-storage stores the encrypted blob in a
SecretNodein the metagraph. The bridge is serialization.
Consequences
- Positive: Core is lean. No database, no crypto, no petgraph. CLI users get a small binary.
- Positive: Services are pluggable. alknet-secret and alknet-storage can be swapped for alternative implementations.
- Positive: No circular dependencies. The dependency graph is a DAG.
- Positive: Deployment topology determines which crates to include. A CLI tunnel uses only alknet-core. A head node uses everything.
- Positive: irpc is feature-gated in core. Minimal deployments don't pay for service layer overhead.
- Negative:
IdentityProvidertrait interop between alknet-core and alknet-storage requires careful versioning. If the trait signature changes, both crates must update. - Negative:
EncryptedDatawire format compatibility between alknet-secret and alknet-storage is implicit (not enforced by the type system). A shared types crate could be extracted if needed, but adds another crate dependency.
References
- research/integration-plan.md — Phase 2, dependency graph
- research/core.md — alknet-core contents
- research/services.md — Service protocols
- research/storage.md — alknet-storage contents
- research/flow.md — alknet-flowgraph contents
- ADR-029 — Identity as core type (narrow interface point)