mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-09 09:11:00 +08:00
fix(mcp): report dirty freshness for architecture
Add canonical-only dirty freshness metadata to get_architecture responses so architecture summaries stay visible while pending dirty files are disclosed. Cover the behavior with an MCP regression test and validate with focused architecture canary, full MCP suite, source-safety, diff hygiene, and product build logs under /private/tmp. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
This commit is contained in:
@@ -4278,6 +4278,14 @@ static char *handle_get_architecture(cbm_mcp_server_t *srv, const char *args) {
|
||||
add_stale_derived_view_warning(doc, root, CBM_STORE_DERIVED_VIEW_ROUTES,
|
||||
"routes derived view is stale; route results may be stale.");
|
||||
}
|
||||
int dirty_pending = 0;
|
||||
int dirty_overlay_ready = 0;
|
||||
if (get_dirty_file_counts(store, project, &dirty_pending, &dirty_overlay_ready)) {
|
||||
add_dirty_file_freshness_counts(doc, root, dirty_pending, dirty_overlay_ready);
|
||||
add_response_warning(doc, root,
|
||||
"get_architecture reads canonical graph summaries; dirty file "
|
||||
"changes may be absent until overlay or reindex completes.");
|
||||
}
|
||||
|
||||
/* Node label summary */
|
||||
if (aspect_wanted(aspects_doc, aspects_arr, "structure")) {
|
||||
|
||||
@@ -1767,6 +1767,51 @@ TEST(tool_get_architecture_warns_on_stale_derived_views) {
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(tool_get_architecture_reports_dirty_metadata_as_canonical_only) {
|
||||
cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL);
|
||||
ASSERT_NOT_NULL(srv);
|
||||
cbm_store_t *st = cbm_mcp_server_store(srv);
|
||||
ASSERT_NOT_NULL(st);
|
||||
|
||||
const char *proj = "arch-dirty";
|
||||
ASSERT_EQ(cbm_store_upsert_project(st, proj, "/tmp/arch-dirty"), CBM_STORE_OK);
|
||||
cbm_mcp_server_set_project(srv, proj);
|
||||
|
||||
cbm_node_t fn = {.project = proj,
|
||||
.label = "Function",
|
||||
.name = "Run",
|
||||
.qualified_name = "arch-dirty.Run",
|
||||
.file_path = "run.c",
|
||||
.properties_json = "{\"is_entry_point\":true}"};
|
||||
ASSERT_GT(cbm_store_upsert_node(st, &fn), 0);
|
||||
|
||||
cbm_dirty_file_state_t dirty = {.project = proj,
|
||||
.rel_path = "run.c",
|
||||
.observed_hash = "arch-dirty-hash",
|
||||
.observed_generation = 13,
|
||||
.source = CBM_STORE_DIRTY_SOURCE_EXPLICIT_REINDEX,
|
||||
.status = CBM_STORE_DIRTY_STATUS_PENDING};
|
||||
ASSERT_EQ(cbm_store_upsert_dirty_file(st, &dirty), CBM_STORE_OK);
|
||||
|
||||
char *resp = cbm_mcp_server_handle(
|
||||
srv, "{\"jsonrpc\":\"2.0\",\"id\":95,\"method\":\"tools/call\","
|
||||
"\"params\":{\"name\":\"get_architecture\","
|
||||
"\"arguments\":{\"project\":\"arch-dirty\",\"aspects\":[\"all\"]}}}");
|
||||
ASSERT_NOT_NULL(resp);
|
||||
char *inner = extract_text_content(resp);
|
||||
ASSERT_NOT_NULL(inner);
|
||||
ASSERT_NOT_NULL(strstr(inner, "\"entry_points\""));
|
||||
ASSERT_NOT_NULL(strstr(inner, "Run"));
|
||||
ASSERT_NOT_NULL(strstr(inner, "\"warnings\""));
|
||||
ASSERT_NOT_NULL(strstr(inner, "get_architecture reads canonical graph summaries"));
|
||||
ASSERT_TRUE(has_dirty_freshness_counts(inner, 1, 0));
|
||||
|
||||
free(inner);
|
||||
free(resp);
|
||||
cbm_mcp_server_free(srv);
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(tool_get_architecture_path_scoping) {
|
||||
cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL);
|
||||
ASSERT_NOT_NULL(srv);
|
||||
@@ -3995,6 +4040,7 @@ SUITE(mcp) {
|
||||
RUN_TEST(tool_get_architecture_empty);
|
||||
RUN_TEST(tool_get_architecture_emits_populated_sections);
|
||||
RUN_TEST(tool_get_architecture_warns_on_stale_derived_views);
|
||||
RUN_TEST(tool_get_architecture_reports_dirty_metadata_as_canonical_only);
|
||||
RUN_TEST(tool_get_architecture_path_scoping);
|
||||
RUN_TEST(tool_query_graph_missing_query);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user