fix(FN-XXXX): guard Database against nested .fusion/.fusion paths

Throws if a caller passes a path whose last two segments are both `.fusion` — that pattern only happens when a Store class joins `.fusion` onto a path that already ends in `.fusion`. Surfaces the bug at the call site instead of silently creating a stray nested directory under the project. Complements the recent in-process-runtime PluginStore fix by catching any other call paths still passing the wrong rootDir.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-05-01 21:56:59 -07:00
parent a63e819ad0
commit 46af48934b
2 changed files with 19 additions and 0 deletions

View File

@@ -713,6 +713,20 @@ export class Database {
throw new Error(`[fusion] Database constructor requires an absolute fusionDir path, got: ${fusionDir}`);
}
// Defensive: a fusionDir whose last two path segments are both ".fusion"
// indicates a caller mistakenly passed a `.fusion` directory where a
// project root was expected (a Store class joined `.fusion` onto a path
// that already ended in `.fusion`). Failing fast here surfaces the bug
// at the originating call site rather than silently creating a stray
// `.fusion/.fusion/` tree under the project.
if (!inMemory && /\.fusion[\\/]\.fusion(?:[\\/]|$)/.test(fusionDir)) {
throw new Error(
`[fusion] Refusing to open Database at nested .fusion/.fusion path: ${fusionDir}\n` +
"This means a caller passed a .fusion directory where a project root was expected. " +
"Audit the call site for an extra `join(rootDir, '.fusion')` step.",
);
}
// Ensure .fusion directory exists (only meaningful for disk-backed mode;
// in-memory mode never touches the filesystem here).
if (!inMemory && !existsSync(fusionDir)) {