docs(release): wave 5 release readiness — crate docs, README, CHANGELOG, matrix, dry-run (w5-release-readiness)
- resolve the rustdoc warning set (9 incl. private-link class in client_ops.rs + redundant explicit links + a duplicated tty_map paragraph): cargo doc warning-free on default and --all-features - docs honesty: the five recorded limits ride the published crate-root rustdoc (§Known limits: write_all no-deadline, PTY rule-5, port-0-only mint echo, no-reconnect policy, no-accept-all); crate docs state the feature graph + the fail-closed invariant - two no_run usage doctests (server mount + dial) — the README examples stay compile-checked in every matrix build - README.md lands (the door, feature graph, examples, custody posture, license); CHANGELOG.md carries the 0.1.0 founding entry - feature matrix green (6 test builds, clippy x2 -D warnings, fmt, doc) + the fuzz corpus gate (11 invariants) - cargo publish --dry-run --allow-dirty clean (76 files packaged + verified; file list checked against the package policy; manifest sanity recorded); the freeze inventory recorded for the gate Verification: scripts/matrix.sh (all builds), fuzz corpus gate, taskgraph validate
This commit is contained in:
1 parent
d37cbc0c8a
commit
ab5236ebbb
9 files changed
+634
-53
No files matched your search
+143
-27
@@ -4,33 +4,149 @@ All notable changes to this crate are documented here. The format is
|
||||
based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
||||
this crate adheres to [Semantic Versioning](https://semver.org/).
|
||||
|
||||
## [Unreleased]
|
||||
## [0.1.0] - 2026-10-30
|
||||
|
||||
The founding entry — the crate's first release. `alkssh` is the alk
|
||||
family's SSH adapter (family ADR-003): a thin wrapper around russh
|
||||
0.65 terminating the vanilla-ssh wire and bridging to/from alkcall
|
||||
channels — the two-direction door for vanilla clients. The wire is
|
||||
russh's; the crate's substance is the channel-type mappings
|
||||
(session/pty → alktty, direct/forwarded-tcpip → alktunnels, git exec →
|
||||
alkgit), each behind its cargo feature in a flat, independent graph
|
||||
(ADR-003): **a default build has no capabilities and serves nothing
|
||||
but clean declines** — every unfeatured or unimplemented request is
|
||||
declined fail-closed, never half-served or silently fallen back, and
|
||||
never advertised. Identity is the family's: a verified key's
|
||||
fingerprint → alkcall `IdentityProvider`; keys the crate holds come
|
||||
from alkvault-backed sources, encrypted at rest, decrypted at use,
|
||||
never env vars (ADR-005). The crate is a door, not a backend — no
|
||||
binary, no deployment policy; a downstream app embeds it, enables
|
||||
features, and brings identity/ACL configuration.
|
||||
|
||||
### Added
|
||||
|
||||
- Initialized: docs-only phase 0 base — SDD process (`docs/sdd_process.md`),
|
||||
opencode agent definitions, rust crate manifest (lib only, no
|
||||
dependencies yet), MIT OR Apache-2.0 licensing. The russh pin, the
|
||||
capability feature graph, and the channel-type mapping table are
|
||||
phase 0 research output (family ADR-003, OQ-08 remaining scope).
|
||||
- Phase 0 research set under `docs/research/`: `vision.md` (scope
|
||||
questions), `russh.md` (0.64.1-era inventory + pin considerations),
|
||||
`auth-bridge.md` (fingerprint → identity server path; vault-backed
|
||||
at-rest client key storage — the vault as secret store, not key
|
||||
derivation), `mapping-table.md` (channel type/request → family seam
|
||||
+ feature), `pocs.md` (POC-1..3 plan).
|
||||
- Phase 0 completed — all three POCs passed against the current
|
||||
published russh with vanilla tooling (121 checks total); findings
|
||||
in `poc-1-auth-bridge.md` (31), `poc-2-vault-keys.md` (39),
|
||||
`poc-3-mapping-bakeoff.md` (51, three mapping-table corrections
|
||||
recorded), plus the reverse-runner client-direction extraction
|
||||
(`reverse-runner.md`). POC source is disposable, never merged.
|
||||
- Phase 1 architecture under `docs/architecture/`: the index +
|
||||
open-questions tracker (OQ-01…13), the spec docs
|
||||
(`overview.md`, `mapping.md`, `client.md`, `auth.md`), and ADRs
|
||||
001–006 (Accepted) — the `alk/ssh` ALPN pin; the russh 0.65.0 pin
|
||||
(aws-lc-rs, no compression, `rsa` off); the capability feature
|
||||
graph (flat, two-direction, `dynamic-forward` retired); auth
|
||||
dispositions; vault-key custody; and the mapping/dispatch
|
||||
decisions (route-1 bridge, exec-only git, parse-only session
|
||||
dispatch).
|
||||
**Phase 0/1 — research and architecture** (the contract the
|
||||
implementation lands):
|
||||
|
||||
- SDD process, phase 0 research set (`docs/research/`), and the three
|
||||
passed POCs (auth bridge, vault keys, mapping bake-off; findings in
|
||||
`poc-1..3` + `reverse-runner.md`; POC source never merged).
|
||||
- Phase 1 architecture under `docs/architecture/`: the spec docs and
|
||||
ADRs 001–006 (Accepted) — the `alk/ssh` ALPN pin; the russh 0.65.0
|
||||
pin (aws-lc-rs, no compression, rsa off); the capability feature
|
||||
graph; auth dispositions; vault-key custody; the mapping/bridge/
|
||||
dispatch decisions.
|
||||
|
||||
**Wave 1 — foundations:**
|
||||
|
||||
- The manifest: the russh 0.65 pin (`aws-lc-rs`, default features
|
||||
off), the flat feature graph (`session` / `git` / `tunnel` /
|
||||
`sftp`, `default = []`).
|
||||
- The fail-closed error taxonomy (`thiserror`): `AdapterError`,
|
||||
`DialError`, `KeySourceError`, `OpError`, `OpenDeclineReason` —
|
||||
declines are dispositions, never panics; no `unwrap` outside tests.
|
||||
- Vault-backed key custody in code: the `KeySource` /
|
||||
`HostKeySource` seams and the ADR-005 implementations
|
||||
(`VaultKeySource`, `VaultHostKeySource`) — decrypt-at-use /
|
||||
decrypt-at-construction, the `Zeroizing` seam, one
|
||||
`decode_secret_key` conversion.
|
||||
- The `HostKeyPolicy` seam (OQ-05, policy-blind) with the fail-closed
|
||||
default `RejectAll` — no accept-all built-in exists in the crate.
|
||||
- The contract-invariant fingerprint computation (the crate's single
|
||||
fingerprint path, the `SHA256:` format both the auth bridge and the
|
||||
host-key policy consume).
|
||||
- The config surface: `ServeConfig`, `DialConfig`, `Limits` (the
|
||||
bounded-resources budget model — wall clock always set, channel
|
||||
caps, keepalive posture) — unset fields decline at request time
|
||||
(OQ-08), construction never validates.
|
||||
|
||||
**Wave 2 — the server stack:**
|
||||
|
||||
- `SshAdapter` — the mount point: `SshAdapter::new(serve)` builds the
|
||||
russh server from the config (fail-closed on key-source failure);
|
||||
`adapter.handle(stream)` serves one connection.
|
||||
- The auth bridge: russh auth hooks → ADR-004 dispositions —
|
||||
verified-key fingerprint → `IdentityProvider::resolve_from_fingerprint`,
|
||||
fail-closed on every path; bounded auth attempts.
|
||||
- Parse-only dispatch + the fail-closed decline core: every unroutable
|
||||
or unfeatured request answers a clean, channel-scoped decline; the
|
||||
spawned serving-path shapes (`channel_failure` then close).
|
||||
- Spawn-and-return plumbing (ADR-006 decision 4): serving paths run
|
||||
spawned (russh handlers return fast at this pin), with the
|
||||
exit-status-before-close mechanics.
|
||||
- Bounded resources at the handler surface: per-connection channel
|
||||
caps (refuse-never-queue) and listener caps.
|
||||
- The in-process loopback harness (the contract-test vehicle).
|
||||
|
||||
**Wave 3 — the server mappings (the spine):**
|
||||
|
||||
- Per-feature seam handles (`SessionSeam`, `GitSeam`,
|
||||
`TunnelListenSeam`): unset seam → decline even with the feature on.
|
||||
- Decline-path tracing (`tracing` events on every decline class).
|
||||
- The git mapping (exec-only, ADR-006): the full exec grammar —
|
||||
`git-{upload,receive}-pack '/<repo>'` parsed and dispatched to
|
||||
alkgit; a subsystem request can never carry the repository and
|
||||
declines; `1` is honestly reported for push `ng`.
|
||||
- The session mapping: pty/shell/exec through the alktty seam over a
|
||||
translation bridge (chunk-framed both directions), OQ-44's reserved
|
||||
ttymodes JSON, the exit-chunk → SSH exit derivation (rules 1–6),
|
||||
control rows (window-change, signal) on a bounded per-channel
|
||||
surface.
|
||||
- Tunnel leg 1: the route-1 bridge — `direct-tcpip` /
|
||||
`direct-streamlocal` opens ride the assembly's `TunnelSession` over
|
||||
the family fabric; fabric failure is a clean `ConnectFailed` reject.
|
||||
- Tunnel leg 2: the `-R` listen flow — `tcpip_forward` /
|
||||
`streamlocal_forward` dial the fabric, arrivals correlate through
|
||||
the token router (miss → teardown-at-birth), the data leg opens
|
||||
`forwarded-tcpip`/`forwarded-streamlocal` back toward the client,
|
||||
port-0 mints echo the actually-bound port.
|
||||
|
||||
**Wave 4 — the client direction:**
|
||||
|
||||
- The dial surface: `dial(DialConfig)` — key load (decrypt-at-dial),
|
||||
bounded russh client config, the host-key policy call, exactly one
|
||||
publickey attempt; `SshConnection` the handle.
|
||||
- The op rows: `exec` / `pty_exec` / `shell` (the alktty chunk plane),
|
||||
`tunnel_direct` / `tunnel_direct_unix` (byte duplex),
|
||||
`git_service` (pack duplex + consumed exit) — plus the `sftp`
|
||||
decline row (always declines, every build).
|
||||
- The `-R` leg: `reverse_listen` / `reverse_listen_unix` + the
|
||||
`AcceptorRegistry` (refuse-never-replace) and the acceptor traits —
|
||||
the hub asks the vanilla server to listen and serves the accepted
|
||||
channels.
|
||||
- Lifecycle primitives (OQ-12): explicitly cancellable listener
|
||||
handles, clean `close()` (`Disconnect::ByApplication`) — drop is
|
||||
never the clean path at this pin; no reconnect/restore policy (the
|
||||
crate ships primitives, the assembly composes).
|
||||
- Hardening riders: the git row's status-before-close by construction,
|
||||
the channel-not-held guard wire rows, tty control-row coverage, the
|
||||
`ListenRouter` token-collision pre-check.
|
||||
|
||||
**Wave 5 — validation and release:**
|
||||
|
||||
- The decline-matrix contract suite: every mapping-decline row × every
|
||||
build it can appear in × both directions (the matrix runner
|
||||
`scripts/matrix.sh` — one command over all feature builds).
|
||||
- Real-tool e2e both directions: OpenSSH (pty/shell/exec, `-L`, `-R`,
|
||||
`-D` + curl), git clone and push through the door, and a real
|
||||
`sshd` against the client direction (exec, direct-tcpip dial, `-R`
|
||||
listen + acceptor) — check-gated, skipped rows carry reasons.
|
||||
- The `fuzz/` sidecar: the ingress surfaces (exec parse grammar,
|
||||
fingerprint format, key decode, `TerminalParamsWire`) with the
|
||||
committed-seed corpus gate (`cargo test --manifest-path
|
||||
fuzz/shared/Cargo.toml`).
|
||||
- Release readiness: warning-free crate docs with the known-limits
|
||||
records riding the published rustdoc, this README, and the publish
|
||||
dry-run posture.
|
||||
|
||||
### Notes
|
||||
|
||||
- `sftp` is a feature of decline: enabling it adds no capability —
|
||||
the `sftp` subsystem request still declines in every build until
|
||||
the alkfs mapping lands (OQ-13; the decline stays contract
|
||||
territory).
|
||||
- The `env` request declines unconditionally (OQ-09): session cwd/env
|
||||
are assembly-supplied, never wire-derived.
|
||||
- The russh pin (0.65, `aws-lc-rs`, `des`/`dsa` never enabled) is a
|
||||
wire-relevant one-way door: bumps are deliberate, tested, and
|
||||
recorded (ADR-002).
|
||||
Reference in new issue
Block a user