Problem
A clean run of the @maka/storage test suite leaves 159 directories behind in the developer's real cache directory. Nothing fails, so nothing surfaces it.
$ ls ~/Library/Caches/Maka/runtime-hosts | wc -l
27740
$ node --test --test-concurrency=2 "packages/storage/dist/__tests__/*.test.js"
ℹ tests 912
ℹ pass 898
ℹ fail 0
$ ls ~/Library/Caches/Maka/runtime-hosts | wc -l
27899
On this machine the directory has accumulated 27,740 entries. Disk cost is negligible (264K — most hold a single empty owner.lock), but the count grows without bound and nothing ever reclaims it.
Cause
resolveRootControlNamespace() deliberately resolves to the real OS account home and cannot be redirected by an environment variable:
// packages/storage/src/root-authority.ts
export function resolveRootControlNamespace(): string {
const accountHome = userInfo().homedir;
if (process.platform === 'darwin') {
return join(accountHome, 'Library', 'Caches', 'Maka', 'runtime-hosts');
}
...
}
That is reasonable for a trust boundary — owner.lock decides who may write a State Root, so an env var must not be able to move it. The consequence is that tests write there too, and the control directory sits outside the temporary State Root they create.
So a helper of this shape cleans up the State Root but not its control directory:
async function withTempDir(run: (base: string) => Promise<void>): Promise<void> {
const base = await mkdtemp(join(tmpdir(), 'maka-runtime-policy-'));
try {
await run(base);
} finally {
await rm(base, { recursive: true, force: true }); // the State Root, not the control directory
}
}
Tests that do clean up carry an extra explicit line:
await rm(join(resolveRootControlNamespace(), capability.rootId), { recursive: true, force: true });
There is no shared helper for it in @maka/storage, so the line is copied per file, and seventeen files do not have it.
Which files leak
Measured by running each test file on its own and counting the directory before and after:
| Directories leaked |
File (packages/storage/src/__tests__/) |
| 54 |
runtime-policy-stores.test.ts |
| 22 |
managed-workspace-baseline.test.ts |
| 18 |
managed-workspace-owner.test.ts |
| 16 |
memory-bundle-store.test.ts |
| 15 |
usage-stores.test.ts |
| 5 |
artifact-writer-lock.test.ts |
| 4 |
storage-writer-composition.test.ts |
| 3 |
artifact-stores.test.ts |
| 3 |
daily-review-authority.test.ts |
| 3 |
goal-authority.test.ts |
| 3 |
shell-run-authority.test.ts |
| 3 |
sqlite-long-term-memory-store.test.ts |
| 3 |
sqlite-workflow-store.test.ts |
| 3 |
task-ledger-authority.test.ts |
| 2 |
state-root-composition.test.ts |
| 1 |
project-catalog-authority.test.ts |
| 1 |
sqlite-core-execution-store.test.ts |
Total 159, matching the whole-suite delta.
@maka/runtime-host was checked the same way and does not leak: execution-host-recovery.test.ts and storage/root-authority.test.ts both measured a delta of 0, because their shared ExecutionFixture.close() already removes the control directory, the endpoint directories and the base.
Proposed fix
Add one shared helper under packages/storage/src/__tests__/fixtures/, mirroring runtime-host's endpoint-hygiene.ts, and call it from the seventeen files where a temporary State Root is torn down. This keeps the trust boundary exactly as it is and only makes the tests clean up what they created.
Out of scope here
Reclaiming control directories that are already stale is a separate question. It needs a definition of "stale" that is safe against a live owner.lock, so it should not ride along with a test-hygiene change.
Problem
A clean run of the
@maka/storagetest suite leaves 159 directories behind in the developer's real cache directory. Nothing fails, so nothing surfaces it.On this machine the directory has accumulated 27,740 entries. Disk cost is negligible (264K — most hold a single empty
owner.lock), but the count grows without bound and nothing ever reclaims it.Cause
resolveRootControlNamespace()deliberately resolves to the real OS account home and cannot be redirected by an environment variable:That is reasonable for a trust boundary —
owner.lockdecides who may write a State Root, so an env var must not be able to move it. The consequence is that tests write there too, and the control directory sits outside the temporary State Root they create.So a helper of this shape cleans up the State Root but not its control directory:
Tests that do clean up carry an extra explicit line:
There is no shared helper for it in
@maka/storage, so the line is copied per file, and seventeen files do not have it.Which files leak
Measured by running each test file on its own and counting the directory before and after:
packages/storage/src/__tests__/)runtime-policy-stores.test.tsmanaged-workspace-baseline.test.tsmanaged-workspace-owner.test.tsmemory-bundle-store.test.tsusage-stores.test.tsartifact-writer-lock.test.tsstorage-writer-composition.test.tsartifact-stores.test.tsdaily-review-authority.test.tsgoal-authority.test.tsshell-run-authority.test.tssqlite-long-term-memory-store.test.tssqlite-workflow-store.test.tstask-ledger-authority.test.tsstate-root-composition.test.tsproject-catalog-authority.test.tssqlite-core-execution-store.test.tsTotal 159, matching the whole-suite delta.
@maka/runtime-hostwas checked the same way and does not leak:execution-host-recovery.test.tsandstorage/root-authority.test.tsboth measured a delta of 0, because their sharedExecutionFixture.close()already removes the control directory, the endpoint directories and the base.Proposed fix
Add one shared helper under
packages/storage/src/__tests__/fixtures/, mirroringruntime-host'sendpoint-hygiene.ts, and call it from the seventeen files where a temporary State Root is torn down. This keeps the trust boundary exactly as it is and only makes the tests clean up what they created.Out of scope here
Reclaiming control directories that are already stale is a separate question. It needs a definition of "stale" that is safe against a live
owner.lock, so it should not ride along with a test-hygiene change.