Files
alknet/docs/architecture/open-questions.md
glm-5.1 f77b515968 docs(architecture): add Phase 0 architecture specs for ALPN-as-service model
Foundational architecture documents following the SDD process:

ADRs:
- 001: ALPN-based protocol dispatch (one endpoint, ALPN negotiation)
- 002: ProtocolHandler trait (replaces StreamInterface/MessageInterface)
- 003: Crate decomposition (one crate per handler, core provides shared infra)
- 004: Auth as shared core (IdentityProvider, hybrid resolution model)
- 005: irpc as call protocol foundation
- 006: ALPN string convention and connection model (alknet/ prefix, one ALPN per connection)

Docs:
- overview.md: crate graph, shared types, ALPN registry, failure modes
- README.md: index with doc table, ADR table, lifecycle definitions
- open-questions.md: 10 OQs across 7 themes (3 resolved, 7 open)

Crate spec stubs for all 11 planned crates (alknet-core through alknet CLI).

Key decisions resolved during self-review:
- AuthContext resolution is hybrid: endpoint resolves TLS-level auth,
  handlers resolve protocol-level auth (resolves OQ-02)
- ALPN is per-connection not per-stream, corrected ADR-001 (resolves OQ-06)
- ALPN naming uses alknet/ prefix without versions (resolves OQ-03)
- HandlerError return type on ProtocolHandler trait
- alknet/secret removed from ALPN registry until OQ-08 resolved
2026-06-15 22:14:58 +00:00

165 lines
7.6 KiB
Markdown

