2 months ago
de67a62Delegates the deny-side path checks to the platform layer's fail-direction
case folding (docs/platform-abstraction-plan.md rows 12, 13, 21, 22):
- PROTECTED_METADATA_DIR_NAMES moves into src/platform/paths.ts;
pathCrossesProtectedMetadata delegates to crossesProtectedMetadata, which
folds segments on win32 AND darwin — closing the .GIT/.COWORK hooks bypass
that let a not-yet-existing '.GIT/hooks/pre-commit' target pass the guard on
case-insensitive filesystems.
- permissions.ts canonicalization (credential-deny + metadata) now uses the
one native-realpath engine instead of a local JS-realpath walk that did not
resolve on-disk casing, so a cased '.COWORK/AUTH' spelling can no longer
evade the credential-read deny on macOS/Windows.
- utils/paths boundary canonicalize{,Sync} delegate to the same engine (async
no longer uses a divergent JS realpath).
Plus two HIGH one-liners:
- ServerRuntime conversation-import homedir uses platform home() instead of
'env.HOME ?? process.cwd()' (HOME is unset on Windows → import was a
silent no-op there).
- MCP stdio transport merges configured env onto the platform-safe child env
(childEnv) instead of replacing it, so Windows children keep
SystemRoot/PATH/APPDATA.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>Parent1452c93