Skip to content

Commit b997003

Browse files
authored
Merge pull request #22 from irshadnilam/new-architecture
Rewrite radkit SDK around new agent/runtime architecture
2 parents 5265b00 + 360d0cd commit b997003

222 files changed

Lines changed: 28198 additions & 33129 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/docs.yml

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,41 @@
1-
name: Deploy Documentation
1+
name: Deploy to GitHub Pages
2+
23
on:
4+
# Trigger the workflow every time you push to the `main` branch
5+
# Using a different branch name? Replace `main` with your branch’s name
36
push:
4-
branches:
5-
- main
7+
branches: [main]
8+
# Allows you to run this workflow manually from the Actions tab on GitHub.
9+
workflow_dispatch:
10+
11+
# Allow this job to clone the repo and create a page deployment
612
permissions:
7-
contents: write
13+
contents: read
14+
pages: write
15+
id-token: write
16+
817
jobs:
9-
deploy:
18+
build:
1019
runs-on: ubuntu-latest
1120
steps:
12-
- uses: actions/checkout@v4
13-
- name: Configure Git Credentials
14-
run: |
15-
git config user.name github-actions[bot]
16-
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
17-
- uses: actions/setup-python@v5
18-
with:
19-
python-version: 3.x
20-
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
21-
- uses: actions/cache@v4
21+
- name: Checkout your repository using git
22+
uses: actions/checkout@v4
23+
- name: Install, build, and upload your site
24+
uses: withastro/action@v3
2225
with:
23-
key: mkdocs-material-${{ env.cache_id }}
24-
path: .cache
25-
restore-keys: |
26-
mkdocs-material-
27-
- run: pip install mkdocs-material
28-
- name: Deploy MkDocs
29-
working-directory: docs
30-
run: mkdocs gh-deploy --force
26+
path: docs
27+
node-version: 22 # The specific version of Node that should be used to build your site. Defaults to 20. (optional)
28+
# package-manager: pnpm@latest # The Node package manager that should be used to install dependencies and build your site. Automatically detected based on your lockfile. (optional)
29+
# env:
30+
# PUBLIC_POKEAPI: 'https://pokeapi.co/api/v2' # Use single quotation marks for the variable value. (optional)
31+
32+
deploy:
33+
needs: build
34+
runs-on: ubuntu-latest
35+
environment:
36+
name: github-pages
37+
url: ${{ steps.deployment.outputs.page_url }}
38+
steps:
39+
- name: Deploy to GitHub Pages
40+
id: deployment
41+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
.idea
55
/temp
66
CLAUDE.md
7+
.env.example

