Add architecture specs for the alknet-call crate: - call-protocol.md: CallAdapter, EventEnvelope wire format, bidirectional stream model with ID-based correlation, PendingRequestMap, protocol operations (call/subscribe/batch/schema), per-request identity resolution, connection/stream lifecycle, error codes - operation-registry.md: OperationSpec, async Handler type, OperationRegistry, AccessControl with trusted call bypass, OperationEnv with context propagation (parent_request_id, identity inheritance), service discovery, irpc integration layering, naming convention (no leading slash in names) - ADR-012: Call protocol uses bidirectional QUIC streams with EventEnvelope framing and ID-based correlation. Protocol is stream-agnostic and symmetric. Resolves OQ-07. Key design decisions: - Handler type is async (Fn returning Pin<Box<dyn Future>>) - OperationEnv::invoke propagates parent context (identity, metadata, parent_request_id) - Identity resolution is per-request, not per-connection - Operation names without leading slash (fs/readFile, not /fs/readFile) - Batch is a client-side pattern, not a protocol primitive (OQ-14) - Phase 1 uses service/op paths, node prefix added later (OQ-13) Also: promote ADR-010 and ADR-011 from Proposed to Accepted, add OQ-13 and OQ-14 to open-questions.md.
154 lines
8.3 KiB
Markdown
154 lines
8.3 KiB
Markdown
---
|
|
status: draft
|
|
last_updated: 2026-06-16
|
|
---
|
|
|
|
# Open Questions
|
|
|
|
Questions are organized by theme. Each question has a stable OQ-ID for cross-referencing from spec documents.
|
|
|
|
Door type classifications follow ADR-009:
|
|
- **One-way door**: Reversal requires rewriting significant code or permanently closes a capability. Requires ADR before implementation.
|
|
- **Two-way door**: Reversal is cheap or additive. Can be decided during implementation.
|
|
|
|
## Theme: Core Types
|
|
|
|
### OQ-01: BiStream Type Definition
|
|
|
|
- **Origin**: [overview.md](overview.md)
|
|
- **Status**: resolved
|
|
- **Door type**: One-way
|
|
- **Priority**: high
|
|
- **Resolution**: BiStream is a trait (`AsyncRead + AsyncWrite + Send + Unpin`). Handlers receive a `Connection` (not a single BiStream). This preserves the WASM door — browser clients can implement BiStream over WebTransport streams. See ADR-007.
|
|
- **Cross-references**: ADR-002, ADR-007, ADR-009
|
|
|
|
### OQ-02: AuthContext Resolution Timing
|
|
|
|
- **Origin**: [overview.md](overview.md)
|
|
- **Status**: resolved
|
|
- **Door type**: One-way
|
|
- **Priority**: high
|
|
- **Resolution**: Hybrid model (Option C) — endpoint resolves what it can (e.g., TLS client certificate), handler resolves what it must (e.g., AuthToken in first frame). AuthContext may be partial when `handle()` is called. See ADR-004.
|
|
- **Cross-references**: ADR-002, ADR-004
|
|
|
|
## Theme: ALPN and Routing
|
|
|
|
### OQ-03: ALPN String Naming Convention
|
|
|
|
- **Origin**: [overview.md](overview.md)
|
|
- **Status**: resolved
|
|
- **Door type**: One-way
|
|
- **Priority**: medium
|
|
- **Resolution**: Custom ALPNs use `alknet/<name>` prefix (no version), standard ALPNs use IANA strings. No version negotiation initially. See ADR-006.
|
|
- **Cross-references**: ADR-001, ADR-006
|
|
|
|
### OQ-04: Dynamic Handler Registration at Runtime vs Static at Startup
|
|
|
|
- **Origin**: [overview.md](overview.md)
|
|
- **Status**: resolved
|
|
- **Door type**: Two-way
|
|
- **Priority**: low
|
|
- **Resolution**: Static registration at startup. `HandlerRegistry` is immutable after construction. ALPN strings in the TLS `ServerConfig` are derived from the registry at startup — adding a handler at runtime requires rebuilding the TLS config. The `ArcSwap<HandlerRegistry>` pattern can be applied later if needed (two-way door). See ADR-010.
|
|
- **Cross-references**: ADR-001, ADR-010, [endpoint.md](crates/core/endpoint.md)
|
|
|
|
## Theme: Transport and Endpoint
|
|
|
|
### OQ-05: Multi-Connectivity Endpoint
|
|
|
|
- **Origin**: [overview.md](overview.md)
|
|
- **Status**: resolved
|
|
- **Door type**: One-way
|
|
- **Priority**: high
|
|
- **Resolution**: `AlknetEndpoint` supports both `quinn::Endpoint` (public QUIC+TLS) and `iroh::Endpoint` (P2P relay-assisted) simultaneously, both optional and feature-gated. Both produce QUIC connections that dispatch through the same `HandlerRegistry` by ALPN string. These are not interchangeable transports — they serve fundamentally different deployment contexts (public IP vs NAT traversal). TCP is not an endpoint concern — bare TCP SSH is handled by the SSH handler directly. See ADR-010.
|
|
- **Cross-references**: ADR-001, ADR-010, [endpoint.md](crates/core/endpoint.md)
|
|
|
|
### OQ-06: Server-Side ALPN vs Client-Side ALPN
|
|
|
|
- **Origin**: ADR-001
|
|
- **Status**: resolved
|
|
- **Door type**: One-way
|
|
- **Priority**: low
|
|
- **Resolution**: One ALPN per connection. Clients open one QUIC connection per ALPN. QUIC connections are cheap (multiplexed over the same UDP flow). See ADR-006.
|
|
- **Cross-references**: ADR-001, ADR-006
|
|
|
|
## Theme: Call Protocol
|
|
|
|
### OQ-07: Call Protocol Scope Within a Connection
|
|
|
|
- **Origin**: ADR-005
|
|
- **Status**: resolved
|
|
- **Door type**: Two-way
|
|
- **Priority**: medium
|
|
- **Resolution**: The call protocol uses bidirectional QUIC streams with EventEnvelope framing and ID-based correlation via PendingRequestMap. The protocol is stream-agnostic — the client can open one stream per operation, multiplex on one stream, or any mix. Correlation is by request ID, not by stream. Both sides can initiate calls. One `alknet/call` connection gives access to the full operation registry (call, subscribe, batch, schema). No multiplexing layer is needed inside the connection. See ADR-012.
|
|
- **Cross-references**: ADR-005, ADR-012
|
|
|
|
## Theme: Security
|
|
|
|
### OQ-08: Vault Integration Point
|
|
|
|
- **Origin**: [overview.md](overview.md)
|
|
- **Status**: resolved
|
|
- **Door type**: One-way
|
|
- **Priority**: medium
|
|
- **Resolution**: CLI-embedded with call protocol exposure. The CLI binary instantiates `VaultServiceHandle` locally and registers vault operations in the call protocol's operation registry. alknet-vault has no ALPN and no alknet-core dependency. Key derivation is local-only; only public key material crosses the network via `alknet/call`. The vault is a capability source — derived keys and decrypted credentials are injected into operation contexts at the assembly layer, not passed as vault references to handlers. See ADR-008.
|
|
- **Cross-references**: ADR-003, ADR-005, ADR-008
|
|
|
|
## Deferred Questions
|
|
|
|
These questions are acknowledged but not active. They will be promoted to open when their crate becomes a Phase 1 implementation target.
|
|
|
|
### OQ-09: WASM Target Boundaries
|
|
|
|
- **Origin**: [overview.md](overview.md)
|
|
- **Status**: deferred
|
|
- **Door type**: One-way (when applicable)
|
|
- **Priority**: low
|
|
- **Resolution**: Not an active question — WASM compatibility is a design constraint (see ADR-009, overview.md design principles), not a deliverable. Specific WASM targeting decisions will be made when individual crates are implemented. The BiStream trait decision (ADR-007) has already preserved the most important WASM door.
|
|
- **Cross-references**: ADR-007, ADR-009
|
|
|
|
### OQ-10: Git Adapter Scope — Smart Protocol Only or Full Server?
|
|
|
|
- **Origin**: [overview.md](overview.md)
|
|
- **Status**: deferred
|
|
- **Door type**: Two-way
|
|
- **Priority**: low
|
|
- **Resolution**: Deferred per the cleanup plan. Start with git smart protocol over QUIC streams. ERC721 integration and full server capabilities are additive. Resolve when speccing alknet-git.
|
|
- **Cross-references**: ADR-001
|
|
|
|
## Theme: alknet-core
|
|
|
|
### OQ-11: Handler-Level Auth Resolution Observability
|
|
|
|
- **Origin**: [auth.md](crates/core/auth.md)
|
|
- **Status**: open
|
|
- **Door type**: Two-way
|
|
- **Priority**: medium
|
|
- **Resolution**: When a handler resolves identity inside `handle()`, should the resolved `Identity` be stored somewhere for observability (e.g., connection logging), or is the handler's local variable sufficient? Options: (A) handlers return the resolved identity from `handle()`, (B) handlers call a method on Connection to set identity, (C) handlers log locally and the resolved identity stays local. Two-way door — can be decided during implementation.
|
|
- **Cross-references**: ADR-004, ADR-011
|
|
|
|
### OQ-12: TLS Certificate Provisioning in AlknetEndpoint
|
|
|
|
- **Origin**: [endpoint.md](crates/core/endpoint.md), [config.md](crates/core/config.md)
|
|
- **Status**: resolved
|
|
- **Door type**: Two-way
|
|
- **Priority**: medium
|
|
- **Resolution**: Start with file paths in StaticConfig (option a). The CLI binary provides `tls_cert` and `tls_key` paths at startup. ACME auto-provisioning (option b) and external cert managers (option c) are additive — they can be added as features without changing the core StaticConfig or endpoint lifecycle. `StaticConfig` does NOT include `acme_domain` in v1; ACME will be a separate feature when implemented.
|
|
- **Cross-references**: ADR-010, [config.md](crates/core/config.md)
|
|
|
|
### OQ-13: Operation Path Format and Routing Scope
|
|
|
|
- **Origin**: [operation-registry.md](crates/call/operation-registry.md)
|
|
- **Status**: open
|
|
- **Door type**: Two-way
|
|
- **Priority**: medium
|
|
- **Resolution**: Phase 1 uses `/{service}/{op}` (e.g., `/vault/derive`, `/services/list`). The head/worker `/{node}/{service}/{op}` routing from the reference implementation is a Phase 2+ concern that can be added when remote dispatch is implemented — the node prefix is additive and doesn't break existing operations. Two-way door.
|
|
- **Cross-references**: ADR-005, ADR-012
|
|
|
|
### OQ-14: Batch Operation Semantics
|
|
|
|
- **Origin**: [call-protocol.md](crates/call/call-protocol.md)
|
|
- **Status**: open
|
|
- **Door type**: Two-way
|
|
- **Priority**: low
|
|
- **Resolution**: Phase 1 treats batch as a client-side pattern — multiple `call.requested` events with correlated IDs, responses arrive independently. Batch-specific event types can be added later if needed (e.g., `batch.requested`, `batch.responded`) without breaking the existing protocol. Two-way door.
|
|
- **Cross-references**: ADR-012 |