CBM_WS_DENY_TOO_SHALLOW ("path is too broad to index as one root") has
no override today: cbm_workspace_verdict_is_overridable() only lifts
CBM_WS_DENY_SENSITIVE, and `allow-root --list` already documents
shallow/absolute refusals as "always-refused" rather than configurable.
That default is right -- a bare top-level tree like "/etc" or "/home"
is almost always a mistake -- but it leaves no way to say "I mean this
one specific broad root, on purpose." That's a real case: a person who
deliberately wants one combined project spanning several sibling repos
under a shared parent has no path forward today short of physically
restructuring their checkout.
PATH_ALLOW_BROAD names one exact canonical path that lifts a
CBM_WS_DENY_TOO_SHALLOW verdict, and only that verdict:
- exact match only, not a prefix -- naming one broad root must not
quietly approve every root below it too, the same "/Users"-style
breadth this depth rule exists to catch in the first place
- process environment, not a recorded grant: it never appears in
cbm_workspace_grant_list, and cbm_workspace_verdict_is_overridable()
is untouched, so CBM_WS_DENY_ABSOLUTE and CBM_WS_DENY_SENSITIVE stay
exactly as unliftable as before
- read once per call site with getenv(), mirroring how CBM_ALLOWED_ROOT
is already threaded into cbm_workspace_root_allowed() from each of
its four callers, rather than read inside
cbm_workspace_classify_root() itself -- that function is documented
as a pure function of its arguments precisely so it stays
host-independent and directly testable
Also updates the refusal message to name the fix, the same way the
sensitive-root refusal already names `allow-root --approve-sensitive`.
Adds ws_allow_broad_root_lifts_too_shallow_for_an_exact_match_only
alongside the existing too-shallow coverage, checking the exact-match
requirement, the untouched sensitive/absolute paths, and that nothing
is written to the grant store.
Signed-off-by: Mark Murawski <github@kobaz.net>