Skip to content

Crates, Cargo features and registries

The four crates

Crate Depend on it for docs.rs
rtb-cli Application::builder, clap wiring, version / doctor / init / config / credentials / telemetry rtb-cli
rtb-docs The docs command, the TUI browser, the HTTP server, full-text search rtb-docs
rtb-update The update command, the Updater API, the pre-run policy hook rtb-update
rtb-mcp The mcp command and the MCP server rtb-mcp

All four share one version line and are released together from this repo. Mixing versions across them is not a supported configuration.

Item-level API documentation lives on docs.rs and is generated from the source, so it cannot drift. This site documents behaviour, not signatures.

Cargo features

There is exactly one Cargo feature in the family:

Crate Feature Default Enables
rtb-docs ai off docs ask and the rtb-chat-backed AiAnswerStream implementation

rtb-cli, rtb-update and rtb-mcp declare no features of their own.

With ai off, the docs ask subcommand still exists and still parses — it fails at run time with rtb::docs::ai_disabled and help text telling you to rebuild with --features ai. That is deliberate: a command that vanishes looks like a typo, where one that explains itself does not.

Runtime Feature gating is a different mechanism entirely — see the CLI reference.

Toolchain

Requirement Value
rust-version (MSRV) 1.82
Edition 2021
Toolchain pinned for development 1.97.1, via rust-toolchain.toml

The pin exists because the trybuild compile-fail fixtures compare rustc's diagnostic output byte for byte, and a floating channel re-renders those on every stable release. It is a development pin, not a consumer requirement — the MSRV is what a downstream tool has to satisfy.

Four linkme distributed slices carry everything that self-registers. A crate that is not linked contributes nothing to any of them, which is why an unused rtb-docs dependency produces no docs command.

Slice Defined in Element Consumed by
rtb_app::command::BUILTIN_COMMANDS rtb-app fn() -> Box<dyn Command> Application::build, and mcp list
rtb_app::command::BUILTIN_PRERUN_HOOKS rtb-app fn(App) -> PreRunFuture Application::run_with_args, before dispatch
rtb_cli::health::HEALTH_CHECKS rtb-cli fn() -> Box<dyn HealthCheck> doctor
rtb_cli::init::INITIALISERS rtb-cli fn() -> Box<dyn Initialiser> init

Slice order is decided by the linker and is not stable across compiler versions or dependency-graph changes. Registration order is therefore not something to depend on — commands are sorted by name before clap sees them, and health checks and initialisers run in whatever order the linker produced.

The unsafe_code position

Every crate sets unsafe_code = "deny" at the workspace level rather than forbid. deny is not a weaker guarantee here — it is what allows the modules that register into a linkme slice to carry a narrowly-scoped #![allow(unsafe_code)] for the #[link_section] attribute the macro emits. No hand-written unsafe block exists anywhere in the family.