feat(workspace): record broad approvals with allow-root --approve-broad

Replace the PATH_ALLOW_BROAD environment variable with a recorded grant,
the shape agreed in review: `codebase-memory-mcp allow-root
--approve-broad <path>` records an explicit human approval for one root
refused as too broad (CBM_WS_DENY_TOO_SHALLOW), mirroring
--approve-sensitive end to end.

- cbm_workspace_grant_add() takes approve_broad next to
  approve_sensitive. Each flag lifts only its own verdict, absolute
  denials stay unliftable, and a refusal names the flag that would
  lift it.
- The approval is stored with a '^' marker, listed by allow-root --list
  as "(approved broad)", and honoured by cbm_workspace_root_allowed()
  only for CBM_WS_DENY_TOO_SHALLOW and only on an exact path match,
  keeping the exact-match rule of the original change.
- cbm_workspace_root_allowed() returns to its previous signature. Every
  caller (MCP index_repository and index-job start, auto-index, daemon
  sessions, the HTTP UI) reads the same grant store, so stdio and
  daemon sessions decide identically and nothing depends on the
  environment a daemon was started with.
- The too-broad refusal names `allow-root --approve-broad <path>`, a
  command a person runs.
- cbm_workspace_classify_root() and cbm_workspace_verdict_is_overridable()
  are unchanged.

The regression test keeps its name and its exact-match, sibling,
absolute and sensitive checks, now against the grant store, and adds
that a broad marker never lifts a sensitive verdict.

Co-authored-by: Mark Murawski <github@kobaz.net>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
Martin VogelandMark Murawski committed 2026-10-20 19:26:31 +02:00
1 parent b9df26094f
commit 3e2de74e98
10 files changed
+227 -133

No files matched your search

+9
View File
@@ -237,6 +237,15 @@ root because they are too broad or too sensitive to index as a unit:
- a credential directory at any depth — `.ssh`, `.aws`, `.gnupg`, `.kube`,
`.docker`, `.netrc`, `.git-credentials`, `.password-store`, macOS `Keychains`.
A single top-level directory can still be indexed as one root on purpose, for
example a container or build machine that keeps its project in `/work`, `/app` or
`/src`, by approving that exact path in a terminal:
`codebase-memory-mcp allow-root --approve-broad /work`. The approval is recorded
like any other allowed root, listed as `(approved broad)` by `allow-root --list`,
and covers no other top-level directory; as with any recorded root, indexing is
then confined to the recorded roots. Filesystem, drive and share roots cannot be
approved.
Two limits are worth stating plainly. This constrains *scope*, not
*sensitivity*: inside a root that is allowed, every file the process can read may
be indexed and later returned. And the credential list is a denylist, so it