SSH integration tests share one sshd user and collide under parallel jobs #27

Open
opened 2026-09-24 07:56:27 +00:00 by kayg · 11 comments
Owner

Now that several jobs run scripts/verify integration on the dev VM at the same time, the SSH tests (crates/ssh/tests/real_sshd.rs and the SSH contract gate) fail intermittently: host-trust setup errors, and the owner_loss_terminates_shell flake seen twice before.

Likely cause: every run shares the single test sshd on 127.0.0.1:2222 and the single user sshtarget, and each test run rewrites /home/sshtarget/.ssh/authorized_keys (last rewritten at 09:54 CEST today, during parallel runs). Concurrent runs overwrite each other's keys and host-key expectations.

Fix: each test run gets its own isolated SSH target: an ephemeral sshd on a random localhost port (or in a labelled throwaway container) with its own host key, its own user or AuthorizedKeysFile, and teardown. Keep real sshd (no mocks). Update scripts/provision-dev-vm if the shared target is no longer needed.

Now that several jobs run `scripts/verify integration` on the dev VM at the same time, the SSH tests (`crates/ssh/tests/real_sshd.rs` and the SSH contract gate) fail intermittently: host-trust setup errors, and the `owner_loss_terminates_shell` flake seen twice before. Likely cause: every run shares the single test `sshd` on 127.0.0.1:2222 and the single user `sshtarget`, and each test run rewrites `/home/sshtarget/.ssh/authorized_keys` (last rewritten at 09:54 CEST today, during parallel runs). Concurrent runs overwrite each other's keys and host-key expectations. Fix: each test run gets its own isolated SSH target: an ephemeral `sshd` on a random localhost port (or in a labelled throwaway container) with its own host key, its own user or `AuthorizedKeysFile`, and teardown. Keep real sshd (no mocks). Update `scripts/provision-dev-vm` if the shared target is no longer needed.
Author
Owner

Starting work in /home/kayg/wt/ssh-test-isolation on branch ssh-test-isolation, based on dev at 7bda001e5bd8ff42c3768fb1e6cbba317d22789e.

I will isolate every SSH test and benchmark behind a real per-run local sshd, identify the acknowledgement timeout's cause, remove the shared sshtarget fixture if no other consumer remains, and run the requested concurrent SSH suite plus verification gates.

Starting work in `/home/kayg/wt/ssh-test-isolation` on branch `ssh-test-isolation`, based on `dev` at `7bda001e5bd8ff42c3768fb1e6cbba317d22789e`. I will isolate every SSH test and benchmark behind a real per-run local `sshd`, identify the acknowledgement timeout's cause, remove the shared `sshtarget` fixture if no other consumer remains, and run the requested concurrent SSH suite plus verification gates.
Author
Owner

Research and fixture decision:

  • Choose a foreground per-test sshd -D -f <private config> on a random loopback port. On this Debian 13 VM, I ran it as uid 1001 (kayg) without sudo. A generated per-run host key and per-run AuthorizedKeysFile authenticated a real SSH command as kayg, with UsePAM no and StrictModes yes.
  • OpenSSH's Debian trixie sshd_config(5) explicitly says UsePAM yes prevents running sshd as non-root; it documents StrictModes and AuthorizedKeysFile: https://manpages.debian.org/trixie/openssh-server/sshd_config.5.en.html. sshd(8) documents foreground -D and per-server key/config options: https://manpages.debian.org/trixie/openssh-server/sshd.8.en.html.
  • A second real-daemon attempt to log in as sshtarget failed with Failed to set uids to 30033, while the daemon ran as uid 1001. An unprivileged daemon can serve the test process's own login UID, so tests and benches will use that account. StrictModes yes rejects an authorized-keys path under world-writable /tmp; the per-run directory must be placed under a user-owned, non-writable parent such as the test user's home.
  • This avoids requiring Docker/Podman for the SSH contract test and starts OpenSSH directly. Rootless Podman does support labels and random published ports, but would add a container runtime dependency and container startup/cleanup to this test: https://docs.podman.io/en/latest/markdown/podman-run.1.html.
