Six implementation tasks + the gate under tasks/implementation/, chained sequentially (the auth hooks, dispatch, and channel cap all edit the same per-connection Handler impl): - w2-server-mount: SshAdapter::handle mount + russh Config construction from the serve-config (honest advertisement, host-key decrypt-at-construction, the Limits knob mapping) + the Handler skeleton at fail-closed defaults - w2-auth-bridge: the ADR-004 dispositions (ed25519-only explicit decline, fingerprint-only resolution, explicit declines for every non-publickey method) - w2-loopback-harness: the in-process client/server contract-test vehicle over the wave-1 doubles - w2-dispatch-decline-core: parse-only dispatch + the fail-closed decline core, contract-tested per feature build - w2-spawn-return: the structural constraint pinned by test + the exit-reporting mechanics via the cloned Session::handle() - w2-bounded-resources: the in-crate concurrent-channel cap at the handler surface - review-wave-2: the gate The plan carries the wave-2 decomposition record with four interpretations flagged for the gate (skeleton-level git probe, declining routing stubs, the adapter error surface, the harness transport choice). taskgraph validate: 19 tasks, clean.
3.0 KiB
3.0 KiB
id, name, status, depends_on, scope, risk, impact, level
| id | name | status | depends_on | scope | risk | impact | level | |
|---|---|---|---|---|---|---|---|---|
| w2-spawn-return | Wave 2 — spawn-and-return plumbing + exit/status reporting mechanics | pending |
|
narrow | medium | phase | implementation |
Description
Land the structural constraint in code (ADR-006 decision 4): russh at this pin runs server handler callbacks inline inside the session's packet loop — a blocking handler suspends all packet routing for the connection and deadlocks against the peer's immediate follow-up bytes (POC-3 proved by construction with receive-pack). Therefore:
- Every serving path is
tokio::spawned; handlers return fast. The dispatch's routing stubs become spawned serving paths (still declining stubs — the seams are wave 3), so the pattern is in place before any real mapping hangs on it. - Exit/status reporting mechanics — reporting from spawned tasks
rides the cloned
Session::handle():exit-statussent before channel close, from the spawned task. The derivation contract's rules (which code → which SSH exit shape) are wave-3 session-mapping material (mapping.mdrules 1–6); this task lands the mechanics — the handle clone, the exit-status send, the ordering-before-close — proven end to end. - The proof — a stub serving path that spawns, completes
asynchronously (after the handler has returned), and reports
exit-status(N)+ close through the cloned handle; the loopback harness client observes the exit-status arriving after the handler already returned. A handler-returns-fast assertion (the handler completes while the spawned task is still running) pins the constraint as a test, not a convention.
This is a load-bearing correctness constraint of the whole spine, not an implementation choice — the wave-3 mappings inherit the pattern mechanically from the stubs this task leaves behind.
Acceptance Criteria
- Every serving path (the dispatch stubs) runs in a
tokio::spawn; no handler hook awaits a serving path inline - Exit/status reporting from spawned tasks rides the cloned
Session::handle();exit-statusis sent before channel close - A harness test proves the mechanics end to end: the client
observes
exit-status(N)from a spawned stub that completed after the handler returned - A handler-returns-fast assertion pins the structural constraint as a test
cargo test,cargo clippy --all-targets -- -D warnings,cargo fmt --checkpass
References
- docs/architecture/decisions/006-mapping-bridge-and-dispatch.md (decision 4 — the structural constraint)
- docs/architecture/mapping.md §The structural constraint: spawn-and-return; §exit_status row (sent before close, from the spawned task)
- docs/plans/implementation.md §Wave 2 (the spawn-and-return bullet)
- docs/research/poc-3-mapping-bakeoff.md (the deadlock-by-construction evidence)
Notes
To be filled by implementation agent
Summary
To be filled on completion