chore(nests): mv cli/hang-interop → nestsClient/tests/hang-interop
Per maintainer request: the Rust sidecar workspace lives under the module that owns it, parallel to the upcoming nestsClient-browser-interop/ harness. The cargo workspace, Gradle wiring, gitignore, CI YAML, plan docs, and harness kdoc are all updated. cargo build --release still compiles; HangInteropTest.amethyst_speaker_to_hang_listener_stereo_440_660 green at the new path. Note: the live Phase 4 browser-harness agent (worktree agent-a97a6be483ecee618) was branched from before this move and references `cli/hang-interop` in its plan-doc imports. It will need to rebase onto this commit before it pushes; no code-level conflicts since the agent works exclusively in nestsClient-browser-interop/ + a new BrowserInteropTest.kt. https://claude.ai/code/session_01ERJPUYfdLPwZ99pr5EcEcV
This commit is contained in:
@@ -107,13 +107,13 @@ the spec, and the concrete pickup points for Phase 2.
|
||||
|
||||
## What landed
|
||||
|
||||
### Cargo workspace (`cli/hang-interop/`)
|
||||
### Cargo workspace (`nestsClient/tests/hang-interop/`)
|
||||
|
||||
- Workspace with three binary crates: `hang-listen`, `hang-publish`,
|
||||
`udp-loss-shim`. **All three are Phase-1 stubs** — they parse their
|
||||
CLI flags via `clap`, print a banner, and exit 0. Phase 2 fills the
|
||||
bodies.
|
||||
- `cli/hang-interop/REV` documents the pinned upstream
|
||||
- `nestsClient/tests/hang-interop/REV` documents the pinned upstream
|
||||
`kixelated/moq` rev (`9e2461ee...`) plus the published crate
|
||||
versions on crates.io that track that rev (`moq-relay 0.10.25`,
|
||||
`moq-token-cli 0.5.23`, `hang 0.15.8`, `moq-lite 0.15.15`,
|
||||
@@ -128,7 +128,7 @@ the spec, and the concrete pickup points for Phase 2.
|
||||
the binary already exists in the cache.
|
||||
- `interopInstallMoqTokenCli` — same shape for `moq-token-cli`.
|
||||
- `interopBuildSidecars` — `cargo build --release` over the local
|
||||
`cli/hang-interop/` workspace.
|
||||
`nestsClient/tests/hang-interop/` workspace.
|
||||
- `interopBuildHangSidecars` — umbrella task that depends on the
|
||||
three above. Runs as a test dependency only when
|
||||
`-DnestsHangInterop=true` is set.
|
||||
@@ -210,7 +210,7 @@ rendition with `container.kind == "legacy"` and
|
||||
`Bytes`-encoded VarInt timestamp + Opus packet, run the Opus
|
||||
packets through `audiopus::Decoder`, write Float32 PCM to
|
||||
`--output-pcm`. Dependencies to add to
|
||||
`cli/hang-interop/hang-listen/Cargo.toml`:
|
||||
`nestsClient/tests/hang-interop/hang-listen/Cargo.toml`:
|
||||
|
||||
```toml
|
||||
hang = "0.15"
|
||||
@@ -297,7 +297,7 @@ the smoke test.
|
||||
## Files
|
||||
|
||||
```
|
||||
cli/hang-interop/
|
||||
nestsClient/tests/hang-interop/
|
||||
├── REV
|
||||
├── Cargo.toml + Cargo.lock
|
||||
├── hang-listen/{Cargo.toml,src/main.rs} # Phase 2: real subscribe + decode
|
||||
|
||||
@@ -90,7 +90,7 @@ git rev. Cached.
|
||||
rev. Use the same rev as the production `nostrnests/nests` Docker
|
||||
image's `moq-relay` build, if discoverable; otherwise pin to the
|
||||
latest commit on `main` at implementation time and document it in a
|
||||
`cli/hang-interop/REV` file.
|
||||
`nestsClient/tests/hang-interop/REV` file.
|
||||
- Build: `cargo build --release -p moq-relay --manifest-path <pinned/checkout>/Cargo.toml`.
|
||||
- Cache key: pinned rev sha. First run: ~30 s cold build. Warm: < 1 s.
|
||||
- Config (rendered to a temp file at test setup):
|
||||
@@ -140,10 +140,10 @@ self-signed cert without populating the system trust store.
|
||||
|
||||
### Rust hang sidecar binaries
|
||||
|
||||
New cargo workspace at `cli/hang-interop/` in this repo.
|
||||
New cargo workspace at `nestsClient/tests/hang-interop/` in this repo.
|
||||
|
||||
```toml
|
||||
# cli/hang-interop/Cargo.toml
|
||||
# nestsClient/tests/hang-interop/Cargo.toml
|
||||
[workspace]
|
||||
members = ["hang-listen", "hang-publish", "udp-loss-shim"]
|
||||
|
||||
@@ -157,7 +157,7 @@ anyhow = "1"
|
||||
|
||||
Three binaries:
|
||||
|
||||
#### `hang-listen` — `cli/hang-interop/hang-listen/src/main.rs`
|
||||
#### `hang-listen` — `nestsClient/tests/hang-interop/hang-listen/src/main.rs`
|
||||
Args: `--relay-url <https://...>` `--jwt <token>` `--broadcast <path>` `--duration <secs>` `--output-pcm <path-or-->`.
|
||||
Behaviour:
|
||||
1. Connect to relay via `web-transport-quinn` with WT-Available-Protocols
|
||||
@@ -176,7 +176,7 @@ Output format: little-endian Float32 PCM, no header. One channel for
|
||||
mono, interleaved L/R for stereo (controlled by catalog's
|
||||
`numberOfChannels`). The Gradle test reads this file or pipe.
|
||||
|
||||
#### `hang-publish` — `cli/hang-interop/hang-publish/src/main.rs`
|
||||
#### `hang-publish` — `nestsClient/tests/hang-interop/hang-publish/src/main.rs`
|
||||
Args: `--relay-url <...>` `--jwt <token>` `--broadcast <path>` `--freq-hz <int>` `--duration <secs>` `--channels <1|2>`.
|
||||
Behaviour:
|
||||
1. Connect, open session, claim broadcast under given path.
|
||||
@@ -189,7 +189,7 @@ Behaviour:
|
||||
opus_packet`, push into groups of 5 frames, FIN per group.
|
||||
4. Run for `duration` seconds, then send `Announce::Ended` and exit.
|
||||
|
||||
#### `udp-loss-shim` — `cli/hang-interop/udp-loss-shim/src/main.rs`
|
||||
#### `udp-loss-shim` — `nestsClient/tests/hang-interop/udp-loss-shim/src/main.rs`
|
||||
Args: `--listen 127.0.0.1:<port>` `--upstream 127.0.0.1:<port>` `--loss-rate <0..1>`.
|
||||
Behaviour: standard tokio UDP relay. For each datagram received,
|
||||
`if rng.gen::<f32>() < loss_rate { drop }` else forward. Used for I9.
|
||||
@@ -503,15 +503,15 @@ Total: ~5 days. P0 deliverable (1+2+4) is **3 days**.
|
||||
|
||||
### Phase 1 — Native moq-relay + Rust sidecars (1 day)
|
||||
|
||||
1. Pick `kixelated/moq` rev. Clone to `cli/hang-interop/.cache/moq` or
|
||||
1. Pick `kixelated/moq` rev. Clone to `nestsClient/tests/hang-interop/.cache/moq` or
|
||||
reference via `git` Cargo source. Document rev in
|
||||
`cli/hang-interop/REV`.
|
||||
2. Write `cli/hang-interop/Cargo.toml` workspace + the three binary
|
||||
`nestsClient/tests/hang-interop/REV`.
|
||||
2. Write `nestsClient/tests/hang-interop/Cargo.toml` workspace + the three binary
|
||||
crates (`hang-listen`, `hang-publish`, `udp-loss-shim`). Verify
|
||||
`cargo build --release` succeeds end-to-end.
|
||||
3. Add Gradle task `interopBuildHangSidecars` (in
|
||||
`nestsClient/build.gradle.kts`) that:
|
||||
- Runs `cargo build --release` in `cli/hang-interop/`.
|
||||
- Runs `cargo build --release` in `nestsClient/tests/hang-interop/`.
|
||||
- Exposes binary paths to JVM tests via `tasks.test { systemProperty(...) }`.
|
||||
- Caches based on `Cargo.lock` hash.
|
||||
4. Write `NativeMoqRelayHarness.kt` (subprocess management, JWT mint,
|
||||
@@ -603,8 +603,8 @@ jobs:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
cli/hang-interop/target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('cli/hang-interop/Cargo.lock') }}
|
||||
nestsClient/tests/hang-interop/target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('nestsClient/tests/hang-interop/Cargo.lock') }}
|
||||
- run: ./gradlew :nestsClient:jvmTest -DnestsHangInterop=true
|
||||
|
||||
browser-interop:
|
||||
@@ -619,7 +619,7 @@ jobs:
|
||||
~/.cargo/registry
|
||||
~/.cache/ms-playwright
|
||||
nestsClient-browser-interop/node_modules
|
||||
key: ${{ runner.os }}-browser-${{ hashFiles('nestsClient-browser-interop/bun.lockb', 'cli/hang-interop/Cargo.lock') }}
|
||||
key: ${{ runner.os }}-browser-${{ hashFiles('nestsClient-browser-interop/bun.lockb', 'nestsClient/tests/hang-interop/Cargo.lock') }}
|
||||
- run: ./gradlew :nestsClient:jvmTest -DnestsBrowserInterop=true
|
||||
```
|
||||
|
||||
@@ -640,7 +640,7 @@ Acceptable for PR-level CI.
|
||||
|
||||
| Risk | Mitigation |
|
||||
|---|---|
|
||||
| `kixelated/moq` HEAD breaks pin | Pin git rev in `cli/hang-interop/Cargo.toml` + REV file. Bump deliberately. |
|
||||
| `kixelated/moq` HEAD breaks pin | Pin git rev in `nestsClient/tests/hang-interop/Cargo.toml` + REV file. Bump deliberately. |
|
||||
| moq-relay config schema changes between revs | Pin rev. Document `relay.toml` fields used. Smoke test: boot relay, assert known broadcast lookup works, in `@BeforeAll`. |
|
||||
| Self-signed cert + Chromium WebTransport rejection | Use `--ignore-certificate-errors-spki-list` (preferred) or `--ignore-certificate-errors` for test-only Chromium instance. |
|
||||
| JVM Opus encoder/decoder availability | If `:nestsClient` JVM target lacks Opus, vendor `audiopus` JNI or write a small wrapper. Reuse `MediaCodecOpusEncoder`/`Decoder` if a JVM `MediaCodec` polyfill exists; otherwise pure-Java `concentus` library is a fallback. Decide at Phase 1. |
|
||||
@@ -664,7 +664,7 @@ Acceptable for PR-level CI.
|
||||
committed at `nestsClient/plans/2026-05-06-cross-stack-interop-test-gap-matrix.md`.
|
||||
6. Both `-DnestsHangInterop=true` and `-DnestsBrowserInterop=true`
|
||||
in the default PR-level GitHub Actions config.
|
||||
7. `cli/hang-interop/REV` and `nestsClient-browser-interop/REV`
|
||||
7. `nestsClient/tests/hang-interop/REV` and `nestsClient-browser-interop/REV`
|
||||
document the pinned upstream revs.
|
||||
8. New plan filed at
|
||||
`nestsClient/plans/2026-05-06-cross-stack-interop-test-results.md`
|
||||
|
||||
@@ -192,14 +192,14 @@ FFT assertion on each. ZCR can be done the same way.
|
||||
### `hang-listen` already supports stereo
|
||||
|
||||
Verify by reading the existing
|
||||
`cli/hang-interop/hang-listen/src/main.rs`: it already passes
|
||||
`nestsClient/tests/hang-interop/hang-listen/src/main.rs`: it already passes
|
||||
`audio_cfg.channel_count` into `opus::Decoder::new(...)` and
|
||||
allocates a stereo PCM buffer if the catalog says so. No Rust
|
||||
change needed.
|
||||
|
||||
### `hang-publish` already supports stereo
|
||||
|
||||
Verify by reading `cli/hang-interop/hang-publish/src/main.rs`:
|
||||
Verify by reading `nestsClient/tests/hang-interop/hang-publish/src/main.rs`:
|
||||
the `--channels <1|2>` flag plumbs through to the catalog, the
|
||||
opus encoder, and the sine generator. No Rust change needed.
|
||||
*(Note: the current sine generator uses the same frequency on
|
||||
|
||||
@@ -104,7 +104,7 @@ nestsClient-browser-interop/
|
||||
Pin all `@moq/*` deps to the same versions `nostrnests/nests`
|
||||
ships in `NestsUI-v2/package.json`. Document the rev in
|
||||
`nestsClient-browser-interop/REV` (parallel to
|
||||
`cli/hang-interop/REV`).
|
||||
`nestsClient/tests/hang-interop/REV`).
|
||||
|
||||
### 2. `listen.ts` — browser listener
|
||||
|
||||
|
||||
Reference in New Issue
Block a user