Commit Graph
13 Commits
Author SHA1 Message Date
glm-5.3-flash 6beabe9457 docs: UDP tunnel POC summary — shape validated end-to-end
17 tests pass (7 codec + 10 integration). The producer/consumer
shape, ADR-049 establishment integration, codec decision, and typed
establishment errors all validated over alkcall 0.5.0 channels.

Key findings folded into the ledger:
- OQ-TN-05 resolved for stream substrates: no backend trait —
  pump_halves generic over boxed halves (TCP into_split, UDP
  UdpHalf adapter); remaining thread is only the hub re-produce
  composition question
- OQ-TN-06 convergence test satisfied: producer pump and consumer
  pump are the same shape modulo channel side; extraction decidable
  in Phase 1
- New finding for the alkcall ledger: OpenHandler JoinHandle
  semantics are load-bearing and undocumented — a handler that
  returns before the data plane starts tears the channel down at
  birth (the POC found this by hanging; the pump must be awaited
  inline). Plus: Establishment should carry the channel plan
  (the reserved extension point) to kill the establisher handoff
  side-channel
- UdpHalf truncation semantics flagged for the Phase 1 ADR
  (recommend fail-loud over silent truncation)

POC crate: /workspace/alktunnels-udp-poc (db224cc).
2026-09-07 07:53:39 +00:00
glm-5.3-flash 20672be48c docs: codec direction set — raw pass-through (TCP) + u16 length prefix (UDP)
Structural rationale: alktty's 5-byte header is a sub-demux key for
five logical streams sharing one BiStream; a tunnel has exactly one
data stream per direction, so no type byte. TCP needs no length
prefix (channels already length-prefixes every chunk). UDP needs
boundary re-framing only, and u16 suffices (UDP max payload 65507).

Wire overhead table: tunnel TCP = 8 B/chunk total (channels header
only), tunnel UDP = 10 B/datagram, vs alktty's 13 B. udpgw
calibration: 5 B + per-datagram address.

Trade-offs accepted: no in-band control path for TCP channels ever
(post-ADR-049 this is clean; escape hatch = new ALPN, not a wire
change); sentinel collision does not exist (UDP len=0 = empty
datagram, legal; EOF is the channels-level sentinel on the BiStream
at a different layer); future multi-endpoint UDP gateway framing
lives inside datagram payloads (udpgw precedent).

