- 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
11 KiB
status, last_updated
| status | last_updated |
|---|---|
| draft | 2026-10-26 |
Open questions
Centralized tracker for alkssh. Seeded from the phase 0 POC findings
(docs/research/poc-{1,2,3}-*.md), the research docs' OQ seeds, and
the reverse-runner extraction. Numbers are repo-local (family and
alkcall trackers have their own OQ spaces).
Theme A — wire & family topology
OQ-01: Does an alk/ssh relay/browser-leg consumer emerge?
- Origin: mapping-table.md §topology,
vision.mdscope Q1 - Status: deferred(scope)
- Door type: two-way (the pin is one-way; consumer existence is not)
- Priority: medium
- Impacts: none for the phase 1 scope — ADR-001 pins the contract so relay/browser legs don't foreclose it; the phase 1 docs serve edge termination only. A future relay leg would exercise
docs/architecture/client.md's accept surface in a new role. - Blocked on: a concrete consumer — either the browser-WASM route (alkcall ADR-009 sketch) materializing in an assembly, or a hub deployment needing SSH-in-relay. No such use case exists yet.
- Resolution: Not yet decidable — no consumer use case exists. ADR-001 decides everything decidable now: the ALPN pin's raw-stream contract, and its transport-blindness.
- Cross-references: ADR-001, OQ-13
Theme B — session-channel dispatch & mapping details
OQ-02: What is the session-channel dispatch shape (SOCKS-detect vs parse, and who bounds the window)?
- Origin: poc-3-mapping-bakeoff.md §Stage B.3,
mapping-table.md§notes - Status: deferred(unclear)
- Door type: two-way
- Priority: high
- Impacts: blocks the exact dispatch contract detail in the
mapping.mdspec (ordering: exec-parse vs SOCKS-detect vs pipe; the detect window's bound; crate default vs assembly config). - Investigation: the pieces exist — POC-3 proven both modes (stage A parse-then-route for git; stage B bounded first-byte sniff for SOCKS) and proven both serve "session" channels behind different features. Unclear is the composition: walk 2+ concrete session-channel flows (git exec, family-native SOCKS client, plain pipe exec) and pin dispatch precedence, the detect window's default bound, and the configuration seam. Do during
mapping.mdwriting. - Resolution: Not yet decidable by inspection — needs the composition worked through, not new facts.
- Cross-references: OQ-08
OQ-03: Username disposition — resolved
- Origin: poc-1-auth-bridge.md §2,
auth-bridge.md§The mapping - Status: resolved
- Resolution: usernames are never the identity model and carry no routing semantics — the fingerprint is the sole resolution path (POC-1:
ssh anything@hostworks with the same identity). Whether a username string appears in logs is deployment policy, outside the crate. Rides as the recorded contract in theauth.mdspec / ADR-004.
OQ-04: OpenSSH certificate auth — is there ever a CA-trust use case?
- Origin:
mapping-table.md(auth rows), poc-1-auth-bridge.md OQ seed 4 - Status: deferred(scope)
- Door type: two-way
- Priority: low
- Impacts: none —
auth_openssh_certificateis declined (the ADR-004 disposition), and POC-1 established the decline exists. A revisit only matters if alkforge ever wants CA-issued certificates. - Blocked on: a concrete OpenSSH-CA use case arriving in an embedding assembly.
- Resolution: Not yet decidable — decline initial; no CA-trust story in the family identity model today.
Theme C — auth, identity & key custody
OQ-05: What is the client-side host-key pin store? — resolved (policy-seam shape)
-
Origin: auth-bridge.md §Host keys,
reverse-runner.md§5 -
Status: resolved — the seam is decided; where learned pins persist is assembly detail (the crate takes a policy, not a pin store).
-
Resolution: two basic client cases, one seam:
- Known beforehand — trust anchors exist. Family-built runners mint their host key at assembly time, so the expected fingerprint is known before first contact: assembly-supplied pins, hard decline on mismatch (no soft failure).
- Unknown beforehand — vanilla
sshdon container fleets the assembly didn't provision; no anchor exists until first contact. The crate surfaces the presented host key (host, port, fingerprint) to an assembly-providedHostKeyPolicythat decides: prompt-and-record, provider-metadata match, or learn-and-record. The OpenSSH "add to known_hosts?" moment becomes an assembly policy rather than crate behavior.
Crate rules that make this family-shaped: the crate's default policy is fail-closed (reject unknown, hard-decline mismatch — russh's own reject-all default, kept); the crate never decides trust itself; accept-all is never a crate option (that collapse is the old-code anti-pattern, and for ephemeral fleets strict pinning is the wrong control anyway — the anchor there is hub-held key material/lifecycle, not host pins). The contract lands in the client-side ADR (written with
client.md; expected to be ADR-007) and theauth.mdspec. -
Cross-references: OQ-07,
reverse-runner.md, poc-2-vault-keys.md §5 (host keys ride the vault model)
OQ-06: One vault, many roles? — resolved
- Origin: poc-2-vault-keys.md OQ seed 3
- Status: resolved
- Resolution: not an alkssh constraint. The crate takes vault handles the assembly injects; whether the assembly runs separate vault instances per role (client keys vs host keys) is assembly policy. ADR-005 records the boundary: vault handle in, key material out, version semantics owned by the vault.
OQ-07: Is the alkvault decrypt plain-String zeroization gap closed at the vault or at the adapter?
- Origin: poc-2-vault-keys.md §2 + OQ seed 1
- Status: open
- Priority: medium
- Impacts: an in-family cross-crate ask (alkvault API change vs alkssh-side convention). Blocks nothing functionally — POC-2 proves the adapter-side
Zeroizingwrap correct — but decides where the security convention lives for the whole family (alkhttp secrets ride the same&str-out surface). - Resolution: pending. Candidates: alkvault returns
Zeroizing<String>(family-wide fix, touches a published crate), or the adapter-side wrap is the recorded family convention (ADR-005). Bring to alkvault; if upstream accepts, ADR-005 cites the follow-up; if not, ADR-005 records the adapter obligation as the convention. - Cross-references: OQ-05, ADR-005
Theme D — session-request mapping details
OQ-08: Shell command convention for shell_request
- Origin:
mapping-table.md(shell row), poc-3-mapping-bakeoff.md OQ seed 3 - Status: open
- Priority: medium
- Impacts: blocks the
mapping.mdsession-row detail (what alkttydriveswhen a vanillassh hostlands). The POC's stand-in (bash/sh -c) was explicit assembly policy, not wire-derived. - Resolution: pending. Direction known (assembly policy, nothing wire-supplied); the decision is the concrete convention surface: a config field on the assembly vs a crate-level default that the assembly may override. Decide when writing
mapping.md.
OQ-09: env_request policy — is an allowlist ever wanted?
- Origin:
mapping-table.md(env_request row) - Status: deferred(scope)
- Door type: two-way
- Priority: low
- Impacts: none — decline-by-default is the fixed posture (wire env is not family config). An allowlist (
LANG, …) only matters if a consuming assembly has a concrete need. - Blocked on: a concrete consumer use case requiring wire-supplied environment variables.
- Resolution: Not yet decidable — no use case; decline stands.
OQ-10: The alktty exit chunk carries no signal identity — widen the chunk or map by assembly policy?
- Origin: poc-3-mapping-bakeoff.md §D.2,
mapping-table.md(exit_signal row) - Status: open
- Priority: medium
- Impacts: blocks the
exit-signalfidelity detail inmapping.md; an in-family upstream ask (alktty wire change, third-party-upstream posture applies family-internally too). - Resolution: pending. Candidates (per POC-3): alktty widens the exit chunk with the signal name (filed as an ask — alkssh never silently works around), or alkssh maps negative exit codes via assembly policy (fidelity compromise: name inferred/coarse). Also in scope for the same OQ: pipe-mode signals are pid-only vs PTY process-group scope (backend-semantics fidelity note for the session rows). Decide the fallback during
mapping.md; the upstream ask stays open until alktty answers. - Cross-references: OQ-08
OQ-11: direct-streamlocal platform surface — compile-time or runtime decline shape?
- Origin:
mapping-table.md(streamlocal row) - Status: open
- Priority: low
- Impacts: blocks the
tunnelfeature's platform matrix detail (unix-only compile-out vs universal-compile runtime decline), a small contract test question. - Resolution: pending — decide during
mapping.md; default direction is runtime decline (matches fail-closed and windows-on-ssh portability) unless the unix-only compile split proves simpler.
OQ-12: Client reconnect: does the crate own forward/session restoration? — resolved
- Origin:
reverse-runner.md§4 - Status: resolved
- Resolution: the crate owns lifecycle primitives only — bound-port handles (forward listeners return the actually-bound port, per russh's
tcpip_forward -> u32), explicit cancellable forward/session handles, and clean disconnects. Reconnect-and-restore policy (rebinding persisted tunnel ports per alkminer's flow) is assembly-owned. Recorded as a constraint inclient.md; no reconnect policy is baked into the crate.
Theme E — deferred features
OQ-13: The sftp client+server halves when alkfs lands
- Origin:
mapping-table.md(sftp rows),reverse-runner.md, POC-2 scope notes - Status: deferred(scope)
- Door type: two-way
- Priority: low (until alkforge phase 0 resumes)
- Impacts: the
sftpfeature ships declining from the first build (honest advertisement, decline contract tested on both sides); the alkforge CI deploy path (binary/artifact push, alkminer-precedent evidence) and the alkfs server seam are the eventual consumers. - Blocked on: alkfs — family ADR-002, paused so alkforge can land; alkssh's sftp implementation follows alkfs' maturity.
- Resolution: Not yet decidable — the target protocol is pending. The placeholder contract (decline, tested) is in scope for the first architecture pass.
- Cross-references: OQ-01
Deferred / Blocked (at a glance)
| OQ | Blocked on | Priority |
|---|---|---|
| OQ-01 | concrete relay/browser-leg consumer | medium |
| OQ-02 | (deferred(unclear)) investigation during mapping.md |
high |
| OQ-04 | concrete OpenSSH-CA use case | low |
| OQ-09 | concrete wire-env use case | low |
| OQ-13 | alkfs landing (family ADR-002) | low (for now) |