const UNIMPLEMENTED_ERROR_CODE: i32 = -32001;
fn write_unimplemented_message(tool_name: &str) -> String {
format!(
"Tool '{tool_name}' is not yet implemented. Tracking: KAIZEN-0200. \
This is a known stub that was previously masquerading as real output — \
see R21-1 / D90 / D92."
)
}
fn unimplemented_response(request_id: Value, tool_name: &str) -> McpResponse {
McpResponse::error(
request_id,
UNIMPLEMENTED_ERROR_CODE,
write_unimplemented_message(tool_name),
)
}
async fn handle_duplicates_vectorized(request_id: Value, _args: Option<Value>) -> McpResponse {
info!("⚠️ analyze_duplicates_vectorized invoked — returning unimplemented (R21-1)");
unimplemented_response(request_id, "analyze_duplicates_vectorized")
}
async fn handle_graph_metrics_vectorized(request_id: Value, _args: Option<Value>) -> McpResponse {
info!("⚠️ analyze_graph_metrics_vectorized invoked — returning unimplemented (R21-1)");
unimplemented_response(request_id, "analyze_graph_metrics_vectorized")
}
async fn handle_name_similarity_vectorized(request_id: Value, _args: Option<Value>) -> McpResponse {
info!("⚠️ analyze_name_similarity_vectorized invoked — returning unimplemented (R21-1)");
unimplemented_response(request_id, "analyze_name_similarity_vectorized")
}
async fn handle_symbol_table_vectorized(request_id: Value, _args: Option<Value>) -> McpResponse {
info!("⚠️ analyze_symbol_table_vectorized invoked — returning unimplemented (R21-1)");
unimplemented_response(request_id, "analyze_symbol_table_vectorized")
}
async fn handle_incremental_coverage_vectorized(
request_id: Value,
_args: Option<Value>,
) -> McpResponse {
info!("⚠️ analyze_incremental_coverage_vectorized invoked — returning unimplemented (R21-1)");
unimplemented_response(request_id, "analyze_incremental_coverage_vectorized")
}
async fn handle_big_o_vectorized(request_id: Value, _args: Option<Value>) -> McpResponse {
info!("⚠️ analyze_big_o_vectorized invoked — returning unimplemented (R21-1)");
unimplemented_response(request_id, "analyze_big_o_vectorized")
}
async fn handle_enhanced_report(request_id: Value, _args: Option<Value>) -> McpResponse {
info!("⚠️ generate_enhanced_report invoked — returning unimplemented (R21-1)");
unimplemented_response(request_id, "generate_enhanced_report")
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod fail_loud_tests {
use super::*;
use serde_json::json;
fn assert_unimplemented(resp: &McpResponse, expected_tool: &str) {
assert!(
resp.result.is_none(),
"fail-loud response must not carry a result payload"
);
let err = resp
.error
.as_ref()
.expect("fail-loud response must carry an error");
assert_eq!(
err.code, UNIMPLEMENTED_ERROR_CODE,
"error code must be -32001 (application-defined 'not implemented')"
);
assert!(
err.message.contains(expected_tool),
"error message must name the invoked tool, got: {}",
err.message
);
assert!(
err.message.contains("not yet implemented"),
"error message must clearly state unimplemented, got: {}",
err.message
);
assert!(
err.message.contains("KAIZEN-0200"),
"error message must reference tracking ticket, got: {}",
err.message
);
}
#[tokio::test]
async fn duplicates_vectorized_fails_loud() {
let r = handle_duplicates_vectorized(json!(1), Some(json!({"project_path": "/tmp"}))).await;
assert_unimplemented(&r, "analyze_duplicates_vectorized");
}
#[tokio::test]
async fn graph_metrics_vectorized_fails_loud() {
let r =
handle_graph_metrics_vectorized(json!(2), Some(json!({"project_path": "/tmp"}))).await;
assert_unimplemented(&r, "analyze_graph_metrics_vectorized");
}
#[tokio::test]
async fn name_similarity_vectorized_fails_loud() {
let r = handle_name_similarity_vectorized(
json!(3),
Some(json!({"project_path": "/tmp", "query": "foo"})),
)
.await;
assert_unimplemented(&r, "analyze_name_similarity_vectorized");
}
#[tokio::test]
async fn symbol_table_vectorized_fails_loud() {
let r =
handle_symbol_table_vectorized(json!(4), Some(json!({"project_path": "/tmp"}))).await;
assert_unimplemented(&r, "analyze_symbol_table_vectorized");
}
#[tokio::test]
async fn incremental_coverage_vectorized_fails_loud() {
let r =
handle_incremental_coverage_vectorized(json!(5), Some(json!({"project_path": "/tmp"})))
.await;
assert_unimplemented(&r, "analyze_incremental_coverage_vectorized");
}
#[tokio::test]
async fn big_o_vectorized_fails_loud() {
let r = handle_big_o_vectorized(json!(6), Some(json!({"project_path": "/tmp"}))).await;
assert_unimplemented(&r, "analyze_big_o_vectorized");
}
#[tokio::test]
async fn enhanced_report_fails_loud() {
let r = handle_enhanced_report(json!(7), Some(json!({"project_path": "/tmp"}))).await;
assert_unimplemented(&r, "generate_enhanced_report");
}
#[tokio::test]
async fn no_args_still_fails_loud_not_silent() {
let r = handle_duplicates_vectorized(json!(8), None).await;
assert_unimplemented(&r, "analyze_duplicates_vectorized");
}
#[test]
fn message_is_stable_and_mentions_tracking() {
let msg = write_unimplemented_message("analyze_duplicates_vectorized");
assert!(msg.contains("analyze_duplicates_vectorized"));
assert!(msg.contains("not yet implemented"));
assert!(msg.contains("KAIZEN-0200"));
assert!(msg.contains("masquerading"));
}
#[test]
fn dispatch_through_handle_vectorized_tools_fails_loud() {
use crate::models::mcp::ToolCallParams;
let rt = tokio::runtime::Runtime::new().expect("runtime");
for tool in VECTORIZED_TOOLS {
let params = ToolCallParams {
name: (*tool).to_string(),
arguments: json!({"project_path": "/tmp", "query": "foo"}),
};
let resp = rt.block_on(handle_vectorized_tools(json!(99), params));
assert_unimplemented(&resp, tool);
}
}
}