diff --git a/rust/crates/sift_cli/assets/skills/sift/SKILL.md b/rust/crates/sift_cli/assets/skills/sift/SKILL.md index 32d21a69e..fc73d0ede 100644 --- a/rust/crates/sift_cli/assets/skills/sift/SKILL.md +++ b/rust/crates/sift_cli/assets/skills/sift/SKILL.md @@ -52,6 +52,9 @@ exists. - **Report detail:** `list_report_rule_summaries`. - **Test results:** `list_test_reports`, `list_test_steps`, `list_test_measurements`, `count_test_steps`, `count_test_measurements`. + These, along with the `create_test_report` and `append_test_measurements` + writes below, are gated behind the `test-reports` Cargo feature (default on). + A server built with `--no-default-features` will not expose them. - **Data:** `get_data` writes channel data to a Parquet file. `sql` queries Parquet files. `upload_dataset` streams a Parquet dataset into Sift. - **Links:** `explore_url`. diff --git a/rust/crates/sift_mcp/CLAUDE.md b/rust/crates/sift_mcp/CLAUDE.md index c109bbf9a..b6e9fdb55 100644 --- a/rust/crates/sift_mcp/CLAUDE.md +++ b/rust/crates/sift_mcp/CLAUDE.md @@ -629,6 +629,30 @@ and `derive_and_upload` are the reference implementations. --- +## Reference — feature flags + +The crate defines Cargo features to let downstream consumers strip individual tool domains from +the built server. Feature-gated modules follow the same rules as everything else, plus these: + +- **`test-reports`** (default on). Gates `service::test_reports`, `tool::test_reports`, the + `test_report_service` field and its construction in `server/mod.rs`, the + `Self::test_reports_router()` merge, and `UrlService::build_test_report_url`. Building with + `--no-default-features` yields a server without the `list_test_reports`, `list_test_steps`, + `list_test_measurements`, `count_test_steps`, `count_test_measurements`, `create_test_report`, + and `append_test_measurements` tools. All other tools remain available. + +When gating a domain behind a feature: + +- Wrap every declaration and reference — `pub mod`, `use`, struct field, service construction, + router merge, `Self { ... }` init, and any helper on a cross-domain service (see + `UrlService::build_test_report_url`) that only that domain calls. +- Verify both `cargo build -p sift_mcp` and `cargo build -p sift_mcp --no-default-features` + build clean, with no dead-code warnings from unused helpers left behind. +- Update the tool inventory in `rust/crates/sift_cli/assets/skills/sift/SKILL.md` to name the + feature next to the affected tools, so agents know why a tool they expected may be missing. + +--- + ## Pre-merge checklist Run through this before declaring the tool done: diff --git a/rust/crates/sift_mcp/Cargo.toml b/rust/crates/sift_mcp/Cargo.toml index da188dbde..f221a6136 100644 --- a/rust/crates/sift_mcp/Cargo.toml +++ b/rust/crates/sift_mcp/Cargo.toml @@ -31,6 +31,9 @@ parquet.workspace = true polars = { workspace = true, features = ["lazy", "parquet", "sql"] } tokio-stream.workspace = true +[features] +test-reports = [] + [dev-dependencies] sift_test_util.workspace = true tokio-stream.workspace = true diff --git a/rust/crates/sift_mcp/src/server/mod.rs b/rust/crates/sift_mcp/src/server/mod.rs index 3c9569e2a..e4be60508 100644 --- a/rust/crates/sift_mcp/src/server/mod.rs +++ b/rust/crates/sift_mcp/src/server/mod.rs @@ -10,11 +10,13 @@ use rmcp::{ use sift_rs::SiftChannel; use crate::policy::RetryPolicy; +#[cfg(feature = "test-reports")] +use crate::service::test_reports::TestReportService; use crate::service::{ annotations::AnnotationService, assets::AssetService, channels::ChannelService, data::DataService, docs::DocsService, ingest::IngestService, ping::PingService, report_templates::ReportTemplateService, reports::ReportService, rules::RuleService, - runs::RunService, test_reports::TestReportService, url::UrlService, users::UserService, + runs::RunService, url::UrlService, users::UserService, }; #[derive(Clone)] @@ -33,6 +35,7 @@ pub struct SiftMcpServer { pub report_service: ReportService, pub report_template_service: ReportTemplateService, pub rule_service: RuleService, + #[cfg(feature = "test-reports")] pub test_report_service: TestReportService, pub docs_service: DocsService, pub user_service: UserService, @@ -93,6 +96,7 @@ impl SiftMcpServer { tool_router.merge(Self::ping_router()); tool_router.merge(Self::rules_router()); tool_router.merge(Self::annotations_router()); + #[cfg(feature = "test-reports")] tool_router.merge(Self::test_reports_router()); tool_router.merge(Self::docs_router()); tool_router.merge(Self::users_router()); @@ -113,6 +117,7 @@ impl SiftMcpServer { let report_template_service = ReportTemplateService::new(channel.clone(), retry_policy.clone()); let rule_service = RuleService::new(channel.clone(), retry_policy.clone()); + #[cfg(feature = "test-reports")] let test_report_service = TestReportService::new(channel.clone(), retry_policy.clone()); let docs_service = DocsService::new(channel.clone(), retry_policy.clone()); let user_service = UserService::new(channel.clone(), retry_policy); @@ -129,6 +134,7 @@ impl SiftMcpServer { report_service, report_template_service, rule_service, + #[cfg(feature = "test-reports")] test_report_service, docs_service, user_service, diff --git a/rust/crates/sift_mcp/src/service/mod.rs b/rust/crates/sift_mcp/src/service/mod.rs index a83451035..2ab197f71 100644 --- a/rust/crates/sift_mcp/src/service/mod.rs +++ b/rust/crates/sift_mcp/src/service/mod.rs @@ -9,6 +9,7 @@ pub mod report_templates; pub mod reports; pub mod rules; pub mod runs; +#[cfg(feature = "test-reports")] pub mod test_reports; pub mod url; pub mod users; diff --git a/rust/crates/sift_mcp/src/service/url/mod.rs b/rust/crates/sift_mcp/src/service/url/mod.rs index 595e35311..dd029df5a 100644 --- a/rust/crates/sift_mcp/src/service/url/mod.rs +++ b/rust/crates/sift_mcp/src/service/url/mod.rs @@ -127,6 +127,7 @@ impl UrlService { Ok(format!("{host}/reports/{}", encode_value(report_id))) } + #[cfg(feature = "test-reports")] pub fn build_test_report_url(&self, test_report_id: &str) -> Result { let host = self.app_host()?; Ok(format!( diff --git a/rust/crates/sift_mcp/src/tool/mod.rs b/rust/crates/sift_mcp/src/tool/mod.rs index b82d00e17..199d51416 100644 --- a/rust/crates/sift_mcp/src/tool/mod.rs +++ b/rust/crates/sift_mcp/src/tool/mod.rs @@ -10,5 +10,6 @@ pub mod report_templates; pub mod reports; pub mod rules; pub mod runs; +#[cfg(feature = "test-reports")] pub mod test_reports; pub mod users;