mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-05 02:29:55 +02:00
Make agent instructions imperative and command-first, add nested crates/vnidrop and shared guides, and keep compose-skill as the UI source of truth with VniDrop-specific overrides.
4.0 KiB
4.0 KiB
AGENTS.md — crates/vnidrop (Rust core)
Nearest guide when editing under crates/vnidrop/. Root AGENTS.md
still applies; this file wins for Rust-specific commands and conventions.
Purpose
This crate is the transfer backend exposed to Kotlin via UniFFI (VnidropCore).
It owns Iroh, blobs, SQLite history, tickets, approval handshake, and file streaming.
Read CORE_FLOW.md before changing send/receive/export/cancel.
Commands (run from repo root)
Always prefer workspace commands so lockfile/fmt stay consistent:
cargo fmt --all
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test -p vnidrop
cargo test --workspace --all-targets
Focused integration suites:
cargo test -p vnidrop --test transfer
cargo test -p vnidrop --test approval
cargo test -p vnidrop --test lifecycle
cargo test -p vnidrop --test output_sink
Docs (CI uses -D warnings):
RUSTDOCFLAGS='-D warnings' cargo doc -p vnidrop --no-deps
Run cargo fmt --all after finishing Rust edits without asking.
Module layout
src/
runtime/
mod.rs # CoreInner, startup recovery, emit helpers
facade.rs # UniFFI surface, block_on, cancel entry
share.rs # share / import
receive.rs # receive, download, export, OutputSinkFile
lifecycle.rs # cancel share, delete, status, access mode, shutdown
provider.rs # provider messages, per-peer transfer progress
filesystem.rs # collect sources, atomic publish, path rules
repository.rs # SQLite
approval.rs / handshake.rs / ticket.rs / access_policy.rs / event_hub.rs
api.rs # UniFFI records/enums
tests/ # crate-private unit tests
tests/ # public-API integration tests + support/
Do not reassemble a single huge runtime.rs. Prefer new focused modules if a
file approaches ~800 LoC of non-test code.
Hard constraints
- Public API stability: UniFFI surface changes break Kotlin. Prefer additive changes; update shared Kotlin call sites in the same change when required.
- Streaming stays in Rust. Platform passes paths or FDs; core does not pull whole files into Kotlin.
- Android FDs are files only.
SourceKind::FileDescriptorwithis_directory=truemust fail; directories are expanded on the platform side. - Cancel: signal active-transfer oneshot synchronously before async DB
work. Use existing
take_active_transfer/ facade cancel path. Do not reintroduce nested exclusiveRuntime::block_ondeadlocks. - No lock across await: Clippy
await_holding_lockfails CI. - ReceiveOutputSink: after successful
start_file, exactly one offinish_fileorabort_file(seeOutputSinkFileDrop). - No-overwrite publish for path receives (temp + hard link / exclusive rename).
- Integration tests must use the public API +
tests/support/only.
Code style (Rust)
- Clippy clean with
-D warnings. - Prefer exhaustive
match; avoid catch-all arms that hide new enum variants. - Prefer comparing whole objects in tests when practical.
- Comment only non-obvious why (concurrency, durability, platform FS quirks).
- Do not add one-off private helpers used once if inline is clearer.
- Prefer private modules; export deliberately via
lib.rs/ UniFFI.
Testing
- Unit / private:
src/tests/(see cratetests.rspaths). - Integration:
tests/*.rs+tests/support/mod.rs(TestNode,MemoryOutputSink,CoreGuard, etc.). - Bug fixes need a regression test.
- Prefer gates/latches over multi-second sleeps (see output_sink cancel test).
- Failure tests: durable status and/or events when applicable.
- Recovery tests: shut down core, reopen same data dir.
Details: tests/README.md.
PR / verify checklist for this crate
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test -p vnidrop
If you touched cancel, export, or sinks, also:
cargo test -p vnidrop --test output_sink