Eight implementation tasks + the gate under tasks/implementation/, folding the wave-3 gate's four booked findings in as dedicated tasks (the gate's own disposition — wave-4 material, not wave-3 backports). Hardening set (server-side, independent of the client chain, scheduled first as cheap remediation): - w4-git-exit-close: booked item 1 — the git row's status-before-close by construction (the seam/shape decided + recorded in-task; the saturated-buffer scenario pinned on the wire) - w4-channel-not-held-rows: booked item 2 — the guard's wire rows on git/tty pipe/shell, per build (test-only) - w4-tty-coverage: booked item 3 — the channel_close-fired cancel path + the Closed/Break no-exit-chunk rows + the write_all no-deadline known-limit record - w4-router-collision: booked item 4 — the ListenRouter token-collision fail-closed pre-check Client chain (sequential logistically — one client Handler impl): - w4-dial: the russh client stack + the connection handle + the client Handler skeleton at fail-closed defaults, over an in-process fake-sshd server double - w4-op-rows: exec/pty, direct-tcpip, git exec over the shared grammar, the sftp client-side decline — the POC-3 §D.3 mechanics - w4-reverse-listen: the -R leg — forward requests + the acceptor registry + late-install (the wave's highest-risk task) - w4-lifecycle: the OQ-12 primitives (cancellable handles, clean disconnect, no reconnect policy) review-wave-4 depends on all eight. The gate's item 5 (upstream asks) stays booked with its owners — no task. Plan wave-4 section carries the decomposition record + four flagged interpretations; wave table status updated. Verification: taskgraph validate ✓ (35 tasks)
2.7 KiB
2.7 KiB
id, name, status, depends_on, scope, risk, impact, level
| id | name | status | depends_on | scope | risk | impact | level | ||
|---|---|---|---|---|---|---|---|---|---|
| w4-lifecycle | Wave 4 — lifecycle primitives (cancellable handles + clean disconnect) | pending |
|
narrow | low | component | implementation |
Description
Land the OQ-12 resolution in code (client.md §Lifecycle
primitives): the primitives that make assembly-side reconnect/restore
policy possible — and nothing more:
- Explicitly cancellable handles — every listener/handle the
client direction returns (the
-Rlistener handles fromw4-reverse-listen, the connection handle fromw4-dial) carries an explicit cancellation/clean-close path; no handle relies on drop timing alone for wire-visible state. - Clean disconnect —
Disconnect::ByApplication(russh's clientHandle::disconnect): the explicit-close path leaves no half-open channels, observed clean by the peer (row-pinned through the server double). - No reconnect or restore policy owned by the crate — the module-doc posture: reconnect-and-restore (rebinding persisted tunnel ports — the alkminer flow, reverse-runner fact 4) is assembly policy; the crate provides bound ports, handles, cancellation, clean close. The docs state the boundary explicitly so no later task drifts into baking policy in.
- Contract rows through the server double — cancel a listener mid-connection (the server's forward is torn down, the bound port released); clean disconnect observed by the peer; the connection-handle cancellation path; the no-policy posture is a docs-honesty item for the gate, not a row.
Acceptance Criteria
- Every client-direction listener/handle is explicitly cancellable; no drop-timing-only wire state
Disconnect::ByApplicationclean-close lands; the peer observes a clean disconnect, no half-open channels (row-pinned)- The no-reconnect-policy boundary stated in module docs (the primitives-not-policy posture)
- Contract rows green through the server double
cargo test(+ per-feature +--all-features), clippy ×2 (-D warnings), fmt,cargo doc --no-depspass
References
- docs/architecture/client.md §Lifecycle primitives (the OQ-12 resolution), docs/architecture/open-questions.md (OQ-12 — resolved: primitives only)
- docs/research/reverse-runner.md (fact 4 — reconnect-and-restore is assembly policy, kept in view so the crate never bakes it in)
- docs/research/russh.md §Client surface (
Handle::disconnect, the forward cancel forms) - src/tunnel_map.rs (the server-side teardown posture — the cancel semantics mirror)
Notes
To be filled by implementation agent
Summary
To be filled on completion