docs(tasks): decompose wave 2 — the server stack

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.
This commit is contained in:
glm-5.3-flash committed 2026-10-28 07:38:04 +00:00
1 parent a19cdc4832
commit 18ef55c60d
8 files changed
+612 -1

No files matched your search

+39 -1
View File
@@ -44,7 +44,7 @@ mappings ∥ client direction) → validation & release.
| Wave | Contents | Depends on | Status |
|---|---|---|---|
| [1](#wave-1--foundations) | Manifest landing (russh pin, feature graph); error model; config surface (serve-config + dial-config + `Limits`); vault-backed key sources; host-key policy seam; fingerprint; test doubles | — | decomposed |
| [2](#wave-2--the-server-stack) | `SshAdapter::handle` mount + `Config` construction; the auth bridge; parse-only dispatch + fail-closed decline core; spawn-and-return plumbing; bounded resources; loopback harness | wave 1 | pending |
| [2](#wave-2--the-server-stack) | `SshAdapter::handle` mount + `Config` construction; the auth bridge; parse-only dispatch + fail-closed decline core; spawn-and-return plumbing; bounded resources; loopback harness | wave 1 | decomposed |
| [3](#wave-3--server-mappings) | session → alktty (translation bridge + exit derivation); git → alkgit (exec grammar + dispatch); tunnel → alktunnels route 1; sftp placeholder declines | wave 2 | pending |
| [4](#wave-4--client-direction) | Dial surface; op rows (exec/pty, direct-tcpip, git exec); the `-R` leg (listen + acceptor registry); lifecycle primitives | wave 1 | pending |
| [5](#wave-5--validation--release) | Decline-matrix contract suite; real-tool e2e; fuzzing; docs; **the publish** | waves 3 + 4 | pending |
@@ -203,6 +203,44 @@ frame, before any door is hung:
Wave 2 decomposes after the wave-1 gate, absorbing whatever it
corrects.
**Decomposition record** (2026-10-28, after the wave-1 gate closed
green): wave 2 decomposed into six task files under
`tasks/implementation/` plus the gate. Shape: `w2-server-mount` first
(the `SshAdapter` mount + russh `Config` construction from the
serve-config — the substrate, with the Handler skeletoned at its
fail-closed defaults); then `w2-auth-bridge` (the ADR-004
dispositions fill the auth hooks, over the mount + the wave-1
fingerprint path and doubles); then `w2-loopback-harness` (the
in-process client/server pair — the contract-test vehicle — proving
the doubles live through the stack); then `w2-dispatch-decline-core`
(parse-only dispatch + the fail-closed decline core, contract-tested
per feature build through the harness); then `w2-spawn-return` (the
structural constraint pinned by test + the exit-reporting mechanics
via the cloned `Session::handle()`); then `w2-bounded-resources` (the
in-crate channel cap at the handler surface); and `review-wave-2`
(the gate) depending on all six. The chain is deliberately sequential
— the auth hooks, the dispatch, and the cap all edit the same
per-connection Handler impl, so no two tasks hold it in parallel.
Interpretations recorded (flagged for the wave-2 gate):
- **The git-parseability probe in wave 2 is skeleton-level** (service
prefix + path shape) — enough to contract-test the routing decision
and the session-build's git-gated decline; the full grammar
(quoted/unquoted paths, service-only → decline-with-reason,
per-length limits) is wave-3's git task, which replaces the probe.
- **Wave-2 routing stubs decline cleanly at the family-seam boundary**
— the seams land in wave 3; the stub behavior is documented as
skeleton so the routing decisions are contract-tested now. The
spawn-and-return mechanics are proven on a stub serving path.
- **The adapter error surface is shaped in `w2-server-mount`** — the
construction error wrapping `KeySourceError` (locked → no server)
plus the Handler `type Error` (`From<russh::Error>`); this is where
the wave-1 note's "wire decline reasons are wave-2 shaped" lands.
- **The harness transport and placement are pinned in
`w2-loopback-harness`** (duplex pair vs TCP loopback; module
placement beside the wave-1 doubles) — flagged for the gate.
## Wave 3 — Server mappings
Three parallel branches over the stack (plus the folded sftp row),