From 231fbbaa6162d5053f530ffecfdeab350990880b Mon Sep 17 00:00:00 2001 From: Threepwood-7 Date: Thu, 15 Oct 2026 08:16:08 +0200 Subject: [PATCH] RUST-BUG-001: record Kad swarm gate completion --- docs/products/emulebb-rust/active/INDEX.md | 1 - .../emulebb-rust/active/items/RUST-BUG-001.md | 95 --------------- .../history/items/RUST-BUG-001.md | 110 ++++++++++++++++++ 3 files changed, 110 insertions(+), 96 deletions(-) delete mode 100644 docs/products/emulebb-rust/active/items/RUST-BUG-001.md create mode 100644 docs/products/emulebb-rust/history/items/RUST-BUG-001.md diff --git a/docs/products/emulebb-rust/active/INDEX.md b/docs/products/emulebb-rust/active/INDEX.md index a311db3d..780ca48b 100644 --- a/docs/products/emulebb-rust/active/INDEX.md +++ b/docs/products/emulebb-rust/active/INDEX.md @@ -46,7 +46,6 @@ reused. Parked ideas are not backlog items until explicitly activated. | ID | Class | Title | |---|---|---| -| [RUST-BUG-001](items/RUST-BUG-001.md) | Bug | Eliminate kad_swarm CI isolation debt | | [RUST-FEAT-025](items/RUST-FEAT-025.md) | Feature | Validate conformant duplicate-block rejection diagnostics | | [RUST-FEAT-038](items/RUST-FEAT-038.md) | Feature | Add current-aMule-style endgame source takeover | | [RUST-FEAT-039](items/RUST-FEAT-039.md) | Feature | Size ED2K request depth from measured RTT and bandwidth | diff --git a/docs/products/emulebb-rust/active/items/RUST-BUG-001.md b/docs/products/emulebb-rust/active/items/RUST-BUG-001.md deleted file mode 100644 index b77628d8..00000000 --- a/docs/products/emulebb-rust/active/items/RUST-BUG-001.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -id: RUST-BUG-001 -workflow: github -product: emulebb-rust -phase: Phase 1 -github_issue: https://github.com/emulebb/emulebb-rust/issues/77 -title: Eliminate kad_swarm CI isolation debt -status: OPEN -priority: Minor -category: bug -labels: [kad, tests, ci, flaky, debt] -milestone: post-beta-polish -created: 2026-06-14 -source: PM quality review (2026-06-14) — isolate + document CI timing debt ---- - -> Workflow status is tracked in GitHub: https://github.com/emulebb/emulebb-rust/issues/77. This local document is retained as the durable engineering spec and evidence record. - -# RUST-BUG-001 - Eliminate kad_swarm CI isolation debt - -## Summary - -The `kad_swarm` multi-node networking tests (`emulebb-core` `--test kad_swarm`, -and `local_kad_swarm` cases) have cross-node transfer timing sensitivity. They -are **isolated** in CI: the main test step skips `local_kad_swarm`, and a -separate serialized step runs `kad_swarm` with `--test-threads=1` -(`.github/workflows/ci.yml`). The isolated step is blocking; this item tracks -the remaining isolation debt. - -## Release Triage (2026-09-30) - -**Post-beta.** The isolated swarm step remains visible and blocking, and the -hosted Windows/Linux/macOS matrix passed on candidate `334db49b`. No current -release defect is exposed. The exact remainder is to prove deterministic -parallel execution across the OS matrix and then remove the main-step skip. - -## Why This Matters - -An isolated CI step can still hide scheduler/order coupling that would appear in -the normal workspace test matrix. The tests cover multi-node Kad transfer, a core -capability of the Phase 0 "perfectly functional" gate, so the timing sensitivity -must be diagnosed and folded back into the standard gate. - -## Current State - -- `ci.yml` main test step: `cargo test --workspace --locked -- --skip local_kad_swarm`. -- `ci.yml` isolated blocking step: `cargo test -p emulebb-core --test kad_swarm - --locked -- --test-threads=1`. - -## Intended Shape - -- Diagnose the cross-node transfer-timing sensitivity (likely timing/port/bind or - scheduler ordering), make the tests deterministic under the normal workspace - runner, then fold them back into the main gating matrix. - -## Acceptance Criteria - -- [x] Root cause of the timing flakiness identified and documented. -- [ ] `kad_swarm` / `local_kad_swarm` pass deterministically across the OS matrix. -- [x] CI runs the isolated `kad_swarm` step blocking. -- [ ] CI runs them in the standard workspace matrix without `--skip`. - -## Root Cause (2026-07-05) - -Two independent causes, both fixed: - -1. **Product defect — per-endpoint retry cooldown starved multi-file peers.** - `DownloadSourceRegistry.last_attempted_endpoints` keyed the 20-minute - anti-churn cooldown by bare `(ip, tcp_port)` and stamped it at lease time, - so a peer that had just **successfully** served file A was unleasable for - file B for the whole window. The deferred transfer's attempt then slept the - cooldown remainder inside the defer loop — past the test's 120 s timeout, - and in production serializing multi-file downloads from one peer with - 20-minute gaps (it also dead-locked the A4AF NNP swap re-engage). Fixed by - keying the cooldown per `(endpoint, file)` (the eMule `MIN_REQUEST_TIME` - per client-file relation), with a registry regression test. Diagnosed via - new rust-only `sched` breadcrumbs (`download_attempt_started`, - `download_retry_outcome`) that make a spawned-but-stalled attempt visible - in the diag stream. -2. **CI harness env — loopback `X_LOCAL_IP`.** `ci.yml` exported - `X_LOCAL_IP=127.0.0.1`, which the swarm harness rejects by design - (`node.rs` `lan_bind_ip` asserts non-loopback), so every `local_kad_swarm` - test panicked on every runner. The workflow now resolves the runner's real - primary IPv4 into `X_LOCAL_IP` before the test gate. - -## Notes - -- Until fully folded back, the isolated step must stay visible and blocking so - coverage is not lost; this item is its owner of record. -- 2026-06-19 parity closure review: this is CI isolation debt, not a core - Rust-vs-MFC parity close blocker while the isolated `kad_swarm` step remains - visible and blocking. It still belongs in the Phase 0 cleanup lane before the - normal workspace matrix can be treated as fully rationalized. -- Remaining: witness a green OS matrix on CI post-fix, then evaluate folding - the swarm tests back into the main step (drop `--skip local_kad_swarm`). diff --git a/docs/products/emulebb-rust/history/items/RUST-BUG-001.md b/docs/products/emulebb-rust/history/items/RUST-BUG-001.md new file mode 100644 index 00000000..17571eda --- /dev/null +++ b/docs/products/emulebb-rust/history/items/RUST-BUG-001.md @@ -0,0 +1,110 @@ +--- +id: RUST-BUG-001 +workflow: github +product: emulebb-rust +phase: Phase 1 +github_issue: https://github.com/emulebb/emulebb-rust/issues/77 +title: Eliminate kad_swarm CI isolation debt +status: DONE +priority: Minor +category: bug +labels: [kad, tests, ci, flaky, debt] +milestone: post-beta-polish +created: 2026-06-14 +source: PM quality review (2026-06-14) — isolate + document CI timing debt +--- + +> Workflow status is tracked in GitHub: https://github.com/emulebb/emulebb-rust/issues/77. This local document is retained as the durable engineering spec and evidence record. + +# RUST-BUG-001 - Eliminate kad_swarm CI isolation debt + +## Summary + +The `kad_swarm` multi-node networking tests were isolated from the normal +workspace runner because of cross-node transfer timing failures. The product +and CI-environment causes were fixed earlier, and the final CI debt is now +removed: the standard locked workspace test command runs every +`local_kad_swarm` case under normal parallel execution on all supported CI +operating systems. + +## Current State + +- `tools/rust_quality_gate.py` runs `cargo test --workspace --locked` without a + `local_kad_swarm` skip. +- Composite `ci` and `ci-test` gates run the workspace suite once and no longer + duplicate the Kad integration target in a separate serialized step. +- `test-kad-swarm` remains available as a focused serialized diagnostic command + without weakening or duplicating the required CI path. +- Helper contract tests lock the unfiltered workspace command, prevent a future + composite-gate duplication, and preserve the focused diagnostic gate. + +## Why This Matters + +An isolated CI step could hide scheduler or order coupling that would appear in +the normal workspace matrix. The tests cover multi-node Kad transfer, a core +capability of the functional gate, so they now run under the same scheduling +conditions as every other workspace test. + +## Representative Sites + +- `tools/rust_quality_gate.py` - standard workspace, focused Kad, and composite + CI gate definitions +- `tools/tests/test_rust_quality_gate.py` - executable gate-contract coverage +- `crates/emulebb-core/tests/kad_swarm.rs` - six multi-node Kad integration + cases +- `crates/emulebb-core/src/download_source_registry.rs` - per-file endpoint + retry cooldown fixed during root-cause work + +## Intended Shape + +- Run Kad swarm integration tests in the normal locked workspace suite with the + default parallel test runner. +- Keep a separately addressable focused command for local diagnosis, not as a + second required CI execution path. +- Keep runner LAN address discovery explicit through inherited `X_LOCAL_IP`. + +## Acceptance Criteria + +- [x] Root causes of the timing failures are identified and documented. +- [x] `kad_swarm` and `local_kad_swarm` pass under normal parallel execution + across the Windows, macOS, and Ubuntu matrix. +- [x] CI runs them in the standard workspace matrix without `--skip`. +- [x] Composite gates do not rerun the integration target in a serialized step. + +## Root Cause + +Two independent causes were corrected before the final gate cleanup: + +1. **Product defect — per-endpoint retry cooldown starved multi-file peers.** + `DownloadSourceRegistry.last_attempted_endpoints` keyed the 20-minute + anti-churn cooldown by bare `(ip, tcp_port)`, so a peer that successfully + served file A could not be leased for file B during the same window. The + fix keys the cooldown by `(endpoint, file)`, matching eMule's per-client-file + `MIN_REQUEST_TIME` relationship. +2. **CI environment — loopback `X_LOCAL_IP`.** The swarm harness intentionally + rejects loopback LAN binds. CI now resolves each runner's primary IPv4 and + provides it through `X_LOCAL_IP` before the test gate. + +## Validation + +- `python tools/tests/test_rust_quality_gate.py` (14 tests passed) +- `python tools/rust_quality_gate.py policy` (111 policy tests passed) +- `python tools/rust_quality_gate.py fmt` +- `python tools/rust_quality_gate.py diagnostics` +- `python tools/rust_quality_gate.py clippy` +- Workspace-orchestrated `emulebb-core` Debug tests passed with normal + parallelism: 400 unit tests plus all integration suites, including all six + `kad_swarm` cases in 16.44 seconds. +- The full unfiltered workspace Rust and documentation test suite passed in + Debug configuration. +- PR #113 required CI passed on Windows, macOS, and Ubuntu with the unfiltered + workspace gate. Workflow lint, cargo-deny, policy/format/clippy, CodeQL, and + live REST/OpenAPI conformance also passed. + +## Notes + +- Product root-cause commit `dab4b290` made retry cooldown per endpoint and + file; CI root-cause commit `76af38c0` supplied a real runner LAN address. +- Completed on 2026-10-15 by emulebb-rust PR #113 in preserved commit + `dd05eae7`. +- GitHub issue #77 is closed and the eMuleBB Roadmap item is Done.