Commit Graph
12 Commits
Author SHA1 Message Date
glm-5.3-flash 0ceecf582b docs: remove em dashes from repo prose and forbid them going forward
- Rewrote the remaining em dashes outside docs/reviews/ (preserved as
  historical record, matching the alktty precedent): tests/ (313),
  fuzz/ (34 plus one shell comment), tasks/ (671 plus 12 kept in
  fences), docs/research + sdd_process + plans (525 plus 25 in
  fences), docs/architecture/overview.md fence labels (13), README,
  CHANGELOG, AGENTS.md, fuzz/README.md (176), and the
  .opencode/agents prompts (110)
- Rewrote fenced content too: ASCII tree and module-map label
  separators, Rust snippet comments, and template placeholders; wire
  data, JSON/BAST examples, and transcripts survive verbatim
- Rewrote 6 assert/expect message literals in tests/ and 2 format
  strings in fuzz/shared/src; no test data changed
- Added Project Convention 18: no em dashes in prose (doc comments,
  markdown including docs/ and tasks/, agent prompts, commit
  messages); fence content rule, en-dash clause rule, and the
  no-spaced-hyphen prohibition follow alktty's convention 15

Follows 6b20924 (src doc comments) and cd0afe0 (docs/architecture).

Verification: cargo test (141 pass); cargo clippy --all-targets -D
warnings; cargo fmt --check; cargo doc --no-deps; wasm check and
clippy for wasm32-unknown-unknown with -D warnings; em dash grep over
the repo returns matches only in docs/reviews/
2026-11-03 14:12:46 +00:00
glm-5.3-flash 474844e563 feat: TunnelListener — the listen-flow consumer session (ADR-008 §4)
- src/consumer.rs: `TunnelListener` — the listen-flow sibling of
  `TunnelSession`: `open` rides `open_channel_with_reply` (the U-2
  surface, alkcall 0.8.0) and projects the bind-first `bound`/`listen`
  reply fields via the lenient `listen_reply_fields`; `bound()` /
  `listen()` present them (the Option posture — None for dial/
  accept-first producers and old producers). Teardown ownership
  (ADR-005's posture, listen-flavored): `close` (graceful — `shutdown`
  on the held write half, the explicit EOF sentinel, then the sync
  reap) and `Drop` (the held write half drops → the mux pump's
  implicit-EOF chunk — the far accept dispatcher's teardown signal —
  then the sync reap; never leaks). The held stream is the write half
  (`MpscSendStream`) only, IDLE and private — a listen channel has no
  data-plane role. No `Clone` (compile_fail doc-test).
  `forwarded()` decided: NOT provided — the receipt queue is
  assembly-side bookkeeping; the type hands the assembly the token.
- src/lib.rs: re-exports `TunnelListener`; crate docs mention the
  listen-flow session.
- src/producer.rs: doc-fix drive-by — two pre-existing broken
  intra-doc links (cargo doc is now 0-warning clean).
- tests/harness.rs: `wire_listener_bindfirst` + `ListenerTopology` —
  the opener-dials shape (client + serving on the opener; bind-first
  serving + the call-plane forwarded-open caller on the producer).
- tests/consumer_listener.rs: 5 integration tests — the bind-first
  gate (reply fields + forwarded round-trip through the REAL
  forwarded-openable registration + the teardown cascade), the Option
  posture on a dial producer, close/Drop reaping (the leak-free
  guarantee), the adopt-path pin (`adopt` gains nothing — a forwarded
  channel presents the ordinary session semantics), and the scope
  interaction (`tunnel:open`-only opener opens the listen channel;
  forwarded opens to it fail FORBIDDEN).
- CHANGELOG: Unreleased → Added.

Verification: cargo test 132 passed (157 --all-features; doc tests
2/2 incl. both compile_fail asserts), clippy --all-targets -D warnings
clean (native + wasm32), fmt clean, wasm32-unknown-unknown check
passes (the default crate stays wasm-clean), cargo doc --no-deps clean.
2026-09-19 18:29:18 +00:00
glm-5.3-flash 7d23a89791 feat: the bind-first establisher + accept dispatcher (shape 3, ADR-008 as amended)
- BindFn + BoundListener: the platform-boundary bind seam (the
  protocol never binds, OQ-TN-04); the opaque listener rides the plan
