--- status: draft last_updated: 2026-08-12 --- # 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 | ## Call Protocol — Pub/Sub | OQ | Title | Status | Priority | Resolution | |----|-------|--------|----------|------------| | OQ-22 | Call protocol pub/sub primitive — pub to go with sub | partially resolved | high | ADR-046 resolves the primitive: `OperationType::Pub` + `HandlerKind::Sink` + `call.published` wire event + `invoke_sink()` dispatch path. The fan-out/broker mechanism (one producer, N consumers, topic matching) is deferred to the channels session — the call protocol is point-to-point; the broker is a routing concern that sits above it. ADR-047 §1 names the broker (Gap B) as out-of-scope for alkcall; the hub composes it on top of the `Pub`/`Sub` primitives. See §"Pub/Sub Gap" below. | ### 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 (client→server streaming), and no fan-out (one producer, N consumers). **ADR-046** resolves the directional gap: `OperationType::Pub` is the client→server 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"`). **Fan-out deferred.** The broker (topic registry, `Pub`↔`Sub` matching, N-consumer fan-out) is deferred to the channels session. 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's first consumer is the channels `channel/resources/subscribe` operation (ADR-037) and the hub-as-broker pattern (ADR-042). The `Pub` primitive is the load-bearing piece the broker composes on. ## 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 | open | low | Whether the 8-byte header add/strip is built into the read/write path or a standalone utility. The contract (ADR-035) is decided; the function surface is not | | 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 `alknet-endpoint`, not channels. Named to stop the re-tangle | | 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 | open | medium | ADR-047 §1 names it as a consumer (hub) concern; alkcall's `from_call` reconstructs the marker (Gap F resolved) so the consumer can branch on it | | OQ-38 | ALPN→path-segment mapping | resolved | low | ADR-047 §"Negative" — strip the `alknet/` prefix; ALPNs without that prefix use the full ALPN string (rare, two-way-door) | ## 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 — alknet/ 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 |