Research and fixture decision: - Choose a foreground per-test `sshd -D -f <private config>` on a random loopback port. On this Debian 13 VM, I ran it as uid 1001 (`kayg`) without sudo. A generated per-run host key and per-run `AuthorizedKeysFile` authenticated a real SSH command as `kayg`, with `UsePAM no` and `StrictModes yes`. - OpenSSH's Debian trixie `sshd_config(5)` explicitly says `UsePAM yes` prevents running `sshd` as non-root; it documents `StrictModes` and `AuthorizedKeysFile`: https://manpages.debian.org/trixie/openssh-server/sshd_config.5.en.html. `sshd(8)` documents foreground `-D` and per-server key/config options: https://manpages.debian.org/trixie/openssh-server/sshd.8.en.html. - A second real-daemon attempt to log in as `sshtarget` failed with `Failed to set uids to 30033`, while the daemon ran as uid 1001. An unprivileged daemon can serve the test process's own login UID, so tests and benches will use that account. `StrictModes yes` rejects an authorized-keys path under world-writable `/tmp`; the per-run directory must be placed under a user-owned, non-writable parent such as the test user's home. - This avoids requiring Docker/Podman for the SSH contract test and starts OpenSSH directly. Rootless Podman does support labels and random published ports, but would add a container runtime dependency and container startup/cleanup to this test: https://docs.podman.io/en/latest/markdown/podman-run.1.html.
Author
Owner

The new unprivileged sshd exposed a runner-specific PTY issue: the SSH test logs in as the current user, whose interactive .bashrc starts Zellij. The shell command was echoed, then Zellij took over the terminal; owner_loss_terminates_shell timed out waiting for 24 80 without any timeout change. Adding ForceCommand /bin/bash --noprofile --norc and disabling the MOTD gives the test a clean shell. The focused owner-loss test now passes in 1.19s with the existing deadline. This is separate from the shared authorized-keys race the isolation change removes.

The new unprivileged sshd exposed a runner-specific PTY issue: the SSH test logs in as the current user, whose interactive `.bashrc` starts Zellij. The shell command was echoed, then Zellij took over the terminal; `owner_loss_terminates_shell` timed out waiting for `24 80` without any timeout change. Adding `ForceCommand /bin/bash --noprofile --norc` and disabling the MOTD gives the test a clean shell. The focused owner-loss test now passes in 1.19s with the existing deadline. This is separate from the shared authorized-keys race the isolation change removes.
Author
Owner

Concurrency evidence: launched four independent real_sshd test-binary processes together (PIDs 275699, 275700, 275701, 275702), each with --ignored --nocapture --test-threads=1. All exited 0:

  • run 1: test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 16.24s
  • run 2: test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 16.52s
  • run 3: test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 16.02s
  • run 4: test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 16.36s
Concurrency evidence: launched four independent `real_sshd` test-binary processes together (PIDs 275699, 275700, 275701, 275702), each with `--ignored --nocapture --test-threads=1`. All exited 0: - run 1: `test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 16.24s` - run 2: `test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 16.52s` - run 3: `test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 16.02s` - run 4: `test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 16.36s`
Author
Owner

Review follow-up evidence and decisions:

  • OpenSSH PTY sessions call setsid(), so the test daemon's original process group cannot clean them up. TestSshd::drop now stops/reaps the listener first and repeatedly sweeps per-run SetEnv markers so no new detached session can escape the scan. Each signal uses pidfd_open/pidfd_send_signal after rechecking the process start time and marker; this avoids the check-to-killpg PID reuse window. See the OpenSSH PTY setup source: https://github.com/openssh/openssh-portable/blob/master/sshpty.c and Rustix process API: https://docs.rs/rustix/latest/rustix/process/fn.pidfd_send_signal.html
  • ssh.socket can bind port 22 independently of sshd_config. Provisioning now masks it before OpenSSH package installation and verifies the service is inactive afterward. The temporary loopback-only config protects a service-start during package setup.
  • Added targeted coverage for stale-run cleanup and an ignored real-sshd test that proves dropping a daemon terminates its detached PTY shell.
