Files
alkcall/docs/architecture/open-questions.md
T
glm-5.3-flash 5f019c02f1 docs: re-key architecture docs off the alknet mono-repo — speak as alkcall
The ported docs still framed alknet siblings (alknet-core/-call/-channels/
-http/-tls/-client) as live load-bearing context of this crate. With the
extraction complete and alknet headed for glue-level replacement, the docs
now speak as alkcall and cite the real sibling crates (alkhttp, alktls,
alktty, alktunnels, alktrader).

- ADR-054 (new): re-own the verifier-selection rule in-crate — three
  remote roles (public X.509 endpoint / transport relay / hub),
  ServerCertVerifier by PeerEntry presence, RemoteIdentity None
  load-bearing. Provenance: alknet ADR-034 (never ported), demoted to
  footnote. Resolves OQ-21's cross-repo authority gap.
- OQ-43 (new, deferred(scope)): composition-layer ownership and shape
  after the alknet replacement — the named receiver for the
  downstream-side deferrals (OQ-33 endpoint layer, OQ-41 QUIC-native
  substrate, OQ-42 hub broker, OQ-19 persistence adapters, ADR-045 dial
  seam). README layering diagram redrawn with the composition layer as
  TBD-ownership instead of "alknet / alknode" in concrete.
- Spec docs reframed: titles, self-references, dial/TLS/from_jsonschema
  homes, malformed legacy cite rows removed; dead relative research
  paths qualified as source-repo paths.
- ADR amendments (append-only): 027 (alknet-http -> alkhttp), 031 (post-
  extraction state), 044 (split landed as modules in alkcall), 045
  (name normalization; citation-space note).
- Citation hygiene: unprefixed/colliding source-repo cites prefixed
  ("alknet ADR-NNN (provenance)") across 009/011/022/034/035/038/040/
  043/044/045; stale OQ cites corrected (session registries OQ-04, batch
  semantics OQ-03, verifier rule ADR-054); stale anchors fixed.
- README provenance note consolidated; citation conventions documented.

Verification: markdown link check (all local links resolve, all in-crate
ADR cites point at existing decisions/ files); table integrity check
(uniform row widths across open-questions.md and edited tables); residual
alknet-mention sweep (only provenance/historical/intentional framing
remains); architecture review subagent pass with zero remaining criticals.
Docs-only change — no code paths touched.
2026-10-13 10:53:47 +00:00

14 KiB

status, last_updated
status last_updated
current 2026-10-13 (composition-layer re-key)

Open Questions

Open questions are tracked here, organized by theme. Each question has a status, priority, and (when resolved) a resolution citing the ADR.

Status values: open, resolved, deferred(scope), deferred(unclear), partially resolved, dissolved.

Call Protocol

OQ Title Status Priority Resolution
OQ-01 Call protocol scope within a connection resolved medium ADR-015 — stream model, multiplexing
OQ-02 Operation path format and routing scope resolved medium /{service}/{op} is the correct design
OQ-03 Batch operation semantics resolved low Correlated call.requested events
OQ-04 Session-scoped operation registries resolved medium ADR-019 — OperationEnv trait layering
OQ-05 Abort cascade semantics for nested calls resolved high ADR-020
OQ-06 Privilege model and authority context resolved high ADR-017
OQ-07 Handler identity registration path and composition authority resolved high ADR-018
OQ-08 Operation error schemas resolved high ADR-016
OQ-09 Safe vault operations for call protocol exposure resolved high ADR-010 — none exposed
OQ-10 Remote-safe marking shape dissolved medium ADR-024 — remote_safe/trusted_peer retired
OQ-11 OperationAdapter error type (AdapterError variants) resolved medium DiscoveryFailed, SchemaParse, Transport, Unauthorized, SamePeerCollision
OQ-12 from_call re-import trigger resolved low ADR-028 — manual free function
OQ-13 from_call namespace collision resolved low Same-peer = error; cross-peer dissolved (ADR-024)
OQ-14 CallClient TLS client-auth resolved high quinn client-auth; key-type-aware verification
OQ-15 PeerRef::Any routing policy resolved low Insertion-order first-match
OQ-16 services/list-peers re-export semantics resolved low Opt-in; services/list is own-ops-only
OQ-17 Multi-hop federation deferred(scope) low One-hop model is the commitment; multi-hop is a feature extension
OQ-18 PeerId — crypto identity vs stable logical id resolved high ADR-025 — PeerId = Identity.id (stable)
OQ-19 Persistent peer registry resolved medium ADR-025 — core trait + in-memory default; persistence adapters separate
OQ-20 API key asymmetry dissolved medium PeerEntry supports multiple credential paths
OQ-21 X.509 outgoing-only case resolved medium Three remote roles; PeerEntry asymmetry correct. Re-owned in-crate by ADR-054 — the verifier-selection rule that binds alkcall's surface (RemoteIdentity: None semantics, ServerCertVerifier by PeerEntry presence) is decided here, not by the un-ported source ADR (which is demoted to provenance).

