tasks: Phase 2 decomposition — 12-task dependency graph for v1
tasks/architecture/: - oq-promotion-sync (planning): back-pointers from the phase-0 ledger + AGENTS.md to the promoted OQ tracker (the convergence checklist's final half) - oq-tn-14-tracker: the Safe-Exit external-trigger tracker task for OQ-TN-14 (unix/stdio placement; [external-trigger, deferred-oq], risk trivial, level research per the two-halves rule) tasks/tunnels/ (the implementation graph, 8 generations): - crate-init: module skeleton per overview.md's module map - params: TunnelParams + open-op spec (ADR-001 wire-stable surface) - wire-codec: frame_datagram/DatagramReader + the 8 POC-pinned test families (ADR-003) - producer-open-op: establisher (dial, plan flow R-01) + pump handler (pump_bidi inline R-02) + registration; POC-ported integration tests - consumer-session: TunnelSession (open/adopt, data planes, teardown matrix — ADR-005); generalizes the reverse POC's ReverseTunnel - producer-listen: the listen establisher + AcceptQueue contract (ADR-004 shape 2) - local-socket-halves: the local feature (TCP/UDP/unix halves functions; truncation fail-loud per OQ-TN-13; unix ships per OQ-TN-14's lean-yes, stdio deferred) - review-core-crates: review-injection point before the downstream tasks build on the high-risk producer/consumer shapes - end-to-end-suite: 6 suites / >=20 tests consolidating both POC suites against the public API (the spec's executable form) - review-impl: the phase-gate review (wire/API/conventions/docs sync; findings doc per the alkhttp/alkcall house pattern) Graph verified with taskgraph: 12 tasks valid, no cycles, 8 generations; critical path = oq-promotion-sync -> crate-init -> params -> wire-codec -> producer-open-op -> consumer-session -> review-core-crates -> review-impl; risk concentrated in the two session tasks (both POC-validated); parallel groups available at generations 1 and 6
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
---
|
||||
id: tunnels/local-socket-halves
|
||||
name: "local feature — real socket halves functions (TCP dial, UDP connect, unix)"
|
||||
status: pending
|
||||
depends_on: [tunnels/producer-open-op, tunnels/wire-codec]
|
||||
scope: moderate
|
||||
risk: medium
|
||||
impact: component
|
||||
level: implementation
|
||||
tags: [local, backend, sockets, feature-gate]
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
Add the `local` feature module (`src/local/`) per overview.md §Feature
|
||||
Gates + ADR-004: the real-socket halves functions the assembly layer
|
||||
injects as `DialFn`/`AcceptFn` closures. The POCs' substrate adapters
|
||||
are the reference (they ran all of this); the task is packaging them
|
||||
into the feature-gated module with the crate's conventions.
|
||||
|
||||
### Surface
|
||||
|
||||
```rust
|
||||
// src/local/mod.rs (feature = "local"; non-wasm by design)
|
||||
pub async fn dial_tcp(target: &str) -> Result<TargetHandle, TunnelEstablishError>;
|
||||
// TcpStream::connect (5s timeout per the POCs) → into_split → boxed halves
|
||||
|
||||
pub async fn connect_udp(target: &str) -> Result<TargetHandle, TunnelEstablishError>;
|
||||
// UdpSocket::bind(("0.0.0.0", 0)) → connect(target) → the FRAMED adapter
|
||||
// (UdpHalf + codec — ADR-003; truncation fail-loud per OQ-TN-13)
|
||||
|
||||
pub async fn dial_unix(path: &str) -> Result<TargetHandle, TunnelEstablishError>;
|
||||
// UnixStream::connect → into_split (OQ-TN-14: ships with local v1 — cheap,
|
||||
// same halves shape as TCP)
|
||||
|
||||
pub struct TcpListenerHalves { listener: tokio::net::TcpListener }
|
||||
impl TcpListenerHalves {
|
||||
pub async fn bind(addr: &str) -> Result<Self, ...>;
|
||||
pub fn accept_fn(&self, queue: &AcceptQueue) -> impl Future; // the accept loop feeding the queue
|
||||
}
|
||||
|
||||
pub struct UdpAssociateHalves { sock: Arc<UdpSocket> } // the POC's associate shape
|
||||
```
|
||||
|
||||
- **UDP adapter (`UdpHalf`)**: port from the forward POC
|
||||
(`params.rs`'s `UdpHalfRead`/`UdpHalfWrite`) with the truncation fix:
|
||||
`poll_recv` into a too-small caller buffer must fail loud
|
||||
(OQ-TN-13's resolved posture — ADR-003). The codec wraps at this
|
||||
boundary; the pump never sees UDP specifics.
|
||||
- **Error mapping** to `TunnelEstablishError` variants (the POC's
|
||||
`Into<EstablishmentError>` path).
|
||||
- `TargetHandle` re-used from producer.rs (the halves type lives in
|
||||
producer.rs; local/ depends on it, never vice versa).
|
||||
|
||||
### Feature wiring
|
||||
|
||||
```toml
|
||||
[features]
|
||||
default = []
|
||||
local = ["tokio/net"]
|
||||
```
|
||||
|
||||
- `tokio/net` is the only dep addition (no new external crates; the
|
||||
POCs proved `rt+sync+io-util+macros+time+net` covers everything).
|
||||
- The default crate stays wasm-clean: `local`-gated code must not be
|
||||
importable from `producer.rs`/`consumer.rs` (convention 16 — backend
|
||||
modules are never imported from the shared/producer/consumer
|
||||
modules).
|
||||
- Unix is IN v1 (OQ-TN-14's lean-yes posture; same halves shape as
|
||||
TCP); stdio bridging is NOT (different lifecycle — deferred).
|
||||
|
||||
### Tests
|
||||
|
||||
Behind the feature: TCP dial round-trip through the real establisher
|
||||
path, UDP associate + datagram round-trip with the framed adapter,
|
||||
unix dial round-trip, truncation fail-loud (a short recv surfaces as
|
||||
an error), the 1400-byte MTU datagram through bounded buffers (the
|
||||
POC's sizing test).
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] `cargo test --features local` green; `cargo test` (default)
|
||||
unaffected
|
||||
- [ ] `cargo test --all-features` green (AGENTS.md convention 14)
|
||||
- [ ] wasm32 check on the DEFAULT crate passes; `local` is non-wasm by
|
||||
design (documented)
|
||||
- [ ] Truncation fails loud (the OQ-TN-13 test)
|
||||
- [ ] No socket type appears outside `src/local/`
|
||||
- [ ] Clippy/fmt clean
|
||||
|
||||
## References
|
||||
|
||||
- docs/architecture/overview.md §Feature Gates, §Dependencies
|
||||
- docs/architecture/decisions/004-no-backend-trait.md (the injection
|
||||
point), 003 (the framed adapter)
|
||||
- POC reference: `/workspace/alktunnels-udp-poc/src/producer.rs`
|
||||
(`UdpHalf`, the dial paths), `params.rs` (the UDP adapter)
|
||||
|
||||
## Notes
|
||||
|
||||
> Agent fills during implementation.
|
||||
|
||||
## Summary
|
||||
|
||||
> Agent fills this on completion.
|
||||
Reference in New Issue
Block a user