Commit Graph
8 Commits
Author SHA1 Message Date
glm-5.3-flash 65fb69db61 feat: local-socket-halves — the local feature (TCP/UDP/unix halves functions)
- src/local/mod.rs (feature = "local" -> tokio/net): dial_tcp (5s
  timeout), connect_udp (ephemeral bind + connect + the FRAMED UdpHalf
  adapter), dial_unix (OQ-TN-14 in v1), bind_tcp +
  TcpListenerHalves::accept_loop (the listen shape's assembly half),
  local_dial() (one DialFn covering all three substrates).
- UdpHalf truncation fails loud (OQ-TN-13): poll_read recvs into a
  scratch buffer first and size-checks against the caller's buffer —
  an over-size datagram is io::ErrorKind::InvalidData, never a silent
  truncation (tokio's poll_recv-into-ReadBuf would truncate).
- No socket type appears outside src/local/ (convention 16); the
  default crate stays wasm-clean; stdio bridging is NOT here (alktty
  owns process stdio).
- Tests (tests/local_halves.rs, 7, feature-gated): TCP/UDP/unix dial
  round-trips through the real establisher path, the 1400-byte MTU
  datagram, the truncation fail-loud probe, dial-refusal ->
  dial_failed, listen producer over a real TCP listener end-to-end.

Verified: cargo test green (default + --all-features, 44 + 7),
clippy -D warnings (default + all-features + wasm32), fmt clean,
cargo check --target wasm32-unknown-unknown passes.
2026-09-08 09:44:23 +00:00
glm-5.3-flash 09d32d5aa6 feat: producer-listen — listen establisher (shape 2) + AcceptQueue contract
- AcceptFn: the injected accepted-connection source (the assembly
  layer owns the listener + accept loop; the protocol never binds —
  OQ-TN-04).
- AcceptQueue: the protocol-side queue contract (async push/pop/
  close; FIFO always-before-take ordering; close-while-waiting
  resolves None). Empty-queue posture is assembly-owned (a late
  accept is legitimate; resource_shortage is the closure's mapping;
  the wrapper's 10s establishment timeout is the backstop).
- listen_establisher: same open op, same params, same typed errors —
  registry namespace gate → accept() → Establishment::new(plan);
  the pump handler is untouched (plan-flow with a different source).
- register_tunnel_listen_openable: same spec/pump registration with
  the listen establisher (the honest shape vs a dial/accept enum:
  the establisher is the only difference; one establisher per op id
  per session registry — documented).
- Tests (tests/producer_listen.rs, 6): listen flow end-to-end, FIFO
  ordering across two opens (R-01 plan-flow, listen-flavored), empty
  queue -> resource_shortage, closed listener -> dial_failed,
  unknown resource -> unknown_resource, late-push wait-then-resolve.
- Harness: RegistrationMode enum + wire_listen.
- TargetHandle gains a structural Debug impl (test ergonomics).

Verified: cargo test green (44), clippy -D warnings (native + wasm32),
fmt clean, wasm32 check passes.
2026-09-08 09:37:22 +00:00
glm-5.3-flash fb2389bd62 feat: consumer-session — TunnelSession (open/adopt, data planes, teardown)
- TunnelSession (src/consumer.rs): open (ChannelClient::open_channel)
  + adopt (ChannelManager::adopt_channel) construction, substrate-
  shaped data planes (raw halves for stream; ADR-003 codec + pending
  frame queue for UDP), pump_against (session-owned pump_bidi handle),
  and teardown ownership per ADR-005: close (abort + ungraceful reap),
  join (await + reap + copy counts, pump-less (0,0,reaped)), Drop
  (abort + sync reap, never leaks). No Clone (compile_fail doc-test).
- open_reverse_channel on the CallConnection (the reverse path's
  two-step: call then adopt — the POC's honest shape).
- Error surfaces (src/error.rs): TunnelOpenError (typed ADR-049 §4
  surface via open_ref/establishment_reason), TunnelIoError (wrong-
  substrate, TruncatedDatagram fail-loud, ChannelTaken), ReverseOpenError.
- Tests: tests/consumer_session.rs (12) over two harness topologies —
  forward (wire_forward/ForwardTopology: consumer connect-side pure
  client, producer serving via adapter) and reverse (the POC shape);
  teardown matrix, W4 half-close, out-of-band close + self-reap (W3),
  F-2 empty datagram, AdoptFailed-on-collision (bogus-id adopt parks
  by design — documented), concurrent sessions. Harness: all_substrate_dial.
- Adopt takes substrate (task-note deviation: the data plane shape
  rode the open call; cannot be inferred from the ID).

Verified: cargo test green (38), clippy -D warnings (native + wasm32),
fmt clean, cargo check --target wasm32-unknown-unknown passes.
2026-09-08 09:33:12 +00:00
glm-5.3-flash 2b35da4395 feat: producer-open-op — establisher + pump handler + registration
- tunnel_establisher: registry lookup -> injected DialFn (ADR-004) ->
  Establishment::new(plan) (R-01 plan flow); typed reason table
  (unknown_resource/dial_failed/resource_shortage/handler_error)
- make_tunnel_pump_handler: accept_bi + plan downcast + pump_bidi
  awaited inline (R-02; no spawn-and-forget, no substrate types)
- register_tunnel_openable: spec + establisher + pump + dial + CF-006
  identity witness seam
- TargetHandle +Sync halves (F-1 bound); Substrate + Hash for registry
  keys; tunnel_establisher_with_witness for the per-call identity probe
- tests: duplex harness (reverse-POC topology) + 11 integration tests —
  round-trip, typed errors, FORBIDDEN fail-closed, CF-005 precedence +
  CF-006 witness, plan-flow concurrency (no race), W2 late
  registration, INVALID_INPUT schema rejection, both-sides sanity

Verified: cargo test (14 unit + 11 integration), clippy -D warnings
(native + wasm32), fmt --check, wasm32 check — all clean
2026-09-08 07:23:36 +00:00
glm-5.3-flash 60c625899a feat: wire-codec — UDP datagram framing (frame_datagram/DatagramReader)
- [len: u16 BE] per-datagram framing per ADR-003; len=0 is a legal
  empty datagram (F-2 invariant), never EOF
- DatagramCodecError: Oversize (frame-time, never a wire overflow) +
  InvalidLength (truncated stream — the OQ-TN-13 fail-loud codec-side
  anchor)
- DatagramReader: incremental decoder — datagrams split across chunks,
  batched in one chunk, partial headers; feed -> Vec<Bytes> (zero-copy
  freeze handoff)
- is_mid_datagram teardown diagnostic
- 8 test families pinning the ADR-003/BAST invariants incl. 7-byte
  chunk splits and truncated-stream-never-yields-partial

Verified: cargo test (14 passed), clippy --all-targets -D warnings
(native + wasm32), fmt --check, wasm32 check — all clean
2026-09-08 07:16:18 +00:00
glm-5.3-flash f6fb3a3da2 feat: params — TunnelParams/Substrate wire types + tunnel_open_spec
- TunnelParams {resource, substrate} with deny_unknown_fields (ADR-001
  loud-rejection posture); Substrate enum ships unix in v1 (OQ-TN-14)
- tunnel_open_spec(): channels/tunnel/sub, Sub-typed, alk/tunnel
  channel-open marker, input schema enum [tcp,udp,unix], channel_id
  output schema (minimum 1, required), tunnel:open ACL (ADR-006),
  discovery description
- establishment_reason delegates to alkcall 0.7.0's typed
  ChannelOpenError::establishment_reason; error re-exported through
  params
- 6 unit tests: serde round-trip, unknown/missing-field rejection,
  unknown-substrate rejection, spec conformance to wire.md

Verified: cargo test, clippy --all-targets -D warnings (native +
wasm32), fmt --check, wasm32 check — all clean
2026-09-08 06:48:54 +00:00
glm-5.3-flash 50909ab1ca feat: crate-init — module skeleton (params, wire, producer, consumer, error)
- src/{params,wire,producer,consumer,error}.rs skeletons with module
  docs per overview.md §Module Map; lib.rs crate docs + re-exports
- constants in params.rs (OP_TUNNEL_OPEN, TUNNEL_ALPN,
  TUNNEL_OPEN_SCOPE) + establishment_reason helper (delegates to
  alkcall 0.7.0's ChannelOpenError::establishment_reason)
- MAX_DATAGRAM_LEN (65535) in wire.rs (ADR-003's frame-time bound)
- async-trait dropped: skeleton confirms no trait (ADR-004)

Verified: cargo check, clippy --all-targets -D warnings (native +
wasm32), fmt --check, test, wasm32 check — all clean
2026-09-08 06:48:13 +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