- alkvault 0.1 -> 0.2 (breaking req): decrypt returns Zeroizing<String> (alkvault review 001, resolution paths 1+2); the adapter seam's own wrap in decrypt_and_decode is dropped (the pre-wrap window ADR-005 decision 3 recorded is closed upstream — the vault fences the plaintext from its return onward, every path including the UTF-8 error one; rotate never holds a bare plaintext either). decode_key_arm's signature is unchanged. - alktunnels 0.4.1 -> 0.5.0 (breaking req, additive API): the review-003 W2 adoption's dep half (the establisher shape's registration ride lands in the next commit). - alktty 0.8.1 -> 0.8.2 (patch, PTY exit-signal fidelity): pin text refreshed; no alkssh contract change (the negative-code convention is consumed verbatim). - seam docs re-shaped to the closed-gap posture (key_source module + decrypt arm + decode arm; doubles.rs; fuzz key_decode battery). Verification: cargo test (default + --all-features), clippy x2 -all-features -D warnings, fmt, fuzz corpus replay (11). Verification of the flake check: e2e real_git_push row 6+ isolated passes on both trees (one full-matrix load flake, pre-existing abort race, not this change).
122 lines
6.3 KiB
TOML
122 lines
6.3 KiB
TOML
# Single-crate protocol/door crate (the alktty template). No workspace:
|
|
# the composition story is deferred — alkssh's substance is the mappings
|
|
# (family ADR-003). The `fuzz/` sidecar is its own workspace (excluded —
|
|
# it pins its own nightly toolchain and never rides the root's).
|
|
[workspace]
|
|
members = ["."]
|
|
exclude = ["fuzz"]
|
|
|
|
[package]
|
|
name = "alkssh"
|
|
version = "0.2.0"
|
|
edition = "2024"
|
|
rust-version = "1.89"
|
|
license = "MIT OR Apache-2.0"
|
|
description = "SSH adapter for the alk family: russh-wrapped vanilla-ssh termination bridged to/from alkcall channels — session/pty, tunnels, git exec — with every capability mapping a fail-closed cargo feature (no features: no capabilities)"
|
|
repository = "https://git.alk.dev/alkdev/alkssh"
|
|
keywords = ["ssh", "russh", "protocol", "alkcall", "network"]
|
|
categories = ["network-programming", "asynchronous"]
|
|
# The package policy (the sibling crates' convention): the published crate
|
|
# ships the architecture docs (the authoritative contract) but not the
|
|
# process surface — reviews, research, plans, task files, the working
|
|
# agents' config, AGENTS.md — and not the `fuzz/` sidecar (its own
|
|
# workspace; never a root dep, never a shipped surface).
|
|
exclude = [".opencode/", "AGENTS.md", "docs/reviews/", "docs/plans/", "docs/research/", "docs/sdd_process.md", "tasks/", "fuzz/"]
|
|
|
|
[lib]
|
|
name = "alkssh"
|
|
|
|
[features]
|
|
# ADR-003: flat and independent — no feature implies another; `default = []`
|
|
# by design (a default build has no capabilities; every unfeatured open
|
|
# declines fail-closed). The wave-2 decline core is the first `cfg`
|
|
# consumer; the wave-3 seam-config handles are the second (each optional
|
|
# sibling dep is gated feature-to-dep so a git-build never compiles
|
|
# alktty and vice versa — the wave-1 manifest rule: per-feature sibling
|
|
# deps land with their first consuming wave, which for alktty/alkgit is
|
|
# the wave-3 config fields and for alktunnels `w3-tunnel-direct`, the
|
|
# route-1 bridge).
|
|
default = []
|
|
session = ["dep:alktty", "dep:serde_json", "dep:bytes"]
|
|
git = ["dep:alkgit"]
|
|
tunnel = ["dep:alktunnels"]
|
|
sftp = []
|
|
|
|
[dependencies]
|
|
# async-trait (the alkcall precedent) makes the injected handles
|
|
# dyn-compatible (`Arc<dyn ...>`) — the HostKeyPolicy dial handle needs
|
|
# that, and native AFIT traits are not object-safe at this toolchain.
|
|
async-trait = "0.1"
|
|
# ADR-002: aws-lc-rs only; default features off — no flate2, no rsa
|
|
# (ed25519-only; the tree stays RC-free except the ssh-key pin riding the
|
|
# russh keys path). Never enable russh's `des`/`dsa` features.
|
|
russh = { version = "0.65", default-features = false, features = ["aws-lc-rs"] }
|
|
alkcall = "0.10"
|
|
# alkvault 0.2 (breaking req bump, 0.1 -> 0.2, 2026-11-04): `decrypt`
|
|
# returns `Zeroizing<String>` (alkvault review 001's resolution — the
|
|
# pre-wrap plaintext window ADR-005 decision 3 recorded is closed
|
|
# upstream); the adapter-side wrap is dropped. Pin re-verified against
|
|
# crates.io: MIT OR Apache-2.0.
|
|
alkvault = "0.2"
|
|
# Wave-3 seam-handle types (`config.rs`'s `SessionSeam`/`GitSeam`).
|
|
# Pins verified against crates.io (2026-11-04): alktty 0.8.2 (0.1.0's
|
|
# 0.8.1 pin refreshed — 0.8.2 is the PTY exit-signal-fidelity fix,
|
|
# patch-level, API/wire unchanged; alkssh consumes negative exit
|
|
# codes verbatim so the derivation contract needed no change), alkgit
|
|
# 0.1.0 — both MIT OR Apache-2.0, both rust_version ≤ our 1.89,
|
|
# both over alkcall ^0.10 (shared with our `alkcall = "0.10"` →
|
|
# 0.10.1 resolution). alktty's `local` feature stays off — alkssh
|
|
# never touches a real backend; the `local` shapes stay alktty-side.
|
|
alktty = { version = "0.8.2", default-features = false, optional = true }
|
|
alkgit = { version = "0.1.0", default-features = false, optional = true }
|
|
# tunnel-only: the route-1 bridge's consumer surface (`TunnelSession::
|
|
# open_direct`/`take_halves`, `SubstrateAddr`/`Substrate`) + the
|
|
# forwarded serving surface's establisher shape
|
|
# (`register_tunnel_forwarded_openable_with_establisher` +
|
|
# `ForwardedGate` — the review-003 W2 adoption, ADR-008 Amendment 2's
|
|
# recommended shape). Pin re-verified against crates.io (2026-11-04):
|
|
# 0.5.0 is newest_version, additive API only over 0.4.1 (the wire
|
|
# delta is empty, the base registration is byte-for-byte), MIT OR
|
|
# Apache-2.0, rust_version 1.88 ≤ our 1.89, alkcall ^0.10.1 pinned
|
|
# exactly (single-versioned against our `alkcall = "0.10"`). The
|
|
# `local` feature stays off — the dial seam is injected (`DialFn`);
|
|
# the real dial/backends belong to the assembly, and the tests
|
|
# hand-roll their own dial/dial-fail seams (`tests/tunnel_mapping.rs`).
|
|
alktunnels = { version = "0.5.0", default-features = false, optional = true }
|
|
# session-only: the OQ-44 reserved ttymodes JSON (`TerminalParamsWire.modes`)
|
|
# and the exit-chunk / negotiation-error-frame JSON reads in `tty_map.rs`.
|
|
# Same pin alktty carries (crate resolution stays single-versioned).
|
|
serde_json = { version = "1", optional = true }
|
|
# session-only: the alktty chunk plane is `bytes`-based (`Chunk.bytes`) —
|
|
# the bridge builds sentinel/ctrl chunks with it. Same pin russh/alktty
|
|
# carry (crate resolution stays single-versioned).
|
|
bytes = { version = "1", optional = true }
|
|
tokio = { version = "1.54", features = ["full"] }
|
|
thiserror = "2.0"
|
|
tracing = "0.1"
|
|
parking_lot = "0.12"
|
|
zeroize = "1.9"
|
|
|
|
[dev-dependencies]
|
|
# The git-seam test doubles name `GitPackGen`'s `gix_hash::ObjectId`
|
|
# parameters and alkgit does not re-export them — test-graph only,
|
|
# version matched to alkgit's `^0.28` req (same crate in the lockfile).
|
|
gix-hash = { version = "0.28", features = ["sha1"] }
|
|
# The session shim's scripted stdout/stderr streams ride tokio's
|
|
# `ReceiverStream` — test-graph only (the crate proper hand-rolls no
|
|
# streams).
|
|
tokio-stream = "0.1"
|
|
# The leg-2 fabric double's establisher/params serialization
|
|
# (`w3-tunnel-listen`) — test-graph only (the door's own lib code
|
|
# stays serde-free under the `tunnel` feature; the double's
|
|
# dynamic-bind producer serializes params/reply fields).
|
|
serde_json = "1"
|
|
# The real-tool pty smoke (`w3-tty-session`): alktty's `local` backend
|
|
# composition — the dev-dep `features = ["local"]` unification applies
|
|
# to the TEST graph only (feature unification folds `local` into the
|
|
# optional alktty dep in test builds; the published lib never enables
|
|
# it and `src/` never names a local shape). Same 0.8.2 pin.
|
|
alktty = { version = "0.8.2", default-features = false, features = ["local"] }
|
|
|
|
[profile.release]
|
|
lto = "thin" |