81 Commits
Author SHA1 Message Date
glm-5.3-flash d72820ddc2 release: v0.5.0 — the correlation gate (forwarded-op establishment phase)
- Cargo.toml: 0.4.1 -> 0.5.0 (minor, not patch: the release adds
  public API — ForwardedGate, ForwardedPlan,
  register_tunnel_forwarded_openable_with_establisher — additive only;
  the base registration stays byte-for-byte, the wire delta is empty)
- CHANGELOG: Unreleased cut to 0.5.0 (the establisher-variant entry +
  the release paragraph; the compare links updated)
- README: the forwarded-op serving snippet shows the recommended gate
  shape (register_tunnel_forwarded_openable_with_establisher) beside
  the base one

Review 003 W1 absorbed in-repo; W2/W3 are the alkssh/alksocks repos'
adoption waves. Verification: cargo test (default + --all-features),
fuzz corpus replay (fuzz/shared), clippy --all-targets -D warnings
(native + wasm32), wasm32 check, fmt --check, cargo doc --no-deps,
taskgraph validate (33 tasks), cargo publish --dry-run --allow-dirty
all green
v0.5.0
2026-11-03 17:37:18 +00:00
glm-5.3-flash 74e6289a8e docs(tasks): fix the end-to-end-suite frontmatter, drop the W2/W3 pointer tasks
- tasks/tunnels/end-to-end-suite.md quoted the name value (the
  unquoted colon broke the YAML parse: TaskFrontmatter read as null)
- tasks/tunnels/corrmiss-alkssh-adopt.md and corrmiss-alksocks-adopt.md
  deleted (cross-repo pointer tasks; W2/W3 are booked in the alkssh
  and alksocks repos per plan 003 + review 003 §Status)
- the two Notes references to the deleted task ids re-pointed at plan
  003 §W2/§W3

taskgraph validate: 33 tasks, no issues
2026-11-03 17:37:12 +00:00
glm-5.3-flash ecb24678bb docs(readme): drop the redundant version-history section
The graduation and 0.2.1 through 0.4.1 release notes duplicate
CHANGELOG.md; the README now flows from the WASM target section
straight into Features.
2026-11-03 14:19:38 +00:00
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 cd0afe0497 docs(architecture): eliminate em dashes from the spec docs
Rewrote every prose em dash under docs/architecture/ with natural
grammar (sentence splits, colons, semicolons, parentheses, commas);
wire-format fences, JSON/BAST examples, and byte diagrams untouched.

Verified: grep -rln '—' docs/architecture/ returns only
overview.md's fenced dependency/module-map blocks (12 dashes),
left verbatim per the fenced-code rule; all other files at zero.
2026-11-03 14:02:07 +00:00
glm-5.3-flash 6b20924f68 docs: remove em dashes from Rust doc comments
Rewrote each em-dash construction in doc and inline comments with
varied prose (colons, semicolons, parentheses, split sentences);
no code or identifiers changed. The one string-literal em dash
(UDP oversize error, local/mod.rs) became '; '.
No string-literal em dashes remain except none were found beyond it.

Verification:
- grep -rn '—' src/ --include='*.rs' -> no output
- cargo test: all ok (125 tests)
- cargo clippy --all-targets: 0 warnings
- cargo fmt --check: clean
2026-11-03 13:48:51 +00:00
glm-5.3-flash 92c3cc5123 docs: close out review 003's doc trail — status resolved-for-W1, plan 003 W1 AC ticked, stale-comment sweep
- docs/reviews/003-…alkssh-input.md: Status block now resolved —
  W1 absorbed (plan 003 §Decisions 1–4 + ADR-008 Amendment 2); W2/W3
  pointed at the plan's §W2/§W3, open until those repos land
- docs/plans/003-…: status header planned → W1 landed (W2/W3 open);
  the W1 plan-level AC box ticked; W2/W3 + family-coherence boxes
  left unticked (sibling-repo sessions)
- Stale-comment sweep (src/ + docs/architecture/) aligned three
  stragglers still riding the pre-amendment miss vocabulary:
  - src/producer.rs: the accept-loop arm's "correlation miss →
    handler_error-class" comment → the typed unknown_resource
    open_failed under the establisher variant (Amendment 2)
  - wire.md §The Forwarded Op reply/errors: the miss is the typed
    unknown_resource open_failed (establisher variant); base shape's
    in-session miss = the assembly-side post-open decline,
    correlation-miss at debug
  - producer.md §The Forwarded Op: "no establisher" → the two-shape
    posture (Amendment 2 pointer); last_updated bumped

Verification: cargo test (14 suites, 0 failures), clippy --all-targets
-D warnings clean, cargo fmt --check clean, cargo doc --no-deps clean.
2026-11-03 12:53:27 +00:00
glm-5.3-flash c7e8c875fd review(tunnels/corrmiss-review): the W1 gate surface approved before the consumer waves fork
- API vs ADR-008 Amendment 2 ink: all pins hold (ForwardedGate shape,
  registration signature, error mapping via the existing
  From<TunnelEstablishError> table, typed parse-failure posture,
  timeout: None, unchanged scope table); ForwardedPlan marker matches
  the API task's pinned payload choice
- Two-shape posture consistent across docs/re-exports; one drift
  fixed: make_forwarded_op_handler's doc header retitled from "the
  no-establisher serving shape" to "the serving-shape wrapper both
  registrations share"
- CHANGELOG: Added entry under [Unreleased] for the establisher
  variant (the implementation tasks left it unrecorded)
- Five gate tests re-checked to pin the wire-observable contract at
  the CallError surface (channel:open_failed / unknown_resource /
  FORBIDDEN ordering / residual-race reap / malformed-params delta)
- Verification (re-run at review): cargo test green (14 suites),
  clippy --all-targets -D warnings native clean, wasm clippy + check
  clean, fmt clean, --all-features green, cargo doc --no-deps clean
- Task status -> completed; Notes/Summary record the outcome. The
  surface is ready for the W2 (alkssh) / W3 (alksocks) adoptions.
