Commit Graph
16 Commits
Author SHA1 Message Date
glm-5.3-flash dc2eab3b21 chore: consume alkcall 0.7.0; W1/CF-005 resolved — identity seam validated
alkcall 0.7.0 resolved every open downstream-consumer finding,
including this crate's reverse-flow POC W1 (filed as ledger CF-005,
with the CF-006 corollary):
- CF-005 (a): ServingConfig.identity — the explicit override
- CF-005 (b): transport Connection::identity() propagates to
  channel 0 — set_identity before dialing is the mTLS/QUIC path
- CF-006: the establisher/pump handler receive the per-call opener
  identity (dispatch-resolved), not the install-time context
- CF-007: ADR-016 code list completed (doc-only)
- F-1 (POC finding): the ChannelPlan type doc now carries the
  Send + Sync payload constraint

alktunnels updates:
- Cargo.toml: alkcall 0.6.0 -> 0.7.0 (lockfile resolves 0.7.0)
- AGENTS.md convention 11: pin note updated; the 0.7.0 identity
  surface marked load-bearing (precedence order + per-call opener)
- AGENTS.md architecture context: CF-005/CF-006 row added; the
  'What the POC does NOT settle' list replaced with the accurate
  settled state (Phase 0 complete; Phase 1 = the spec)
- reverse-poc-summary: W1 marked RESOLVED with the remediation
  validated from the POC's topology (16 tests over 0.7.0: transport
  identity alone authorizes, ServingConfig.identity overrides,
  identity-less fails closed, CF-006 witness); F-1 marked documented
  upstream; what-the-POC-does-not-validate and verification blocks
  updated
- phase-0-findings OQ-TN-10: reverse POC entry notes the 0.7.0
  re-validation and W1 resolution

The reverse POC (/workspace/alktunnels-reverse-poc, 8b35818) re-
validated: the default harness now authorizes on transport identity
alone — the 0.6.0-era auth_token workaround is dead code.

Verification: cargo test, clippy --all-targets -D warnings,
fmt --check, wasm32 check, doc --no-deps — all clean
2026-09-07 17:59:53 +00:00
glm-5.3-flash 603f398f6d docs: reverse-flow POC summary — -R shape validated end-to-end
POC at /workspace/alktunnels-reverse-poc (14 tests, clippy/fmt clean,
repeat-run stable) over alkcall 0.6.0:

- The review 007 non-finding trace confirmed by execution: the hub
  (accept side) opens tunnel channels toward a connect-side worker
  serving its own open op (from_connection_with_serving +
  ChannelOperations::register_on + post-hoc openable registration)
- ADR-047 §5 exercised in the Pub-like orientation: the worker
  (connect side) allocates odd IDs; the hub adopts
- R-01 plan flow under concurrency: two same-resource opens, distinct
  channels, distinct dialed handles — the forward POC's handoff race
  is structurally gone
- OQ-TN-03's last open thread closed: no advertisement op 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
- W4 EOF sentinel propagation validated (half-close semantics);
  W3 adopter self-reaping pinned as a TunnelSession spec requirement;
  W2 post-hoc registration viable

Findings:
- F-1: ChannelPlan's Send+Sync bound constrains plan payloads
  (socket halves carry + Sync; spec should pin the constraint)
- F-2: empty UDP datagrams collide with the EOF sentinel in raw
  pass-through (pinned by an executable test) — the length-framed
  codec is mandatory for UDP; raw pass-through stays
  stream-substrate-only. Second validation of the codec decision;
  OQ-TN-02 mandate strengthened

W1 (connect-side serving path resolves caller identity only via
payload auth_token) filed upstream as alkcall consumer-findings
ledger CF-005 (alkcall 0d287a9).

Verification: cargo test 14/14, clippy --all-targets -D warnings,
fmt --check — all clean, repeat-run stable
2026-09-07 10:06:42 +00:00
glm-5.3-flash b3b00f37bd chore: consume alkcall 0.6.0; OQ-TN-06 resolved by ADR-050
alkcall 0.6.0 landed the review 007 remediation (filed from this
crate's UDP POC pass):
- R-01: Establishment carries the plan (ADR-049 amendment 2) —
  typed-opaque ChannelPlan, OpenHandler gains the plan param, the
  wrapper threads it; the POC's side-channel HandleHandoff and its
  same-resource race are dead (the establisher returns the dialed
  handle: Ok(Establishment::new(plan)))
- R-02: OpenHandler JoinHandle lifetime contract documented (early
  return = teardown-at-birth) + yield-once acceptance flag and
  debug! birth-teardown hint
- R-03: pump_bidi pinned upstream (ADR-050) — two pumps,
  shutdown-on-completion, (u64, u64) copy counts, errors EOF-shaped

alktunnels updates:
- Cargo.toml: alkcall 0.5.0 -> 0.6.0 (lockfile resolves 0.6.0)
- AGENTS.md convention 8: use alkcall channels::pump_bidi, do not
  hand-roll; await it inline inside the OpenHandler's task
- AGENTS.md convention 11: pin note updated; amendment 2 marked
  load-bearing (Establishment::new replaces side-channel handoff)
- AGENTS.md convention 13: fixed ADR citation bug (was "alkcall
  ADR-024, ADR-050" — those are peer-graph-routing and pump-bidi;
  intended targets are alknet ADR-024/ADR-050 with their alkcall
  ports ADR-019/ADR-011)
- AGENTS.md architecture context: ADR-050 + ADR-049 amendment 2 rows
- phase-0-findings OQ-TN-06: RESOLVED — pump_bidi landed upstream;
  the POC is cited as convergence input alongside alktty and the
  assembly-layer copies; Phase 1 consumes the helper
- phase-0-findings OQ-TN-09: implementation note updated —
  Establishment::new(plan) replaces the handoff sketch
- poc-summary: resolutions addendum for both upstream findings
  (R-01/R-02/R-03 with the typed-opaque and (u64, u64) deviations
  recorded); references note 0.6.0 supersession

Verification: cargo test (0 tests, ok), clippy --all-targets
-D warnings, fmt --check, wasm32 check, doc --no-deps — all clean
2026-09-07 09:27:08 +00:00
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