diff --git a/crates/uffs-cli/Cargo.toml b/crates/uffs-cli/Cargo.toml index 43a06f427..4293d28ad 100644 --- a/crates/uffs-cli/Cargo.toml +++ b/crates/uffs-cli/Cargo.toml @@ -92,14 +92,23 @@ which.workspace = true uffs-time.workspace = true # ───────────────────────────────────────────────────────────────────────────── -# Features +# Features (contract documented per playbook §988 — see +# `crates/uffs-cli/src/main.rs` `# Features` rustdoc and +# `docs/architecture/code-quality/dependency_policy.md`) # ───────────────────────────────────────────────────────────────────────────── -# `mcp-http-probe`: enable `uffs system-status` probing of the MCP HTTP -# gateway. Disabled by default because it is the sole user of -# `std::net::TcpStream` in the CLI, which unconditionally links -# `ws2_32.dll` on Windows and adds measurable process-launch overhead. -# Without this feature, `system-status` still reports the configured -# HTTP bind address — it just doesn't actively probe `/status`. +# +# `mcp-http-probe` — **default-off**, **additive**. +# +# * Enables `uffs status` probing the MCP HTTP gateway's `/status` +# endpoint inside `commands::system_status`. +# * Adds no crate-graph deps; uses `std::net::TcpStream` (libstd). +# * Disabled by default because `std::net::TcpStream` is the sole +# reason `ws2_32.dll` would be linked on Windows, adding ~50 ms +# to cold-start launch. Without the feature, `uffs status` still +# reports the configured HTTP bind address — it just does not +# actively probe `/status`. +# * Semver: removing the probe behaviour or its observable output +# is breaking; adding richer probe output is not. [features] default = [] mcp-http-probe = [] diff --git a/crates/uffs-cli/src/main.rs b/crates/uffs-cli/src/main.rs index 39b4329dd..fa42cffb1 100644 --- a/crates/uffs-cli/src/main.rs +++ b/crates/uffs-cli/src/main.rs @@ -7,6 +7,25 @@ //! This binary detects subcommands and forwards raw search args via //! `search_cli` RPC. Argument transforms specific to the search //! subcommand live in [`commands::search::args`]. +//! +//! # Features +//! +//! Documented per the workspace dependency policy +//! (`docs/architecture/code-quality/dependency_policy.md`, playbook §988). +//! +//! | Feature | Default? | Enables | Adds deps | Binary-size impact | Semver | +//! |---|:---:|---|---|---|---| +//! | `mcp-http-probe` | **no** | Active probing of the MCP HTTP gateway's `/status` endpoint inside `uffs status` (see [`commands::system_status`]). Without it, `uffs status` still reports the configured HTTP bind address but does not actively probe. | None on the crate graph. Uses `std::net::TcpStream` (libstd) — but on Windows targets that drag in `ws2_32.dll`, adding ~50 ms to cold-start process launch. | Disabling drops the only `std::net` user from the CLI: `ws2_32.dll` is left unlinked. This is **the** reason the feature is default-off — the CLI is the thin / fast-path binary. | Removing the probe behaviour or its observable output behind `mcp-http-probe` is breaking; adding richer probe output is not. | +//! +//! ## Why `mcp-http-probe` is default-off +//! +//! `uffs-cli` is the thin synchronous fast-path binary. Every byte +//! and every millisecond of cold-start matter (the CLI typically +//! runs once per shell invocation; the daemon is the long-lived +//! reactor). `std::net::TcpStream` is the lone reason `ws2_32.dll` +//! would be linked on Windows; gating its use behind a non-default +//! feature lets package builds opt in only when probe data is worth +//! the launch-time hit. // CLI main module uses single-call functions by design #![expect( diff --git a/crates/uffs-client/Cargo.toml b/crates/uffs-client/Cargo.toml index d3884162c..01628960d 100644 --- a/crates/uffs-client/Cargo.toml +++ b/crates/uffs-client/Cargo.toml @@ -46,11 +46,24 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] targets = ["x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc"] +# ───────────────────────────────────────────────────────────────────────────── +# Features (contract documented per playbook §988 — see +# `crates/uffs-client/src/lib.rs` `# Features` rustdoc and +# `docs/architecture/code-quality/dependency_policy.md`) +# ───────────────────────────────────────────────────────────────────────────── +# +# `async` — **default-on**, **additive**. +# +# * Enables the async `connect::UffsClient` (tokio reactor) used by +# `uffs-daemon`'s embedded client and `uffs-mcp`'s bridge. +# * Adds `dep:tokio` (with the `net` feature). +# * Default-on so existing consumers (`uffs-daemon`, `uffs-mcp`) +# keep working with no change. `uffs-cli` overrides with +# `default-features = false` to drop tokio + `ws2_32.dll` from +# the sync-CLI binary. +# * Semver: removing items behind `async` is breaking; adding new +# items behind it is not. [features] -# Default enables the async `UffsClient` (tokio-based) so existing -# consumers (`uffs-daemon`, `uffs-mcp`) keep working with no change. -# The CLI (`uffs-cli`) overrides with `default-features = false` to -# drop tokio + `ws2_32.dll` from the hot-path binary. default = ["async"] async = ["dep:tokio"] diff --git a/crates/uffs-client/src/lib.rs b/crates/uffs-client/src/lib.rs index 8e4a8f748..d0780c41d 100644 --- a/crates/uffs-client/src/lib.rs +++ b/crates/uffs-client/src/lib.rs @@ -14,6 +14,24 @@ //! let drives = client.drives().await?; //! ``` //! +//! # Features +//! +//! Documented per the workspace dependency policy +//! (`docs/architecture/code-quality/dependency_policy.md`, playbook §988). +//! +//! | Feature | Default? | Enables | Adds deps | API impact | Semver | +//! |---|:---:|---|---|---|---| +//! | `async` | yes | The async [`connect::UffsClient`] (tokio reactor) used by `uffs-daemon`'s embedded client + `uffs-mcp`'s bridge | `dep:tokio` (with the `net` feature) | **Additive**: enabling adds [`connect`], `connect_keepalive`, `connect_logging`, `connect_platform`, and the async test surface. All sync items ([`connect_sync::UffsClientSync`], [`protocol`], [`schema`]) compile identically with the feature off. | Removing an item behind `async` is breaking; adding one is not. | +//! +//! ## Why `async` is default-on +//! +//! `uffs-daemon` and `uffs-mcp` both consume `uffs-client` with default +//! features so the async [`connect::UffsClient`] is available without +//! an explicit feature opt-in. `uffs-cli` overrides with +//! `default-features = false` (see `crates/uffs-cli/Cargo.toml`) to +//! drop tokio + `ws2_32.dll` from the sync-CLI binary — the canonical +//! "consumer chooses to shrink the surface" pattern. +//! //! ## API hygiene policy (Phase 3b §3.4 / §3.6 / §3.7) //! //! - **`protocol::*` wire DTOs / wire enums** — `pub` fields **are** the diff --git a/crates/uffs-mcp/Cargo.toml b/crates/uffs-mcp/Cargo.toml index 3d27229d2..77537cda4 100644 --- a/crates/uffs-mcp/Cargo.toml +++ b/crates/uffs-mcp/Cargo.toml @@ -57,6 +57,25 @@ name = "uffs-mcp-http" path = "src/bin/http_gateway.rs" required-features = ["streamable-http"] +# ───────────────────────────────────────────────────────────────────────────── +# Features (contract documented per playbook §988 — see +# `crates/uffs-mcp/src/lib.rs` `# Features` rustdoc and +# `docs/architecture/code-quality/dependency_policy.md`) +# ───────────────────────────────────────────────────────────────────────────── +# +# `streamable-http` — **default-on**, **additive**. +# +# * Enables the `http` module + the `uffs-mcp-http` binary +# (`src/bin/http_gateway.rs`). The binary carries +# `required-features = ["streamable-http"]` and so does not +# build at all when the feature is off. +# * Adds `rmcp/transport-streamable-http-server`, `dep:axum`, +# `dep:tower-service`. +# * Default-on so UFFS ships the HTTP gateway as a first-class +# transport alongside stdio. Downstream MCP integrations that +# only want the stdio transport pass `default-features = false`. +# * Semver: removing items behind `streamable-http` is breaking; +# adding new items behind it is not. [features] default = ["streamable-http"] streamable-http = [ diff --git a/crates/uffs-mcp/src/lib.rs b/crates/uffs-mcp/src/lib.rs index 1c4fffe34..6dd8f2380 100644 --- a/crates/uffs-mcp/src/lib.rs +++ b/crates/uffs-mcp/src/lib.rs @@ -25,6 +25,25 @@ //! uffs_mcp::run_mcp_server().await //! # } //! ``` +//! +//! # Features +//! +//! Documented per the workspace dependency policy +//! (`docs/architecture/code-quality/dependency_policy.md`, playbook §988). +//! +//! | Feature | Default? | Enables | Adds deps | API impact | Semver | +//! |---|:---:|---|---|---|---| +//! | `streamable-http` | yes | The [`http`] module + the `uffs-mcp-http` binary (`src/bin/http_gateway.rs`). Activates rmcp's streamable-HTTP server transport. | `rmcp/transport-streamable-http-server`, `dep:axum`, `dep:tower-service` | **Additive**: enabling adds `pub mod http`, the `mcp_serve` helper in `main.rs`, and the `uffs-mcp-http` binary (which carries `required-features = ["streamable-http"]` and so does not build at all when the feature is off). All stdio surfaces ([`handler::UffsMcpServer`], `resources`, `roots`, `schemas`, [`text`], `tools`) compile identically with the feature off. | Removing an item behind `streamable-http` is breaking; adding one is not. | +//! +//! ## Why `streamable-http` is default-on +//! +//! UFFS ships the HTTP gateway as a first-class transport (the +//! stdio-only path covers Claude Desktop / Cursor / Windsurf, but +//! `uffs daemon http` and browser-side MCP clients need the streamable +//! HTTP server). Downstream MCP integrations that only want the +//! stdio transport can pass `default-features = false` to drop +//! axum and tower-service from their binary; both transports share +//! the same tool / resource / prompt surface. // On docs.rs only: enable the `doc_cfg` rustdoc feature so cfg-gated items // render with their cfg badge. Gated behind `cfg(docsrs)` so local