* feat(ssh): wire rung B to the glibc 2.17 compat runtime; gate rung C vault on full node:sqlite
- COMPAT_RELAY_RUNTIMES lists linux-x64-glibc217; rung B plans the compat slot and compat
pinned Node when glibc is below 2.28 or rung A refused with libc_floor/missing_lib.
- The relay version folds the compat runtime's executable hash; refusals are cached per runtime.
- The orcad template stages an optional linux-x64-glibc217 target (base package + compat
node-pty slot + compat runtime marker); the verifier and materializer accept it.
- node-pty slot loader falls back to the compat slot when the default slot is missing or
needs a newer glibc.
- Runtime store GC keeps the compat pin beside the default one on every relay connect.
- hasNodeSqliteReaderApi (DatabaseSync + backup) gates relay session search and the relay
OpenCode reader, which now names the host Node version in its unavailable reason; the SSH
vault reader installs the compat Node on old-glibc hosts and uploads nothing when no
pinned Node can run.
- Rung D: a remembered noexec reports home_noexec and never advises installing Node.
* fix(ssh): re-prove a replayed noexec after rung D so allowing exec recovers the host
* fix(ssh): keep the rung B compat runtime pinned in the relay-connect store GC
* test(ssh): mock deployment-target facts in the Windows OpenCode runtime tests
* ci(ssh): build the glibc 2.17 compat slot for the hostile-host matrix; CentOS 7 lands on rung B
---------
Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
Co-authored-by: m4air <m4air@Mac.localdomain>
* test(ssh): upload a root reached through a symlinked parent
The upload-root realpath fix landed with #24180; this keeps macoshost's case
where the root is passed explicitly beneath a symlinked parent.
* ci(ssh): macOS hostile-host lane on a loopback user-level sshd
Adds local-sshd cells for darwin-arm64 (macos-14) and darwin-x64
(macos-15-intel): a non-root sshd on 127.0.0.1 logs in as the runner user
with SetEnv PATH=<shims>:/usr/bin:/bin:/usr/sbin:/sbin and an empty HOME, so
no rc file restores Homebrew. The driver asserts rung A, terminal echo,
cached runtime reuse, GC keeping the in-use runtime, no toolchain or xattr
calls, and that the SFTP-uploaded Node carries no quarantine and runs as
uploaded. Docker cells are unchanged; each machine runs only cells it can host.
* test(ssh): fail a hostile-host run that would skip every named or hostable cell
A cell named for the wrong OS or arch was silently skipped, so a macOS job on a
mismatched runner went green having deployed nothing. Named cells must now be
hostable here, and a gated run must select at least one cell.
---------
Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
* fix(ssh): classify a musl host missing libstdc++ as missing_lib, not wrong_libc
musl's loader follows each missing-library line with one 'Error relocating ... symbol
not found' per unresolved symbol, and the relocation pattern was checked first. Check
missing libraries before relocation errors; the ld-linux/ld-musl interpreter case stays
wrong_libc.
* build(orcad): allow a partial deployment template for CI
build-orcad-template --targets a,b builds and verifies only the named slots, so a CI job
that can fill just the x64 Linux prebuild slots can still materialize rung A/C addons.
Without the flag every target is still built and verified.
* ci(ssh): hostile-host matrix for the relay runtime ladder
Drives the real client-side relay deploy against Docker sshd targets and asserts the
design D6 rung each lands on: Debian 10 and AlmaLinux 8 (glibc 2.28) and Alpine (musl)
on rung A; Alpine without libstdc++ refused missing_lib down to D; Ubuntu 22.04 with a
host Node 20 and a noexec home straight to D (home_noexec); CentOS 7 (glibc 2.17)
refused libc_floor at A and C, falling to a host-npm path with no Node; and a
no-egress Debian 10 still on rung A. Launched cells also prove the terminal echoes,
no npm or compiler ran, a second connect reuses the uploaded runtime, and runtime GC
keeps the in-use runtime while collecting an idle one.
New workflow ssh-hostile-hosts.yml runs on dispatch and on path-filtered PRs.
* test(ci): pin the hostile-host workflow to the headless-server builder images
The matrix builds its runtime slots in copies of the node-server lanes' Alpine
and manylinux images; this contract fails when NODE_RUNTIME_PIN or either
builder digest moves in one workflow and not the other.
* test(ssh): reconnect as the same client and retry a grace-held PTY owner in the hostile-host matrix
---------
Co-authored-by: m4air <m4air@m4airs-Air.localdomain>