Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
de8f34f
docs(agents): targeted /inits improvements to AGENTS.md
metaphorics May 17, 2026
370fdc4
chore(docs): delete stale root PLAN.md (verbatim duplicate of docs/pl…
metaphorics May 18, 2026
1459d5e
docs(threat-model): replace pre-D-4 QUIC/Noise references with WireGuard
metaphorics May 18, 2026
c535320
docs(crates): drop pre-D-4 QUIC/Noise rustdoc residue across source f…
metaphorics May 18, 2026
d8917d4
chore(workspace): drop pre-D-4 workspace deps (snow, serde_with, futu…
metaphorics May 18, 2026
14dba46
chore(bibeam-runtime): drop unused deps (clap, anyhow, tower-http)
metaphorics May 18, 2026
c18ae1d
chore(lints): allow clippy::redundant_pub_crate workspace-wide (rustc…
metaphorics May 18, 2026
b591db5
chore(bibeam-cli): strip 31 #[allow(clippy::redundant_pub_crate)] blo…
metaphorics May 18, 2026
ec32ce7
chore(lints): bump too-many-arguments-threshold 5→7 (matches boringtu…
metaphorics May 18, 2026
f304aae
chore(crates): strip 8 #[allow(clippy::too_many_arguments)] blocks ma…
metaphorics May 18, 2026
8e4556c
chore(tests): strip redundant clippy allows already covered by clippy…
metaphorics May 18, 2026
49ac4d1
refactor(bibeam-core): move SessionClaims from bibeam-protocol to bib…
metaphorics May 18, 2026
0683511
refactor(bibeam-node): collapse rotation_handler::CohortHandler into …
metaphorics May 18, 2026
b865df4
refactor(bibeam-node): tighten docs and visibility for RotationHandle…
metaphorics May 18, 2026
5bf793e
refactor(bibeam-node): collapse coordinator/rate_limit::RateLimitConf…
metaphorics May 18, 2026
06f74ab
refactor(bibeam-node): merge rotation_deadline_now + lease_expires_at…
metaphorics May 18, 2026
747124e
chore(bibeam-node): drop unused From<ExitModeError> for bibeam_core::…
metaphorics May 18, 2026
1d43192
chore(bibeam-runtime): drop unused Default impl on ReadyLatch + cerem…
metaphorics May 18, 2026
4f5f840
test(crypto): drop compile-time ZeroizeOnDrop assertions (Mandate 3 —…
metaphorics May 18, 2026
c33c903
test(crypto,protocol): drop derive-generated PartialEq tests + redund…
metaphorics May 18, 2026
3c2834d
test(bibeam-node): drop noop_handler_is_object_safe_and_does_nothing …
metaphorics May 18, 2026
051f575
test(bibeam-node,bibeam-transport): drop 7 metric-naming convention t…
metaphorics May 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 31 additions & 16 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ This file gives an AI coding assistant the minimum it needs to make a useful fir
## Commands

```bash
# format / lint / test / doc — match what hooks and CI run
# format / lint / test / doc / supply-chain — match what hooks and CI run
just fmt # cargo fmt --all
just lint # cargo clippy --workspace --all-targets --all-features -- -D warnings
just test # cargo nextest run --workspace --all-features
just doc # RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps --all-features

# full local CI pipeline
just ci
# format / lint / test / doc / supply-chain — match what hooks and CI run
just ci # fmt-check + lint + test + doc + deny + machete (see Justfile:41)

# per-crate README regeneration (do this after editing any Cargo.toml description)
cargo run -p xtask -- gen-readmes # write
Expand All @@ -27,15 +27,17 @@ cargo run -p xtask -- gen-readmes --check # drift gate

`just bootstrap` (run once per dev machine) installs `prek`, `cargo-nextest`, `typos-cli`, `cocogitto`, and `taplo-cli`, then arms the git hooks via `prek install`.

`just bootstrap-phase2` (only after the first real feature PR) installs the release stack: `git-cliff`, `release-plz`, `cargo-dist` (see Justfile:52).

## Workspace layout

See [`docs/architecture.md`](./docs/architecture.md) for the crate boundary map, the two-plane control/data split, and the request flow. The ten crates live under `crates/`:

## Strict regime — non-negotiable

- Clippy runs `pedantic` + `nursery` + `cargo` groups at `warn` plus a surgical restriction-deny list (no `panic`, `unwrap_used`, `expect_used`, `todo`, `unimplemented`, `unreachable`, `dbg_macro`, `print_stdout`, `print_stderr`, `mem_forget`, `unwrap_in_result`, `let_underscore_must_use` in non-test code). CI invokes `-D warnings`.
- Clippy runs `pedantic` + `nursery` + `cargo` groups at `warn` plus a surgical restriction-deny list (see full list + rust/rustdoc lints in [`Cargo.toml`](./Cargo.toml):174-201; tests exempt via [`clippy.toml`](./clippy.toml):16-20). CI invokes `-D warnings`.
- **Cognitive complexity ≤ 15** per function. State machines that legitimately exceed it may carry `#[allow(clippy::cognitive_complexity)]` with a justification in the commit body.
- **Conventional Commits required.** `cog verify` runs at commit-msg time. See [`CONTRIBUTING.md`](./CONTRIBUTING.md) for accepted types.
- **Conventional Commits required.** `cog verify` runs at commit-msg time. See [`CONTRIBUTING.md`](./CONTRIBUTING.md) for accepted types, branch policy, review axes (Correctness > Hygiene > Footprint), and the 5-point dep rubric.
- **Per-crate READMEs are generated.** Never hand-edit `crates/*/README.md`. Edit the `[package].description` and run `cargo run -p xtask -- gen-readmes`.

## Security context
Expand All @@ -50,27 +52,40 @@ See [`docs/architecture.md`](./docs/architecture.md) for the crate boundary map,
- Using `std::sync::Mutex` / `std::sync::RwLock` — `clippy.toml` disallows them in favor of `parking_lot` equivalents.
- Using `chrono::DateTime` — `clippy.toml` disallows it in favor of `time::OffsetDateTime`.
- Using `println!` / `eprintln!` / `dbg!` in non-test code — disallowed by the restriction lints. Use `tracing` macros.
- Re-implementing what already exists. The anonymity-set ≥30 floor IS enforced today (`crates/bibeam-node/src/coordinator/admission_gate.rs` — R-FLOOR per-region partition + `NoAnonymousPathAvailable` refusal per R-3 formalism). Genuinely Phase 2 / not-yet-implemented: release-plz, cargo-dist, dependabot, coordinator replication protocol (P2A-1 only recorded the decision).
- Re-implementing what already exists. The anonymity-set ≥30 floor (R-3) IS enforced today (`crates/bibeam-node/src/coordinator/admission_gate.rs` — R-FLOOR per-region partition + `NoAnonymousPathAvailable` refusal). Phase-2 release tooling (release-plz, cargo-dist, dependabot, git-cliff) now has committed configs + `just bootstrap-phase2`; publish/installers still gated. Full enablement is future work.
- Bypassing the heavy pre-commit surface (prek-managed, see [`.pre-commit-config.yaml`](./.pre-commit-config.yaml):35-71). The policy is deliberate: fail on fmt/taplo/typos/xtask/clippy/nextest/deny/machete/doc *before* you write a commit message that `cog verify` will then reject (rationale in [`CONTRIBUTING.md`](./CONTRIBUTING.md):29-35).
- Hyphenated negative prefixes in comments (the three-letter form starting with `m`, hyphen, then a verb such as `paired` / `keyed` / `bind` / `classified` / `delivered`) trip the `typos` pre-commit hook because that three-letter token is read as a misspelling of `miss` / `mist`. Use `wrongly <verb>` or rewrite the phrase. The hook also enforces `unparsable` over the alternate spelling with an `e`.
- Adding a third-party dependency without checking the rubric in [`CONTRIBUTING.md`](./CONTRIBUTING.md) — active in the last 12 months, no RustSec advisory, latest release not yanked.
- Treating `docs/protocol.md` or `docs/plan/tasks.md` as current without knowing their post-D-4 state. `protocol.md` has been rewritten to reflect Phase A WireGuard corrections; `tasks.md` has partial post-D-4 updates. Canonical sources: [`docs/architecture.md`](./docs/architecture.md):54 (data plane) + [`docs/threat-model.md`](./docs/threat-model.md):122 (multi-hop + R-3) + [`docs/plan/init.md`](./docs/plan/init.md):13 (MSRV/prek/lefthook pivots).

## Picked design decisions (D-* + R-*)

Quick reference so you don't grep the plan-doc on every change. Full rationale lives in `docs/plan/init.md` §11; the docs themselves are the source of record for downstream readers.
Quick reference. Full grounding lives in [`docs/architecture.md`](./docs/architecture.md) (Operational decisions + two-plane crate map) + [`docs/threat-model.md`](./docs/threat-model.md):112 (R-1/R-3/D-6 sections) + [`docs/plan/init.md`](./docs/plan/init.md):13 (MSRV/prek/lefthook pivots + 0.2c corrections) + [`docs/plan/init.md`](./docs/plan/init.md):66 (original 17 decisions). The old "§11" pointers are stale post-correction; decisions were moved into architecture + threat-model.

- **D-1** ECH (Encrypted ClientHello): **best-effort** when rustls supports it for BiBeam's own coordinator TLS (CLI/node → coord); user-app ECH is transparent end-to-end. Policy knob `ech = "best-effort" | "deferred"` (CLI default `Deferred`). (arch:67, threat:11, cli/config.rs:51)
- **D-3** Exit-mode forwarding: **L3 via `tun-rs` + kernel NAT44/66** (primary), **L4 via `fast-socks5`** (fallback when TUN unavailable). (arch:127, plan/tasks:114)
- **D-4** VPN protocol family: **WireGuard wire-compat via `boringtun`** end-to-end (clients see a stock WG peer). (arch:56,69, threat:122)
- **D-5** GeoIP region cross-check: **warn-only** at MVP (`AuditKind::RegionMismatch`); admission proceeds. Region = free-form operator `String` (R-2). (region_verify.rs:1, admission_gate.rs:131)
- **D-6** Multi-hop construction: **option (c)** — stateful UDP forwarder + *end-to-end* client↔exit WG (TURN-style). Intermediates see only addr pair + ciphertext. (arch:56, threat:122-166)
- **R-1** (coord-crate dissolution): single `bibeam-node` binary; `is_coordinator` flag mounts the axum+redb admission module. Coord + data keys in same process (operators should physically separate). (arch:52, threat:114)
- **R-2** Region is operator-tagged free-form `String` on records; coord cross-checks vs GeoIP (ISO-3166) + allowlist CIDRs; per-region partitioning prevents anon-set pollution.
- **R-3** Per-position anonymity floor is **topology-only** (≥30 at *every* hop independently; **no cross-hop union**). Under-floor → refuse (`NoAnonymousPathAvailable`, one fresh audit row per drain poll). Region-isolated. (admission_gate.rs:186-240,300, threat:160)
- **R-MULTIHOP-PROTO** packet-to-lease binding: **option (B)** — explicit `RelayFrame { chain_id, wg_payload }`. Coord **never** holds WG X25519 private keys (client + exit mint locally at registration, publish only pubkeys). (threat:164, multihop.rs:206)

- **D-1** ECH (Encrypted ClientHello): **deferred** at MVP — wired through F-TRANS.2's rustls config + F-CLI.7 `--ech-policy` flag; default `Deferred`.
- **D-3** Exit-mode forwarding: **L3 via `tun-rs` + kernel NAT44/66** (primary), **L4 via `fast-socks5`** (fallback when TUN unavailable).
- **D-4** VPN protocol family: **WireGuard wire-compat via `boringtun`** end-to-end (clients see a stock WG peer).
- **D-5** GeoIP region cross-check: **warn-only** at MVP. Mismatch emits `AuditKind::RegionMismatch`; admission proceeds.
- **D-6** Multi-hop construction: **option (c) — stateful UDP forwarder + end-to-end client↔exit WG** (TURN-style). Intermediates see address pair + ciphertext, never plaintext. Verified by the `forwarder_relays_opaque_payload_byte_preserving` integration test in `crates/bibeam-node/tests/multihop_e2e.rs`.
- **R-2** Region is operator-tagged free-form `String` on `PeerRecord`/`RelayRecord`/`ExitRecord`; coord cross-checks against GeoIP per D-5. (R-1 — coord-crate dissolution — is documented inline above in *Workspace layout*; not repeated here.)
- **R-3** Per-position anonymity floor is **topology-only**: every position p in a multi-hop path must independently satisfy `|position_cohort(C, p)| + 1 ≥ 30`. **No union across hops** (an earlier draft's union claim was rejected by review). Under-floor → refuse, don't auto-route.
- **R-MULTIHOP-PROTO** packet-to-lease binding: **option (B)** — explicit `RelayFrame { chain_id, wg_payload }` encapsulation. Coord NEVER holds WG private keys; client + exit each generate their own keypairs at registration and publish only public keys.
**Cross-cutting invariants (expensive to rediscover):**
- **Data / control plane split** (arch:7): control crates (`discovery`, crypto PASETO, `node/coordinator/`) never see WG private keys or inner traffic; data crates (`tun`, `transport/wg_*`, exit) never perform admission or issue tokens. Any change must respect the boundary.
- **Key custody + forwarder visibility** (D-6/R-4): intermediates see only outer address + WG ciphertext shape; never plaintext, transport keys, or identities. Coord is a pairing service only.
- **Anonymity floor mechanics** (R-3 + R-2): per-position + per-region + per-poll audit (no dedup, no continuous re-gate between rotations). Refuse rather than route. One audit row per poll for operator visibility.
- **Historical pivot record** (plan/init.md:13): MSRV pin removed (0.2c), lefthook → prek, "latest stable only, no dedicated MSRV CI job". The "why no pin" rationale lives only in the correction notes.

## Where to look first

- A new lint failure: [`clippy.toml`](./clippy.toml) and `[workspace.lints.*]` in [`Cargo.toml`](./Cargo.toml).
- A new hook failure: [`.pre-commit-config.yaml`](./.pre-commit-config.yaml).
- A CI failure that does not reproduce locally: the [GitHub workflow](./.github/workflows/ci.yml) runs three operating systems; macOS and Windows runners catch path and line-ending issues.
- A "where does this fit?" question: [`docs/architecture.md`](./docs/architecture.md).
- A "why does the scaffold look like this?" question: [`docs/plan/init.md`](./docs/plan/init.md) — the spec that drove Phase 1.
- A "why does the scaffold look like this?" question: [`docs/plan/init.md`](./docs/plan/init.md) — the spec that drove Phase 1 (plus corrections at :13).
- Supply-chain policy or new third-party dep: [`deny.toml`](./deny.toml) (yanked=deny, "Revisit by YYYY-MM-DD" ignore convention, license allowlist, bans, graph.all-features) + [`CONTRIBUTING.md`](./CONTRIBUTING.md):58-68 (5-point rubric) + :70 (review axes).
- Release / changelog / dist automation: [`release-plz.toml`](./release-plz.toml), [`dist-workspace.toml`](./dist-workspace.toml), [`cliff.toml`](./cliff.toml) (parser order critical for `chore(release)`), [`cog.toml`](./cog.toml), [`.github/dependabot.yml`](./.github/dependabot.yml) (weekly groups).
- Formatting + cross-OS churn prevention: [`.taplo.toml`](./.taplo.toml) (reorder_keys/arrays=false to protect Cargo.lock), [`.editorconfig`](./.editorconfig) (2-space for toml/yml + md no-trim), [`rustfmt.toml`](./rustfmt.toml), [`.cargo/config.toml`](./.cargo/config.toml) (retry=3, git-fetch-with-cli).
- Hook surface + prek policy: [`.pre-commit-config.yaml`](./.pre-commit-config.yaml) (heavy pre-commit vs light pre-push, fail_fast=false, nextest --no-tests=warn in hook, xtask --release gen-readmes --check).
79 changes: 0 additions & 79 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 2 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ repository = "https://github.com/gosuda/BiBeam"
homepage = "https://github.com/gosuda/BiBeam"
authors = ["GoSuda BiBeam contributors"]
readme = "README.md"
keywords = ["vpn", "p2p", "quic", "noise", "privacy"]
keywords = ["vpn", "p2p", "wireguard", "anonymity", "privacy"]
categories = ["network-programming", "cryptography"]

[workspace.dependencies]
Expand All @@ -28,18 +28,15 @@ bibeam-runtime = { version = "0.0.1", path = "crates/bibeam-runtime" }
tokio = { version = "1.40", features = ["rt-multi-thread", "macros", "net", "sync", "time", "io-util", "signal", "process", "fs"] }
tokio-util = { version = "0.7", features = ["codec", "io", "rt"] }
tokio-stream = { version = "0.1", features = ["sync", "time"] }
futures = "0.3"
futures-util = "0.3"

# --- transport / crypto / proto ---
boringtun = "0.7"
quinn = { version = "0.11", default-features = false, features = ["rustls-ring", "runtime-tokio"] }
quinn-proto = "0.11"
rustls = { version = "0.23", default-features = false, features = ["std", "ring"] }
tokio-rustls = "0.26"
rustls-pemfile = "2"
webpki-roots = "1"
snow = { version = "0.10", features = ["ring-accelerated"] }
x25519-dalek = { version = "2", features = ["serde", "static_secrets"] }
ed25519-dalek = { version = "2", features = ["serde", "rand_core"] }
chacha20poly1305 = "0.10"
Expand Down Expand Up @@ -96,7 +93,6 @@ caps = "0.5"
# --- serde / data ---
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_with = { version = "3", features = ["base64", "hex"] }
postcard = { version = "1", features = ["alloc", "use-std"] }
bytes = "1"
toml = "1.1"
Expand Down Expand Up @@ -167,6 +163,7 @@ must_use_candidate = "allow"
similar_names = "allow"
too_many_lines = "allow" # complexity caught by cognitive_complexity instead
multiple_crate_versions = "allow" # transitive duplicates from rust-crypto + dalek ecosystems; not load-bearing for safety
redundant_pub_crate = "allow" # rustc `unreachable_pub` already enforces the intent (pub-in-private); clippy's variant is pure noise on top of it

# cognitive complexity gate (threshold lives in clippy.toml)
cognitive_complexity = "warn"
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ Seven libraries + two role-specific daemons + one ops runner. See [docs/architec
|---|---|
| [`bibeam-core`](./crates/bibeam-core) | Shared types, errors, identity primitives |
| [`bibeam-protocol`](./crates/bibeam-protocol) | Wire frames + postcard codec |
| [`bibeam-crypto`](./crates/bibeam-crypto) | Noise IK, AEAD, PASETO, key management |
| [`bibeam-transport`](./crates/bibeam-transport) | QUIC + Noise datagram tunnel + STUN hole-punch |
| [`bibeam-crypto`](./crates/bibeam-crypto) | WG key generation, AEAD, PASETO session tokens |
| [`bibeam-transport`](./crates/bibeam-transport) | WireGuard (boringtun) data plane over UDP + STUN hole-punch |
| [`bibeam-tun`](./crates/bibeam-tun) | Cross-platform TUN device + L3 packet pipeline |
| [`bibeam-discovery`](./crates/bibeam-discovery) | Coordinator client + rendezvous types |
| [`bibeam-runtime`](./crates/bibeam-runtime) | Tracing, metrics, config, signals, health |
Expand All @@ -47,7 +47,7 @@ Per-crate `README.md` files are **generated** by `cargo run -p xtask -- gen-read
## Reading order

1. [`docs/architecture.md`](./docs/architecture.md) — two-plane diagram, crate boundaries, request flow.
2. [`docs/protocol.md`](./docs/protocol.md) — wire format, handshake, token claims, cohort lifecycle.
2. [`docs/protocol.md`](./docs/protocol.md) — WG wire format, session tokens, control-plane API, cohort lifecycle.
3. [`docs/threat-model.md`](./docs/threat-model.md) — adversaries, scope, mitigations.
4. [`docs/operator-runbook.md`](./docs/operator-runbook.md) — bringing up a coordinator or node.
5. [`CONTRIBUTING.md`](./CONTRIBUTING.md) — strict regime, dep-selection rubric, commit conventions.
Expand Down
Loading
Loading