- 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.
- 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
- 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
- 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
- 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)
- 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
- 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
- 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.
- 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.
- 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.