docs: rewrite AGENTS.md to agents.md / Codex style

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.
This commit is contained in:
2026-07-12 20:26:31 +02:00
parent 4de004cc1f
commit ff8e046cf7
3 changed files with 502 additions and 246 deletions

128
crates/vnidrop/AGENTS.md Normal file
View File

@@ -0,0 +1,128 @@
# AGENTS.md — `crates/vnidrop` (Rust core)
Nearest guide when editing under `crates/vnidrop/`. Root [`AGENTS.md`](../../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`](CORE_FLOW.md) before changing send/receive/export/cancel.
---
## Commands (run from repo root)
Always prefer workspace commands so lockfile/fmt stay consistent:
```bash
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:
```bash
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`):
```bash
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
1. **Public API stability:** UniFFI surface changes break Kotlin. Prefer additive
changes; update shared Kotlin call sites in the same change when required.
2. **Streaming stays in Rust.** Platform passes paths or FDs; core does not pull
whole files into Kotlin.
3. **Android FDs are files only.** `SourceKind::FileDescriptor` with
`is_directory=true` must fail; directories are expanded on the platform side.
4. **Cancel:** signal active-transfer oneshot **synchronously** before async DB
work. Use existing `take_active_transfer` / facade cancel path. Do not reintroduce
nested exclusive `Runtime::block_on` deadlocks.
5. **No lock across await:** Clippy `await_holding_lock` fails CI.
6. **ReceiveOutputSink:** after successful `start_file`, exactly one of
`finish_file` or `abort_file` (see `OutputSinkFile` Drop).
7. **No-overwrite publish** for path receives (temp + hard link / exclusive rename).
8. 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 crate `tests.rs` paths).
- 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`](tests/README.md).
---
## PR / verify checklist for this crate
```bash
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test -p vnidrop
```
If you touched cancel, export, or sinks, also:
```bash
cargo test -p vnidrop --test output_sink
```