pravah 0.2.0

Typed, stepwise agentic information flows for Rust
Documentation
# Contributing to Pravah

---

## Getting Started

```bash
git clone https://github.com/vivsh/pravah
cd pravah
cargo test          # all tests must pass before you begin
```

No environment variables are required for the pure-Rust test suite.
Integration tests that hit live providers are gated with `#[ignore]` — skip them unless you're working on a specific provider.

---

## Coding Guidelines

These apply to all `.rs` files.

### Errors

- Use `thiserror`-derived structured errors. Never use `Box<dyn std::error::Error>` as a return type.
- Never panic. Use `Result` and `Option` to propagate failures; avoid `unwrap()`, `expect()`, and `unreachable!()` in non-test code.

### Async

- Do not call blocking code inside async functions. Use `spawn_blocking` for CPU-bound or blocking I/O work.
- `tokio` features are narrowed to `["rt-multi-thread", "macros", "fs", "process"]`. Do not add new sub-modules without updating `Cargo.toml`.

### Object-safe traits

- `Client` is a `dyn`-compatible trait. Until Rust stabilises `async fn` in object-safe traits, `#[async_trait]` is required on every `impl Client`. Do not remove it.

### Types and schema

- All node input/output types must derive `Serialize`, `Deserialize`, and `JsonSchema`.
- The node key in the graph equals the schemars schema name, which equals the unqualified Rust type name. Input and output types must have distinct names — a collision produces `FlowError::Invalid` at build time.

### Functions and files

- Keep functions under 50 lines. If a function grows beyond that, break it into well-named helpers.
- Keep source files under 1000 lines. If a module grows larger, split it into a folder module where `mod.rs` contains only `mod` declarations and re-exports.

### Memory

- Avoid unnecessary cloning. Prefer references and borrowing.

### Comments and docs

- Doc comments (`///`) should be terse and written as if by a human, not auto-generated prose.
- Do not add comments that exist only to visually separate sections of code.
- Every test function must have a doc comment that describes what it verifies.

### Feature flags

- New optional dependencies must be gated behind a feature flag. Add the flag to `[features]` in `Cargo.toml` and document it in the feature table in `AGENTS.md`.

---

## Testing

- Unit tests live in a `#[cfg(test)] mod tests` block in the same source file.
- Flow integration tests go in `tests/flows.rs` using the mock `ClientFactory`.
- Provider / network tests go in `tests/integration.rs` and must be gated with `#[ignore]`.
- Use `#[tokio::test]` for async tests; plain `#[test]` for sync tests.
- Unix-specific tests (e.g. symlink sandbox) use `#[cfg(unix)]`.
- All tests must pass with `cargo test` before opening a pull request.

---

## Pull Request Checklist

- [ ] `cargo test` passes with no failures or new warnings.
- [ ] `cargo check` passes with no new warnings.
- [ ] `cargo build --examples` passes if any example was added or modified.
- [ ] New public items have a doc comment.
- [ ] New feature flags are documented in the feature table in `AGENTS.md`.
- [ ] Structural changes to the flow graph or trait contracts are reflected in `ARCHITECTURE.md`.
- [ ] Operational changes (new commands, new modules, new gotchas) are reflected in `AGENTS.md`.

---

## Documentation File Guidelines

### `ARCHITECTURE.md`

- **Purpose**: LLM-oriented specification. Its goal is to prevent hallucinations when generating or reviewing code against this codebase.
- **Audience**: LLMs and developers who need exact contracts before writing code.
- **Rules**:
  - Every public trait must appear with its exact Rust signature, including all bounds and lifetimes.
  - Every required derive macro must be listed explicitly.
  - Naming conventions that have non-obvious runtime consequences must be called out.
  - Builder methods must show the exact closure signature, not a paraphrase.
  - Error enum variants must be listed with their payload types.
  - Do not add prose explanations — prefer short code blocks and bullet points.
  - Do not describe intent; describe the contract.

### `AGENTS.md`

- **Purpose**: Operational guide for AI coding agents working in this repository.
- **Audience**: AI agents that have already read `ARCHITECTURE.md`.
- **Rules**:
  - Commands must be copy-pasteable verbatim.
  - The module map must stay in sync with `src/` — update it whenever a file is added, removed, or renamed.
  - "Where to Add Things" sections must list every file that needs to be touched, in the correct order.
  - "Gotchas" must be added whenever a non-obvious invariant exists that an LLM is likely to violate.
  - Do not duplicate information that is already in `ARCHITECTURE.md`.

### `CONTRIBUTING.md` (this file)

- **Purpose**: Human and AI contributor guide for process, coding standards, and documentation hygiene.
- **Rules**:
  - Coding guidelines here must stay consistent with `.github/instructions/rust.instructions.md`.
  - If a rule in `rust.instructions.md` changes, update the corresponding bullet here.
  - Do not duplicate exact API contracts — those belong in `ARCHITECTURE.md`.
  - Do not duplicate operational commands — those belong in `AGENTS.md`.

### `README.md`

- **Purpose**: Public-facing introduction — crate overview, quick-start example, feature list.
- **Rules**:
  - Keep the quick-start example compilable. Verify with `cargo build --examples` after any API change.
  - Do not document internal implementation details here.
  - Do not duplicate the full API — link to `ARCHITECTURE.md` for contracts.

### `.github/instructions/rust.instructions.md`

- **Purpose**: IDE and agent instruction file that applies coding rules to every `.rs` file.
- **Rules**:
  - This is the authoritative source for Rust coding style rules.
  - Any rule added here must also be summarised in the "Coding Guidelines" section of this file.
  - Use the `applyTo` front-matter to scope rules correctly.