Call Protocol — Pub/Sub

OQ Title Status Priority Resolution
OQ-22 Call protocol pub/sub primitive — pub to go with sub resolved high The question had two halves, both now decided. (1) The primitive: ADR-046 delivers OperationType::Pub + HandlerKind::Sink + call.published wire event + invoke_sink() dispatch + CallConnection::publish(). (2) Placement of the fan-out/broker: out of scope for alkcall — the call protocol is point-to-point; a topic registry that outlives individual calls is a routing concern that sits above it. The hub composes the broker on top of the Pub/Sub primitives (ADR-047 §"What this ADR decides" Gap B). The broker design itself is tracked as OQ-42. See §"Pub/Sub Gap" below.
OQ-42 Hub message broker (topic registry, Pub↔Sub matching, N-consumer fan-out) deferred(scope) medium Deferred downstream: the broker is a hub composition layering on alkcall's Pub/Sub primitives, not an alkcall deliverable (OQ-22 placement resolution, ADR-047 Gap B). Blocked on: a concrete producing crate committing to fan-out — a spec that requires one produced topic with N independent spoke subscribers (plausible first candidate: alktrader market-data distribution; ADR-046 §fan-out records the consumer-blind rationale). Not circular — the primitives it composes on are delivered and load-bearing (ADR-046), and no alkcall API surface advertises or depends on the broker. The hub itself lives in the composition layer (owner — OQ-43).

Pub/Sub Gap

The call protocol's StreamingHandler / invoke_streaming() path (ADR-021) is point-to-point: a call.requested arrives, the handler produces a stream of call.responded events back to that one caller. There was no mechanism for a producer to stream data to a responder (producer→consumer streaming), and no fan-out (one producer, N consumers).

ADR-046 resolves the directional gap: OperationType::Pub is the producer→consumer streaming complement to Sub (was Subscription, renamed for symmetry). HandlerKind::Sink is the consuming handler type. call.published is the wire event carrying stream chunks. invoke_sink() is the dispatch path. CallConnection::publish() is the client method. The Subscription variant is renamed to Sub (wire string "sub").

Placement decided: the broker is not an alkcall deliverable. The fan-out/broker mechanism (topic registry, Pub↔Sub matching, N-consumer fan-out) sits above the call protocol: the call protocol is point-to-point (one initiator, one responder, a stream between them); a topic registry that outlives individual calls is a different lifecycle and a different concern. The broker is a hub composition on top of the Pub/Sub primitives — ADR-047 §"What this ADR decides" (Gap B) places it out of scope for alkcall. The Pub primitive is the load-bearing piece the broker composes on (delivered, ADR-046); ADR-053 served the broker's originally-named first consumer (channel/resources/subscribe) with enumerators instead.

The broker design is downstream work (OQ-42, deferred(scope)). It unblocks when a concrete producing crate commits to fan-out. The original deferral's rationale (ADR-046 §fan-out — designing the broker without its first real consumer produces a half-design) still holds: the honest state is a tracked, concretely-blocked deferral, not a pending promise. The "channels session" phrasing in ADR-046 §fan-out should be read as this placement decision (the channels work has since landed; what remains unbuilt is the downstream hub broker).

Channels

