MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / cbm_workspace_classify_root

Function cbm_workspace_classify_root

src/foundation/workspace.c:234–308  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

232}
233
234cbm_ws_verdict_t cbm_workspace_classify_root(const char *canonical_path, const char *home_dir,
235 const char *cache_dir) {
236 if (!canonical_path || !canonical_path[0] || ws_volume_prefix_len(canonical_path) == 0) {
237 /* A relative or empty path is not a usable root; refuse it the same way
238 * as a volume root rather than letting it fall through as allowed. */
239 return CBM_WS_DENY_ABSOLUTE;
240 }
241
242 bool windows_style = ws_is_windows_style(canonical_path);
243 int depth = cbm_workspace_path_depth(canonical_path);
244
245 /* A volume, drive or share root, whatever the platform. */
246 if (depth == 0) {
247 return CBM_WS_DENY_ABSOLUTE;
248 }
249
250 /* Order matters below, and not for cosmetic reasons.
251 *
252 * The home directory normally CONTAINS the cache directory, so testing the
253 * cache first would report every $HOME as "holds the cache" — and, worse,
254 * would make it absolutely denied when the design says a person may override
255 * it. Home is therefore classified first.
256 *
257 * Depth comes before the cache test for the same kind of reason: "/Users" is
258 * both too broad and an ancestor of the cache, and "too broad, name a
259 * project directory below it" is the reason that actually helps the reader. */
260 if (home_dir && home_dir[0] && ws_paths_equal(canonical_path, home_dir)) {
261 return CBM_WS_DENY_SENSITIVE;
262 }
263
264 /* Below a drive or a UNC share the first component is already user space
265 * ("D:/repos", "//srv/share/proj"), so one component is enough there. Below a
266 * POSIX root it is a system tree, so require two. */
267 int min_depth =
268 (windows_style || ws_is_unc(canonical_path)) ? WS_MIN_DEPTH_WINDOWS : WS_MIN_DEPTH_POSIX;
269 if (depth < min_depth) {
270 return CBM_WS_DENY_TOO_SHALLOW;
271 }
272
273 /* No rule here for "this root contains the cache directory".
274 *
275 * An earlier draft refused such roots outright, on the theory that indexing
276 * them would absorb every other project's graph database. Two things make
277 * that wrong. The indexer only parses recognised source files, and a graph
278 * database is binary SQLite it would never extract; and refusing an entire
279 * root is the wrong remedy even where the concern holds — the right one is to
280 * not walk the cache. Excluding the cache from discovery is tracked
281 * separately; classifying the root is not the place for it.
282 *
283 * cache_dir stays in the signature because the exclusion work will need it
284 * and because callers already have it to hand. */
285 (void)cache_dir;
286
287 if (ws_any_component_matches(canonical_path, WS_CREDENTIAL_NAMES,
288 sizeof(WS_CREDENTIAL_NAMES) / sizeof(WS_CREDENTIAL_NAMES[0]),
289 windows_style)) {
290 return CBM_WS_DENY_SENSITIVE;
291 }

Callers 5

cbm_workspace_grant_addFunction · 0.85
test_workspace.cFile · 0.85

Calls 7

ws_volume_prefix_lenFunction · 0.85
ws_is_windows_styleFunction · 0.85
cbm_workspace_path_depthFunction · 0.85
ws_paths_equalFunction · 0.85
ws_is_uncFunction · 0.85
ws_any_component_matchesFunction · 0.85

Tested by

no test coverage detected