- bindfirst_establisher: registry namespace gate -> token mint
  (non-zero-seeded AtomicU32, per-open fresh, per-producer unique,
  token 0 never minted — the wrap shape unit-pinned) -> bind ->
  `bound` + `listen` reply fields -> the BindFirstPlan plan; the
  typed errors pass through (bind failure dial_failed, exhaustion
  resource_shortage, registry miss unknown_resource)
- BindFirstAcceptLoop: the type-erased accept closure (receives the
  opaque listener; yields (peer, halves) per accept; Err is
  loop-critical)
- ForwardedOpener: the per-accept forwarded-open caller — the call
  plane (call_with_payload on channel 0 + manager.adopt_channel; the
  reverse POC's open_reverse_channel shape)
- make_bindfirst_accept_handler: the accept dispatcher — accept_bi
  first (R-02 telemetry), the idle listen-stream EOF sentinel cancels
  the loop + tears the listener down (select!), per-accept pump_bidi
  tasks tracked by the handler's JoinHandle (awaited on loop exit —
  a forwarded pump never outlives its listener), per-accept failure
  isolation (log + drop; v1 no retry), loop-critical accept errors
  end the loop
- register_tunnel_bindfirst_openable: same spec + tunnel:open scope
  gate (the per-registration establisher posture); the injected
  seams ride BindFirstInjections {bind, accept_loop, open_forwarded}
  (8-arg sketch -> the bundle; clippy too_many_arguments) + the
  optional CF-006 identity witness (witness_establisher wrapper)
- harness: RegistrationMode::BindFirst + wire_bindfirst; the consumer
  hook gained the accept-side identity propagation + a shared serving
  registry (Topology.consumer_registry exposed); the forwarded-op
  serving stub (make_forwarded_stub_handler — correlate by token,
  accept the BiStream, pump_bidi against the correlated halves; the
  opener-side registration lands with tunnels/forwarded-receipt)
- tests: 6 new integration tests (the full flow e2e — the acceptance
  gate incl. the byte round-trip through the whole path, the
  dial-open neither-field projection, EOF teardown, per-accept
  isolation, typed establishment errors, token discipline) + 6 unit
  tests (the mint discipline, the establisher flow at the
  Establishment surface, the witness wrapper)

Verified: cargo test green (118 default; 138 --all-features), clippy
--all-targets -D warnings clean (native + wasm32), fmt clean,
wasm32-unknown-unknown check passes, cargo doc --no-deps clean.
2026-09-19 09:07:28 +00:00
glm-5.3-flash 0789ab62cb feat: the direct op (channels/tunnel/direct, ADR-007) end to end
- params.rs: OP_TUNNEL_DIRECT / TUNNEL_DIRECT_SCOPE constants;
  SubstrateAddr (untagged {host,port} | {path}; also the ADR-008 §3
  peer shape); TunnelDirectParams with render_target();
  tunnel_direct_spec() — Sub-typed, External, alk/tunnel ALPN
  marker, scope ["tunnel:direct"] (never implied by tunnel:open),
  per-substrate if/then target sub-schema (malformed targets fail
  the registry's schema gate as INVALID_INPUT before the
  establisher). 7 unit tests.
- producer.rs: direct_establisher (+ witness variant) — parse,
  render the target to the registry backing-string form, dial via
  the SAME injected DialFn; no registry lookup (unknown_resource
  can never fire); typed errors per ADR-007 §4 minus the registry
  row; CF-006 witness seam. register_tunnel_direct_openable reuses
  the base pump handler (plan-flow unchanged).
- consumer.rs: TunnelSession::open_direct — separate constructor
  (two scopes are two capabilities), plain open_channel (dial
  establishers never bind), identical session/data-planes/teardown.
- tests/producer_direct_op.rs: 15 integration tests — tcp + udp e2e
  round-trips, malformed-target rejection (no phantom session),
  dial-failure pass-through, NOT_FOUND posture, scope separation
  both ways (FORBIDDEN, raw-call + session-level), CF-006 witness
  (raw + session paths), parse backstop, target-rendering pin.
  Harness: Direct registration mode, wire_direct* topologies,
  direct_identity/both_scopes_identity.
- CHANGELOG: Unreleased → Added.

Verified: cargo test green (93 native, 94 --all-features); clippy
-D warnings clean (native + wasm32); fmt clean; wasm32 check passes
(default crate stays wasm-clean); cargo doc clean.