---
status: draft
last_updated: 2026-06-15
---
# Open Questions
Questions are organized by theme. Each question has a stable OQ-ID for cross-referencing from spec documents.
## Theme: Core Types
### OQ-01: BiStream Type Definition
- **Origin**: [overview.md](overview.md), future [crates/alknet-core/spec.md](crates/alknet-core/spec.md)
- **Status**: open
- **Priority**: high
- **Resolution**: (pending)
- **Cross-references**: ADR-002
What exactly does BiStream expose? The pivot proposal defines it as a joined `(SendStream, RecvStream)` implementing `AsyncRead + AsyncWrite`. Should it be:
- A concrete type wrapping quinn's `SendStream` + `RecvStream`?
- A trait `BiStream: AsyncRead + AsyncWrite + Send + Unpin` with a QuinnBiStream implementation?
- A type alias or newtype?
The choice affects WASM compatibility (quinn doesn't compile to WASM) and testing (mock BiStream needs to be constructible without a QUIC connection). If BiStream is a trait, WASM targets can implement it over WebTransport streams.
### OQ-02: AuthContext Resolution Timing
- **Origin**: [overview.md](overview.md), future [crates/alknet-core/spec.md](crates/alknet-core/spec.md)
- **Status**: resolved
- **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-002 and ADR-004.
- **Cross-references**: ADR-002, ADR-004
~~Should AuthContext be fully resolved before `handle()` is called, or should the handler participate in credential extraction?~~
Resolved: The hybrid approach. The endpoint resolves TLS-level credentials (client certificate fingerprints). Handlers that use protocol-level credentials (AuthToken, Bearer headers) extract them inside `handle()` and call `IdentityProvider` to resolve. The `AuthContext` passed to `handle()` may contain only transport-level information.
## Theme: ALPN and Routing
### OQ-03: ALPN String Naming Convention
- **Origin**: [overview.md](overview.md)
- **Status**: resolved
- **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
~~The pivot proposal uses `alknet/ssh`, `alknet/call`, `alknet/git`, etc. Questions:~~
Resolved: See ADR-006 for the full convention. Custom ALPNs use `alknet/` prefix without version numbers. Standard ALPNs (`h2`, `http/1.1`, `h3`) use their IANA strings and route to HttpAdapter. If a protocol needs a breaking change, a new ALPN string is registered.
### OQ-04: Dynamic Handler Registration at Runtime vs Static at Startup
- **Origin**: [overview.md](overview.md)
- **Status**: open
- **Priority**: medium
- **Resolution**: (pending)
- **Cross-references**: ADR-001
Can handlers be registered and deregistered while the endpoint is running, or only at startup?
The previous implementation used `ArcSwap<DynamicConfig>` for hot-reloading routing rules. The same pattern could apply to handler registration. However:
- Adding a handler at runtime requires updating the TLS ALPN advertisement (may require endpoint restart)
- Removing a handler at runtime affects in-flight connections
- The CLI assembles handlers at startup — is dynamic registration even needed?
## Theme: Transport and Endpoint
### OQ-05: Multi-Transport Endpoint
- **Origin**: [overview.md](overview.md)
- **Status**: open
- **Priority**: medium
- **Resolution**: (pending)
- **Cross-references**: ADR-001
The previous implementation supported TCP, TLS, and iroh (QUIC P2P) transports. In the new model, does the endpoint:
- Accept connections on a single QUIC listener (quinn) and the ALPN handles the rest?
- Also support raw TCP listeners (for clients that don't speak QUIC)?
- Support iroh as an additional transport that produces QUIC connections?
iroh's Router pattern accepts a quinn::Endpoint and dispatches by ALPN. The alknet endpoint likely wraps a quinn::Endpoint with TLS configuration that advertises all registered ALPNs. Iroh connectivity could be an additional transport that produces the same BiStream type.
### OQ-06: Server-Side ALPN vs Client-Side ALPN
- **Origin**: ADR-001
- **Status**: resolved
- **Priority**: low
- **Resolution**: One ALPN per connection. Clients open one QUIC connection per ALPN. See ADR-006.
- **Cross-references**: ADR-001, ADR-006
~~The ADR focuses on server-side dispatch (client connects, server selects ALPN). What about the client side? When a client opens a stream to a specific ALPN on an existing connection, does it: - Open a new QUIC connection with the target ALPN? - Open a bidirectional stream on an existing connection with ALPN metadata?~~
Resolved: ALPN is negotiated per-connection, not per-stream. A client that wants multiple ALPNs opens one QUIC connection per ALPN. QUIC connections are cheap (multiplexed over the same UDP flow). See ADR-006.
## Theme: Call Protocol
### OQ-07: Call Protocol Scope Within a Connection
- **Origin**: ADR-005
- **Status**: open
- **Priority**: medium
- **Resolution**: (pending)
- **Cross-references**: ADR-005
If a client opens a connection with ALPN `alknet/call`, can it make multiple operations over that connection? Is each operation a separate QUIC stream, or can operations be multiplexed within a single stream?
irpc supports both request/response and streaming. The mapping to QUIC streams needs definition:
- One stream per request/response pair?
- One stream per streaming subscription?
- Or a single long-lived stream with multiplexed operations?
## Theme: Security
### OQ-08: Secret Service Integration Point
- **Origin**: [overview.md](overview.md)
- **Status**: open
- **Priority**: medium
- **Resolution**: (pending)
- **Cross-references**: ADR-004
alknet-secret is standalone (no alknet-core dependency). How does the rest of the system access it?
- As an irpc service that other services call? (current implementation)
- As an ALPN handler on `alknet/secret` that only internal services use?
- As a library that alknet-core calls directly (breaking the independence)?
- As a library that the CLI embeds, exposing it via the call protocol?
The answer affects whether alknet-secret needs to know about BiStream and ProtocolHandler, or if it remains purely an irpc service that the CLI bootstraps and other services call over local irpc.
## Theme: WASM and Browser
### OQ-09: WASM Target Boundaries
- **Origin**: [overview.md](overview.md)
- **Status**: open
- **Priority**: medium
- **Resolution**: (pending)
- **Cross-references**: OQ-01
Which crates need to compile to WASM?
- alknet-call client (for browser/NAPI usage) — yes
- alknet-sftp protocol core — yes (browser SFTP clients)
- alknet-git pkt-line parser — potentially
- alknet-core (BiStream, AuthContext) — only the types, not the endpoint/router
This affects the BiStream type definition (OQ-01) and dependency choices. If alknet-call's client needs to work in WASM, it can't depend on tokio or quinn directly — it needs abstracted I/O.
## Theme: Git and Distributed
### OQ-10: Git Adapter Scope — Smart Protocol Only or Full Server?
- **Origin**: [overview.md](overview.md)
- **Status**: open
- **Priority**: low
- **Resolution**: (pending)
- **Cross-references**: ADR-001
The pivot proposal mentions Git over QUIC streams (no HTTP layer). Does the GitAdapter implement:
- Just the git smart protocol (ls-refs, fetch, receive-pack) over QUIC streams?
- A full git server with ref management, pack generation, etc.?
- The ERC721 integration for on-chain repository management?
This is deferred per the cleanup plan but worth noting as an open question.