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)
5.2 KiB
5.2 KiB
id, name, status, depends_on, scope, risk, impact, level
| id | name | status | depends_on | scope | risk | impact | level | |
|---|---|---|---|---|---|---|---|---|
| w4-op-rows | Wave 4 — the client op rows (exec/pty, direct-tcpip, git exec, sftp decline) | pending |
|
moderate | medium | phase | implementation |
Description
Land the op rows — family op → vanilla translation per
client.md's table, pointed upstream at a vanilla server (the
reverse-runner shape: the hub drives every channel open). Type
symmetry at the seam is the contract: family-protocol types in,
vanilla wire ops out, no vanilla-concept leaks up. The POC-3 §D.3
mechanics are the body of knowledge this task lands in code:
- Session exec/pty rows (under
session) —channel_open_session- the exec/pty-req/shell-req translations onto the alktty session
types (pipe vs PTY; exit semantics):
Channel::exec()— norequest_execat this pin; Success/Failure arrive on the channel queue viawait()-drain, not asErrfrom the request call (drain until the expected message,continuepast the rest);window_change/signalare fire-and-forget and must be sent beforeinto_stream()(the Channel is consumed by conversion); never consume the channel queue beforeinto_stream()(await()on a fresh channel breaks it — POC-1 §6, both sides). The data pump + the exit consumption mirror the server direction's derivation contract (the pipe-mode pid-only signal caveat rides the alktty exit-chunk semantics —mapping.md's contract, consumed not re-derived).
- the exec/pty-req/shell-req translations onto the alktty session
types (pipe vs PTY; exit semantics):
direct-tcpiptyped dial (undertunnel) — the row the-Lleg and the alksocksDialFncompose over:channel_open_direct_tcpipresolves toErr(ChannelOpenFailure)on server reject (POC-1 §6) — the typed open, nowait()beforeinto_stream; the connection stays usable after a declined open (pinned by row). Thedirect-streamlocaltwin with the runtime-Unix gate (OQ-11 symmetry: universal compile, clean off-Unix decline).- Git exec consumption (under
git) — the same exec grammar the server side parses (git-{upload,receive}-pack '/repo'), reused, not forked — pointed upstream at a vanillasshd: parse → exec → the pack duplex pumped → exit-status consumed. The per-length limits and service-only decline classes ride the shared grammar's verdicts. - The sftp subsystem placeholder decline (every build, OQ-13) —
the client-side half of the tested decline placeholder: a
subsystem "sftp"open declines cleanly in every build (the feature exists, the route doesn't until alkfs lands). The server-side rows already landed in wave 2; this lands the client mirror so both directions are contract-tested. - Contract rows through the server double, per build — the
w4-dialfake-sshdvehicle grown with the op-row surfaces: featured + working rows (exec exit-status, pty window-change ordering, direct-tcpip pump, git exec round trip), decline rows (server-rejected opens, the sftp decline, off-Unix streamlocal), the connection-stays-usable row after each decline class. The real-tool smoke posture decided + recorded (a realsshdexec is cheap where tooling permits — check-gated like the wave-3 smokes; else named wave-5 e2e territory explicitly).
Acceptance Criteria
- Exec/pty rows land under
sessionwith the POC-3 §D.3 mechanics pinned in code + rows (exec()notrequest_exec;wait()-drain Success/Failure;window_change/signalbeforeinto_stream; queue never consumed before conversion) direct-tcpip(+ streamlocal twin, runtime-Unix gate) lands undertunnel: typed open, reject →Err(ChannelOpenFailure), the connection stays usable after a decline (row-pinned)- Git exec consumption lands under
gitover the shared grammar (no forked parser); the pack duplex pumps; exit-status consumed - The sftp subsystem placeholder declines in every build (the client-side OQ-13 mirror)
- Per-build contract rows green through the server double; the smoke posture decided + recorded
cargo test(+ per-feature +--all-features), clippy ×2 (-D warnings), fmt,cargo doc --no-depspass
References
- docs/architecture/client.md §Op rows (the table), §Correctness facts, §What the crate does not include (job supervision is assembly work — the crate gives channels + exit semantics)
- docs/architecture/mapping.md §The exit derivation contract (the mirror the client consumes), docs/architecture/decisions/003-feature-graph.md (the feature rows), docs/architecture/decisions/006-mapping-bridge-and-dispatch.md (exec-only git, both directions)
- docs/research/poc-3-mapping-bakeoff.md §D.3 (the client mechanics —
the body of knowledge), docs/research/poc-1-auth-bridge.md §6 (the
open-call
Errsemantics), docs/research/reverse-runner.md (the per-connection surface table — the consumer evidence) - src/git_map.rs (the grammar reused), src/tty_map.rs (the exit-chunk
semantics consumed), russh 0.65
client::Handle(channel_open_session/channel_open_direct_tcpip/channel_open_direct_streamlocal)
Notes
To be filled by implementation agent
Summary
To be filled on completion