Review follow-up evidence and decisions: - OpenSSH PTY sessions call `setsid()`, so the test daemon's original process group cannot clean them up. `TestSshd::drop` now stops/reaps the listener first and repeatedly sweeps per-run `SetEnv` markers so no new detached session can escape the scan. Each signal uses `pidfd_open`/`pidfd_send_signal` after rechecking the process start time and marker; this avoids the check-to-`killpg` PID reuse window. See the OpenSSH PTY setup source: https://github.com/openssh/openssh-portable/blob/master/sshpty.c and Rustix process API: https://docs.rs/rustix/latest/rustix/process/fn.pidfd_send_signal.html - `ssh.socket` can bind port 22 independently of `sshd_config`. Provisioning now masks it before OpenSSH package installation and verifies the service is inactive afterward. The temporary loopback-only config protects a service-start during package setup. - Added targeted coverage for stale-run cleanup and an ignored real-sshd test that proves dropping a daemon terminates its detached PTY shell.
Author
Owner

Finding from the first four-process run: one process failed pty_resize_and_replay at assert!(replayed.gap()); its other 11 tests passed. The test slept for one second after sending 2 MiB and could assert before the output had crossed the 1 MiB replay limit under concurrent VM load. Replaced the sleep with a completion file written by the real remote shell after the 2 MiB stream; the test still does not drain PTY output before checking the replay gap. Targeted rerun passed: 1 passed; 0 failed; finished in 3.62s. I will repeat the four-process proof after the full gates.

Finding from the first four-process run: one process failed `pty_resize_and_replay` at `assert!(replayed.gap())`; its other 11 tests passed. The test slept for one second after sending 2 MiB and could assert before the output had crossed the 1 MiB replay limit under concurrent VM load. Replaced the sleep with a completion file written by the real remote shell after the 2 MiB stream; the test still does not drain PTY output before checking the replay gap. Targeted rerun passed: `1 passed; 0 failed; finished in 3.62s`. I will repeat the four-process proof after the full gates.
Author
Owner

Second replay-test finding: after the remote command completed, the SSH client could still be publishing buffered PTY output. Reattaching from offset 0 queued a full replay window plus live output; under four simultaneous suites the new consumer was correctly terminated as slow_consumer before reaching the marker. The test now waits until the SSH stream has produced 2 MiB, reattaches at that tail offset to consume the completion marker, then separately attaches from offset 0 to assert the replay gap. All four concurrent test-binary processes passed: each reported 12 passed; 0 failed (16.15s, 16.66s, 16.59s, 16.50s).

Second replay-test finding: after the remote command completed, the SSH client could still be publishing buffered PTY output. Reattaching from offset 0 queued a full replay window plus live output; under four simultaneous suites the new consumer was correctly terminated as `slow_consumer` before reaching the marker. The test now waits until the SSH stream has produced 2 MiB, reattaches at that tail offset to consume the completion marker, then separately attaches from offset 0 to assert the replay gap. All four concurrent test-binary processes passed: each reported `12 passed; 0 failed` (16.15s, 16.66s, 16.59s, 16.50s).
Author
Owner

Finished on ssh-test-isolation, head 855fbe6cb1e3e2969f5cca4719d15b6869635830 (base 7bda001e5bd8ff42c3768fb1e6cbba317d22789e).