OQ Title Status Priority Resolution
OQ-23 Full channel-level flow-control windowing deferred(scope) low Bounded-buffer decided (ADR-040); full windowing blocked on HOL-blocking deployment observation
OQ-24 Channels add/strip API shape resolved low Resolved by the shipped surface: the strip is integrated into the read/write path — the demux loop consumes read_header/write_chunk so a handler's BiStream yields payload chunks and never sees the 8-byte header (ADR-035; matches ADR-037's payload-parse contract). The low-level primitives (parse_header/write_header/read_header/write_chunk/write_eof in channels::wire) remain exposed as the standalone utility for tooling/codegen, but no handler-facing add/strip wrapper exists or is needed.
OQ-31 channel/open ACL granularity resolved high ADR-047 — channel/open dissolves into per-ALPN ops; each op has its own access_control
OQ-32 Quota lifecycle (opener vs closer, transport drop) resolved high ADR-047 §7 — the per-connection opener ledger; decrement on every teardown path, keyed by opener
OQ-33 Per-identity connection cap (endpoint layer) deferred(scope) low Named as a separate layer (ADR-047 §"ALPN category reframe" references the findings); belongs at the endpoint/connect-accept layer of the composition stack, not channels. Named to stop the re-tangle. The endpoint layer's home is the composition layer (owner — OQ-43; today it lives in the alknet glue).
OQ-34 channel_open marker wire format resolved medium ADR-047 §2 — boolean "channel_open": true in services/schema; ALPN derivable from op name
OQ-35 OperationEnv::channel_manager() coupling resolved high ADR-047 §4 — extension trait ChannelOperationEnv in channels-call; call crate stays free of channels types
OQ-36 channel_id allocation in Pub case resolved medium ADR-047 §5 — "connection owner allocates" (the side that holds the ChannelManager); amends "responder allocates"
OQ-37 from_call relay wrapper for marked ops resolved medium ADR-022 amendment 2026-10-13 — there is no from_call relay wrapper, and there won't be one: marked (channel_open) announcements are refused with MARKED_SPEC_UNSUPPORTED, and register_imported/register_imported_all refuse marked specs (ADR-047 amendment 4 §4.8) — a marked op's data plane (the allocated channel's BiStream) has no overlay path. The sanctioned compositions are named in the refusal: ChannelRelay::register_relay_openable (ADR-051) for a relaying hub, ChannelClient (ADR-043) for direct consumption. from_call's discovery still reconstructs the marker (ADR-047 Gap F) for reporting, but importing a marked spec is refused at the overlay landing.
OQ-38 ALPN→path-segment mapping resolved low ADR-047 §"Negative" — strip the alk/ prefix; ALPNs without that prefix use the full ALPN string (rare, two-way-door)
OQ-39 channel/control control-handle surface resolved medium ADR-052 — the control-handle surface is implemented: per-channel control callbacks contributed by the ALPN establisher (Establishment::with_control), wrapper-installed and teardown-removed in the manager; the op routes the ALPN-specific message and answers channel:no_control_handle when the channel's ALPN registered none. The stub (channel:control_not_implemented) was removed with the single-publish fix (reviews 010 S-02 / 011).
OQ-40 channel/resources/subscribe live subscription resolved medium ADR-053 — the live subscription is implemented: one ResourceEnumerator per openable ALPN (provided by the producing crate, snapshot-then-changes), aggregated by the handler over the scan-once snapshot; an empty registry emits one { "resources": [] } seed and stays open. The one-shot error stub was removed with the single-publish fix (reviews 010 S-03 / 011). The alktunnels discovery-UI note (review 006 E-02) is served by the enumerator surface.
OQ-41 QUIC-native multi-stream substrate deferred(scope) medium Deferred downstream — the substrate lives in the dial/accept layer, which alkcall does not own. Only the in-line substrate mode is implemented (single bidi stream, header-demuxed N channels); the QUIC-native multi-stream mode (accept remaining bidi streams, read headers off each — ADR-034 §substrate modes) belongs in the composition layer's QUIC accept loop. Blocked on: the composition layer's multi-stream substrate integration (owner — OQ-43; today the alknet glue, being replaced). Impacts: none in-crate — the wire format and demux loop are correct for both substrates; alkcall stays transport-agnostic (no QUIC dependency, WASM-compatible).

Core Types

OQ Title Status Priority Resolution
OQ-25 BiStream type definition resolved high ADR-005 — trait, Connection parameter
OQ-26 AuthContext resolution timing resolved high ADR-003 — hybrid resolution
OQ-27 ALPN string naming convention resolved medium ADR-004 — alk/ prefix
OQ-28 Dynamic handler registration resolved low ADR-019 — curated static, overlays dynamic
OQ-29 Handler-level auth resolution observability resolved medium set_identity() on Connection for observability
OQ-30 Dynamic resource ownership resolved high ADR-011 — OwnershipProvider, resource_id_path

Composition Layer

The layer above alkcall that owns dial/accept, hub composition, and endpoint concerns. As of 2026-10 that layer is the alknet glue (the alknet mono-repo's crates: its client dial helper AlknetClient, its endpoint crate, its hub wiring); the mono-repo itself is being replaced by thin glue over alkcall and its sibling protocol/host crates (alkhttp, alktty, alktunnels, alktrader, alktls, …). Several deferred questions name "downstream" as their receiver — this OQ is the named receiver for all of them, so the deferrals survive the replacement rather than being repo-pinned to a codebase slated for deletion.

OQ Title Status Priority Resolution
OQ-43 Composition-layer ownership and shape after the alknet replacement deferred(scope) medium Deferred scope: who owns dial/accept/hub composition, the endpoint layer (OQ-33), the QUIC-native substrate (OQ-41), and persistence adapters (OQ-19) after the alknet mono-repo is replaced — and whether that composition is one thin glue workspace (an alknode-type crate consuming alkcall + the sibling crates) or several small glue binaries. Blocked on: the glue-workspace decision being committed (the stated direction is "a couple kloc of glue", but the shape — one workspace vs several binaries — and its ownership are not yet committed). Impacts: re-keys the deferrals OQ-33, OQ-41, OQ-42, OQ-19; determines the dial seam's future home (ADR-045's AlknetClient, today in the alknet glue); determines where hub-relay wiring templates are consumed (ADR-042, ADR-051). Not blocking any alkcall v0.9 API surface — alkcall is transport-blind and composition-blind by construction (ADR-031, ADR-035). Cross-references: OQ-33, OQ-41, OQ-42, OQ-19; ADR-045, ADR-031, ADR-042, ADR-051.