base-project 0.1.2

Shared project conventions and development tasks for Base Rust crates
Documentation
# Base Rust Conventions

Use these conventions for Rust repositories in the `base-rs` organization. A project's local `.agents/` files and package-specific documentation can add requirements for that repository.

## Repository and package boundaries

- Use a separate repository when packages need independent versions, release notes, or tags.
- Keep packages in one workspace when they are intentionally released together: use one shared version, one root `releases.md`, and one release tag.
- Name crates for their public purpose. Use the `base-` prefix where needed to identify Base packages in the flat crates.io namespace; keep Rust module paths semantic and concise.
- Use Cargo's standard `src/`, `tests/`, and `examples/` directories. Use integration tests for public behavior across crate boundaries.

## Rust version support

Use Rust 1.87 as the default minimum supported version for Base crates. This baseline supports [precise lifetime captures in traits](https://blog.rust-lang.org/2025/05/15/Rust-1.87.0/). Declare the minimum in `Cargo.toml` using `rust-version`, and verify compatibility with both that version and current stable Rust. Use current stable Rust for everyday development. Raise the minimum deliberately when language features, compiler fixes, or dependencies justify it, recording the reason in release notes.

## Crate and module paths

Treat the Cargo crate name as the root namespace. Do not repeat it with a same-named top-level module. Keep modules for meaningful domain concepts, and re-export the main public API from the crate root when deeper modules only organize its implementation. For example, callers can import the agent-context API from the root:

```rust
use bake_agent_context::{Definition, Installer, Package, Specification};
```

Keep public paths independent of redundant namespace layers such as `bake_agent_context::context`. Public modules remain useful when they name a real part of the API: a crate named `protocol_http` can expose `protocol_http::headers::AcceptHeader`, where `headers` identifies the domain concept within the crate.

## Source naming

- Use `snake_case` for modules, source files, functions, methods, and variables. Use `UpperCamelCase` for structs, enums, traits, and type parameters.
- Treat acronyms and initialisms as single words in `UpperCamelCase`, following the [Rust API Guidelines]https://rust-lang.github.io/api-guidelines/naming.html#casing-conforms-to-rfc-430-c-case: write `HtmlRenderer`, `HttpClient`, `UrlParser`, and `FileIo`. Use lowercase acronyms in `snake_case`, including filenames such as `html_renderer.rs`, `http_client.rs`, and `file_io.rs`. This keeps Base's Rust APIs consistent with the Rust ecosystem; names required by external APIs retain their original spelling.
- Make public type and trait names fully descriptive; include the kind of thing being named instead of relying on the module path to supply it. For example, use `io_stream::BufferedStream` rather than `io_stream::Buffered`.
- Prefer clear, consistent names. Avoid abbreviations unless they are an established domain initialism or required by an external API.
- Follow Rust's conversion naming conventions: `as_` for inexpensive borrowed views, `to_` for conversions that perform work while preserving the source, and `into_` for consuming conversions. Name getters after their property, such as `name()` and `name_mut()`.
- Prefer natural noun phrases that lead with the primary concept and become more specific from left to right. For numeric bounds, prefer the measured quantity followed by `_limit`, such as `size_limit`, `line_length_limit`, or `header_count_limit`. Add `minimum_` or `maximum_` when the direction needs to be explicit, as in `minimum_size_limit` or `maximum_size_limit`.
- Keep constant names aligned with the corresponding settings, using the same semantic name and word order: `SIZE_LIMIT` for `size_limit`. Use the `DEFAULT_` prefix when it meaningfully distinguishes a default from another value in the same scope. For example, `DEFAULT_SIZE_LIMIT` supplies the initial configured size limit, while `ABSOLUTE_SIZE_LIMIT` names an enforced ceiling.
- Give each primary public struct, enum, or trait its own source file, named after the item using lowercase `snake_case`. Keep small, closely related helper types alongside it when that makes the code easier to understand.

## Consistency across packages

Before introducing a new semantic, layout, or naming pattern, check how related Base packages handle the same concern. Reuse an established pattern when it fits the package's purpose. When a package establishes or changes a pattern, document the rationale and intended usage in that package's context so later work has a reference. Preserve differences that reflect real domain needs; consistency should make related packages easier to understand, not flatten their APIs into one shape.

## API design

- Prefer unique ownership and borrowing for values with a clear owner. Use `Rc` or `Arc` when components need shared ownership with independent lifetimes; use `Arc` for shared ownership across threads.
- Accept borrowed inputs such as `&str`, `&[T]`, and `&T` when ownership is unnecessary. When ownership is required, take inputs by value so callers control moving or cloning. Accept iterators when an operation only needs iteration.
- Use named fields, newtypes, and enums to make domain meaning explicit. Named fields clarify otherwise ambiguous positional values, newtypes distinguish values with different meanings, and enums give meaningful names to choices.
- Implement standard traits when their semantics fit the type, and derive implementations where possible. Provide `Default` for configuration types when there is a meaningful default configuration.
- Express APIs through ordinary functions, types, and traits when they communicate the operation clearly. Use macros when their syntax or generated code provides a concrete benefit.
- Use `new` for a type's primary general constructor and `with_...` for construction with particular settings. Prefer operation names such as `open`, `connect`, or `parse` when they better describe construction. Use `try_` when it meaningfully distinguishes a fallible alternative.

## Implementation

- Choose loops, iterator chains, and pattern matching for readability. Use `if let`, `let ... else`, or `match` when they express a condition and handle its value together.
- Use `expect` with an explanation when an invariant justifies a panic.
- Keep lint exceptions narrowly scoped and explain them with `reason`. Prefer `#[expect(...)]` when a diagnostic is expected so obsolete exceptions are reported.

## Source and documentation

- Do not hard wrap prose in source comments, including documentation comments, to a fixed column width. Keep each paragraph on one source line; preserve line breaks for lists, code examples, and other meaningful structure.
- Use Markdown in comments where it helps communicate intent, including backticks for identifiers, lists, and fenced code examples.
- Document public API behavior and representative usage. Describe failure conditions, panic conditions, and safety obligations where applicable.
- Keep authored repository-root Markdown files to lowercase `readme.md`, `license.md`, and `releases.md`.
- Start `license.md` with `# MIT License`.
- Keep `readme.md` human-focused: explain the project, its motivation when useful, how to use it, recent releases, and how to contribute. Follow the `Readme Structure` guide supplied by `bake-readme`.
- Put reusable, package-specific agent guidance in `context/`; keep repository-only instructions and project-owned skills in `.agents/`. Treat the root `agents.md` as repository-owned guidance.
- Keep current project-specific design requirements in tracked `design/*.md`. These capture concrete performance, structural, and semantic constraints with their scope and validation method. Before planning or changing behavior, discover and read applicable requirements and use `base-design-review`. Follow `base-design-author` for document structure and lifecycle when user requirements are introduced, changed, or removed.
- Refer to skills by their installed names and context guides by their package and title when crossing between skills and context. The installer places them in separate directories, so relative links between them do not survive installation. Keep Markdown links within context files installed together or to stable external documentation.
- Avoid duplicating Rust-wide guidance from `bake-agent-context`; add project context for the architecture and decisions that are specific to the crate.
- Follow the Agent Context section in `readme.md` to install and discover shared context and skills. The `bake-agent-context` guide explains the installer's behavior.

## Dependency versions in documentation

- Prefer installation commands such as `cargo add base-markdown` or `cargo add --manifest-path bake/Cargo.toml base-project`. Let Cargo select the dependency and write its manifest requirement. See [Cargo's `cargo add` documentation]https://doc.rust-lang.org/cargo/commands/cargo-add.html.
- Treat `Cargo.toml` as the authority for supported dependency requirements and the workspace's root `Cargo.lock` as its resolved selection, following [Cargo's manifest and lockfile guidance]https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html. Link to the relevant manifest; `cargo metadata --locked` identifies resolved package versions and manifest paths. Use the resolved provider's manifest when checking installed tooling.
- Describe required capabilities, APIs, and task names in prose. When a numeric minimum explains a compatibility boundary, keep it in one provider-owned guide with the reason and a link to the supporting release or API documentation. Other guides should refer to that source.
- Keep explicit versions where they convey necessary information: migration instructions, historical release notes, minimum supported Rust versions, or reproducible examples tied to a particular release. Preserve historical references when newer releases appear.
- Use manifest snippets when explaining dependency requirements or features, and validate them against the supported API. Choose ranges according to the package's compatibility policy. The open-ended minimum for private `base-project` tooling follows its setup guidance; runtime libraries use requirements appropriate to their supported APIs.
- When a version must appear in several current documents, generate those references from authoritative metadata as part of the documentation tasks.

## Development and releases

- Keep development tasks in a private `bake/` package. Depend on `base-project` there so task tooling does not become a runtime dependency of the published library.
- Use the `cargo:after_version_bump` hook registered by `base-project` to update `license.md`, `releases.md`, and the generated sections of `readme.md`, then normalize those files and all Markdown under the public `context/` directory.
- Follow the `base-project-pull-requests` skill, including independent adversarial review and local iteration until all non-trivial issues are resolved.
- Follow the `base-project-releasing` skill to prepare and publish a release. It links to Bake Cargo task documentation for workflow setup, trusted publishing, reviewers, and tag creation.