Approach. Each SSH test run starts a real foreground sshd -D on an ephemeral loopback port, with a private host key, AuthorizedKeysFile, config and log in a temp directory. It uses UsePAM no and StrictModes yes. The parent owns teardown; Drop stops the listener and sweeps detached test processes, and suite startup removes stale marked processes. An unprivileged sshd can serve the process owner's UID, but cannot switch to a different login UID, so this isolates the test runner's account. I chose it over a container because it uses the installed OpenSSH binary directly and needs no container engine or image. See Debian sshd(8) for foreground mode and Debian sshd_config(5) for the PAM, authorized-keys and strict-mode settings.

owner_loss_terminates_shell was timing out because the runner's interactive .bashrc starts Zellij and hijacks the PTY. The isolated server uses ForceCommand /bin/bash --noprofile --norc; the test passes with its original timeout. No production SSH behavior changed. The shared sshtarget fixture was removed from scripts/provision-dev-vm; no SSH test or benchmark uses it.

Four concurrent SSH suites: all four processes exited 0, with 12 passed and 0 failed each:

run 1 exit=0: test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 16.15s
run 2 exit=0: test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 16.66s
run 3 exit=0: test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 16.59s
run 4 exit=0: test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 16.50s

scripts/verify fast output:

PASS fast: migrations are append-only
PASS fast: JavaScript dependencies
PASS fast: build web app
PASS fast: cargo fmt --check
PASS fast: cargo clippy
PASS fast: cargo test
PASS fast: svelte-check
PASS fast: UI package svelte-check
PASS fast: stream package typecheck
PASS fast: Vitest
PASS fast: UI package Vitest
PASS fast: stream package Vitest
PASS fast: OpenAPI and TypeScript client drift
PASS fast: terminal TypeScript
PASS fast: terminal Vitest

scripts/verify integration output:

PASS integration: JavaScript dependencies
PASS integration: build web app
PASS integration: build release binary
PASS integration: real HTTP behavior
PASS integration: Docker socket _ping
PASS integration: rootless Podman socket _ping
PASS integration: engine adapters against Docker and Podman
PASS integration: TypeScript stream client against Docker and Podman
PASS integration: stream authorization and CLOSE regressions against Docker
PASS integration: persistent PTY termination preempts blocked send
PASS integration: resource HTTP API against Docker and rootless Podman
PASS integration: compiled CLI and MCP against real server and engines
PASS integration: SSH contract against isolated real sshd

No push; issue remains open.

