Files
glm-5.3-flash f4b5f896b4 docs: sweep em dashes from all markdown prose
Renames the written-usage rule into practice across the contract surface:
docs/ (architecture, research, plans, sdd), tasks/ (all 43 task files,
taskgraph validate passes), AGENTS.md, README.md, CHANGELOG.md, and the
.opencode/agents/ prompts. Every replacement is a sense-preserving
rewrite (colons, semicolons, commas, parentheses, sentence splits, varied),
never a mechanical swap; no spaced hyphens were substituted. Enum fields,
frontmatter, tables, wire data, and cited identifiers survive verbatim;
en dashes inside numeric ranges keep their meaning.

Verification: taskgraph validate (43 tasks), repo grep clean (single
exempt hit: the verification command's own search pattern in AGENTS.md),
cargo test, clippy --all-targets -D warnings, fmt --check, doc all green.
2026-11-04 20:28:00 +00:00

113 lines
5.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
status: reviewed
last_updated: 2026-10-28
---
# Overview: alkssh
## What this crate is
alkssh is the alk family's SSH adapter (family ADR-003): a thin
wrapper around **russh** that terminates the vanilla-SSH wire and
bridges to/from family protocols. It is **a door in both directions,
vanilla on the outside** (vision principle 2; ADR framing in
`mapping.md` / `client.md`):
- **Server direction**: a door *for vanilla clients*. Vanilla `ssh`,
`git`, and (never for us, by design) sftp tooling connect as they
would to any sshd; each accepted SSH channel/request is mapped onto
exactly one family protocol seam and exactly one cargo feature.
Primary current purpose: the alkforge git door.
- **Client direction**: a door *to vanilla servers*. A family app
(the reverse-runner hub) dials vanilla `sshd` (rented fleets,
runpod/vast.ai-style boxes) and the ops map family-side onto
alktty/alktunnels/alkgit types; the runner stays vanilla by design.
The crate's substance is glue and mapping; no SSH framing is authored
in-family (family ADR-003 decision 1); russh owns the wire, and the
pin is ADR-002.
## Position in the family
| Concern | Owner |
|---|---|
| SSH wire protocol (KEX, ciphers, channel mux, userauth state machines) | russh (pinned, ADR-002) |
| SSH channel-type → family-protocol mapping | **this crate** (the spine, `mapping.md` / `client.md`) |
| Identity (fingerprint → `Identity`) | alkcall `IdentityProvider`, assembly-implemented; never the vault (vault = secrets *we* hold) |
| Secrets we hold (client dial keys, host keys) | alkvault-backed sources (ADR-005) |
| The `alk/ssh` ALPN | ADR-001 (edge-termination contract; relay/browser legs have no consumer in scope, OQ-01 resolved) |
| Deployment policy (which features, which ACLs) | the embedding assembly (alkforge) |
Composability boundary: alkssh is a door, not a backend. It depends
on alkcall types at the wire layer and the mapped crates' session or
client surfaces, and carries no deployment policy. A downstream app
embeds it, enables features (ADR-003), brings identity/ACL config.
## Public surface (categories)
The crate is a library (`[lib]`, no binary, a stated non-goal); the surface
categories the phase-1 specs define:
- **Server stack** (`mapping.md`): serve configuration (feature-gated
seam wiring, bounded-resource limits, honest-advertisement auth
config) + the serving loop that accepts vanilla connections and
dispatches per the mapping table.
- **Client stack** (`client.md`): dial surface (address, key source,
host-key policy, keepalive/timeout config), the op-row consumers
(session exec/pty, tunnel dial, `-R` listen + acceptor), and
lifecycle primitives (bound-port handles, cancel; OQ-12: no
reconnect policy is owned).
- **Key sources** (`auth.md`): vault-backed source construction per
ADR-005 for both directions (client keys *and* host keys).
- **Identity plumbing** (`auth.md`): the fingerprint→identity bridge
at the server; the identity→seam propagation for mapped channels.
Feature graph (ADR-003): `session`, `git`, `tunnel`, `sftp`
(placeholder); flat, independent, `default = []` (no capabilities),
two-direction symmetry, fail-closed declines contract-tested on every
side of every feature.
## Bounded-resources policy (family convention)
Every session is bounded by wall clock, size, and channel count
(AGENTS.md convention 9; the knobs are russh's `Config` per ADR-002's
surface notes):
| Resource | Knob | Default posture |
|---|---|---|
| Session wall clock | `inactivity_timeout` | set (assembly-tunable) |
| Rekey volume/time | `Limits` | russh-enforced (post-0.64-full-enforcement) |
| Per-channel memory | `window_size`, `maximum_packet_size`, `channel_buffer_size` | set |
| Auth attempts | `max_auth_attempts` | 10 default (ADR-004: the counting `none` probe) |
| Keepalives (client direction, cloud fleets) | `keepalive_interval`/`keepalive_max` | 15 s / 3 (reverse-runner evidence: NAT'd runners) |
| Concurrent channels per session | ours (in-crate) + per-identity policy when bridged | ours to cap |
No unbounded loops, no unbounded buffers; the fail-closed declines
plus the knobs above are the whole posture.
## Non-goals
Per `vision.md`: no in-family SSH protocol machinery (ever); not an
sshd (no local accounts, no OpenSSH `authorized_keys` semantics, no
PAM); no sftp serving until alkfs lands (OQ-13 resolved; the feature
exists as a tested declining placeholder); no binary/CLI; no password
or keyboard-interactive auth in either direction; no x11 or agent
forwarding at all (not even feature-gated, ADR-003 §5).
## Lifecycle note
This crate follows the family crate template (alktty root pattern):
`src/` modules re-exported from `lib.rs`, one module per file, public
API = crate-root re-exports. The dependency set (russh per ADR-002,
alkcall types, per-feature sibling deps: alktty/alktunnels/alkgit) and
the manifest (`rust-version` 1.89, edition 2024) land at
implementation start; ADR-002 records the manifest decisions.
## References
- [README.md](README.md) (index), [open-questions.md](open-questions.md) (OQ-01…13)
- ADRs 001–006 in [decisions/](decisions/)
- `docs/research/`: vision, POC findings (1/2/3), russh inventory,
auth bridge, mapping table (validated), reverse-runner extraction
- Family ADR-003 (the structural decision), family ADR-002 (alkforge;
why exclusion matters)