Residual for the Phase 1 codec ADR: empty-datagram semantics; u16 BE
over varint (leaned, MTU-bounded anyway).
2026-09-07 07:21:25 +00:00
glm-5.3-flash d88e148fdc chore: consume alkcall 0.5.0; OQ-TN-09 resolved by ADR-049
alkcall 0.5.0 landed the review 006 remediation (filed from this
crate's Phase 0 pass):
- E-01/N-1: channel-open establishment phase (ADR-049) —
  register_openable_with_establisher, bounded await, teardown-on-
  failure, typed channel:open_failed reply (reason in details);
  ChannelClient::open_channel returns ChannelOpenError
- E-02: OperationSpec.description disclosed via discovery
- E-03/E-04/N-2: teardown-race log, early-arrival bound docs,
  count accessor

alktunnels updates:
- Cargo.toml: alkcall 0.4.0 -> 0.5.0 (lockfile resolves 0.5.0)
- AGENTS.md convention 11: pin note updated; ADR-049 marked
  load-bearing (tunnel opens use register_openable_with_establisher)
- phase-0-findings OQ-TN-09: RESOLVED by ADR-049 — the in-band
  control-frame hunch is superseded (establishment is the open op's
  reply, not a stream frame); residual for Phase 1 narrowed to
  half-open semantics; v1 needs no mid-stream control frame
- phase-0-findings OQ-TN-08: per-op metadata residue resolved by
  E-02 (description field; OQ-40 enumerate half stays deferred)
- tun2proxy prior-art + alktty-pattern sections: frame-vocabulary
  notes updated to point at the ADR-049 supersession
- upstream posture paragraph updated: review 006 is the working
  proof of the ask-early rule

Verification: cargo test (0 tests, ok), clippy --all-targets
-D warnings, fmt --check, wasm32 check, doc --no-deps — all clean
2026-09-06 20:05:41 +00:00
glm-5.3-flash 1a3eb8418d docs: SSH/SOCKS5 survey + fold findings into OQ ledger
Research specialist survey (docs/research/ssh-socks5-survey.md):
SSH forwarding model (direct-tcpip/forwarded-tcpip payloads, open-
failure reason codes, tcpip-forward registration lifecycle), SOCKS5
(ATYP, CONNECT, UDP ASSOCIATE), error-vocabulary comparison table,
endpoint-at-open vs per-datagram analysis, and an explicit anti-
prior-art list (SSH window updates, packet-size negotiation, dual
channel numbering, SOCKS5 FRAG/auth/BND semantics, udpgw
KEEPALIVE/pooling — all mechanisms channels already owns or the
substrate change obsoletes).

Key corrections to phase-0 findings:
- OQ-TN-02 category error fixed: SSH has NO UDP forwarding at all;
  the earlier '-D UDP associate over SSH' line was wrong (SSH -D
  carries only the SOCKS5 TCP control connection). Real UDP-over-
  stream prior art: tun2proxy udpgw + SOCKS5's own UDP relay.
- OpenSSH -D is protocol-level indistinguishable from -L (one
  direct-tcpip channel per SOCKS CONNECT) — direct confirmation of
  the -D = 'tunnel a socks5 connection' resolution.

OQ ledger updates:
- OQ-TN-01: minimal params shape supported ({resource, substrate});
  direct-streamlocal is the extensibility template; ATYP not needed
  in base params
- OQ-TN-02: RESOLVED as split by path — endpoint-at-open for base UDP
  resources; per-datagram addressing only inside the -D payload;
  channel ID replaces CONN_ID (no second demux); KEEPALIVE drops
- OQ-TN-07: option A (single alk/tunnel ALPN) strengthened
- OQ-TN-09: reason-code vocabulary from SSH's four codes + detail
  string; udpgw ERR bit flagged as the counterexample to avoid
- OQ-TN-10: reverse-flow POC gains the tcpip-forward template
- Checklist: SSH/SOCKS5 survey item checked off
2026-09-06 09:20:08 +00:00
glm-5.3-flash 648feb194d docs: record POC placement conventions in OQ-TN-10
Worktree/branch for repo-dependent POCs; standalone crate in the
global workspace for self-contained POCs (alknet-channels-poc
precedent); findings always land in docs/research/.
2026-09-06 09:15:24 +00:00
glm-5.3-flash 42790797b5 docs: OQ-TN-09 direction set; alktty stream-splitting pattern as prior art
- OQ-TN-08 residue updated with the upstream posture: we own alkcall,
  upstream asks happen early (alktty/alkhttp precedent — both required
  upstream fixes/additions; only 3 downstream dependents now, each
  resolved issue makes future dependents cheaper). Ops-listing
  metadata is expected to be a small upstream alkcall change, not a
  workaround.
- OQ-TN-09: control-frame hunch accepted (self-contained frame,
  alktty ADR-006 shape; dial errors are channel-closing, byte EOFs
  stay per-direction); frame vocabulary follows the alktty pattern;
  concrete set = Phase 1 ADR.
- New prior art section: the alktty stream-splitting pattern
  (split BiStream -> ChunkReader/ChunkWriter -> pump to handle halves)
  proposed as the general tunnel pattern — 'tty without the five
  stream types'. Comparison table (tty vs TCP vs UDP codecs/handles/
  pumps); implications for OQ-TN-09 (ctrl frames via stream types),
  OQ-TN-05 (handle = boxed AsyncRead/AsyncWrite halves; UDP flow
  table is the real design surface), OQ-TN-06 (helper convergence
  test against pump_session may be nearly free). Open: codec choice
  (reuse 5-byte / stripped / raw + UDP framing).
- Checklist updated accordingly.
2026-09-06 09:02:12 +00:00
glm-5.3-flash 0397194fe6 docs: resolve OQ-TN-08 — far-side ownership, ops-listing discovery, -D as socks5 tunnel
Untangles the 'host owns the resource and proxies on top' posture for
tunnels:
- Protocol-crate levels assume the resource is owned by the other side
  of the connection; alkcall's existing op-level ACL applies as-is. No
  new policy layer, target allowlists, or tunnel-specific ownership
  machinery. Proxy/overlay is a downstream (assembly-layer) concern
  (hub workers expose tunnels; hub overlays them per-ACL).
- Discovery resolved: openable channels are operations (alkcall
  ADR-047), so the existing bidirectional ACL-filtered ops listing IS
  tunnel-resource discovery. A consumer learns a socks5/postgres/redis
  tunnel is available from the same listing it already uses for ops.
- -D simplifies to 'just tunnel a socks5 connection': socks5 server
  lives on the producing side; target selection happens in the socks5
  protocol, not tunnel params; the dynamic-target policy residue
  dissolves (socks5 resource ACL governs reachability).

Residue for Phase 1: per-resource metadata in the ops listing
(substrate type, name/description) — an alkcall ADR-047 interaction,
not a new mechanism. OQ-TN-01 discovery residue and the hub-model
residue list cross-linked accordingly.
2026-09-06 08:41:34 +00:00
glm-5.3-flash 069350bd51 docs: reframe OQ-TN-01 as resource identification, not addressing
Four corrections from discussion:
- ALPN prefix: alknet/ -> alk/ swap happened in alkcall v0.1.1; docs
  must not perpetuate the old prefix (consumers would bake it in)
