Files
alkssh/tasks/implementation/w4-op-rows.md
T
glm-5.3-flash dba64d65d3 docs(tasks): decompose wave 4 — the client direction
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)
2026-10-29 05:59:03 +00:00

5.2 KiB
Raw Blame History

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
w4-dial
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() — no request_exec at this pin; Success/Failure arrive on the channel queue via wait()-drain, not as Err from the request call (drain until the expected message, continue past the rest); window_change/signal are fire-and-forget and must be sent before into_stream() (the Channel is consumed by conversion); never consume the channel queue before into_stream() (a wait() 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).
  • direct-tcpip typed dial (under tunnel) — the row the -L leg and the alksocks DialFn compose over: channel_open_direct_tcpip resolves to Err(ChannelOpenFailure) on server reject (POC-1 §6) — the typed open, no wait() before into_stream; the connection stays usable after a declined open (pinned by row). The direct-streamlocal twin 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 vanilla sshd: 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-dial fake-sshd vehicle 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 real sshd exec 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 session with the POC-3 §D.3 mechanics pinned in code + rows (exec() not request_exec; wait()-drain Success/Failure; window_change/signal before into_stream; queue never consumed before conversion)
  • direct-tcpip (+ streamlocal twin, runtime-Unix gate) lands under tunnel: typed open, reject → Err(ChannelOpenFailure), the connection stays usable after a decline (row-pinned)
  • Git exec consumption lands under git over 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-deps pass

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 Err semantics), 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