AGENTS.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# radkit Rust Engineering Playbook
2+
3+
This playbook documents the expectations for production-grade Rust within the radkit agent SDK. It covers design principles, ownership discipline, safety, validation, and the workflow needed to ship confidently across native and WASM targets.
4+
5+
## Engineering Values
6+
- Prefer clarity over cleverness. Readability, predictability, and explicit invariants take precedence over micro-optimizations.
7+
- Embrace soundness. Design APIs so the compiler can enforce correctness with types, lifetimes, and traits.
8+
- Minimize hidden state. Favor pure functions, explicit data flow, and narrow interfaces between modules.
9+
- Guard portability. Ensure code paths work across Linux, macOS, Windows, and WASM unless a platform-specific feature is explicitly required.
10+
11+
## Project Configuration
12+
- Declare the current `rust-version` (MSRV) in `Cargo.toml` and update it intentionally. All CI jobs must build and test against this MSRV.
13+
- Use Rust 2021 edition unless a later stable edition is required; keep `rust-toolchain.toml` in sync with the workspace toolchain.
14+
- At the crate root enable the strongest baseline lints we can sustain, e.g.
15+
```rust
16+
#![deny(unsafe_code, unreachable_patterns, unused_must_use)]
17+
#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
18+
```
19+
Document any relaxed lint so reviewers know why it is needed.
20+
- Keep `lib.rs`/`main.rs` dependency graphs under control by isolating optional functionality in feature-gated modules.
21+
22+
## API and Architecture Design
23+
- Model domain concepts explicitly. Use `struct` and `enum` types with `#[non_exhaustive]` only when future-proofing is intentional.
24+
- Prefer `trait`-driven design over type erasure. Implement conversion traits (`From`, `TryFrom`, `Into`) for ergonomic interop.
25+
- Hide implementation detail behind `pub(crate)` modules. Expose the smallest viable public surface and document invariants via `///` comments.
26+
- Keep constructors and builders validating their inputs; use smart constructors to guarantee invariants after instantiation.
27+
- Separate synchronous, asynchronous, and WASM-specific APIs with feature flags or module boundaries to avoid mixing concerns.
28+
29+
## Ownership and Borrowing Discipline
30+
- Default to borrowing (`&T`, `&mut T`) and slices (`&[T]`) in APIs; take ownership only when necessary. Return `&str`/`&[u8]` instead of allocating `String`/`Vec` when data lives long enough.
31+
- Avoid `clone()` on hot paths. Reach for `Cow<'_, T>`, iterators, or reference-counted pointers (`Arc`, `Rc`) when sharing data.
32+
- Design explicit lifetimes when returning references from structs. Prefer `Arc` + `Weak` for shared ownership with drop ordering requirements.
33+
- Work with interior mutability (`Mutex`, `RwLock`, `parking_lot`, `RefCell`) only when borrowing rules cannot model the invariants. Document why interior mutability is required.
34+
- Validate invariants inside `Drop` implementations and avoid surprising side effects; do not block or panic inside `Drop` paths.
35+
36+
## Async and Concurrency
37+
- Restrict asynchronous APIs to types that are `Send + Sync` unless the lack of thread safety is explicitly documented.
38+
- Never block the runtime. Route CPU intensive or blocking I/O work through `spawn_blocking` or dedicated worker threads.
39+
- Propagate cancellation with `futures::select!`, `tokio::select!`, or cooperative checks so async tasks tear down quickly.
40+
- Use `Arc` + `RwLock`/`Mutex` sparingly; prefer message passing (`mpsc`, `broadcast`, `watch`) or atomics for shared state.
41+
- Validate cross-task ordering with tools like `loom` for tricky concurrency primitives; document assumptions about ordering and visibility.
42+
- Ensure WASM code paths stay single-threaded: guard multi-threaded constructs with `#[cfg(not(target_family = "wasm"))]`.
43+
44+
## Error Handling
45+
- Surface typed errors from library boundaries using `thiserror` or manual enums. Provide context with `anyhow::Context` or `eyre::WrapErr` inside leaf functions, but do not leak `anyhow::Error` across crate boundaries.
46+
- Map external errors into our domain-specific variants early so upstream code can match on them predictably.
47+
- Avoid panics except for programmer bugs (`debug_assert!`) or irrecoverable invariants. Audit `unwrap`/`expect` in PRs; justify any remaining usage in comments.
48+
- Use `Result<T, E>` even for internal helpers if failure is possible. Prefer returning `Option<T>` only when absence is the only failure mode.
49+
50+
## Formatting, Lints, and Static Analysis
51+
- Run `cargo fmt --all` before every commit; CI rejects formatting drift.
52+
- Keep `cargo clippy --workspace --all-targets --all-features -D warnings` green. Document every `#[allow]` with a reason and a follow-up issue if needed.
53+
- Periodically run `cargo fix --allow-dirty` to adopt new idioms introduced by compiler upgrades, but always review the diff manually.
54+
- Use `cargo udeps` to remove unused dependencies and `cargo deny` or `cargo audit` to flag vulnerable or unlicensed crates as part of release pre-checks.
55+
56+
## Testing and Validation
57+
- Require unit tests for every public function, trait impl, state machine, and error path. Favor table-driven tests for deterministic coverage.
58+
- Exercise async logic with `tokio::test` (native) and `wasm-bindgen-test` (WASM). For concurrent code, include regression tests that drive cancellation and ordering edge cases.
59+
- Add property or fuzz tests (`proptest`, `arbitrary`, `cargo fuzz`) for parsing, serialization, and protocol logic.
60+
- Keep integration tests hermetic by mocking filesystem, network, and time; use contract tests when integrating with real services is unavoidable.
61+
- Track branch coverage with `cargo llvm-cov` (native) and `wasm-bindgen-test --coverage` (WASM). Treat meaningful coverage gaps as blockers before merge.
62+
63+
## Observability and Diagnostics
64+
- Emit structured logs through `tracing` with consistent target names. Use `#[tracing::instrument]` on async entry points to preserve spans across awaits.
65+
- Attach error context (`tracing::error!`, `tracing::warn!`) with actionable messages; avoid logging secrets or personal data.
66+
- Collect metrics via the workspace metrics facade (histograms for latency, counters for events). Update dashboards or alerts when behavior changes.
67+
- Provide troubleshooting guides in module-level docs for complex components; include sample traces or metric expectations where helpful.
68+
69+
## Performance and Memory
70+
- Favor iterators, slices, and views over temporary allocations. Reuse buffers with `SmallVec`, `Bytes`, or pooling strategies when profiling proves the need.
71+
- Benchmark critical paths with `cargo bench` or `criterion` before landing optimizations. Capture flamegraphs (`cargo flamegraph`) to validate wins.
72+
- Keep hot data structures in cache-friendly shapes (avoid large enums with padding; consider `#[repr(C)]` only with clear justification).
73+
- Audit cloning, locking, and allocations during code review; measure before optimizing and document trade-offs.
74+
75+
## Dependency Management
76+
- Default to `std`, `futures`, and `tokio` (or WASM executor) primitives. Introduce new crates only with an ADR or design note describing rationale, maintenance plan, and licensing.
77+
- Prefer minimal feature sets. Disable default features for crates we import and enable exactly what we need.
78+
- Regularly run `cargo update -p <crate>` alongside release branches; capture upgrade notes in `CHANGELOG.md`.
79+
- Keep native-only dependencies behind `cfg` gates or feature flags. Provide WASM-friendly alternatives to avoid pulling incompatible crates into the WASM artifact.
80+
81+
## Runtime Compatibility Helpers
82+
- Route native/WASM behavioral differences through `radkit/src/compat.rs` so calling sites stay portable; prefer using the helpers (`MaybeSend`, `compat::spawn`, `compat::time`, etc.) instead of ad-hoc `#[cfg]` blocks in business logic.
83+
- Extend `radkit/src/compat.rs` when new cross-target abstractions are needed, mirroring APIs on both sides and documenting any WASM limitations in the module so downstream crates can plan around them.
84+
- Gate platform-specific dependencies inside `compat.rs` and re-export neutral aliases; avoid leaking executor-specific types (e.g., `tokio::Mutex`) outside the module.
85+
- Exercise both native and WASM code paths whenever `compat.rs` changes by running native tests plus the relevant WASM smoke/regression tests to catch divergences early.
86+
87+
## Build Targets
88+
- Maintain dual build targets:
89+
- Native: `cargo build --workspace --all-features` for development, load testing, and services.
90+
- WASM: `cargo build --target wasm32-wasi --release` for deployment.
91+
- Guard native-only build steps in `build.rs` with `cfg!(not(target_arch = "wasm32"))` and fail fast with helpful messages when the target is unsupported.
92+
- Run smoke tests for WASM artifacts via `wasmtime`, `wasmer`, or the host embedding to validate ABI changes.
93+
94+
## Release and Packaging
95+
- Follow semantic versioning. Breaking API changes require a major version bump and migration guide under `docs/`.
96+
- Automate tagging with `cargo release` or an equivalent tool; include generated documentation and release notes in the pipeline output.
97+
- Ship reproducible builds: pin toolchain versions, vetted dependencies, and ensure `cargo package` is clean (`cargo package --allow-dirty` is prohibited).
98+
- Archive WASM artifacts with their interface metadata and checksum for downstream verification.
99+
100+
## Code Review and Collaboration
101+
- Open design discussions (RFCs or ADRs) before implementing cross-cutting changes or introducing new dependencies.
102+
- Keep PRs focused and under ~400 lines where possible. Include a narrative explaining the change, validation performed, and follow-up tasks.
103+
- Reviewers check for ownership leaks, blocking operations, error propagation, and missing tests before approving.
104+
- Merge only with green CI covering formatting, clippy, unit/integration tests, WASM tests, and audit checks.
105+
106+
## Workflow Checklist
107+
1. Update or add targeted tests before implementing behavior changes.
108+
2. Run `cargo fmt`, `cargo clippy --all-targets --all-features -D warnings`, and native tests (`cargo test --workspace`).
109+
3. Run WASM tests or smoke checks (`wasm-pack test --node`, `wasmtime <artifact>.wasm`, or equivalent) when code affects shared logic.
110+
4. Inspect coverage via `cargo llvm-cov` (native) and `wasm-bindgen-test --coverage` for relevant crates; backfill missing cases.
111+
5. Verify documentation builds cleanly with `cargo doc --no-deps` and keep public API changes documented.
112+
6. Capture release notes or changelog entries for externally visible changes.
113+
7. Land the change only after peer review and green CI across all required jobs.
114+
115+
Adhering to these practices keeps the radkit SDK reliable, portable, and maintainable while delivering a disciplined developer experience.

0 commit comments

Comments
 (0)