Task: tasks/tunnels/direct-op.md (status: completed)
2026-09-19 04:58:37 +00:00
glm-5.3-flash 5792efba39 chore: raise rust-version floor to 1.88
The 1.85 claim is now false at the dependency level: the lockfile pins
alkcall 0.7.x, and alkcall 0.7.1 raised its MSRV floor to 1.88, so no
1.85 toolchain can resolve this dependency graph regardless of what
Cargo.toml declares. Raising the floor keeps the claim honest and
aligns with the ecosystem floor. Verified: on a 1.85 toolchain with
--ignore-rust-version, the build fails in the graph (icu_locale_core
2.3.0, MSRV 1.86, via alkcall's jsonschema -> idna chain) before any
alktunnels code is reached — the raise is dependency-driven, and
unlike alktty, two clippy lints promoted since 1.85 surfaced here,
both test-only and behavior-identical:

- tests/harness.rs: unreachable_code — the hanging-establisher probe
  ends in a typed Err(EstablishmentError::HandlerError) instead of an
  unreachable!() cast (the sleep never completes; the per-op timeout
  cancels the task, so behavior is unchanged)
- tests/end_to_end.rs: uninlined_format_args — channel_id inlined
  into the format! string

Version-line bump deferred (crate is unpublished); no CHANGELOG here
yet.

Verification:
- 1.88: test 71 default / 91 all-features pass, clippy --all-targets
  --all-features -D warnings, wasm32-unknown-unknown check + clippy
  clean (target component installed)
- stable 1.94: test 71/91 pass, clippy --all-targets --all-features
  -D warnings, fmt, doc --no-deps, wasm32 check + clippy clean
2026-09-10 03:52:04 +00:00
glm-5.3-flash 63dbdb64a5 test: coverage weak spots — the UdpHalf sender-block recipe found (option 1)
- DatagramReader::feed is infallible (the oversize bound is enforced
  at frame time; the same zombie category as 4014ba6's InvalidLength).
  The Vec<Result> shape, the local adapter's dead InvalidData mapping,
  and consumer.rs's `?` drop.
- The sender-block machinery test (root-gated veth fixture, auto-skip
  without root): the peer address unassigned + the neighbor table
  flushed pins the connected sender in a persistent WouldBlock/ENOBUFS
  state; the test drives the WouldBlock stash, the readiness-Pending
  arms, AND the accepted-byte high-water Pend in one behavior, then
  resolves (addr assign + peer bind) and asserts the queued datagrams
  drain and deliver. Jumbo MTU (65535) keeps IP fragmentation out of
  the way; the block-state probe runs on a throwaway socket (an
  oversized probe's partially-built skb chain stays corked on EAGAIN
  and poisons the socket).
- pump_queue_to_socket's stash arm now matches ENOBUFS(105) alongside
  WouldBlock — the blocked-neighbor state reports 105, and both mean
  "the socket cannot take this datagram now".
- connect_udp's resolve-failure arm covered (an RFC 6761 .invalid
  target maps to dial_failed; rootless).
- The no-witness tunnel_establisher wrapper covered (a harness
  DialNoWitness mode + a full open round-trip through the wrapper).

Negative result pinned in the task doc: tokio 1.53 structurally masks
UDP ICMP errors out of the poll drive (poll_recv_ready/try_io mask
ERROR out of the read direction), so the recv-side ECONNREFUSED
mapping arm is unreachable through the pump's drive — it joins the
defensive list.

Coverage: 92.86% -> 93.91% lines (50 -> 41 uncovered, all deliberate).

Verification: cargo test + cargo test --all-features (91 tests),
clippy --all-targets --all-features, fmt, wasm32 check+clippy,
cargo doc — all clean.
2026-09-09 08:52:23 +00:00
glm-5.3-flash 8f14fd1913 test: coverage weak spots — datagram EOF, UDP take_halves framing, reverse pump_against, queue contracts
Closes the behavioral test gaps the 2026-09-09 coverage review found
(88.28% → 92.86% lines; details in tasks/tunnels/coverage-weak-spots.md):

- Datagram EOF paths (consumer.rs:377-382, 255) — previously
  zero-covered documented contracts: a clean stream EOF resolves
  `Ok(None)` (the pump-less session's shutdown signal), a mid-datagram
  EOF fails loud with `TruncatedDatagram` (OQ-TN-13), both over a new
  closable UDP echo dial (`closing_udp_echo_dial`, both shapes).
- UDP `take_halves` (consumer.rs:201-205) — pins the N-3 framing
  contract: taken halves carry raw `[len: u16 BE]` wire bytes, and
  the data-plane accessors fail `ChannelTaken` after the take.
- Reverse UDP `pump_against` (consumer.rs:289) — the framed side
  round-trips end-to-end (payload + the F-2 empty datagram `len=0`
  survives the pump), the N-11 boundary contract.
- `AcceptQueue::push` after close returns `Err(handle)`, closed pop
  resolves `None`, and the accept loop's queue-closed mapping ends
  the loop with the handler error (producer.rs:279-288, local
  accept_loop).
- `establishment_reason` wrapper (params.rs) — unit test over the
  typed surface (open_failed reason / non-establishment /
  AdoptFailed); plus the schema-gate preemption probe in
  producer_open_op (missing substrate is `INVALID_INPUT` before the
  establisher runs).
- `UdpHalf` write machinery (local/mod.rs) — four poll-driven tests:
  queue accept + flush drain to the wire + shutdown best-effort,
  repeated flush cycles, the unconnected-socket error mapping
  (deterministic EDESTADDRREQ), and the shutdown-drain-swallows-
  errors posture. Host probes recorded in the task doc: no UDP
  sender-blocking shape is reachable on this host (loopback/veth
  drop silently; the fresh-socket try_send quirk is timing-tolerated,
  never asserted), so the stash/high-water paths stay uncovered by
  host limitation, not by oversight.

Verified: cargo test (default + --all-features), clippy --all-targets
-D warnings, fmt --check, wasm32 check + clippy, llvm-cov 92.86%.
2026-09-09 06:48:58 +00:00
glm-5.3-flash a0f939c6df review: phase-gate review 001 — spec conformance of the v1 implementation
Findings + review doc: docs/reviews/001-implementation-review.md (the
alkcall house pattern). Closes tunnels/review-core-crates and
tunnels/review-impl.

Findings:
- U-1 [major, NOT fixed] — the local UDP adapter is not the framed
  adapter ADR-003 mandates: codec-framed bytes reach real targets,
  empty datagrams are EOF-shaped at the adapter (tunnel teardown),
  >8 KiB datagrams split, unframed target-initiated datagrams are
  dropped. Executable-pinned by real-socket probes (temporary test,
  deleted after the run). Remediation task: tunnels/fix-udp-framed-adapter.
- C-1 [major, fixed] — AcceptQueue::pop lost wakeup in the
  check→register window (open op hangs to the establishment bound);
  fixed via the tokio notify_waiters contract (Notified created before
  the check each iteration) + multi-thread regression test.
- N-4/N-5/N-7/N-8/N-9/N-10/N-11 [minor, fixed] — serialize TunnelParams
  in open_reverse_channel; stale doc ref; broken doc link; root
  re-exports (TunnelParams/Substrate/tunnel_open_spec/OP_TUNNEL_OPEN);
  README (publish dry-run was failing on the missing readme); harness
  comment; pump_against UDP framing doc note.
- N-2 retracted by executable falsification (codec buffering is
  bounded by construction); N-6 non-finding with rationale.

Verified: 63 tests default / 70 with --features local, 3x repeat-run
clean both configs; clippy -D warnings (all-targets + wasm32); fmt;
doc warning-free; wasm32 check; cargo publish --dry-run passes.
2026-09-08 10:58:11 +00:00
glm-5.3-flash 2efac9b609 feat: end-to-end suite — 18-test consolidation over the shared harness
- tests/end_to_end.rs: 1 MiB backpressure, deadline→timeout (ADR-049 §2),
  CF-006 witness (transport + token), odd-ID asserts + distinctness
  (ADR-047 §5), full CF-005 precedence chain (ServingConfig override,
  distinct-id token probe, fail-closed), R-01 concurrency ×3, listen
  FIFO + typed-error table, datagram batching + 7-byte chunk-split
  codec probe + reverse codec session + TCP/UDP concurrent, teardown
  matrix arms (close-with-pump / join copy counts / Drop-with-pump /
  failed-adopt), no-phantom-channel + R-02 data-plane-tracking asserts
- tests/harness.rs: RegistrationMode::Timeout (hanging establisher,
  per-registration bound), wire_serving_identity (CF-005 (a) shape)
- task doc: status completed, notes + summary

Verified: cargo test (68), cargo test --features local (75), 3×
repeat-run clean both configs, clippy -D warnings (all-targets, local,
wasm32), fmt --check, wasm32 check
2026-09-08 10:03:42 +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