Post-implementation spec sync after the call-completion batch landed (commits e4a2594..a3825f5). The sub-agent review flagged no spec drift, but comparing the implemented types against the spec sketches surfaced five details the specs didn't name — filled in here so the spec matches what was built: - client-and-adapters.md: name the shared Dispatcher (protocol/dispatch.rs) + RemoteFilter mechanism that enforces ADR-028's default-deny at dispatch time (the load-bearing security gate — checks remote_safe before building context, before any capability material reaches the handler). Add ClientError/RemoteIdentity types, the spawn_dispatch lower-level API, and the services_list_handler_peer_scoped wiring (the assembly layer must register the peer-scoped services/list handler for a CallClient's registry, not the plain one). Record the v1 TLS client-auth gap (AcceptAnyServerCertVerifier, with_no_client_auth) as OQ-29. - call-protocol.md: point the adapter dispatch-loop description at the shared Dispatcher (dispatch.rs) so readers find the mechanism ADR-017 §1 commits to. - open-questions.md: OQ-29 — CallClient TLS client-auth + remote-identity verification is a two-way-door remainder; the no-env-vars invariant is unaffected (auth_token flows via call-protocol payload, not TLS). - READMEs: current-state now reflects completion done + reviewed (207 lib + 2 integration tests); OQ-29 added to both OQ summaries.
13 KiB
status, last_updated
| status | last_updated |
|---|---|
| draft | 2026-06-26 |
Alknet Architecture
Current State
Pre-implementation. The project has completed a pivot from a three-layer model to an ALPN-as-service model. The greenfield workspace contains only alknet-vault (stable — implementation complete and verified, local-only by construction per ADR-025, HD-derivation key model per ADR-026) and research/reference material. Foundational ADRs (001–028) are in place. ADR-024 resolves the registry mutability question and the OperationContext.env type identity crisis by layering the registry by trust boundary. ADR-025 drops irpc from the vault, making it local-only by construction. ADR-026 records the HD-derivation key model as a foundational decision. Review #003 (type/API surface completeness) resolved: DerivedKey derive contradiction, encrypt prose, return-type divergence, RwLock contradiction, drift table gaps, ADR-022 stale sketches, Capabilities/SessionOverlaySource/CallConnection/CachedKey definitions, CompositeOperationEnv dispatch contract, with_local signature, payload schemas, timeout propagation, and request ID generation. The alknet-core and alknet-call crate specs are in draft; the alknet-vault crate specs are stable.
The alknet-call crate is implemented and reviewed — both the server-side core and the client/adapter surface. The server-side core (CallAdapter, CallConnection dispatch loop, wire framing, pending map, abort cascade, operation registry, service discovery) and the client/adapter surface (CallClient, from_call, from_jsonschema, OperationAdapter trait, shared Dispatcher) are implemented and tested (207 lib + 2 integration tests passing). The call-completion gap analysis (docs/research/alknet-call-completion/gap-analysis.md) identified the missing client/adapter surface specced in ADR-017 plus four decisions (DC-1..4); all are resolved — DC-1 by ADR-028 (peer-scoped default-deny filtering), DC-2/3/4 as two-way-door defaults in client-and-adapters.md (OQ-25..28). A post-implementation review (tasks/call/review-completion.md) confirmed spec conformance; the one spec-sketch omission (connect()'s ClientError return type) was the intended illustrative-sketch gap, now filled in. A TLS client-auth gap surfaced during implementation is tracked as OQ-29.
Next step: The alknet-call crate is ready for downstream consumers (alknet-http's OperationAdapter implementations, the container-service/runner pattern, alknet-agent, alknet-napi). The remaining open questions (OQ-25..29) are all two-way-door shape/defaults, not blockers. The next crate phase is alknet-http (Phase 0 findings in docs/research/alknet-http/).
Architecture Documents
| Document | Status | Description |
|---|---|---|
| overview.md | draft | Workspace-level overview, crate graph, shared types, design principles |
| open-questions.md | draft | Centralized OQ tracker with door-type classifications |
| crates/core/README.md | draft | alknet-core crate index |
| crates/core/core-types.md | draft | ProtocolHandler, HandlerError, Connection, BiStream, StreamError |
| crates/core/endpoint.md | draft | ALPN router, HandlerRegistry, accept loop, shutdown |
| crates/core/auth.md | draft | AuthContext, Identity, IdentityProvider, AuthToken, resolution flow |
| crates/core/config.md | draft | StaticConfig, DynamicConfig, ArcSwap, ConfigReloadHandle |
| crates/call/README.md | draft | alknet-call crate index |
| crates/call/call-protocol.md | draft | CallAdapter, EventEnvelope framing, stream model, PendingRequestMap, bidirectional calls, streaming subscribe example |
| crates/call/operation-registry.md | draft | OperationSpec, Handler, OperationRegistry, AccessControl, capability injection, service discovery, irpc integration |
| crates/call/client-and-adapters.md | draft | CallClient (outbound connection opener), from_call / from_jsonschema, OperationAdapter trait, adapter location map, no-env-vars invariant, exchange-of-operations pattern |
| crates/vault/README.md | stable | alknet-vault crate index |
| crates/vault/mnemonic-derivation.md | stable | BIP39, SLIP-0010, BIP-0032, derivation paths, key types |
| crates/vault/encryption.md | stable | AES-256-GCM, EncryptedData, key versioning, salt (Phase B reserved) |
| crates/vault/service.md | stable | VaultServiceHandle lifecycle, direct dispatch, cache, error model |
| crates/vault/protocol.md | stable | DerivedKey redaction, KeyType, serialization behavior |
ADR Table
| ADR | Title | Status |
|---|---|---|
| 001 | ALPN-Based Protocol Dispatch | Accepted |
| 002 | ProtocolHandler Trait | Accepted |
| 003 | Crate Decomposition | Accepted |
| 004 | Auth as Shared Core (IdentityProvider) | Accepted |
| 005 | irpc as Call Protocol Foundation | Accepted |
| 006 | ALPN String Convention and Connection Model | Accepted |
| 007 | BiStream Type Definition | Accepted |
| 008 | Vault Integration Point | Accepted |
| 009 | One-Way Door Decision Framework | Accepted |
| 010 | ALPN Router and Endpoint | Accepted |
| 011 | AuthContext Structure and Resolution Flow | Accepted |
| 012 | Call Protocol Stream Model | Accepted |
| 013 | Rust as Canonical Implementation Language | Accepted |
| 014 | Secret Material Flow and Capability Injection | Accepted |
| 015 | Privilege Model and Authority Context | Accepted |
| 016 | Abort Cascade for Nested Calls | Accepted |
| 017 | Call Protocol Client and Adapter Contract | Accepted |
| 018 | Vault as Standalone Crate | Accepted |
| 019 | Vault Assembly-Layer-Only Access | Accepted |
| 020 | HD Derivation for Encryption Keys | Accepted |
| 021 | Key Rotation via Version-Indexed Paths | Accepted |
| 022 | Handler Registration, Provenance, and Composition Authority | Accepted |
| 023 | Operation Error Schemas | Accepted |
| 024 | Operation Registry Layering | Accepted |
| 025 | Vault Local-Only Dispatch | Accepted |
| 026 | Vault Key Model — HD Derivation | Accepted |
| 027 | TLS Identity Redesign — ACME + RawKey Decoupling | Accepted |
| 028 | Peer-Scoped Registry Filtering for CallClient Inbound Dispatch | Accepted |
Open Questions
See open-questions.md for the full tracker.
Resolved one-way doors:
- OQ-01: BiStream type — trait with Connection parameter (ADR-007)
- OQ-02: AuthContext timing — hybrid model (ADR-004)
- OQ-03: ALPN naming —
alknet/prefix, no version (ADR-006) - OQ-05: Multi-connectivity endpoint — quinn + iroh, both feature-gated (ADR-010)
- OQ-06: ALPN per connection, not per stream (ADR-006)
- OQ-08: Vault integration — CLI-embedded, assembly-layer only (ADR-008, ADR-014)
- OQ-16: Safe vault operations for call protocol exposure — none for now (ADR-014)
- OQ-18: Privilege model —
internal= authority switch, External/Internal visibility, handler identity + scoped env (ADR-015) - OQ-17: Abort cascade —
call.abortedcascades to descendants; defaultabort-dependents,continue-runningopt-in (ADR-016) - OQ-15: Call protocol client and adapter contract —
CallClientopens connections;from_callimports remote ops; connection direction independent of call direction (ADR-017)
Resolved two-way doors:
- OQ-04: Dynamic handler registration — static at startup (ADR-010); scoped to the
HandlerRegistry(ALPN-level) by ADR-024, which governsOperationRegistrymutability separately - OQ-07: Call protocol scope — bidirectional streams, EventEnvelope, ID-based correlation (ADR-012)
- OQ-11: Handler-level auth resolution observability — handlers store resolved identity on Connection (Option B); two identity scopes: connection-level (observability) and per-request (ACL)
- OQ-12: TLS identity provisioning — two use cases: RFC 7250 raw keys (default, P2P) and X.509 certs (domain-hosted, browsers). ACME designed in ADR-027; RawKey decoupled from iroh feature.
- OQ-13: Operation path format —
/{service}/{op}is the correct design for alknet-call, not a simplification - OQ-14: Batch operation semantics — multiple correlated
call.requestedevents is the correct protocol design, not a simplification - OQ-19: Session-scoped registries — agent-written operations via
OperationEnvtrait layering; protocol doesn't need changes;OperationEnvmust remain a trait. Generalized by ADR-024 to cover connection-scoped overlays as well. - OQ-20: Encryption key derivation — HD derivation from BIP39 seed, not PBKDF2; salt field unused in v2 (wire-format compat) (ADR-020)
- OQ-21: Remote vault access — resolved (ADR-025): vault is local-only by construction; remote access requires a separate vault-server crate with its own ADR
- OQ-22: Key rotation — version-indexed derivation paths;
rotatemethod re-encrypts (ADR-021) - OQ-23: Handler identity registration path — registration bundle with provenance, composition authority, scoped env, capabilities (ADR-022)
- OQ-24: Operation error schemas — declared domain errors with typed
detailspayload; adapter fidelity forfrom_openapi/to_openapi(ADR-023)
Open (two-way-door remainders from alknet-call completion):
- OQ-25: Remote-safe marking shape — existence of default-deny
CallClientfiltering locked by ADR-028; shape (remote_safe: boolv1 vs per-peer allowlist) open - OQ-26:
OperationAdaptererror type —import()returnsResult<_, AdapterError>; variants decided in implementation - OQ-27:
from_callre-import trigger — v1 default auto-on-reconnect; explicitrefresh()additive - OQ-28:
from_callnamespace collision — v1 default error-on-collision (no prefix by default) - OQ-29:
CallClientTLS client-auth + remote-identity verification — v1 connects withwith_no_client_auth()andAcceptAnyServerCertVerifier; wiring RawKey client-auth is additive (the no-env-vars invariant is unaffected —auth_tokenflows through the call-protocol payload, not TLS)
Deferred (not active):
- OQ-09: WASM target boundaries — design constraint, not deliverable
- OQ-10: Git adapter scope — start with smart protocol, add ERC721 later
Document Lifecycle
| Status | Meaning | Transitions |
|---|---|---|
draft |
Under active development. May change significantly. | → reviewed when open questions are resolved |
reviewed |
Architecture is final. Implementation may begin. Changes require review. | → stable when implementation is complete and verified |
stable |
Locked. Changes require review and may warrant an ADR. | → deprecated when superseded |
deprecated |
Superseded. Kept for reference. | Removed when no longer referenced |
References
- Pivot proposal:
docs/research/pivot/alpn-service-architecture.md - Cleanup plan:
docs/research/pivot/cleanup-plan.md - SDD process:
docs/sdd_process.md - Reference implementation:
/workspace/@alkdev/alknet-main/