- XY problem: except in the -D/dynamic composition case, params only
  identify a produced resource + substrate discriminator (tcp/udp/
  extensible); the producer owns where the resource comes from (most
  likely a local port); UDP must be structurally supported even
  though TCP dominates expected use
- self-contained JSON open-op object accepted as the params path
  (alktty NegotiateRequest precedent)
- russh has no UDP channel support at all — no direct-udp prior art;
  noted in OQ-TN-02 and the survey list; SOCKS5 relevance scoped to
  the -D composition path

Residue for OQ-TN-01: resource naming shape, discovery mechanism,
exact JSON layout (Phase 1 ADR before first consumer).
2026-09-06 06:43:53 +00:00
glm-5.3-flash 4df3c618d4 docs: resolve OQ-TN-03 via hub-owns-the-connection model
Captures the standing hub stance as prior art: the hub owns the
connection and explicitly proxies to expose resources for others.
Role follows the resource — whoever reaches the target is the producer
(registers openable channels), whoever wants bytes is the consumer.
SSH -L/-R collapse to the same producer/consumer pair with the entry
point on different machines (assembly-layer wiring); the exposed port
is a virtual ACL-scoped resource (register_openable shape), not a
bind; the hub proxy is a producer wrapping a consumer, terminating
and re-producing per hop so ACL applies per hop (distinct from
ADR-042 transparent relay); -D composes as a consumer opening
channels with per-connection dynamic targets.

OQ-TN-03 resolved. OQ-TN-04 mostly resolved (binding always
assembly-layer, optional, either side). OQ-TN-01 reframed: params
name a produced resource — resource naming + discovery added. OQ-TN-08
strengthened: register_openable per-resource registration is the
primary gate; remaining residue is the dynamic-target policy hook.
OQ-TN-05 gains the hub re-produce composition sub-question. OQ-TN-02
cross-linked: endpoint-at-open aligns with resource naming; per-
datagram addressing matches the -D composition path.
2026-09-05 20:24:13 +00:00
glm-5.3-flash 7e387ac05f docs: capture tun2proxy udpgw prior art in phase 0 findings
Documents the previously-undocumented UDP gateway prior art discussed
with the alknet-channels POC agent (/workspace/tun2proxy/src/udpgw.rs):
per-datagram length framing over a stream (LEN|FLAGS|CONN_ID|[SOCKS5
addr]|DATA), SOCKS5 ATYP addressing in-band, CONN_ID flow multiplexing,
keepalive/ERR flag packets, MTU cap, idle expiry. Folds implications
into OQ-TN-01 (addressing fork: per-channel vs per-datagram), OQ-TN-02
(framing mechanics production-proven; remaining fork documented),
OQ-TN-07 (single-ALPN option strengthened), OQ-TN-09 (flag-packet
vocabulary maps to establishment/error frame question), OQ-TN-10 (UDP
POC scope narrowed to channels-layer fit), and the survey checklist.
Also records the transport story: TCP vs QUIC is the alkcall layer's
concern; the tunnel crate is transport-agnostic.
2026-09-05 20:07:15 +00:00
glm-5.3-flash c2d5cbbbd9 docs: phase 0 research findings — open questions OQ-TN-01..10
Captures the ten open design questions from the setup discussion:
addressing format, UDP datagram semantics, -L/-R/-D direction model,
no-forced-binding API surface, backend inversion point, two-pump
helper extraction, ALPN strategy, access control scope, lifecycle/
error reporting, and candidate targeted POCs. Includes the settled
foundation (POC-validated prior art), a prior-art survey list, and
the Phase 0 convergence checklist.
2026-09-05 19:48:14 +00:00
glm-5.3-flash 43a5e4204e scaffold: AGENTS.md, Cargo.toml, licenses, agent conventions adapted for alktunnels
- AGENTS.md adapted from alkcall (via alktty's pattern) for the tunnel
  protocol crate: substrate-agnostic conventions, two-pump contract,
  no-forced-binding requirement, alkcall 0.4.0 dependency, wasm-clean
  default crate, ALPN naming
- .opencode/agents/implementation-specialist.md conventions section
  adapted from alkcall's call-protocol rules to tunnel-crate rules
  (mirroring alktty's adaptation)
- docs/sdd_process.md package reference fixed to alktunnels
- Cargo.toml scaffold: wasm-clean tokio subset, alkcall 0.4.0
- LICENSE-MIT / LICENSE-APACHE copied from alktty
- src/lib.rs protocol-only stub; docs/architecture/ lands in Phase 1

Verification: cargo test (0 tests, ok), cargo clippy --all-targets
-- -D warnings, cargo fmt --check, cargo clippy
--target wasm32-unknown-unknown -- -D warnings — all clean
2026-09-05 19:40:38 +00:00
glm-5.3-flash 44a9ceb455 init 2026-09-05 19:00:17 +00:00