Finished on `ssh-test-isolation`, head `855fbe6cb1e3e2969f5cca4719d15b6869635830` (base `7bda001e5bd8ff42c3768fb1e6cbba317d22789e`). **Approach.** Each SSH test run starts a real foreground `sshd -D` on an ephemeral loopback port, with a private host key, `AuthorizedKeysFile`, config and log in a temp directory. It uses `UsePAM no` and `StrictModes yes`. The parent owns teardown; Drop stops the listener and sweeps detached test processes, and suite startup removes stale marked processes. An unprivileged `sshd` can serve the process owner's UID, but cannot switch to a different login UID, so this isolates the test runner's account. I chose it over a container because it uses the installed OpenSSH binary directly and needs no container engine or image. See [Debian sshd(8)](https://manpages.debian.org/trixie/openssh-server/sshd.8.en.html) for foreground mode and [Debian sshd_config(5)](https://manpages.debian.org/trixie/openssh-server/sshd_config.5.en.html) for the PAM, authorized-keys and strict-mode settings. `owner_loss_terminates_shell` was timing out because the runner's interactive `.bashrc` starts Zellij and hijacks the PTY. The isolated server uses `ForceCommand /bin/bash --noprofile --norc`; the test passes with its original timeout. No production SSH behavior changed. The shared `sshtarget` fixture was removed from `scripts/provision-dev-vm`; no SSH test or benchmark uses it. **Four concurrent SSH suites:** all four processes exited 0, with 12 passed and 0 failed each: ```text run 1 exit=0: test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 16.15s run 2 exit=0: test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 16.66s run 3 exit=0: test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 16.59s run 4 exit=0: test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 16.50s ``` **`scripts/verify fast` output:** ```text PASS fast: migrations are append-only PASS fast: JavaScript dependencies PASS fast: build web app PASS fast: cargo fmt --check PASS fast: cargo clippy PASS fast: cargo test PASS fast: svelte-check PASS fast: UI package svelte-check PASS fast: stream package typecheck PASS fast: Vitest PASS fast: UI package Vitest PASS fast: stream package Vitest PASS fast: OpenAPI and TypeScript client drift PASS fast: terminal TypeScript PASS fast: terminal Vitest ``` **`scripts/verify integration` output:** ```text PASS integration: JavaScript dependencies PASS integration: build web app PASS integration: build release binary PASS integration: real HTTP behavior PASS integration: Docker socket _ping PASS integration: rootless Podman socket _ping PASS integration: engine adapters against Docker and Podman PASS integration: TypeScript stream client against Docker and Podman PASS integration: stream authorization and CLOSE regressions against Docker PASS integration: persistent PTY termination preempts blocked send PASS integration: resource HTTP API against Docker and rootless Podman PASS integration: compiled CLI and MCP against real server and engines PASS integration: SSH contract against isolated real sshd ``` No push; issue remains open.
Author
Owner

Starting independent review and verification on branch ssh-test-isolation, worktree /home/kayg/wt/ssh-test-isolation, at head 855fbe6cb1e3e2969f5cca4719d15b6869635830 (job base 7bda001e5bd8ff42c3768fb1e6cbba317d22789e). Fetched current dev at d4d16de95dfe5c2519c48cb251bcf086305268da; merging it before review as requested. I will check isolated real-sshd runs, strict host-key behavior, shell setup, all sshtarget references, then run scripts/verify fast and scripts/verify integration.

Starting independent review and verification on branch `ssh-test-isolation`, worktree `/home/kayg/wt/ssh-test-isolation`, at head `855fbe6cb1e3e2969f5cca4719d15b6869635830` (job base `7bda001e5bd8ff42c3768fb1e6cbba317d22789e`). Fetched current `dev` at `d4d16de95dfe5c2519c48cb251bcf086305268da`; merging it before review as requested. I will check isolated real-sshd runs, strict host-key behavior, shell setup, all `sshtarget` references, then run `scripts/verify fast` and `scripts/verify integration`.
Author
Owner

SSH test review — #27

Branch ssh-test-isolation, final head fc3717b743d46f33ce610955d86e81ca82a76bcd. Merged current origin/dev at f1bedf994ce5399cf4b53ff0ca693ff0db4cfb9d. No push.

  1. PASS — Isolation. Six concurrent full SSH suites each exited 0 with 15 passed; 0 failed; the contended run began at one-minute load 12.07. Six simultaneously held fixtures had six distinct ports, host-key fingerprints and private authorized_keys paths (mode 0600). After SIGKILLing all six fixture owners, no fixture directory or matching sshd listener remained. The regular successful suites also left no run directories or listeners. The SIGKILL leak found during review was fixed in 54af6d685dab2e28781e6326ac72db5439586667, with a regression test.
  2. PASS — Real sshd and host-key checking. Tests run /usr/sbin/sshd (OpenSSH_10.0p2 Debian-7+deb13u4). strict_host_key_change passed in all six suites: after trusting the first server key, a second real server on the same port with a different host key is refused as HostKeyMismatch.
  3. PASS — Clean-shell test setup. The test-only ForceCommand /bin/bash --noprofile --norc controls shell startup while retaining real OpenSSH, authentication, host-key checks and PTY behavior. owner_loss_terminates_shell passed in all six suites. Product SSH sessions request a PTY and the user's shell, with no startup suppression. A user's shell startup file that launches Zellij can take over that PTY; track this as a later product issue, not a test defect. OpenSSH ForceCommand, Bash startup files.
  4. PASS — Provisioning. Repository search found no sshtarget, 127.0.0.1:2222 or localhost:2222 references.
  5. FAIL — Gates. scripts/verify integration passed all 13 steps, including isolated real sshd. scripts/verify fast failed twice in unchanged packages/stream: both runs failed the 4108 close-code assertion; the first also failed the 1008 burst-close assertion. git diff origin/dev -- packages/stream is empty. [blocks-merge] The required fast gate is still red on this branch due to that existing stream test failure; no stream files were changed in this SSH-scoped job.

Gate output

fast (second run; output lines quoted verbatim):

PASS fast: migrations are append-only
PASS fast: JavaScript dependencies
PASS fast: build web app
PASS fast: cargo fmt --check
PASS fast: cargo clippy
PASS fast: cargo test
PASS fast: svelte-check
PASS fast: UI package svelte-check
PASS fast: stream package typecheck
PASS fast: Vitest
PASS fast: UI package Vitest
FAIL fast: stream package Vitest
$ vitest run

 RUN  v5.0.1 /home/kayg/wt/ssh-test-isolation/packages/stream

 ❯ src/client_protocol_failures.test.ts (49 tests | 1 failed) 292ms
   ❯ review-stream protocol regressions (49)
     × maps a browser policy close without throwing from onmessage 20ms

 FAIL  src/client_protocol_failures.test.ts > review-stream protocol regressions > maps a browser policy close without throwing from onmessage
AssertionError: expected undefined to be 4108 // Object.is equality

- Expected:
4108

+ Received:
undefined

 ❯ src/client_protocol_failures.test.ts:222:30
    220|     const socket = FakeSocket.instances.at(-1)!;
    221|     for (let index = 0; index < 401; index += 1) socket.receive(encode…
    222|     expect(socket.closeCode).toBe(4108);
       |                              ^
    223|   });
    224|

 Test Files  1 failed | 2 passed (3)
      Tests  1 failed | 61 passed (62)
   Start at  13:53:02
   Duration  797ms (transform 55%, tests 36%, import 7%, worker 1%)

