feat(client): land the lifecycle primitives — listener handles + the clean-disconnect boundary (w4-lifecycle)

- src/client_accept.rs: the ReverseListener handles (ReverseEndpoint
  carried; cancel() the wire-honest teardown) returned by the -R listen
  rows; the shared cancel paths both the handles and the stateless wire
  forms compose into; the confirmed cancel releases the listener count
  exactly once; no Drop hides a wire op
- src/client.rs: the SshConnection internals behind the Arc
  (ConnectionShared) — the handles' independent cancels compose on the
  same stack; the §Lifecycle posture module docs (primitives-not-policy,
  OQ-12; the abrupt-drop/clean-close facts, row-pinned)
- rows: drop-handle no-wire-state, handle-cancel + budget release,
  cancel-mid-data-leg (tunnel build) + the every-build abrupt-drop row;
  existing reverse rows adapted to the handles; the unix cancel rides
  the handle flavor
- docs/architecture/client.md: the §Lifecycle primitives landing block;
  task file filled

Verification: cargo test (default / session / git / tunnel / all-features)
all green; clippy ×2 -D warnings clean; fmt clean; cargo doc --no-deps clean
This commit is contained in:
glm-5.3-flash committed 2026-10-29 17:42:29 +00:00
1 parent 7e5989f574
commit dec644e653
8 files changed
+762 -106

No files matched your search

+25
View File
@@ -113,6 +113,31 @@ half-capability, which the family forbids (ADR-003 symmetry +
primitives (bound ports, handles, cancellation, clean close) to
make that possible.
> **The landed lifecycle surface (`w4-lifecycle` — recorded at
> landing):** the `-R` listens return **`ReverseListener` handles** —
> the `ReverseEndpoint` carried (the *actually bound* values:
> the wire address + the bound port / the socket path — the
> assembly's own record for a rebind policy it may compose), the
> explicit `cancel()` the wire-honest teardown (the confirmed cancel
> also releases the connection's listener count; a repeat rides the
> wire and hits the unknown-listener refusal). The **stateless**
> cancel forms (`reverse_listen_cancel` + the unix twin) ride beside
> the handles 1:1 (sshd's global-request cancels are stateless — a
> cancel by the raw wire strings works from anywhere, including
> after the handle itself is gone: the handle shares the
> connection's internals through the arc, so its `cancel()` is the
> same wire op). **No `Drop` hides a wire op** on any of these
> handles: a cancellation/bundle of the wire ops is async and cannot
> run in a sync `Drop`, and at this russh pin dropping the last
> wire-stack handle ends the client runner — the transport *breaks*
> (the peer observes an error-class session end, never the clean
> disconnect message). The primitives-not-policy posture is the
> module-docs contract: `client.rs` §Lifecycle posture (the
> primitives list + the abrupt-drop/clean-close boundary,
> row-pinned both ways) and `client_accept`'s recorded decisions;
> the alkminer reconnect-and-restore flow stays assembly
> composition (reverse-runner fact 4).
## What the crate does *not* include (client direction)
- **Job supervision** — background-job lifecycle (the alkminer