From 8a5c7e5d64852fc97ffe340ec7e12d6115a87735 Mon Sep 17 00:00:00 2001 From: Jacob Gelman <3182119+ladvoc@users.noreply.github.com> Date: Mon, 4 May 2026 16:57:14 -0700 Subject: [PATCH 1/3] Add AGENTS.md --- AGENTS.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..a94a82d96 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,40 @@ +# AGENTS.md + +## API changes + +- Breaking public API changes are to be avoided unless necessary to complete your task + - Be explicit when you plan to make breaking API changes +- When introducing new API surface, always default to private or `pub(crate)` unless there is a specific reason to expose publicly +- Introduce new public APIs sparingly +- New public types that will be extensively used should be added to the prelude + +## Dependencies + +- When using APIs from third-party crates, never assume you already know the API + - **ALWAYS** reference [_docs.rs_](https://docs.rs) for docs of the specific version being used +- Pull in new dependencies as a last resort + - Explore docs of existing dependencies first to discover new APIs that can be leveraged to get the desired behavior + +## Safety + +- Avoid `unwrap` except in tests + - When unavoidable, prefer `expect` instead and provide a concise message explaining what went wrong (e.g., "Invalid state") +- Avoid `unsafe` unless absolutely necessary + - Typically will only be used in an FFI context (i.e., in `webrtc-sys`) +- When unavoidable, follow these guidelines + - Wrap unsafe code in a safe function or struct + - Isolate only the unsafe operations + - Every unsafe block should have a `// SAFETY:` comment explaining why the operation is actually safe (e.g., verifying pointers are non-null) + +## Style guidelines + +- Always format using `cargo fmt` +- Avoid excessive nesting and prefer [`let-else`](https://doc.rust-lang.org/rust-by-example/flow_control/let_else.html) +- Avoid long parameter lists; group related inputs into a purpose-built struct when it improves readability + +## Documenting changes + +- Changes are documented using [_knope_](https://knope.tech) +- Every PR needs a changeset +- Changeset must list any crates which need to be bumped stemming from the change +- Document changes interactively from the CLI with `knope document-change` or create manually in `/.changeset` From 1b5f70cb4a27f674daf61cd5a59ec05eb8a621c9 Mon Sep 17 00:00:00 2001 From: Jacob Gelman <3182119+ladvoc@users.noreply.github.com> Date: Tue, 5 May 2026 17:13:38 -0700 Subject: [PATCH 2/3] Remove prelude instruction --- AGENTS.md | 1 - 1 file changed, 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index a94a82d96..2fc92df53 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,7 +6,6 @@ - Be explicit when you plan to make breaking API changes - When introducing new API surface, always default to private or `pub(crate)` unless there is a specific reason to expose publicly - Introduce new public APIs sparingly -- New public types that will be extensively used should be added to the prelude ## Dependencies From f9f3a3b78b797713f43298ec67b7a14af0acbbfa Mon Sep 17 00:00:00 2001 From: Jacob Gelman <3182119+ladvoc@users.noreply.github.com> Date: Tue, 5 May 2026 17:55:34 -0700 Subject: [PATCH 3/3] Design patterns, conventions, and docs --- AGENTS.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 2fc92df53..14d47243d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,6 +6,13 @@ - Be explicit when you plan to make breaking API changes - When introducing new API surface, always default to private or `pub(crate)` unless there is a specific reason to expose publicly - Introduce new public APIs sparingly +- New APIs should have idiomatic doc comments + - All new functions and types should have at least a one-line description + - Stay concise and elaborate only when necessary to document unexpected behavior or requirements + - Use intra-doc links +- Include doc tests when doing so meaningfully clarifies API usage + - Design to be runnable (i.e., no `ignore`) + - Hide lines that are only for setup from generated docs by prefixing with `#` ## Dependencies @@ -14,6 +21,23 @@ - Pull in new dependencies as a last resort - Explore docs of existing dependencies first to discover new APIs that can be leveraged to get the desired behavior +## Design patterns & conventions + +- Functions should generally accept `&str`/`&[T]` rather than `String`/`Vec` +- Generally avoid clones, but pay special attention when cloning in a high-frequency code path + - In such cases, reach for smart pointers (e.g., `Arc`) instead +- When porting code from other languages, avoid mechanical translation + - Apply Rust-specific design patterns and conventions when doing so improves readability or safety + - Some patterns common in other languages are heavily discouraged in Rust (e.g., singleton) +- Leverage the [new type pattern](https://doc.rust-lang.org/rust-by-example/generics/new_types.html) where applicable +- Implement `From`/`TryFrom` for performing conversion between types +- Avoid large, catch-all error enums for new APIs + - Prefer smaller, context-scoped enums whose variants are limited to errors that can actually occur at that call site +- Prefer the actor pattern for async tasks + - Model as a struct encapsulating local state with an async, consuming run method + - Other methods can operate on `&self` to keep `run` small +- The `livekit` crate is designed to be async runtime agnostic + ## Safety - Avoid `unwrap` except in tests