error: script "test" exited with code 1

integration (output lines quoted verbatim):

PASS integration: JavaScript dependencies
PASS integration: build web app
PASS integration: build release binary
PASS integration: real HTTP behavior
PASS integration: Docker socket _ping
PASS integration: rootless Podman socket _ping
PASS integration: engine adapters against Docker and Podman
PASS integration: TypeScript stream client against Docker and Podman
PASS integration: stream authorization and CLOSE regressions against Docker
PASS integration: persistent PTY termination preempts blocked send
PASS integration: resource HTTP API against Docker and rootless Podman
PASS integration: compiled CLI and MCP against real server and engines
PASS integration: SSH contract against isolated real sshd
## SSH test review — #27 Branch `ssh-test-isolation`, final head `fc3717b743d46f33ce610955d86e81ca82a76bcd`. Merged current `origin/dev` at `f1bedf994ce5399cf4b53ff0ca693ff0db4cfb9d`. No push. 1. **PASS — Isolation.** Six concurrent full SSH suites each exited 0 with `15 passed; 0 failed`; the contended run began at one-minute load 12.07. Six simultaneously held fixtures had six distinct ports, host-key fingerprints and private `authorized_keys` paths (mode `0600`). After SIGKILLing all six fixture owners, no fixture directory or matching `sshd` listener remained. The regular successful suites also left no run directories or listeners. The SIGKILL leak found during review was fixed in `54af6d685dab2e28781e6326ac72db5439586667`, with a regression test. 2. **PASS — Real sshd and host-key checking.** Tests run `/usr/sbin/sshd` (`OpenSSH_10.0p2 Debian-7+deb13u4`). `strict_host_key_change` passed in all six suites: after trusting the first server key, a second real server on the same port with a different host key is refused as `HostKeyMismatch`. 3. **PASS — Clean-shell test setup.** The test-only `ForceCommand /bin/bash --noprofile --norc` controls shell startup while retaining real OpenSSH, authentication, host-key checks and PTY behavior. `owner_loss_terminates_shell` passed in all six suites. Product SSH sessions request a PTY and the user's shell, with no startup suppression. A user's shell startup file that launches Zellij can take over that PTY; track this as a **later product issue**, not a test defect. [OpenSSH ForceCommand](https://man.openbsd.org/sshd_config#ForceCommand), [Bash startup files](https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html). 4. **PASS — Provisioning.** Repository search found no `sshtarget`, `127.0.0.1:2222` or `localhost:2222` references. 5. **FAIL — Gates.** `scripts/verify integration` passed all 13 steps, including isolated real sshd. `scripts/verify fast` failed twice in unchanged `packages/stream`: both runs failed the 4108 close-code assertion; the first also failed the 1008 burst-close assertion. `git diff origin/dev -- packages/stream` is empty. **[blocks-merge]** The required fast gate is still red on this branch due to that existing stream test failure; no stream files were changed in this SSH-scoped job. ### Gate output `fast` (second run; output lines quoted verbatim): ```text PASS fast: migrations are append-only PASS fast: JavaScript dependencies PASS fast: build web app PASS fast: cargo fmt --check PASS fast: cargo clippy PASS fast: cargo test PASS fast: svelte-check PASS fast: UI package svelte-check PASS fast: stream package typecheck PASS fast: Vitest PASS fast: UI package Vitest FAIL fast: stream package Vitest $ vitest run RUN v5.0.1 /home/kayg/wt/ssh-test-isolation/packages/stream ❯ src/client_protocol_failures.test.ts (49 tests | 1 failed) 292ms ❯ review-stream protocol regressions (49) × maps a browser policy close without throwing from onmessage 20ms FAIL src/client_protocol_failures.test.ts > review-stream protocol regressions > maps a browser policy close without throwing from onmessage AssertionError: expected undefined to be 4108 // Object.is equality - Expected: 4108 + Received: undefined ❯ src/client_protocol_failures.test.ts:222:30 220| const socket = FakeSocket.instances.at(-1)!; 221| for (let index = 0; index < 401; index += 1) socket.receive(encode… 222| expect(socket.closeCode).toBe(4108); | ^ 223| }); 224| Test Files 1 failed | 2 passed (3) Tests 1 failed | 61 passed (62) Start at 13:53:02 Duration 797ms (transform 55%, tests 36%, import 7%, worker 1%) error: script "test" exited with code 1 ``` `integration` (output lines quoted verbatim): ```text PASS integration: JavaScript dependencies PASS integration: build web app PASS integration: build release binary PASS integration: real HTTP behavior PASS integration: Docker socket _ping PASS integration: rootless Podman socket _ping PASS integration: engine adapters against Docker and Podman PASS integration: TypeScript stream client against Docker and Podman PASS integration: stream authorization and CLOSE regressions against Docker PASS integration: persistent PTY termination preempts blocked send PASS integration: resource HTTP API against Docker and rootless Podman PASS integration: compiled CLI and MCP against real server and engines PASS integration: SSH contract against isolated real sshd ```
Author
Owner

Orchestrator: merged to dev at ba5f99c and pushed. The merged tree is identical to the reviewed head fc3717b. Gates: integration 13/13 (from the review); fast 15/15 on two re-runs, after the review's red fast came from the known flaky stream Vitest case (#31). The product follow-up is #32 (a user rc file starting a multiplexer, for 14b).

Orchestrator: **merged to `dev` at `ba5f99c`** and pushed. The merged tree is identical to the reviewed head `fc3717b`. Gates: integration 13/13 (from the review); fast 15/15 on two re-runs, after the review's red `fast` came from the known flaky stream Vitest case (#31). The product follow-up is #32 (a user rc file starting a multiplexer, for 14b).
Commenting is not possible because the repository is archived.
No labels
No milestone
No project
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/infraternal-v0#27
No description provided.