refactor(hub): oneshot waiters and plugin hygiene - #40
Conversation
Replace Condvar slot wait with sync_channel, unify drain idle semantics, and harden tests/deps/docs/playground AT quick cmds. Co-authored-by: Cursor <cursoragent@cursor.com>
|
|
There was a problem hiding this comment.
All reported issues were addressed across 23 files
Tip: instead of fixing issues one by one fix them all with cubic
Re-trigger cubic
Fix flaky live-URC PTY wait, expand ACL/contracts/JNI exchange, Windows nextest, nightly emulator workflow, hub fixtures/chunking, golden negatives, and publish-surface smoke. Co-authored-by: Cursor <cursoragent@cursor.com>
Return open() canonical path, restore deprecated PortBackend, cover read/drain reclaim race, and tighten inventory/AT tests. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
7 issues found across 30 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="scripts/ci-fast.sh">
<violation number="1" location="scripts/ci-fast.sh:25">
P3: This dedicated invocation recompiles the root crate and re-runs the `command_inventory` and `acl_smoke` lib tests immediately after `cargo test --workspace`/`cargo nextest run --workspace` (lines above) already executed the full lib test suite, which includes `src/tests/command_inventory_test.rs` and `src/tests/acl_smoke_test.rs`. The subset run adds a full rebuild + run cycle to a gate advertised as "fast" with no coverage gain. Since both lib tests are already covered by the workspace run, drop this step or run it in place of the full workspace run if the intent is a targeted fast subset.</violation>
<violation number="2" location="scripts/ci-fast.sh:27">
P3: This gate never installs JS dependencies, so on a fresh checkout `pnpm check && pnpm test` fails on missing node_modules rather than on the code being checked. Add `pnpm install` before the JS step (and ideally `cargo build`/fetch deps earlier) so the gate is runnable from a clean clone.</violation>
</file>
<file name="android/src/test/kotlin/app/tauri/serialplugin/manager/UsbFdBridgeTest.kt">
<violation number="1" location="android/src/test/kotlin/app/tauri/serialplugin/manager/UsbFdBridgeTest.kt:317">
P2: This test doesn't verify shutdown unblocks a pending permission wait. `shutdown()` never completes entries in `permissionFutures`, so the worker only finishes because the test explicitly calls `completePermissionForTest(DEVICE, false)` afterward — the test passes identically whether or not shutdown aborts the wait. In production a thread blocked in `requestPermission` (`fut.get(30s)` on the single-thread ioExecutor) is not unblocked by `shutdown()`, and this test masks that hang. Make shutdown complete/cancel pending permission futures and have the test assert the worker finishes from shutdown alone.</violation>
</file>
<file name="src/hub/shared.rs">
<violation number="1" location="src/hub/shared.rs:1234">
P3: The fixture's `expected_match` field is read but never used to drive the completion-variant check: the test hardcodes `matches!(matched, ExchangeMatch::Ok)` and separately asserts `expected_match == "ok"`. Derive the expected variant from `expected_match` (or drop the field) so a future fixture with a different expected match actually drives the assertion instead of failing on the hardcoded `matches!` first.</violation>
</file>
<file name="src/tests/acl_smoke_test.rs">
<violation number="1" location="src/tests/acl_smoke_test.rs:74">
P3: The synthetic test asserts on its own hand-built permissions array, so it can never fail and verifies nothing about the actual ACL wiring. The neighboring deny_open_permission_is_defined already covers the real contract by reading open.toml; drop this test or point it at a real source rather than self-constructed data.</violation>
</file>
<file name="src/android/registry.rs">
<violation number="1" location="src/android/registry.rs:229">
P2: After `exchange_wait` returns, the hub still retains this waiter because this helper never clears it. `feed_bytes` prioritizes that waiter over read/watch/idle routing, so later harness RX is swallowed; clear it after every wait result, including timeout/error.</violation>
</file>
<file name="crates/android-usb-serial/tests/golden_parity.rs">
<violation number="1" location="crates/android-usb-serial/tests/golden_parity.rs:461">
P2: The corruption `"!!!!"` is not valid base64, so `decode_b64` (which falls back to an empty vec via `unwrap_or_default()`) turns it into `[]` rather than real corrupted bytes. The test only passes because this fixture's `controls[0]` payload is `[0,0,0]`; if a fixture regen ever makes that first control payload empty, the corrupted value decodes to the same empty vec and `controls_match` returns true, failing the test confusingly. Corrupt with valid-but-different base64 (e.g. re-encode `[1,2,3]`) so the mismatch is a genuine byte difference independent of the decode fallback.</violation>
</file>
Tip: instead of fixing issues one by one fix them all with cubic
Re-trigger cubic
Pin jni 0.21 for Android compile, replace Windows nextest with cargo test, share Android setup action with caches, and clear hub/permission waiters that left harness hangs. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep a single android-integration prebuild job in test.yml; connected JNI stays local-only. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
All reported issues were addressed across 13 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Fix all with cubic | Re-trigger cubic
Add npm description/keywords, crates discoverability fields, leaner crate exclude, publish.sh (cargo then npm), SECURITY and CONTRIBUTING. Co-authored-by: Cursor <cursoragent@cursor.com>
Replace unmaintained standard-version with release-it + Cargo sync hook; harden UsbFdBridge shutdown; run full Windows cargo test. Co-authored-by: Cursor <cursoragent@cursor.com>
Check npm/cargo auth up front, install JS deps first, then npm publish (session expiry) before cargo publish. Co-authored-by: Cursor <cursoragent@cursor.com>
Drop mixed npm whoami/login from the release docs and script. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
All reported issues were addressed across 17 files (changes from recent commits).
Tip: instead of fixing issues one by one fix them all with cubic
Re-trigger cubic
Exclude tauri-plugin-serialplugin from Windows cargo test (0xc0000139), sync permission shutdown under lock, tighten publish guards and license copyright metadata. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
All reported issues were addressed across 10 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Fix all with cubic | Re-trigger cubic
MIT requires preserving upstream copyright on derivative code. Document CARGO_REGISTRY_TOKEN alongside cargo login. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
sync_channel(1), atomic slot install, read fallthrough, and one shared drain idle path (desktop = shared).PortBackend, widetauri/tauri-pluginreqs with updated lockfile, README drift fixes, thin guest-js cleanup, playground AT quick buttons.Test plan
cargo test --lib hub::cargo test --lib -- command_inventory acl_smoke invoke_contractcargo test --lib -- cancel_exchange_while_at_in_flight write_succeeds_while_exchange_waiting exchange_fails_fast_on_disconnectpnpm testcargo clippy --all-targets -- -D warningsMade with Cursor
Summary by cubic
Replaces the hub's Condvar read/drain waiters with
sync_channel(1)oneshot signaling and unifies desktop/shared drain idle paths, fixing waiter wake-up races. Also hardens CI, testing, dependencies, and release tooling for publish readiness.Refactors
PortBackendis deprecated as an alias ofExchangeIobut kept exported for patch compatibility until the next major.SerialPort.open()now resolves with the canonical path string instead ofundefined.jnito 0.21, widenstauri/tauri-plugin/serderequirements, and bumpsbase64/serialport.s00d, and unify underLICENSE-MIT/LICENSE-APACHE; release tagging moved to release-it with a Cargo version sync hook and pnpm-only publish auth.Testing & CI
cargo test(nextest hits an exe failure) and excludes the plugin lib from Windows runs; connected JNI tests stay local-only.Written for commit e101bd5. Summary will update on new commits.