diff --git a/docs/contract-1-ratification.md b/docs/contract-1-ratification.md index 57c4e7d3..87df7b1f 100644 --- a/docs/contract-1-ratification.md +++ b/docs/contract-1-ratification.md @@ -219,6 +219,21 @@ every door contract 1 requires?" — is a set-membership check between their --- +## A defect this work surfaced but did not fix + +`src/vfs/VirtualFileSystem.ts` builds a path-prefix filter as +`path: { $startsWith: options.path }` — with a `$` prefix. No operator in this +engine carries a `$`, so `validateWhereFilter()` rejects it with +`INVALID_QUERY` before any index read: **`vfs.searchFiles({ path })` throws +today, on every call that passes a path.** It is pre-existing and unrelated to +the operator work above (the validator refuses it before the index path is +reached), and it is left as a filing rather than fixed here, because the right +answer is a design question — a path-prefix search cannot be served by an +equality/range index, so it needs either a path-segment index or an explicit +in-memory narrow, not a spelling correction. + +--- + ## Summary of what changed in code for this ratification | item | change | diff --git a/src/brainy.ts b/src/brainy.ts index 711d8d02..c479fcc3 100644 --- a/src/brainy.ts +++ b/src/brainy.ts @@ -16732,8 +16732,19 @@ export class Brainy implements BrainyInterface { if (legacyEntityPaths.length === 0) { // Already flat (root entities, no head-branch entities) → stamp the marker // so future opens short-circuit. A genuinely empty/fresh dir gets no marker. - const rootEntities = await probe.listRawObjects('entities') - if (rootEntities.length > 0) { + // "Are there any entities?" is answered by ONE directory read, not by a + // recursive listing of every file in the tree: this runs on the open path + // of every store that does not yet carry the marker (a restore, a store + // built by an older release), and on a large store that listing walks the + // whole canonical tree to learn a boolean. + const oneLevel = ( + probe as unknown as { listRawPrefixes?: (prefix: string) => Promise } + ).listRawPrefixes + const hasRootEntities = + typeof oneLevel === 'function' + ? (await oneLevel.call(probe, 'entities')).length > 0 + : (await probe.listRawObjects('entities')).length > 0 + if (hasRootEntities) { await probe.writeRawObject('_system/migration-layout.json', { layout: 'flat-v8', version: 8,