2026-11-03 12:42:02 +00:00
glm-5.3-flash f42ce47d17 test(producer): the forwarded gate — gate miss/pass, residual race, scope-gate ordering (plan 003 W1)
- New tests/producer_forwarded_gate.rs (the establisher variant's pins;
  the base shape's tests/producer_forwarded.rs untouched):
  - gate miss: typed channel:open_failed with details.reason ==
    unknown_resource, no phantom channel, the pump handler never runs
    (the gate's invocation witness IS set — the miss is at the gate)
  - gate pass: the base serving flow unchanged — parsed params
    witnessed verbatim + full byte round-trip through the
    establisher-registered variant
  - residual race: gate pass + route gone at handler time → the
    handler's error path reaps via teardown-at-birth (the base
    correlation-miss semantics re-pinned under the established shape)
  - scope-gate ordering: tunnel:forwarded-less identity is FORBIDDEN
    and the gate closure is never invoked (ACL precedes the
    establishment phase)
  - the establisher malformed-params delta pinned: schema gates
    unchanged (INVALID_INPUT); an unknown top-level field becomes a
    typed channel:open_failed (reason handler_error) and the parse
    precedes the gate
- No harness changes (wire_with + Topology.consumer_registry as-is)
- Verification: cargo test green (14 suites, 0 failures); clippy
  --all-targets -D warnings native + wasm-target clippy clean (wasm
  --all-targets cannot compile on this baseline — pre-existing,
  mio/socket2 dev-deps do not target wasm; see the task Notes);
  cargo fmt --check clean; cargo check --target
  wasm32-unknown-unknown clean; --all-features test run green

Tasks: tunnels/corrmiss-gate-tests (status → completed)
2026-11-03 12:37:19 +00:00
glm-5.3-flash 5b2f7255f7 feat(producer): the forwarded-op establisher variant — ForwardedGate + register_tunnel_forwarded_openable_with_establisher
Implements plan 003 W1's API item (ADR-008 Amendment 2, task
tunnels/corrmiss-forwarded-gate): the assembly-injected correlation
gate wrapped into the alkcall OpenEstablisher dance for the forwarded
op's serving half.

- ForwardedGate: sync gate closure over the parsed
  TunnelForwardedParams; a gate Err → typed channel:open_failed
  before the channel is born (no phantom channel)
- register_tunnel_forwarded_openable_with_establisher: reuses
  make_forwarded_op_handler unchanged (additive-only; the base
  registration stays byte-for-byte compatible as the
  compatibility + residual-race-fallback posture)
- ForwardedPlan: empty marker plan payload (typed-opaque posture,
  payload choice pinned); no reply-field contribution
