Here's a list (codex found), happy to split into separate issues if easier.
Critical bugs found
Verified against the current codebase. This is the short list of the highest-severity confirmed issues.
1. embed --stale can wipe valid embeddings on the same page
getChunks() drops embeddings from the in-memory model, then embedPage() / embedAll() rebuild the full chunk list and upsertChunks() deletes + re-inserts rows, writing NULL for chunks that were not re-embedded.
Refs:
src/core/postgres-engine.ts:234-257
src/core/postgres-engine.ts:643-654
src/commands/embed.ts:57-67
src/commands/embed.ts:95-101
2. Transaction handling is not concurrency-safe
Both transaction wrappers temporarily swap shared connection state (sql / this._sql), so overlapping requests can run against the wrong transaction handle.
Refs:
src/core/db.ts:75-86
src/core/postgres-engine.ts:72-83
3. Parallel import checkpointing can skip files after a crash
The import checkpoint stores processedIndex = resumeIndex + processed, but processed is just a completion counter, not a safe prefix boundary under out-of-order worker completion.
Refs:
src/commands/import.ts:47-54
src/commands/import.ts:109-120
src/commands/import.ts:137-143
4. Sync/import slug normalization is inconsistent
pathToSlug() preserves case, while import slug inference lowercases. Deletes and renames can miss stored pages when repo paths contain uppercase characters, leaving stale rows behind or creating duplicates.
Refs:
src/core/sync.ts:107-116
src/core/markdown.ts:149-161
src/core/import-file.ts:118-120
src/commands/sync.ts:181-199
5. redirect can permanently delete files that were never uploaded
redirectFiles() only checks for a .supabase marker, then writes breadcrumbs and deletes local files without verifying each file exists in remote storage.
Refs:
src/commands/files.ts:295-324
6. initSchema() breaks in compiled Bun binaries
Both schema init paths read schema.sql from disk at runtime, but the project builds with bun --compile and migrations are already embedded specifically because filesystem assets are not reliable there.
Refs:
src/core/db.ts:69-70
src/core/postgres-engine.ts:61-62
src/core/migrate.ts:4-8
7. MCP server startup is broken against the locked SDK
setRequestHandler() is called with raw strings instead of request schemas. With the locked @modelcontextprotocol/sdk version, this throws instead of registering handlers.
Refs:
src/mcp/server.ts:16-38
bun.lock (@modelcontextprotocol/sdk@1.29.0)
8. Keyword search returns all chunks from a matching page
searchKeyword() filters on the page-level search_vector but joins all chunks for the page, so a single large page can flood results with irrelevant chunks.
Refs:
src/core/postgres-engine.ts:184-197
9. file_upload / files upload do not upload file contents
Both paths write DB metadata and return success, but never call a storage backend.
Refs:
src/core/operations.ts:556-610
src/commands/files.ts:110-144
src/cli.ts:351-355
10. S3 storage backend does not authenticate requests
S3Storage.signedFetch() is just unsigned fetch(), credentials are never used, and list() bypasses signing entirely.
Refs:
src/core/storage/s3.ts:20-23
src/core/storage/s3.ts:31-38
src/core/storage/s3.ts:62-65
11. gbrain call ignores dry_run
handleToolCall() hardcodes dryRun: false, so gbrain call ... '{"dry_run":true}' still performs real mutations.
Refs:
src/mcp/server.ts:81-86
src/commands/call.ts:4-15
12. Search dedup collapses to one chunk per page
RRF fusion preserves multiple chunks per page, but dedup layer 1 immediately reduces to one result per slug.
Refs:
src/core/search/hybrid.ts:64-85
src/core/search/dedup.ts:31-32
src/core/search/dedup.ts:50-60
Here's a list (codex found), happy to split into separate issues if easier.
Critical bugs found
Verified against the current codebase. This is the short list of the highest-severity confirmed issues.
1.
embed --stalecan wipe valid embeddings on the same pagegetChunks()drops embeddings from the in-memory model, thenembedPage()/embedAll()rebuild the full chunk list andupsertChunks()deletes + re-inserts rows, writingNULLfor chunks that were not re-embedded.Refs:
src/core/postgres-engine.ts:234-257src/core/postgres-engine.ts:643-654src/commands/embed.ts:57-67src/commands/embed.ts:95-1012. Transaction handling is not concurrency-safe
Both transaction wrappers temporarily swap shared connection state (
sql/this._sql), so overlapping requests can run against the wrong transaction handle.Refs:
src/core/db.ts:75-86src/core/postgres-engine.ts:72-833. Parallel import checkpointing can skip files after a crash
The import checkpoint stores
processedIndex = resumeIndex + processed, butprocessedis just a completion counter, not a safe prefix boundary under out-of-order worker completion.Refs:
src/commands/import.ts:47-54src/commands/import.ts:109-120src/commands/import.ts:137-1434. Sync/import slug normalization is inconsistent
pathToSlug()preserves case, while import slug inference lowercases. Deletes and renames can miss stored pages when repo paths contain uppercase characters, leaving stale rows behind or creating duplicates.Refs:
src/core/sync.ts:107-116src/core/markdown.ts:149-161src/core/import-file.ts:118-120src/commands/sync.ts:181-1995.
redirectcan permanently delete files that were never uploadedredirectFiles()only checks for a.supabasemarker, then writes breadcrumbs and deletes local files without verifying each file exists in remote storage.Refs:
src/commands/files.ts:295-3246.
initSchema()breaks in compiled Bun binariesBoth schema init paths read
schema.sqlfrom disk at runtime, but the project builds withbun --compileand migrations are already embedded specifically because filesystem assets are not reliable there.Refs:
src/core/db.ts:69-70src/core/postgres-engine.ts:61-62src/core/migrate.ts:4-87. MCP server startup is broken against the locked SDK
setRequestHandler()is called with raw strings instead of request schemas. With the locked@modelcontextprotocol/sdkversion, this throws instead of registering handlers.Refs:
src/mcp/server.ts:16-38bun.lock(@modelcontextprotocol/sdk@1.29.0)8. Keyword search returns all chunks from a matching page
searchKeyword()filters on the page-levelsearch_vectorbut joins all chunks for the page, so a single large page can flood results with irrelevant chunks.Refs:
src/core/postgres-engine.ts:184-1979.
file_upload/files uploaddo not upload file contentsBoth paths write DB metadata and return success, but never call a storage backend.
Refs:
src/core/operations.ts:556-610src/commands/files.ts:110-144src/cli.ts:351-35510. S3 storage backend does not authenticate requests
S3Storage.signedFetch()is just unsignedfetch(), credentials are never used, andlist()bypasses signing entirely.Refs:
src/core/storage/s3.ts:20-23src/core/storage/s3.ts:31-38src/core/storage/s3.ts:62-6511.
gbrain callignoresdry_runhandleToolCall()hardcodesdryRun: false, sogbrain call ... '{"dry_run":true}'still performs real mutations.Refs:
src/mcp/server.ts:81-86src/commands/call.ts:4-1512. Search dedup collapses to one chunk per page
RRF fusion preserves multiple chunks per page, but dedup layer 1 immediately reduces to one result per slug.
Refs:
src/core/search/hybrid.ts:64-85src/core/search/dedup.ts:31-32src/core/search/dedup.ts:50-60