Phase 2 completes the interface-to-protocol bridge and adds core types that external crates depend on. The 8 tasks are organized into 5 generations with clear dependencies: - Gen 1: StreamInterface/MessageInterface trait split (must go first) - Gen 2: SshSession bridge, RawFraming impl, CredentialProvider (parallel) - Gen 3: API keys in DynamicConfig (depends on CredentialProvider) - Gen 4: ListenerConfig HTTP/DNS stubs + axum scaffold - Gen 5: Review gate before Phase 3 Key design decisions: - 2.4a/2.4b split: SecretStoreCredentialProvider deferred to Phase 3 - API keys (2.6) must land before axum scaffold (2.7) - ListenerConfig (2.5) must land before axum scaffold (2.7) - Gen 2 tasks are parallelizable (separate modules)
5.6 KiB
id, name, status, depends_on, scope, risk, impact, level
| id | name | status | depends_on | scope | risk | impact | level |
|---|---|---|---|---|---|---|---|
| stream-interface-message-interface-split | Rename Interface → StreamInterface, add MessageInterface trait and restructure config types | pending | moderate | medium | phase | implementation |
Description
Rename the current Interface trait to StreamInterface and add a MessageInterface trait for request/response interfaces (HTTP, DNS). This is the most impactful structural change in Phase 2 because all subsequent tasks reference the new trait names and config types.
Per ADR-035 and research/phase2/interface-model.md:
Interface→StreamInterface(the current trait becomes the stream-specific variant; persistent byte streams)InterfaceSessionstays as-is (it's already stream-specific)- Add
MessageInterfacetrait:handle_request(&self, request: InterfaceRequest) -> Result<InterfaceResponse>(stateless request/response) - Add
InterfaceRequestandInterfaceResponsetypes that normalize calls across message interfaces - Add
HttpInterfacestub (struct definition, no route implementations yet) - Add
DnsInterfacestub (struct definition only) - Restructure
InterfaceConfigintoStreamInterfaceConfigandMessageInterfaceConfig - Update
ListenerConfigto includeStream,Http, andDnsvariants per the research docs - Add
TransportKind::WebTransportas a tag-only variant (no acceptor implementation) - Remove any references to
TransportKind::Dns(it was never added, so no removal needed — just ensure it's not added)
Why this must go first: Every other Phase 2 task imports and references these types. The rename and new traits must land before SshSession bridge, RawFraming implementation, or HTTP scaffold work begins. The integration plan section 2.3 explicitly states: "This task should be done early in Phase 2 because all subsequent tasks reference the new trait names."
Current state of the code:
Interfacetrait incrates/alknet-core/src/interface/mod.rswithaccept()→Self::SessionInterfaceSessiontrait incrates/alknet-core/src/interface/session.rswithrecv()/send()InterfaceConfigenum withSsh(SshInterfaceConfig)andRawFraming(RawFramingConfig)variantsInterfaceKindenum withSshandRawFramingvariantsTransportKindhasTcp,Tls,Iroh(noDns)SshInterfaceimplementsInterface,SshSessionimplementsInterfaceSessionRawFramingInterface/RawFramingSessionare stubs (Phase 1 left them)
Acceptance Criteria
Interfacetrait renamed toStreamInterfacethroughout alknet-core (mod.rs, ssh.rs, raw_framing.rs, and all import sites)MessageInterfacetrait defined incrates/alknet-core/src/interface/mod.rswithhandle_request(&self, request: InterfaceRequest) -> Result<InterfaceResponse>InterfaceRequeststruct defined withoperation_path,input,auth_token,metadatafields per interface-model.mdInterfaceResponsestruct defined withresult,status,headersfields per interface-model.mdHttpInterfacestub struct defined (identity_provider, registry, env fields) — no route implementationsDnsInterfacestub struct defined (domain, identity_provider, registry, env fields) — no implementationInterfaceConfigrestructured:StreamInterfaceConfig::SshandStreamInterfaceConfig::RawFramingreplace current variants;MessageInterfaceConfigenum added withHttpandDnsvariants (or the variant types are defined)ListenerConfigenum updated withStream { transport, interface },Http { bind_addr, tls, stealth }, andDns { bind_addr, tls }variantsTransportKind::WebTransportadded as tag-only variant (no acceptor, no feature flag beyond the enum variant)is_valid_pair()/TransportKindBasevalidation updated for StreamInterface pairs only- All existing tests pass after the rename (SshInterface and RawFramingInterface still compile and pass)
- New
StreamInterfaceimplementors still useInterfaceSessionfortype Session MessageInterfacehas at least one compilation test (e.g., a mock struct implements it)HttpInterfaceandDnsInterfacestubs compile and exist in the type systemlib.rsre-exports all new types (StreamInterface,MessageInterface,InterfaceRequest,InterfaceResponse,HttpInterface,DnsInterface)
References
- docs/architecture/decisions/035-streaminterface-messageinterface-split.md — ADR-035
- docs/research/phase2/interface-model.md — Full design rationale
- docs/research/integration-plan.md — Phase 2.3
- crates/alknet-core/src/interface/mod.rs — Current Interface trait
- crates/alknet-core/src/interface/session.rs — InterfaceSession, InterfaceEvent
- crates/alknet-core/src/interface/config.rs — Current InterfaceConfig
- crates/alknet-core/src/interface/pairs.rs — Valid transport-interface pairs
Notes
This is the most mechanically invasive change in Phase 2 due to the rename, but it's low-risk behaviorally. The
Interface→StreamInterfacerename is a find-and-replace operation. The newMessageInterfacetrait and stubs are purely additive. TheListenerConfigrestructuring is additive since no existing code usesListenerConfig::HttporListenerConfig::Dnsyet.
The integration plan section 2.3 notes: "Existing
SshInterfaceandRawFramingInterfacebecomeStreamInterfaceimplementations. No behavior change for stream-based interfaces."
Consider using
#[non_exhaustive]on the new enums (MessageInterfaceConfig,ListenerConfig) so future variants (WebSocket, etc.) don't break downstream.
Summary
To be filled on completion