- Establisher parse failure maps TunnelEstablishError::HandlerError
  → channel:open_failed (deliberately pinned improvement over the
  base shape's silent birth-teardown for malformed ingress); gate
  errors pass through the existing From<TunnelEstablishError> table
  (no new variants; stale token = unknown_resource); timeout: None;
  wrapper order (schema → ACL → allocate → establisher → handler)
  pinned in the establisher doc
- Two-shape posture doc updates: make_forwarded_op_handler's
  correlation-miss block, register_tunnel_forwarded_openable's doc;
  wire.md §The Forwarded Op + tunnel_forwarded_spec() doc synced
  per Amendment 2's "syncs with the API task's in-code doc updates"

Verification: cargo test (85 green, existing suite untouched);
clippy --all-targets -D warnings (native + wasm32); cargo fmt --check;
cargo doc --no-deps (0 warnings); --all-features test run green
2026-11-03 12:28:00 +00:00
glm-5.3-flash 7d2b6d11f0 docs(adr): ADR-008 Amendment 2 — the forwarded op's serving-side establishment phase + the correlation-miss vocabulary
- The serving side of the forwarded op gains an establisher variant:
  an assembly-provided gate closure (over TunnelForwardedParams) the
  crate wraps into the alkcall OpenEstablisher dance via
  register_openable_with_establisher; a stale/missing listen token
  fails the open as a typed channel:open_failed with
  details.reason = unknown_resource — never a phantom channel
  (ADR-049's posture extended to the forwarded op's serving side)
- unknown_resource reused as-is; the wire vocabulary is unextended
  and wire.md is untouched (the empty wire delta stated explicitly)
- Gate order pinned: the tunnel:forwarded ACL precedes the
  establisher (alkcall's open-op wrapper order)
- The residual post-open race keeps teardown-at-birth; canonical
  event name correlation-miss at debug (assembly-side convention);
  the producer-side generic arm stays warn with the typed reason
- Additive-only surface: the base register_tunnel_forwarded_openable
  stays; the establisher variant is the recommended default posture
- Tri-vocabulary history recorded (alkssh correlation-miss/debug,
  alksocks prose/warn, alktunnels handler_error-class generic
  arm/warn + the fabric-side silence) with sources
- The amended §3 sentence is marked inline, not silently replaced

Resolves review 003 via docs/plans/003-correlation-miss-resolve.md
§Decisions 1-4 (W1's ADR bullet). Doc-only; review 003's status block
and wire.md belong to other tasks and are untouched.

Verification: md renders coherently (read back); alkcall 0.10.1
EstablishmentError/reason() mapping and wrapper order verified in the
registry source before pinning
2026-11-03 08:13:50 +00:00
glm-5.3-flash aa3db39e3e docs(tasks): decompose plan 003 — the correlation-miss gate (W1 in-repo, W2/W3 pointer tasks)
- tunnels/corrmiss-adr: the ADR ink (establishment phase for the
  forwarded op's serving side; unknown_resource reused; correlation-miss
  adopted + level posture; the tri-vocabulary history recorded)
- tunnels/corrmiss-forwarded-gate: the additive API — ForwardedGate +
  register_tunnel_forwarded_openable_with_establisher (candidate shape
  verified against alkcall 0.10.0's establisher surface); the two-shape
  doc posture
- tunnels/corrmiss-gate-tests: the four pins (typed gate miss / gate-pass
  flow / residual race reaping / scope-gate-before-establisher order)
- tunnels/corrmiss-review: the checkpoint before the consumer waves
  adopt the surface (the {W2, W3} fork's critical point)
- tunnels/corrmiss-doc-sync: review 003 status + plan checkboxes close-out
- tunnels/corrmiss-alkssh-adopt / corrmiss-alksocks-adopt: cross-repo
  pointer tasks (executed in alkssh / alksocks), gated on the review

Ordering W1 → {W2, W3} per the plan; no cycles; W1's doc-sync closes
after the review checkpoint.
2026-11-03 08:04:36 +00:00
glm-5.3-flash bd8a82b4c4 docs(plan): resolve review 003 — the correlation-miss arrival class
Plan for the review-003 resolution: route the forwarded-op correlation
miss through an establisher (typed unknown_resource failure, the
ADR-049 posture extended), adopt alkssh's correlation-miss as the
canonical event name for the residual decline, and align the family
(alkssh + alksocks waves). Adds the session's verification findings:
the alksocks prose variant (third vocabulary) and the fully-silent
in-session miss on the fabric side.

Verified: cargo fmt --check, cargo test (13 suites ok), clippy
--all-targets -D warnings (native + wasm32). Docs-only change.
2026-11-03 07:56:08 +00:00
glm-5.3-flash ec52a9620d docs(review): alkssh consumer input — the correlation-miss arrival class, event-vocabulary alignment at the forwarded-arrival boundary 2026-10-31 12:56:00 +00:00
glm-5.3-flash 9cca6ed3c4 release: v0.4.1 — the dependency-patch (alkcall 0.10.1)
- Cargo.toml: alkcall 0.10.0 -> 0.10.1 (crates.io, the
  adoption-window ordering fix — review 013, routed from alkgit's
  wave-2 gate; install + park-drain are one atomic section so a
  demux-routed chunk can no longer overtake earlier-parked early
  arrivals, plus the parked-forever loss variant closed) and
  0.4.0 -> 0.4.1 (no alktunnels API change, no wire change, backwards-
  compatible dep bump -> patch)
- CHANGELOG: Unreleased cut to 0.4.1 (the alkcall 0.10.1 ride + the
  compare links updated)
- README: the 0.4.1 note (alkcall 0.10.1 adoption-window ordering fix)
- docs/architecture/overview.md: dep tree alkcall 0.10.1

Verification: cargo test (136 pass, default + all-features),
clippy --all-targets -D warnings (default, all-features,
wasm32-unknown-unknown), fmt --check, doc, wasm32 check, and cargo
publish --dry-run --allow-dirty all green
v0.4.1
2026-10-22 06:24:41 +00:00
glm-5.3-flash 200d7d3835 release: v0.4.0 — the dependency-major (alkcall 0.10.0)
- Cargo.toml: alkcall 0.9.0 -> 0.10.0 (crates.io, the gateway
  ownership-seam release) and 0.3.0 -> 0.4.0 (breaking dep bump +
  public alkcall re-exports -> minor, matching the 0.3.0 ride on
  alkcall 0.9.0)
- Zero source changes: the 0.10.0 breaking surface (the loud
  ownership-wiring default on the GatewayDispatch spine, behind the
  opt-in gateway feature) is off this crate's paths — tunnel opens
  serve via ChannelCore::register_openable* registry dispatch, which
  0.10.0 leaves untouched
- fuzz/shared/Cargo.toml: alkcall 0.10.0 (path-linked alktunnels must
  see one alkcall version)
- CHANGELOG: 0.4.0 section + compare links
- README + docs/architecture/overview.md + AGENTS.md: the 0.10.0
  notes / dep tree / alkcall refs

Verification: cargo test (136 default / 163 with local, all green),
fuzz/shared corpus replay (5/5), clippy --all-targets -D warnings
(native + wasm32-unknown-unknown), fmt --check, wasm32 check, and
cargo publish --dry-run --allow-dirty all green
v0.4.0
2026-10-19 03:43:15 +00:00
glm-5.3-flash 3c6fc29271 docs: AGENTS.md alkcall refs — v0.7.x/0.7.0 pin -> v0.9.x/0.9.0
Stale current-state claims from two versions back: the §11 pin
("alkcall = \"0.7.0\"") and the "alkcall is v0.7.x" statement, plus the
Architecture Context bullet (v0.7.x). The 0.6.0/0.7.0-surface prose
(establishment, CF-005/CF-006 identity seam) keeps its historical
version qualifiers — those describe where upstream landed, not current
state. Dated records in docs/research|reviews, tasks/, and the
CHANGELOG are untouched by design.
2026-10-14 05:25:02 +00:00
glm-5.3-flash 1365272146 release: v0.3.0 — the dependency-major (alkcall 0.9.0)
- Cargo.toml: alkcall 0.8.1 -> 0.9.0 (crates.io, the stub-sweep
  release) and 0.2.1 -> 0.3.0 (breaking dep bump + public alkcall
  re-exports -> minor, matching the 0.7.1 -> 0.8.0 ride on 0.2.0)
- fuzz/shared/Cargo.toml: alkcall 0.9.0 (path-linked alktunnels must
  see one alkcall version)
- src/producer.rs + tests/producer_direct_op.rs: the only code contact
  with the 0.9.0 breaking surface — Establishment no longer derives
  Debug; two expect_err calls -> .err().expect, one untyped
  panic!("{other:?}") fall-through -> typed Err/Ok arms
- CHANGELOG: 0.3.0 section + compare links
- README: the 0.3.0 note
- docs/architecture/overview.md: dep tree alkcall 0.9.0

Verification: cargo test (136 default / 163 with local), fuzz/shared
corpus replay (0 pass, empty target set — no regressions), clippy
--all-targets -D warnings (native + wasm32-unknown-unknown), fmt
--check, wasm32 check, and cargo publish --dry-run --allow-dirty all
green
v0.3.0
2026-10-14 05:23:08 +00:00
glm-5.3-flash 05b25465aa release: v0.2.1 — the hardening (fuzzing adopted + alkcall 0.8.1)
- CHANGELOG: Unreleased cut to 0.2.1 (the fuzz/ workspace: three
  cargo-fuzz targets + stable-toolchain corpus replay in fuzz/shared;
  the two wave-2 diagnostics datagram_backlog/retained_bytes; the
  alkcall 0.8.0 -> 0.8.1 bump — duplicate adopt no longer destroys the
  live channel; compare links updated)
- README: the 0.2.1 hardening note (fuzzing + alkcall 0.8.1 + the two
  additive diagnostics)
- docs/architecture/overview.md: dep tree alkcall 0.8.1
- Cargo.toml: 0.2.0 -> 0.2.1

Verification: cargo test (136 default / 163 with local), fuzz/shared
corpus replay (5 pass), clippy --all-targets -D warnings (default,
all-features, wasm32-unknown-unknown, fuzz/shared), fmt --check, doc,
wasm32 check, and cargo publish --dry-run --allow-dirty all green
(42 packaged files — fuzz/, docs/research|reviews|plans/, tasks/,
.opencode/, AGENTS.md all excluded)
v0.2.1
2026-09-28 10:21:48 +00:00
glm-5.3-flash e3c6f6c9f8 fuzz: wave 2 — session_pumps stateful two-pump target
The wave-2 stateful target from docs/research/fuzzing.md 3.3: op
sequences (arbitrary SessionSequence) over one live channels stack
per exec - MuxRunner -> raw chunk stream -> the real
run_demux_loop_for_client demux -> ChannelManager per side (producer
Connect / consumer Accept over one duplex transport, the reverse
POC's topology). The harness mirrors TunnelSession's data-plane
shapes: datagram planes (codec reader + pending, the
DatagramHalves mirror) and stream planes (pump_bidi against
in-process peer halves, the pump_against mirror).

Invariants (3.3): no-panic/no-wedge (5s reconcile join); two-pump
shutdown-on-completion; lossless p2c copy count; EOF-sentinel
teardown semantics (drain-before-EOF, map empties); FIFO datagram
reconciliation through the real demux path (stateful framing walk,
the wave-1 walk carried across ops); the 1.3 DatagramHalves.pending
backlog bound (<= routed-but-unpulled remainder); decoder-state
retained-bytes bound re-asserted per op.

Harness-model findings (all six wave findings are harness defects,
not crate bugs - the fuzzer-as-harness-checker pattern):
- duplicate adopt is a legal ChannelExists no-op (documented table)
- the p2c-EOF pump join is the DESIGNED half-close shape; the pump
  completes once the c2p source EOFs too (teardown), not before
- route_payload routes into the LOCAL manager (demux direction);
  the producer pump writes the channel send half - the first
  campaign's bytes never reached the consumer; rewritten to the
  real protocol shape (Open allocates, session-index addressing,
  stateful framing model, Pull op, EOF sentinels only from
  teardown/sender-drop)
- clear_all's return is the opener-ledger records, NOT the reaped
  ids (adopted channels carry no ledger entry - the alkcall 7.7
  lesson re-learned); the map-empties assert is the ground truth

Campaign (10-min detached, 6 runner): 228,676 execs, 32 fork jobs,
oom/timeout/crash 0/0/0, exit 0. Coverage 3427 edges / 17.5k
features still expanding at budget end. No crate bugs found - the
two-pump contract, EOF-sentinel semantics, and the pending backlog
bound are demonstrated properties.

Crate addition: TunnelSession::datagram_backlog() (the
DatagramHalves.pending diagnostic the 3.3 bound asserts against, in
the retained_bytes() style) + a suite test pinning its rest states.

Verification: main suite 136 passed; corpus replay (8 committed
seeds + 2 semantic fixtures) green; clippy -D warnings + fmt clean
(main, shared, wasm); wasm check clean; cargo fuzz build clean.
2026-09-28 10:12:09 +00:00
glm-5.3-flash 57285d23bd fuzz: adopt fuzzing (wave 1) + alkcall 0.8.1 bump
Bump the substrate dependency to alkcall 0.8.1 — the bug-fix release
whose fix (duplicate adopt/open no longer destroying the live channel)
is directly relevant to this crate's reverse-path adopt flow.

Adopt fuzzing per docs/research/fuzzing.md, scoped smaller than
alkcall's (the envelope/chunk/demux/manager surfaces are upstream and
now fuzzed there; this crate fuzzes its own named downstream target —
the ADR-003 datagram codec — plus the params/reply parsers):

- fuzz/ workspace per the alkcall pattern: nightly-pinned subtree
  (rust-toolchain.toml), thin fuzz_target! binaries, and a
  stable-toolchain shared crate carrying the invariant logic so the
  committed corpus replays as plain `cargo test` (the fuzz gate in
  the release checklist — no hosted CI, alkcall §7.9 posture).
- Targets (both over already-pub APIs; no #[cfg(fuzzing)] exposure):
  - datagram_codec — DatagramReader::feed + frame_datagram: no-panic,
    infallible decode, size bound, F-2 sentinel layering (empty
    datagram only from a length-0 header at a frame boundary),
    3-byte-slice splitting transparency, re-frame round-trip,
    oversize rejection at the bound, is_mid_datagram framing state,
    and the decoder-state retained-bytes bound.
  - params_parse — serde params/reply parsers + establishment_reason:
    no-panic on raw bytes and bounded structured Values, clean typed
    failure, round-trips, listen: 0 pin, loud/lenient projection-pair
    agreement, pass-through reason extraction model.
- New public diagnostic: DatagramReader::retained_bytes() (decoder-
  state byte count; the fuzz bound asserts against it).
- 96 committed seeds (gen_fuzz_seeds.py) + the campaign-found crash
  input promoted as datagram_codec/seed-900; grown corpora gitignored.
- run-detached.sh: setsid+nohup runner so campaigns never share fate
  with the agent session process tree (fuzzing.md §5).

Campaign findings this session were harness-model defects, not crate
bugs (both invisible to example-based review; the alkcall
"fuzzer as harness-checker" pattern confirmed):

- the F-2 empty-datagram invariant first counted [00 00] pairs in the
  raw stream — a pair inside a payload region is payload, not a
  header; corrected to walk the framing (crash artifact saved).
- establishment_reason is a pass-through extractor of details.reason,
  not a validated table (harness first asserted a closed set).
- is_mid_datagram means a partial datagram, not buffered header bytes
  (a 1-byte header fragment is buffered, not in flight).

Verification: cargo test 135 passed; clippy -D warnings and fmt clean
(main + fuzz/shared); corpus replay green; cargo fuzz build clean;
wasm32-unknown-unknown check clean. Wave-1 campaigns (10-min detached,
fork mode): params_parse 3.14M execs / datagram_codec 827k execs,
0 crashes/OOMs/timeouts; coverage saturated on the codec state space.
2026-09-28 08:09:11 +00:00
glm-5.3-flash d789031863 release: v0.2.0 — the graduation (direct op + bind-first/forwarded metadata flow)
- README sync: the direct op (ADR-007), the bind-first establisher +
  the forwarded op (ADR-008), TunnelListener + the reply-field
  projection, the 0.2 summary section, the local bind-first helpers
- CHANGELOG: Unreleased cut to 0.2.0 (the graduation + the alkcall
  0.8.0 bump; compare links updated)
- Cargo.toml: 0.1.0 -> 0.2.0

Verification: cargo test (135 pass default / 162 with local), clippy
(all targets, -D warnings, both feature sets), fmt, doc, the
wasm32-unknown-unknown check + clippy, and cargo publish --dry-run
--allow-dirty all green
v0.2.0
2026-09-20 09:30:21 +00:00
glm-5.3-flash 20834d297e docs: review 002 recorder — N-3/N-4 durable trail + N-2 ADR-008 widening + the no-action dispositions
- N-3: parse-before-accept telemetry note on make_forwarded_op_handler
  (the accepted-flag reads false for a malformed-params open by design)
- N-4: ADR-007 Consequences lines — the untagged-leniency-is-
  schema-gated paragraph + the overlapping-variants caution
- N-2: ADR-008 §1 widened to name the any-byte idle-read posture
  (the Ok(0)-only reading hangs on a write-happy peer)
- N-5: mint_token's doc comment records the 256-channel cap analysis
- The N-1/N-6/N-7 + G-1/G-3 no-action dispositions recorded in the
  task file (the tracker the task asked for)

Verified: fmt, clippy (native + wasm32), test, cargo doc — all green
2026-09-20 08:32:45 +00:00
glm-5.3-flash 7b06dc7aac docs: review 002 doc-sync — D-1 schema bounds in wire.md + D-2 ADR-007 oneOf erratum
- D-1: wire.md's Direct Op + Forwarded Op sections record the shipped
  schema constraints (port bounds, additionalProperties: false per
  branch, listen minimum: 1) and the registry-side gate ordering
- D-2: ADR-007 §2 corrected in place + a dated erratum (oneOf was
  wrong-shaped; validation is registry-side, not establisher-time);
  wire.md's mirrored sentence corrected

Verified: cargo doc --no-deps clean; cargo fmt --check
2026-09-20 08:31:47 +00:00
glm-5.3-flash f7dff25f9d docs: review 002 trivial batch — D-3 honest serde test name + D-4 CHANGELOG preamble trim
- D-3: inline the serde-layer check into the renamed
  serde_rejects_unknown_substrate_value; delete the overpromising
  jsonschema_valid helper (the registry's real schema gate stays
  pinned end-to-end by the integration probes)
- D-4: trim the stale Unreleased preamble to a one-liner (written
  before the six graduation implementation commits landed)

Verified: cargo fmt --check; cargo clippy --all-targets -D warnings;
cargo test (86 + 2 doc-tests) green
2026-09-20 08:30:48 +00:00
glm-5.3-flash 98afb092ce test: G-4 unix accept loop + G-5 unnamed fail-loud guards
- G-4: drive UnixListenerHalves::accept_loop — bind_unix + temp path,
  the loop exits on the queue-closed handler error after one unix
  client accept (the unix parity twin of the TCP accept-loop test;
  closes the largest single uncovered block, local/mod.rs 591-609).
- G-5: pin ADR-008 §3's two fail-loud sentences — bind_unix("") is
  the kernel autobind (no filesystem path) so local_addr fails loud
  (578-583), and a socket2 autobind client against a NAMED listener
  is refused by accept_pair's unnamed-peer guard (626-633; Linux —
  abstract addresses/autobind are Linux-shaped, mio maps any
  abstract-namespace peer to unnamed).

Verification: cargo test --features local green (162 tests);
clippy --all-targets -D warnings clean (native + wasm32-unknown-
unknown); cargo fmt --check clean.
2026-09-20 07:39:52 +00:00
glm-5.3-flash 7991bf6ad0 test: G-2 graceful-close far teardown + N-2 write-happy-peer posture
- G-2: observe TunnelListener::close's explicit shutdown sentinel at
  the far accept dispatcher — the accept loop cancels, the pushed
  accept is never consumed, the serving-side listen channel reaps
  (ADR-008 §1's teardown contract, graceful half).
- N-2 residue: pin the write-happy-peer teardown posture — a
  non-empty read on the idle listen stream tears the listener down
  (the fail-closed Ok(_) arm; driven via the raw client surface
  since the typed listener holds its write half idle by contract).

Verification: cargo test --features local green (163 tests + 2
doc-tests); clippy --all-targets -D warnings clean (native +
wasm32-unknown-unknown); cargo fmt --check clean.
2026-09-20 07:18:23 +00:00
glm-5.3-flash 57a728dc4b fix: bind-first dispatcher reads substrate from the plan (review 002 M-1)
- BindFirstPlan gains substrate: Substrate, stamped at establisher
  time from the one successful TunnelParams parse (one parse, one
  source of truth; the plan-payload change is pre-consumer)
- make_bindfirst_accept_handler drops the second params re-parse and
  the silent unwrap_or(Substrate::Tcp) fallback entirely — the
  dispatcher reads plan.substrate; no fallback branch remains, so a
  future drift cannot silently stamp Tcp into a UDP listen tunnel's
  forwarded opens (the raw-vs-framed data-plane mismatch class)
- tests: forwarded_opens_carry_plan_stamped_substrate pins the plan
  as the substrate's source over a real UDP bind-first wire flow
  (a substrate-recording forwarded stub observes substrate: udp);
  the unit downcast + establisher-flow tests pin the stamp
- docs: producer.md (the plan carries {listener, token, substrate};
  the forwarded open's substrate also comes from the plan),
  ADR-008 §1 (the stamp + the removed fallback)
- task review-002-m1-substrate-fallback: completed (Notes filled)

Verification: cargo test (145 pass), cargo test --all-features (153),
clippy --all-targets -D warnings (default + all-features), fmt
--check, doc --no-deps, wasm32 check + clippy -D warnings.
2026-09-20 07:00:18 +00:00
glm-5.3-flash 3df5c484c6 tasks: decompose review 002 findings into six remediation tasks
- M-1: the accept dispatcher's silent substrate fallback (plan-stamp
  shape recommended; failure-path test required)
- D-3 + D-4: trivial batch (rename the overpromising schema test
  helper; trim the stale CHANGELOG Unreleased preamble)
- D-1 + D-2: wire.md schema bounds + ADR-007 oneOf->if/then +
  establisher-time -> registry-gate sentence (doc-only, pre-consumer)
- G-2 (+ N-2's write-happy-peer test): observe close()'s EOF sentinel
  at the far accept dispatcher
- G-4 + G-5: unix accept-loop coverage + the unnamed unix fail-loud
  guards (G-1/G-3/G-6/G-7 explicitly left uncovered per the review)
- N-1..N-7 recorder: the two durable-trail notes (N-3 telemetry
  ordering sentence, N-4 ADR lines) + the no-action dispositions

All six independent (no depends_on) so sessions can parallelize;
validated with taskgraph (28 tasks, no cycles).
2026-09-20 06:46:06 +00:00
glm-5.3-flash 46d3a87b24 review 002: the graduation implementation — spec conformance + coverage appendix 2026-09-20 06:26:27 +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 514e0c1f25 feat: the local bind-first halves (shape 3 substrate half, ADR-008 §1)
- `bind_tcp_first` + `TcpListenerHalves::accept_pair`: the real-socket
  BindFn source (port 0 resolved via local_addr — the `bound` reply
  field's data) and the per-accept (peer, halves) pair (the peer rides
  accept()'s return — the forwarded op's `peer` carrier)
- unix bind-first parity shipped (OQ-TN-14): `bind_unix` +
  `UnixListenerHalves` (local_addr / queue-feeding accept_loop /
  bind-first accept_pair; an unnamed peer fails loud — the forwarded
  `peer` param requires an address) + `bind_unix_first`
- assembly conveniences: `local_bind_first()` (tcp/unix dispatch; udp
  fails loud — no accept on a UDP socket, the shape is not defined
  there, never a fake listener) + `local_bindfirst_accept_loop()`
  (downcasts the opaque listener; a foreign type fails loud)
- direct-op DialFn reuse verified + pinned: `local_dial` shared
  unchanged (the UDP framed wrap composes inside the closure);
  `direct_udp_through_local_dial_round_trips_framed` drives a REAL
  udp echo through the direct op's establisher path
- tests/local_bindfirst.rs: tcp e2e over real sockets (bound fidelity
  — the test dials the reported address; two clients → two forwarded
  channels pumping independently, real distinct peers), unix parity
  (real path in `bound`, named-peer client via socket2, real peer path
  on the forwarded open), udp refusal, downcast-miss probe
- accept-first shapes (accept_loop + AcceptQueue) untouched

Verified: cargo test (default) + --all-features green (45 lib; 151
integration), clippy -D warnings clean (native all-features + wasm32),
fmt clean, wasm32 check passes (default crate stays wasm-clean),
cargo doc clean (no new warnings).

Tasks: tunnels/local-bind-halves (status completed; Notes + Summary
filled). CHANGELOG: Unreleased → Added.
2026-09-19 16:30:46 +00:00
glm-5.3-flash 3fb26d9de6 feat: the forwarded op's serving side + the lenient reply projection (ADR-008 as amended)
- `ForwardedHandler` — the injected assembly handler (parsed params +
  channel `BiStream`); the assembly owns the pump, correlating by the
  `listen` token against its waiting-listener bookkeeping
- `make_forwarded_op_handler` — the built-in no-establisher wrapper:
  deny-unknown params parse (a malformed open fails loud → early
  return → teardown-at-birth reaps the channel, no phantom),
  `accept_bi` FIRST (R-02 accepted-flag telemetry), the injected
  handler's `JoinHandle` awaited inline (R-02)
- `register_tunnel_forwarded_openable` — `register_openable` shape
  (no establisher; the data plane starts immediately), scope gate
  `tunnel:forwarded` (ingress, never implied by `tunnel:open`/
  `tunnel:direct`)
- `listen_reply_fields` — the lenient, infallible reply projection
  (unknown extra reply fields tolerated; a malformed shape logs loud
  and surfaces both-`None`), shared with `TunnelListener`, delegating
  to `parse_listen_reply`
- Tests: 4 unit (reply projection) + 4 integration
  (serving-half e2e round-trip, FORBIDDEN gate, malformed-params
  teardown at both gates, correlation-miss teardown)

Verified: cargo test green (126 default; 146 --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 14:48:08 +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 d586a5d2b8 feat: the forwarded op's params + the bind-first plan type (ADR-008 as amended)
- params.rs: OP_TUNNEL_FORWARDED / TUNNEL_FORWARDED_SCOPE; TunnelForwardedParams
  {listen, substrate, peer} (deny-unknown; listen positive via schema minimum 1 +
  a serde pin); tunnel_forwarded_spec() (Sub, External, alk/tunnel ALPN, scope
  tunnel:forwarded, per-substrate if/then peer sub-schema, no establisher);
  TunnelListenReply + parse_listen_reply (the additive bound/listen reply
  projection — unknown reply fields tolerated, malformed ones fail loud)
- error.rs: TunnelError::MalformedReply (the viewer's fail-loud path)
- producer.rs: BindFirstPlan {listener: Arc<dyn Any + Send + Sync>, token: u32}
  — the opaque assembly-typed listener + the correlation token; the mint
  discipline pinned in docs (non-zero-seeded AtomicU32, per-open fresh,
  per-producer unique, wraps acceptable)
- Wire-stable types pin first (the tunnels/params ordering); the establisher +
  accept dispatcher + registration land with tunnels/bindfirst-producer

Verified: cargo test (105 default; 125 --all-features), clippy --all-targets
-D warnings (native + wasm32), fmt --check, wasm32-unknown-unknown check,
cargo doc --no-deps — all clean.
2026-09-19 07:44: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 52b6252531 fix: taskgraph frontmatter variants — scope medium -> moderate, status done -> completed
tunnels/tunnel-listener + tunnels/forwarded-receipt used `scope: medium`
(not a valid variant — single/narrow/moderate/broad/system), which made
taskgraph silently drop both from the graph (validate failed; topo/
list missed them). tunnels/coverage-weak-spots used `status: done`
(pre-existing; valid variants are pending/in-progress/completed/failed/
blocked).

Verified: taskgraph validate (22 tasks), topo, cycles (none),
parallel, critical all resolve with the full graph.
2026-09-18 14:46:25 +00:00
glm-5.3-flash f315b0e0ca docs+tasks: ADR-008 Amendment 1 (correlation token); decompose the graduation into tasks/tunnels
Verification pass against the landed alkcall 0.8.0 surface surfaced one
design gap: ADR-008 §3 pinned the forwarded op's correlation key as the
listen channel's ID, but (1) the serving-side OpenHandler/establisher
surface never exposes the allocated channel ID, and (2) the in-tree
generic ChannelRelay forwards open-op params untouched (it rewrites
only the reply's channel_id), so a spoke's forwarded open would carry
an id the end opener never allocated. Amended (wire still unconsumed —
alksocks is docs-only — so pre-consumer and legal):

- ADR-008 Amendment 1: the bind-first establisher mints a fresh u32
  correlation token per open — carried in the plan (for the accept
  dispatcher) and contributed as the additive `listen` reply field
  (the same projection carrier `bound` rides); the forwarded op's
  params rename `channel` -> `listen` with token semantics. Tokens
  ride reply fields + params through hubs untouched (relay-transparent
  by construction, alkcall ADR-051). Consumer-minted tokens and a new
  upstream handler surface were considered and rejected (rationale in
  the amendment).
- Spec docs synced: wire.md (the `bound`+`listen` reply section, the
  forwarded params), producer.md (bind-first shape + forwarded op),
  consumer.md (TunnelListener gains `listen()`; correlation registry
  posture), overview.md, OQ ledger (OQ-TN-16 updated),
  tunnels-graduation.md.

Task decomposition (tasks/tunnels/, Phase 2 of the graduation — the
alkcall prerequisites are gone):
- direct-op — params/spec/establisher/open_direct (ADR-007)
- bindfirst-params — forwarded-op spec, TunnelListenReply, the
  BindFirstPlan + token mint (wire types first, the params.md
  ordering precedent)
- bindfirst-producer — bind-first establisher, accept dispatcher,
  register_tunnel_bindfirst_openable
- forwarded-receipt — the opener-side serving op + reply-field reader
- tunnel-listener — the listen-flow consumer session (ADR-008 §4)
- local-bind-halves — the `local` TCP bind + accept-pairs loop,
  unix parity decision, direct-op DialFn reuse pin

Dependency order: direct-op and bindfirst-params are independent
roots; bindfirst-producer -> {bindfirst-params}; forwarded-receipt ->
bindfirst-params; tunnel-listener -> {bindfirst-params,
forwarded-receipt}; local-bind-halves -> bindfirst-producer.

Verification: cargo test 71 passed; clippy --all-targets -D warnings;
fmt --check; wasm32-unknown-unknown check + clippy clean (docs + task
files only — no code change).
2026-09-18 14:26:21 +00:00
glm-5.3-flash c31dd5e100 chore: bump alkcall 0.7.1 -> 0.8.0; mark the review-008 asks landed
alkcall 0.8.0 lands both graduation upstream asks (review 008):
- U-2: the establisher → reply projection (ADR-049 amendment 3,
  Establishment::with_reply_field + open_channel_with_reply) — the
  bind-first 'bound' carrier
- U-1: flavor-form open-op ids in discovery (ADR-047 amendment 3) —
  the direct/forwarded ops reconstruct their marker through discovery
plus the bonus: in-tree ChannelRelay + HubLegTemplate (ADR-051) — the
hub re-produce machinery is upstream now; 'bound' flows end-to-end
per-hop truthful, realizing ADR-008 §6's sentence.

OQ-TN-12 resolves upstream (the composition helper a hub proxy needed
is alkcall's ChannelRelay); spec docs note the asks landed. No
alktunnels API or wire change in this bump — the graduation
implementation (tasks/tunnels) follows.

Verification: cargo test 71 passed (91 all-features), clippy
--all-targets -D warnings, fmt --check, wasm32-unknown-unknown check
+ clippy clean
2026-09-18 13:33:06 +00:00
glm-5.3-flash 0d6b23b7cf docs: spec the graduation — ADR-007 (direct op), ADR-008 (listen metadata + forwarded op)
The alksocks graduation research (tunnels-graduation.md) is decided;
the ADRs are normative now:

- ADR-007: the direct open op — channels/tunnel/direct on the one
  alk/tunnel ALPN, params {substrate, target} (self-describing JSON
  target; ATYP bytes rejected as not schema-describable), scope
  tunnel:direct (never implied by tunnel:open), dial-only.
- ADR-008: listen metadata — bind-first listen establisher (reply
  gains additive 'bound' = BND.ADDR fidelity; the BIND deadlock +
  10s-bound findings dissolve) + the forwarded op
  channels/tunnel/forwarded (accept-as-open, params carry
  {channel, substrate, peer} = reply#2 fidelity). Accept-first stays.
- ADR-001/002/006 amendments: params layout is per-op; flavor-form
  op ids on the one ALPN; per-flavor scopes + the hub re-produce
  policy sentence (the hub's ACL governs the final dial).
- wire/producer/consumer/overview/README updated for the new ops,
  the three establisher shapes, TunnelListener, open_direct.
- OQ-TN-15/16 promoted + resolved; upstream alkcall asks filed at
  alkcall/docs/reviews/008-tunnels-graduation-upstream-review.md
  (flavor-form discovery derivation; the establisher → reply
  projection).

Verification: cargo test (22 passed), clippy -D warnings, fmt --check
(docs-only change; wasm check unaffected)
2026-09-16 08:31:56 +00:00
glm-5.3-flash c86021e6a9 docs: research — graduating proxy surface into alktunnels (direct op + BIND metadata carriers)
Downstream alksocks motivation: CONNECT/BIND/ASSOCIATE need three
additions, all generally useful:

- One wire addition: a direct/dynamic open op on the alk/tunnel ALPN
  (channels/tunnel/direct, scope tunnel:direct) — the ssh
  direct-tcpip capability, additive to ADR-001's resource-not-address
  params. Options weighed; second-op lean (ACL separation at the op,
  per the socks5:bind scope-gate precedent).
- The two BIND metadata asks (bound-addr discovery, peer metadata)
  with carrier options, including the forwarded-tcpip alternative
  (reverse open with peer/target in params) that retires both with
  existing reverse-path machinery.
- Callback→provider mapping: the composed providers the graduation
  gives each alksocks seam (DialFn/EgressFactory/BindAcceptFactory)
  next to the local-socket ones.

Also records the vpn-like endgame positioning (virtual-subnet
translation via dial callback, signing as directory/identity-layer)
and alknodes as the OQ-TN-12 re-produce consumer.

Verification: docs-only change (cargo test/clippy/fmt unaffected).
2026-09-15 14:17:39 +00:00
glm-5.3-flash d3a8006b1f docs: drop the Status section from the README (internal dev detail) v0.1.0 2026-09-10 14:39:33 +00:00
glm-5.3-flash 9ad7429440 docs: prepublish v0.1.0 — README rewrite, changelog, packaging, doc statuses
- README rewritten in alktty's shape: quick start (producer dial +
  listen, consumer open/reverse/pump), the role table, the
  resource-not-an-address model, the data-plane summary, features +
  wasm sections — examples mirror tests/harness.rs wiring
- CHANGELOG.md added (0.1.0 entry, Keep a Changelog house style)
- tasks/ added to the package exclude (was shipping 16 internal SDD
  task notes; package 50 -> 35 files)
- docs/architecture spec docs: status draft -> implemented (Phase 2
  complete, review 001 remediated)

Verified: 71 tests default / 91 --features local, clippy -D warnings
(all-targets + wasm32), fmt, cargo doc warning-free,
wasm32-unknown-unknown check, publish dry-run (35 files, 406.2KiB)
2026-09-10 14:27:32 +00:00
glm-5.3-flash 40677e416b chore: lockfile alkcall 0.7.0 -> 0.7.1
The 0.7.1 lockfile resolution behind the MSRV floor raise. The
alkcall requirement in Cargo.toml stays "0.7.1" only after the floor
commit paired it there; the lockfile is the piece that actually moves
the resolved 0.7.x to the version whose MSRV (1.88) this crate now
declares. alkcall 0.7.1 changed no type alktunnels touches
(version-requirement- and patch-level only; full suite green on both
toolchains in the previous commit).
2026-09-10 03:52:07 +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 4014ba66a9 fix: remove the zombie DatagramCodecError::InvalidLength variant
The coverage review found `InvalidLength {declared, have}` is a
zombie: `DatagramReader::feed` never returns `Err` — it buffers
partial frames indefinitely, and the truncated-stream contract is
carried by `is_mid_datagram` (the codec diagnostic) plus
`TunnelIoError::TruncatedDatagram` (the session surface). The
variant's doc claimed it was the truncated-stream error; no spec
(ADR-003, wire.md, bast.md) names it, and no external consumer
exists (verified 2026-09-08 per ADR-005's N-3 amendment), so the
API window is open — removed before the first consumer pins it.

Also removes the `unreachable!` arm its removal strands in the
`local` adapter's recv mapping (a no-panic path; single-variant
destructure now), and records the planned-shape correction in the
completed wire-codec task doc.

Verified: cargo test (--all-features and default), clippy
--all-targets -D warnings, fmt --check, wasm32 check + clippy — all
clean.
2026-09-09 06:48:44 +00:00
glm-5.3-flash 0bf4da3bb6 docs: N-3 decision — take_halves stays raw-framed on datagram sessions
Review 001 N-3 (tasks/tunnels/decide-take-framed-halves), decided
before the first external consumer:

- Option 1 (keep as-is, docs carry it), recorded as ADR-005
  §Amendment. No external consumer exists (window open — the breaking
  reshape was available but undemonstrated); one take_halves semantic
  across substrates beats per-substrate divergence; pump_against
  composes the framed adapter (UdpHalf), not framed halves; and the
  take_framed_halves convenience is additive — it can land after the
  first consumer defines its shape.
- consumer.md's datagram section states the posture; review 001 §N-3
  resolution note landed; task marked completed.

Docs-only (no code change). Verified: fmt --check, doc --no-deps
warning-free, 63 default / 76 local tests green.
2026-09-08 21:24:28 +00:00
glm-5.3-flash 8cf4cc8bb5 fix: UdpHalf is the FRAMED adapter (U-1) — U-2 bind posture, U-3 lazy scratch
Review 001 remediation (tasks/tunnels/fix-udp-framed-adapter):

- U-1 [major]: UdpHalf now composes the ADR-003 codec at the
  substrate boundary — poll_write de-frames channel bytes (incremental
  DatagramReader) and sends each payload as one raw datagram;
  poll_read frames raw target datagrams and hands frame bytes to the
  pump. Targets see payload-only bytes; empty datagrams round-trip
  (the F-2 fix end-to-end); >8 KiB datagrams arrive as ONE datagram.
  Mechanics the verification gates forced beyond the sketch:
  poll_write accepts all offered bytes (tokio copy re-offers a full
  window unsatisfied — partial-frame holds deadlock >8 KiB frames),
  backpressure is an accepted-byte high-water mark, socket drain
  pumps on write/flush/shutdown; >caller-buffer frames stage across
  reads (the truncation probe's assertion surface updated per the
  re-validation correction).
- U-2 [minor]: connect_udp resolves the target and binds the
  unspecified address of the matching family (v6 targets dial from
  [::]:0); bind_tcp gains the wildcard-exposure doc warning.
- U-3 [minor]: the 65535 recv scratch allocates lazily on first recv
  (full-size read kept — try_recv truncates silently; the MTU-shrink
  idea confirmed unsafe in re-validation).
- N-1: the module/connect_udp/UdpHalf docs now describe the composed
  codec truthfully.

Gates (permanent tests in tests/local_halves.rs): recording-target
suite (payload-only at the target, empty-datagram round-trip, 9000-
byte single datagram, unframed-target resolution), the 65507-byte
max-datagram staging probe, and the v6 dial gate.

Docs: ADR-003 §Amendment (the boundary mechanics), wire.md truncation
bullet, consumer.md adopt sketch (substrate param). Review 001
resolution notes on U-1/U-2/U-3/N-1; task marked completed.

Verified: 63 default / 76 local tests ×3 repeat runs; clippy
-D warnings (all-targets + wasm32), fmt --check, doc --no-deps
(warning-free), wasm check, publish dry-run.
2026-09-08 21:22:52 +00:00