Files
alktunnels/docs/architecture/open-questions.md
T
glm-5.3-flash 3a447273a8 docs: resolve OQ-TN-14 — unix in via local, stdio out (alktty owns process stdio)
Split the last open substrate-placement question:

- Unix: ships with the local feature v1 (dial_unix — same halves
  shape as TCP; the wire enum already carried unix per ADR-001;
  the params task's schema list includes all three values)
- Stdio: OUT of scope — a spawned process's stdin/stdout/stderr IS
  alktty's pipe mode (LocalTtyBackend + tokio::process + Stdio::piped,
  alktty tty-local.md): three multiplexed logical streams + the
  exit-code control chunk (alktty ADR-004) + signal forwarding
  (REQ-TTY-02). A stdio bridge here would be alktty's runner mode
  with the terminal stripped out — a strictly worse duplicate that
  also drops the semantics that matter (a byte tunnel has neither
  exit codes nor signals). Remote command execution composes via
  alktty on the same channels substrate.

Updated: open-questions.md OQ-TN-14 (resolved), overview.md feature
gate + deps + OQ summary, producer.md OQ ref, OQ-TN-10 promotion
(#3 split), phase-0-findings + both POC summaries' resolution notes,
params task (schema enum includes unix), local-socket-halves task
(unix ships, stdio does NOT — with the composition rationale),
oq-tn-14-tracker task repurposed (boundary-maintenance: re-opens only
if a consumer needs stdio-without-process-semantics — which would
need its own ADR, or if the alktty/alktunnels boundary needs
sharpening).

Verified: taskgraph valid (12 tasks, no cycles)
2026-09-07 19:44:03 +00:00

12 KiB

status, last_updated
status last_updated
draft 2026-09-07

alktunnels — Open Questions

Centralized tracker. The Phase 0 OQ ledger (docs/research/ phase-0-findings.md, OQ-TN-01..10) is promoted here with statuses current as of the Phase 1 spec; new Phase 1 questions continue the OQ-TN numbering. Format per docs/sdd_process.md.

Theme 1: Wire format and addressing

OQ-TN-01: Target addressing format (open-op params shape)

  • Origin: phase-0-findings.md (OQ-TN-01)
  • Status: resolved — ADR-001
  • Priority: high
  • Resolution: 2026-09-07 (Phase 1). params = self-contained JSON object: { "resource": <string>, "substrate": <string> }. The resource identifier is the producer's stable name (a registered resource id, not an address); substrate is the extensible discriminator (tcp | udp | unix extensible, additive). The producer owns the backing; no URL-style general addressing. Reframe
    • survey input (ssh-socks5-survey §OQ-TN-01 residue) + both POCs.
  • Cross-references: OQ-TN-02, OQ-TN-03, ADR-001, ADR-002

OQ-TN-02: Datagram substrates (UDP) — boundary preservation

  • Origin: phase-0-findings.md (OQ-TN-02)
  • Status: resolved — ADR-003
  • Priority: high
  • Resolution: split by path (2026-09-06 survey) + F-2 mandate (2026-09-07 reverse POC). Base open-op UDP resources: endpoint-at-open (one channel = one flow). Dynamic/-D UDP: per-datagram addressing inside the tunnel payload, assembly-layer. Boundary preservation: mandatory [len: u16 BE] per-datagram framing — mandatory for correctness, not cosmetics (F-2; the full rationale and the executable pin live in ADR-003). Under the codec, len=0 is a legal empty datagram (forward POC validated); EOF is the channels-level sentinel; the layers never collide.
  • Cross-references: OQ-TN-01, OQ-TN-07, ADR-003

OQ-TN-03: Direction semantics (-L / -R / dynamic)

  • Origin: phase-0-findings.md (OQ-TN-03)
  • Priority: high
  • Status: resolved — hub-owns-the-connection model (2026-09-05) + the reverse-flow POC (2026-09-07, reverse-poc-summary.md). No protocol-level direction: role follows the resource. -L/-R are the same open op with the entry point on different machines; no advertisement op is needed (the listener is the initiator's own local resource; a far-side listener is a producer-side listen establisher over the same open op). -D composes at the assembly layer ("tunnel a socks5 connection"), out of base-crate scope.
  • Cross-references: OQ-TN-04, OQ-TN-08, ADR-004, ADR-005

OQ-TN-04: No forced local binding

  • Origin: phase-0-findings.md (OQ-TN-04)
  • Priority: medium
  • Status: resolved — binding is always assembly-layer and optional, on either side; the protocol never binds. API surface: dial flows with no local bind (both POCs), listen flows where the binding is the producer's establisher (listen variant, ADR-004), unbound/abstract flows (in-process pipes — the pump is generic over boxed halves). The concrete produce/consume surface is spec'd in producer.md / consumer.md (ADR-005).
  • Cross-references: OQ-TN-03, ADR-004, ADR-005

Theme 2: Crate architecture

OQ-TN-05: Backend inversion point — TunnelBackend trait?

  • Origin: phase-0-findings.md (OQ-TN-05)
  • Status: resolved — ADR-004
  • Priority: medium
  • Resolution: 2026-09-07 (Phase 1). No trait for substrate access: "produce boxed halves for a resource" is a function (UDP POC, OQ-TN-05 executable input). The only remaining thread — the hub re-produce composition — resolves the same way: a hub proxy is a consumer + producer composed at the assembly layer (the reverse POC's hub is exactly this shape minus re-export); a composition helper is deferred(scope) until a concrete hub-proxy consumer exists (OQ-TN-12).
  • Cross-references: OQ-TN-12, ADR-004

OQ-TN-06: The two-pump helper — extract now?

  • Origin: phase-0-findings.md (OQ-TN-06)
  • Priority: medium
  • Status: resolved (upstream) — alkcall::channels::pump_bidi landed in alkcall 0.6.0 (ADR-050, review 007 R-03), shape as this OQ sketched it; this crate is cited as convergence input. alktunnels consumes the helper; hand-rolling is out.
  • Cross-references: ADR-005 (consumer pump), ADR-050 (upstream)

Theme 3: Protocol surfaces

OQ-TN-07: ALPN strategy

  • Origin: phase-0-findings.md (OQ-TN-07)
  • Status: resolved — ADR-002
  • Priority: high
  • Resolution: 2026-09-07 (Phase 1). Option A: single alk/tunnel ALPN; the substrate discriminator in params selects the framing. Prior art (SSH one channel mechanism; SOCKS5 one control connection; udpgw self-describing framing) gives no reason for the split; option B's consumer-side API bifurcation buys nothing.
  • Cross-references: OQ-TN-01, OQ-TN-02, ADR-001, ADR-002

OQ-TN-08: Access control and ownership scope

  • Origin: phase-0-findings.md (OQ-TN-08)
  • Status: resolved — ADR-006 (2026-09-07 — the posture promoted to a decision). The resource is owned by the far side (alkcall op-level ACL applies as-is; no tunnel-specific policy layer, no allowlists in v1; the ownership seam is the establisher seeing the per-call opener identity). Discovery = the ACL-filtered ops listing (openable channels are operations, ADR-047); OperationSpec.description round-trips through discovery (review 006 E-02). The live resource-enumeration half (alkcall OQ-40) stays deferred upstream. Identity: 0.7.0's precedence chain (token > ServingConfig.identity > transport), per-call opener identity on the open-op hooks (CF-005/CF-006). The tunnel:open scope constant is stable once published (ADR-006 §2). -D = "tunnel a socks5 connection" (target selection in the socks5 protocol).
  • Cross-references: OQ-TN-03, ADR-006, producer.md (scope gating)

OQ-TN-09: Lifecycle, teardown, and error reporting

  • Origin: phase-0-findings.md (OQ-TN-09)
  • Priority: high
  • Status: resolved (superseded by alkcall ADR-049, 0.5.0; narrowed through 0.6.0/0.7.0) — establishment is the open op's awaited phase; dial failure is a typed channel:open_failed call error (reason ∈ dial_failed / unknown_resource / resource_shortage / handler_error / timeout), never a phantom channel. Residual resolved by the POCs: half-open semantics = the two-pump contract (W4 validated); the consumer session owns teardown (W3, ADR-005); v1 needs no mid-stream control frame (pump-phase failures are EOF-shaped by design, ADR-049 §6).
  • Cross-references: ADR-003 (sentinels), ADR-005, alkcall ADR-049

OQ-TN-10: POC scope (Phase 0 closure)

  • Origin: phase-0-findings.md (OQ-TN-10)
  • Priority: low
  • Status: resolved — UDP POC DONE (2026-09-06, 17 tests), reverse-flow POC DONE (2026-09-07, 14 tests; re-validated over alkcall 0.7.0, 16 tests). #3 split (OQ-TN-14): unix ships with the local feature; stdio is OUT — alktty's pipe mode owns process stdio (exit codes + signals are tty semantics). #4 (helper spike) resolved by alkcall ADR-050. Findings F-1 (plan payloads Send + Sync — documented upstream) and F-2 (UDP codec mandatory) recorded; W1 filed upstream and RESOLVED (CF-005/CF-006).
  • Cross-references: ADR-003, OQ-TN-05, OQ-TN-06

Theme 4: Phase 1 residues (new)

OQ-TN-11: Resource naming — collision domain and lifecycle of a resource id

  • Origin: OQ-TN-01's residue (stable resource name vs target address), carried into Phase 1
  • Status: partially resolved — the collision-domain half is resolved by ADR-001: the domain is the producer's registry (per-producer; two producers on the same connection may expose the same resource name independently — the open op resolves against the SERVING side's registry). The lifecycle half stays open: is a resource registry a producer-side assembly construct (the POCs' HashMap — the leading candidate), or does it need protocol-level register/rename/retire ops?
  • Priority: medium
  • Impacts: producer.md's ResourceRegistry shape and the discovery story (OQ-TN-08); a protocol-level registry op would be a new wire surface (one-way door).
  • Resolution: lifecycle half pending — no prior-art pressure (SSH lists no forwards in-band; discovery is the ops listing); decide when a consumer needs shared/lifecycle-managed resources.
  • Cross-references: ADR-001, OQ-TN-08

OQ-TN-12: Hub re-produce composition helper

  • Origin: OQ-TN-05's remaining thread (2026-09-05 hub model)
  • Status: deferred(scope)
  • Priority: low
  • Blocked on: a concrete hub-proxy consumer (a crate that re-produces a consumed tunnel resource) — the reverse POC's hub is the seed shape (consumer + register_openable on the same connection) but does not exercise re-export; if one materializes, decide whether a composition helper belongs in this crate or is assembly-layer wiring of the existing surface.
  • Cross-references: OQ-TN-05, ADR-004, alkcall ADR-042 (relay)

OQ-TN-13: UDP truncation semantics at the codec boundary

  • Origin: forward POC Issues Surfaced #3
  • Status: resolved — ADR-003 (2026-09-07): fail-loud at the adapter level. A receive buffer smaller than the datagram is an error, never a silent truncation — a truncated datagram would corrupt the length-framed stream's framing invariants (the reverse POC's F-2 rationale: the codec's wire discipline is what keeps empty datagrams unambiguous; silent truncation is the same class of invariant break). The codec's MTU bound (65535) makes truncation unreachable for well-formed peers; failing loud turns a spec violation into a typed error.
  • Priority: medium
  • Impacts: the local feature's UDP adapter and TunnelSession::recv_datagram's error surface; consumer-visible (an error vs silent truncation is a behavioral difference), so the decision rides an Accepted ADR before the first consumer.
  • Cross-references: ADR-003, wire.md

OQ-TN-14: Unix-socket and stdio substrate placement

  • Origin: OQ-TN-10 #3 (the cheap un-POC'd item)
  • Priority: low
  • Status: resolved 2026-09-07 (split by substrate):
    • Unix: in scope for the local feature v1 — same halves shape as TCP (dial_unix), cheap, wire enum already carries unix (ADR-001). Implemented by tunnels/local-socket-halves.
    • Stdio: OUT of scope — alktty owns it. A spawned process's stdin/stdout/stderr IS a terminal session in alktty's model: LocalTtyBackend's pipe mode (tokio::process::Command + Stdio::piped(), alktty tty-local.md) is exactly the stdio case — three multiplexed logical streams + the exit-code control chunk (alktty ADR-004) + signal forwarding (REQ-TTY-02). A "stdio bridge" here would be alktty's runner mode with the terminal stripped out: a strictly worse duplicate that also drops the semantics that matter (exit code, signals — a byte tunnel has neither). Consumers needing to run commands remotely compose: alkcall dial → alktty session (pipe mode) — the two crates are siblings on the same channels substrate, not competitors. (The OQ-TN-10 #3 "cheap item" was scoped before the sibling relationship was this clear.)
  • Impacts: tunnels/local-socket-halves (unix yes, stdio no); the wire enum's unix value now has a v1 implementation path.
  • Cross-references: ADR-003, ADR-004, overview.md; alktty tty-local.md §pipe mode, alktty ADR-004 (exit code on a control chunk)