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.
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
---
|
||||
id: tunnels/fix-udp-framed-adapter
|
||||
name: "U-1 remediation — make UdpHalf the FRAMED adapter (ADR-003 at the local boundary)"
|
||||
status: pending
|
||||
depends_on: [tunnels/review-impl]
|
||||
scope: moderate
|
||||
risk: medium
|
||||
impact: component
|
||||
level: implementation
|
||||
tags: [local, udp, codec, adr-003, review-remediation]
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
Review 001 finding U-1 (`docs/reviews/001-implementation-review.md`):
|
||||
the `local` feature's `UdpHalf` (`src/local/mod.rs`) is NOT the framed
|
||||
adapter ADR-003 mandates at the substrate boundary — it is
|
||||
boundary-preserving (one datagram per poll_read/poll_write) but raw.
|
||||
The `[len: u16 BE]` codec exists only on the session side, so
|
||||
UDP-over-`local` tunnels:
|
||||
|
||||
1. deliver codec-framed bytes to real targets (the target sees
|
||||
`[len]payload`, not payload — executable-pinned in the review
|
||||
probes);
|
||||
2. tear the tunnel down on an empty datagram (a raw zero-length
|
||||
datagram is `Ok(())` with 0 bytes filled = EOF-shaped to
|
||||
`tokio::io::copy` — the F-2 violation end-to-end; the session-side
|
||||
codec exists precisely to prevent this);
|
||||
3. split datagrams > ~8 KiB at the target (`tokio::io::copy`'s
|
||||
`DEFAULT_BUF_SIZE` bounds each read; the raw adapter sends each
|
||||
chunk as its own datagram);
|
||||
4. silently drop unframed target-initiated datagrams (the session
|
||||
codec parses a raw datagram's first two bytes as a length header).
|
||||
|
||||
The session-side tests pass because the harness's
|
||||
`framed_udp_echo_dial` frames symmetrically at the test boundary — a
|
||||
correct-shape stand-in for what `connect_udp` itself must do.
|
||||
|
||||
### The fix
|
||||
|
||||
Apply ADR-003's placement: `UdpHalf::poll_write` frames the caller's
|
||||
buffer (`frame_datagram`) and sends one datagram per framed frame;
|
||||
`poll_read` de-frames (feed `DatagramReader`, emit the next payload).
|
||||
Both halves of the association then speak the same framing; `len=0`
|
||||
becomes a 2-byte frame (unambiguous with EOF — the F-2 fix
|
||||
end-to-end).
|
||||
|
||||
### Verification gates (from the review)
|
||||
|
||||
1. A recording UDP echo server asserts the datagrams it receives are
|
||||
**payload bytes only** and an **empty datagram round-trips**
|
||||
(session `recv_datagram` yields `Some(b"")`, channel alive).
|
||||
2. A >8 KiB datagram round-trips as ONE datagram at the target.
|
||||
3. An unframed target-initiated datagram resolves at the session.
|
||||
4. The existing `local_halves` suite stays green unchanged (its
|
||||
session-level round-trips are framing-symmetric today).
|
||||
5. `cargo test` + `--features local` + wasm checks as usual; 3×
|
||||
repeat-run stable.
|
||||
|
||||
### Riders (from the same review, same file)
|
||||
|
||||
- U-2: `connect_udp` binds `("0.0.0.0", 0)` — resolve the target
|
||||
family first (or document the v4-only posture).
|
||||
- U-3: size the recv scratch to the codec's MTU discipline instead of
|
||||
a per-tunnel 65535-byte allocation (or justify the bound).
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] `UdpHalf` frames on write and de-frames on read (ADR-003's
|
||||
placement; the pump stays raw)
|
||||
- [ ] The 5 verification gates pass; suites green 3× in both configs
|
||||
- [ ] U-2/U-3 riders resolved or explicitly deferred with rationale
|
||||
- [ ] Review 001's U-1/U-2/U-3/N-1 sections get resolution notes
|
||||
|
||||
## References
|
||||
|
||||
- `docs/reviews/001-implementation-review.md` §U-1 (executable-pinned
|
||||
probe evidence), §U-2, §U-3, §N-1
|
||||
- `docs/architecture/decisions/003-codec-and-udp-framing.md` (the
|
||||
framed-adapter mandate + F-2), `docs/architecture/wire.md`
|
||||
§Datagram substrate
|
||||
- `src/local/mod.rs` (`UdpHalf`), `src/wire.rs` (the codec to compose)
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: tunnels/review-core-crates
|
||||
name: Mid-phase review — producer + consumer halves before the local feature
|
||||
status: pending
|
||||
status: completed
|
||||
depends_on: [tunnels/consumer-session]
|
||||
scope: moderate
|
||||
risk: low
|
||||
@@ -39,8 +39,8 @@ downstream tasks (Safe Exit); majors create remediation notes for
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] The 5 checklist items each with a verdict
|
||||
- [ ] Criticals (if any) resolved before proceeding; majors logged
|
||||
- [x] The 5 checklist items each with a verdict
|
||||
- [x] Criticals (if any) resolved before proceeding; majors logged
|
||||
|
||||
## References
|
||||
|
||||
@@ -51,6 +51,59 @@ downstream tasks (Safe Exit); majors create remediation notes for
|
||||
|
||||
> Agent fills during implementation.
|
||||
|
||||
### Mid-phase verdicts (2026-09-08, at tree `fb2389b`..`09d32d5` scope)
|
||||
|
||||
Executed with the mid-phase point in view (before
|
||||
`local-socket-halves`/`end-to-end-suite` landed): the five checklist
|
||||
items were run against `producer.rs`/`consumer.rs`/`params.rs`/
|
||||
`wire.rs`/`error.rs` + the then-existing suites, cross-checked against
|
||||
alkcall 0.7.0's wrapper/establisher/pump source. Because both
|
||||
downstream tasks built on the shapes immediately after, the full
|
||||
re-verification (with the complete suite) landed in
|
||||
`tunnels/review-impl` — consolidated findings live in
|
||||
`docs/reviews/001-implementation-review.md` (the review-impl
|
||||
deliverable). Verdicts, summarized:
|
||||
|
||||
1. **Wire conformance — PASS.** Params shape exact
|
||||
(`{resource, substrate}`, `deny_unknown_fields`, enum
|
||||
`["tcp","udp","unix"]` — schema + serde both pinned by tests); op
|
||||
id/ALPN/scope constants asserted against wire.md; codec
|
||||
(`[len: u16 BE]`, `len=0` legal, `Oversize` at frame time, no
|
||||
sentinel) correct.
|
||||
2. **Pump handler shape — PASS.** `pump_bidi` awaited inline inside
|
||||
the spawned handler task; `accept_bi` → plan downcast →
|
||||
`Arc::try_unwrap` → inline await; no spawn-and-forget, no
|
||||
hand-rolled two-pump loop (grep-verified); R-02 pinned by an
|
||||
end-to-end test (`pump_handle_tracks_the_data_plane_r02`).
|
||||
3. **Teardown matrix — PASS.** close (abort + reap), join (await +
|
||||
reap + counts, panic arm logged), Drop (abort + sync reap),
|
||||
pump-less join `(0, 0, reaped)`, failed-adopt no-leak — all pinned
|
||||
with `channel_ids()` leak asserts on both sides. No `Clone`
|
||||
(compile-fail doctest).
|
||||
4. **No substrate types / no hand-rolled pumps / no side-channel
|
||||
handoff — PASS.** The only plan flow is `Establishment::new(plan)`
|
||||
→ wrapper → handler `plan` param (R-01); the only `Mutex<HashMap>`
|
||||
is the `ResourceRegistry` lookup table (a registry, not a plan
|
||||
handoff); `tokio::net` appears only under the `local` gate.
|
||||
5. **Tests green + 3× repeat-run stable — PASS** (both configs).
|
||||
|
||||
### Majors logged (carried to `tunnels/review-impl`, re-verified there)
|
||||
|
||||
- **C-1** (`AcceptQueue::pop` lost wakeup — found in the full sweep,
|
||||
fixed in-review): see review 001 §C-1.
|
||||
- **U-1** (the `local` UDP adapter is not the framed adapter — found
|
||||
by the review-impl probes over real sockets): see review 001 §U-1;
|
||||
remediation task `tunnels/fix-udp-framed-adapter`.
|
||||
|
||||
No criticals: the wire surface (the one-way door) is conformant; no
|
||||
finding blocks the phase.
|
||||
|
||||
## Summary
|
||||
|
||||
> Agent fills this on completion.
|
||||
> Agent fills this on completion.
|
||||
|
||||
Mid-phase review executed as part of the consolidated `tunnels/
|
||||
review-impl` pass (2026-09-08): all five checklist items PASS; two
|
||||
majors logged (C-1, U-1) and carried to the phase-gate review, where
|
||||
C-1 was fixed and U-1 got the remediation task. Full findings +
|
||||
severity grading: `docs/reviews/001-implementation-review.md`.
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: tunnels/review-impl
|
||||
name: Review alktunnels v1 implementation for spec conformance (pre-release gate)
|
||||
status: pending
|
||||
status: completed
|
||||
depends_on: [tunnels/end-to-end-suite, tunnels/review-core-crates]
|
||||
scope: moderate
|
||||
risk: low
|
||||
@@ -67,9 +67,9 @@ tasks; minors get a follow-up batch.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] Review doc filed with severity-graded findings
|
||||
- [ ] Remediation tasks created for anything above trivial
|
||||
- [ ] The 5 checklist sections each covered with a verdict
|
||||
- [x] Review doc filed with severity-graded findings
|
||||
- [x] Remediation tasks created for anything above trivial
|
||||
- [x] The 5 checklist sections each covered with a verdict
|
||||
|
||||
## References
|
||||
|
||||
@@ -81,6 +81,101 @@ tasks; minors get a follow-up batch.
|
||||
|
||||
> Agent fills during implementation.
|
||||
|
||||
### Review executed 2026-09-08 (tree `2efac9b`) — deliverable: `docs/reviews/001-implementation-review.md`
|
||||
|
||||
Method: full source read (`src/` + `tests/`) against the complete spec
|
||||
set; alkcall 0.7.0 API surfaces verified in source (wrapper, establisher
|
||||
types, client errors, manager adopt/teardown, `pump_bidi`); executable
|
||||
probes over real sockets for the `local` UDP path (temporary test file,
|
||||
deleted after the run — probe evidence quoted in the review); the full
|
||||
verification battery (see below). The mid-phase `tunnels/
|
||||
review-core-crates` checklist is subsumed (consolidated in the review
|
||||
doc; that task's Notes carry its verdicts).
|
||||
|
||||
### The five checklist verdicts
|
||||
|
||||
1. **Wire conformance — PASS.** Params shape exact (`deny_unknown_
|
||||
fields`, required both, enum `["tcp","udp","unix"]` — the OQ-TN-14
|
||||
note in this checklist predates the OQ's resolution; `unix` SHIPS
|
||||
per OQ-TN-14's resolution, and the enum carries it correctly); op
|
||||
id/ALPN/scope pinned; codec correct including `len=0` and frame-time
|
||||
`Oversize`; all five typed establishment reasons reachable and
|
||||
proven (3 by test: `unknown_resource`/`dial_failed`/
|
||||
`resource_shortage`; `handler_error` through the same `From` arm;
|
||||
`timeout` by the hanging-establisher probe) + `FORBIDDEN` +
|
||||
`channel:too_many_channels`.
|
||||
2. **Producer conformance — PASS.** Awaited bounded establisher (10s
|
||||
default + per-registration override proven); pure R-01 plan flow
|
||||
(grep-verified — no side-channel handoff, no poll-loop take); pump
|
||||
handler structurally R-02 (`pump_bidi` inline; JoinHandle tracks
|
||||
the data plane, pinned by test); post-hoc registration (W2)
|
||||
supported; listen variant rides the same op with the typed-error
|
||||
table proven.
|
||||
3. **Consumer conformance — PASS.** Full session surface per ADR-005;
|
||||
teardown matrix sound (close/join/Drop/pump-less/failed-adopt — all
|
||||
leak-asserted on both managers); no `Clone` (compile-fail doctest).
|
||||
One documented divergence: `adopt` takes the substrate (the task
|
||||
sketch omitted it — a datagram session cannot exist without it).
|
||||
4. **Conventions sweep — PASS.** No unwrap/expect/panic outside
|
||||
`#[cfg(test)]` (grep-verified); thiserror everywhere; all locks are
|
||||
`tokio::sync::Mutex` (unpoisoned — the `into_inner` rule has no
|
||||
application point, N/A); substrate types confined to `src/local/`
|
||||
+ feature gate; wasm clean (`check` + `clippy --target
|
||||
wasm32-unknown-unknown`, `-D warnings` both); `pump_bidi` consumed,
|
||||
never hand-rolled. Inline `//` comments are the
|
||||
safety-constraint class convention 1 allows.
|
||||
5. **Docs ↔ implementation sync — PASS with drift fixed in-review.**
|
||||
Module map matches; ADRs all Accepted (implementation confirms); N-5
|
||||
(stale doc forward-reference), N-7 (broken doc link), N-8 (missing
|
||||
root re-exports) fixed in-review.
|
||||
|
||||
### Findings (full detail in the review doc)
|
||||
|
||||
- **U-1 [major]** — 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 probes. **NOT fixed — remediation
|
||||
task `tunnels/fix-udp-framed-adapter`** (blocks UDP-over-`local`
|
||||
consumers; wire surface unaffected).
|
||||
- **C-1 [major]** — `AcceptQueue::pop` lost wakeup in the
|
||||
check→register window (open op hangs to the establishment bound on
|
||||
a lost push). **Fixed in-review** (create-`Notified`-before-check
|
||||
per iteration, the tokio `notify_waiters` contract; regression test
|
||||
added).
|
||||
- **U-2/U-3 [minor]** — `connect_udp` v4-only bind posture; 65535-byte
|
||||
per-tunnel scratch. Riders on the U-1 task.
|
||||
- **N-4/N-5/N-7/N-8/N-9/N-10/N-11 [minor]** — fixed in-review (payload
|
||||
serialization, doc staleness, doc link, root re-exports, README +
|
||||
publish dry-run, harness comment, `pump_against` UDP framing doc
|
||||
note).
|
||||
- **N-2** — retracted during the review by executable falsification
|
||||
(the codec's buffering is bounded by construction; the u16 cap IS
|
||||
the bound).
|
||||
- **N-6** — non-finding with rationale (`TunnelEstablishError` has no
|
||||
`Timeout` variant, correctly).
|
||||
|
||||
No criticals — the phase-gate passes.
|
||||
|
||||
### Verification battery (all green)
|
||||
|
||||
- `cargo test`: 62 passed (default) / 69 passed (`--features local`),
|
||||
3× repeat-run clean in both configs
|
||||
- `cargo clippy --all-targets -- -D warnings`: clean
|
||||
- `cargo clippy --target wasm32-unknown-unknown -- -D warnings`: clean
|
||||
- `cargo fmt --check`: clean
|
||||
- `cargo doc --no-deps`: clean after N-7's fix
|
||||
- `cargo check --target wasm32-unknown-unknown`: clean
|
||||
- `cargo publish --dry-run --allow-dirty`: passes after N-9's README
|
||||
|
||||
## Summary
|
||||
|
||||
> Agent fills this on completion.
|
||||
> Agent fills this on completion.
|
||||
|
||||
Phase-gate review complete: the wire surface (the one-way door) is
|
||||
conformant; the API surface matches ADR-005/006; two majors found —
|
||||
U-1 (local UDP framing, remediation task created) and C-1 (queue lost
|
||||
wakeup, fixed with the review commit). The trivial batch + README +
|
||||
publish dry-run also landed with the review. Findings with
|
||||
severity grading and remediation ordering:
|
||||
`docs/reviews/001-implementation-review.md`.
|
||||
Reference in New Issue
Block a user