The format contract (ADR-004 decision 1) is SHA256: + unpadded
standard base64 — not url-safe. The ssh-key re-export and ssh-keygen
both emit the +/ alphabet (visible in the recorded fingerprints); the
'url-safe' wording in ADR-004/auth.md/plans/implementation.md and the
POC-1 §1 finding was a misnomer. Wording corrected; the parity
contract itself unchanged on both sides.
- OQ-10 is not resolved: the mapping-contract derivation details (name
table, core-dumped disposition, −1 disposition) are working
dispositions on mapping.md's exit rows until formalized there / as an
ADR-006 amendment. The 1a40bfb commit prematurely closed them and left
ADR-006's reference (OQ-10 open) stale.
- Premise correction integrated into the seed, not argued after the
fact; the portable-pty 0.9.0 source now cited as verified
(From<std::process::ExitStatus> maps signal-terminated → code 1 +
locale-dependent strsignal string; the number is unrecoverable).
- mapping.md: exit_signal row and the Open Questions entry updated to
open OQ-10 with the working-draft framing.
Verification: cargo test (2/2 targets ok), cargo clippy --all-targets -- -D warnings, cargo fmt --check (docs-only change)
- OQ-10 resolved: alkssh derives SSH exit-signal from the alktty exit
chunk's negative code (−N = signal N, pipe path) server-side; −1
(alktty's could-not-determine sentinel) → exit-status(255), never a
signal claim; core_dumped never asserted in v1; no alktty wire change
- new verified backend finding recorded: portable-pty 0.9 reduces
PTY-mode signal termination to a plain exit code 1 (signal number
unrecoverable through its trait surface) — faithful exit-signal on
the PTY row is an alktty/portable-pty upstream ask, not an alkssh one
- research docs (poc-3 §D.2, pocs.md, mapping-table rows) restated
accurately instead of carrying inline correction scaffolding
Verification: cargo doc --no-deps earlier this session (docs-only change)
- OQ-10's seed overstated alktty's exit-chunk design as a 'signal-identity
gap': the negative code is the documented signal encoding (alktty ADR-004,
ported from alknet ADR-055; src/local/pipe.rs::exit_code_from — Unix
ExitStatus::signal() → -sig), a tty/pty-grounded convention
- 'alktty widens the chunk' demoted from co-equal candidate to gated
exception: it would widen ControlMessage::Exit's one-way parsed shape,
the backend-wide exit_code API, and the alknet ADR-055 lineage — requires
an alktty ADR with explicit tty/pty-grounded justification, never an
alkssh convenience ask
- OQ-10 re-scoped to the real remaining detail: −1 (wait failure vs SIGHUP)
collision, core-dumped disposition, non-Unix semantics, name derivation
- correction notes added in place: poc-3 §D.2, pocs.md, mapping-table.md
(both rows); mapping.md exit_signal row updated
Verification: cargo doc --no-deps (docs-only change)
- the alkssh-level contract is the adapter-side Zeroizing wrap
(ADR-005 decision 3, POC-2-proven); the vault-side fix (Zeroizing-out
API) is filed in alkvault's own tracker — not carried, not gated on
here; ADR-005 §3 wording updated accordingly
Review untangle (three layers: local door / wire protocol / fabric):
- vanilla ssh -D binds its SOCKS5 proxy client-side (the local door —
alksocks' local-door shape) and opens plain direct-tcpip per
connection: the server needs nothing SOCKS-shaped (tunnel row +
route-1 bridge cover the leg; POC-3 correction 2 already said this)
- the family-native SOCKS5-in-channel server row served no consumer
of ours: family apps compose alksocks' local door locally over the
alkssh client's direct-tcpip DialFn — alkssh doesn't depend on
alksocks on this path
- amendments: ADR-003 §1a (feature removed), ADR-006 point 3 (SOCKS-
detect retired; session dispatch is parse-only; request-less
session channels decline), OQ-02 resolution updated with the
simplification, mapping-table.md rows annotated (research doc keeps
POC-3 stage B as the re-add feasibility record)
- ADR-006 (Accepted): direct-tcpip rides the adapter-side bridge
(alktunnels route 1; registry-side bridging rejected as door-posture
inversion; absence note resolved); git over SSH is exec-only with
subsystem declining (vanilla git's connection model is exec of
git-{upload,receive}-pack — POC-3 grammar table); session dispatch:
request-driven parse wins, request-less channels get the bounded
SOCKS-detect (first-byte 0x05, 500 ms default, assembly-configurable);
spawn-and-return recorded as a structural constraint
- OQ-02 resolved by ADR-006; README doc/ADr tables + OQ summary updated
- enabling the rsa feature is reverted: no other family location uses
RSA, ed25519 is the suggested path everywhere; the tree drops
rsa 0.10.0-rc.18 + pkcs1 0.8.0-rc.4 entirely (verified: aws-lc-rs-only
scratch build clean and RC-free except ssh-key =0.7.0-rc.11, which
russh exact-pins itself on the russh::keys path)
- RSA user keys decline fail-closed (russh fails RSA signing explicitly
when the feature is absent — 0.63.2 fix); assembly registration policy
(alkforge: register ed25519) noted as assembler territory
- README ADR table title updated
- ADR-002 (Accepted): pin russh 0.65 (0.65.0 published 2026-10-25
after the POCs' 0.64.1 verification — six security fixes incl.
three in internet-facing classes; breaks are handler-signature
shapes only, wire evidence transfers); aws-lc-rs backend confirmed
with a clean in-scratch build record (no provisioning; ring kept as
the recorded fallback); flate2 off (no compression); rsa on (front-
door compat — supersedes the research docs' earlier off-leaning;
RC-tree posture accepted with a recorded stable-release trigger);
des/dsa never; rust-version 1.89 lands with the dep
- russh.md: re-verification-at-architecture-time section added
(0.65.0 delta: PublicKeyOffer/VerifiedPublicKey, async-trait
removed, GHSA list, verified build + tree facts)
- ADR-003 (Accepted): five features (session/git/tunnel/
dynamic-forward/sftp-placeholder), flat + independent, default [],
two-direction symmetry rule (one name, both doors), client acceptor
fail-closed (not russh's accept-and-drop), x11/auth-agent never
features, honest advertisement per build
- OQ-05 resolved: known-beforehand hosts (assembly-minted/family runners)
-> pinned, hard-decline on mismatch; unknown-beforehand hosts (rental
fleets) -> assembly-provided HostKeyPolicy the crate calls — prompt-
record, provider-metadata match, or learn-and-record. Crate default
stays fail-closed reject-unknown; crate never decides trust; storage
of learned pins is assembly detail
- auth-bridge.md: refinement postscript — no-TOFU is a no-trust-decisions-
-in-crate rule, not pin-everything; alkminer's accept-all was the fleet-
churn collapse, and the real anchor for ephemeral fleets is hub-held
key material, not host pins
- reverse-runner.md §5 rewritten with the same nuance