persistence: true is silently ignored on first artifact creation
Summary
index_repository(persistence=true) only writes .codebase-memory/graph.db.zst when an artifact already exists beside the repo. After the local cache ~/.cache/codebase-memory-mcp/<project>.db is populated by an earlier call, every subsequent index_repository runs through the incremental pipeline, which silently ignores the persistence flag. As a result, a repo that has never been persisted before never gets its first artifact — even though the user explicitly asked for one.
The MCP response also gives no hint that the flag was a no-op:
- Returns
"status":"indexed" (no error)
- Returns
"artifact_present":false (truthful, but easily misread as "indexing went fine, just no artifact yet")
- Omits the usual
artifact_hint: "Persistent artifact written to .codebase-memory/graph.db.zst..." field
Reproduction
# Clean slate
rm -rf ~/.cache/codebase-memory-mcp
rm -rf /path/to/repo/.codebase-memory
# Call 1 — full pipeline runs (persistence:false here for clarity)
index_repository(repo_path="/path/to/repo", mode="full", persistence=false)
# → ~/.cache/codebase-memory-mcp/<project>.db is created
# → no artifact (correct, persistence wasn't requested)
# Call 2 — incremental pipeline runs (BUG: persistence:true ignored)
index_repository(repo_path="/path/to/repo", mode="full", persistence=true)
# Response:
# "status":"indexed", "artifact_present":false ← no artifact_hint
# Disk:
# /path/to/repo/.codebase-memory/ ← still does not exist
Expected: .codebase-memory/graph.db.zst is written because persistence=true was passed.
Actual: the flag is dropped on the floor; no artifact is created.
Real-world impact
I hit this while indexing 6 sibling repos in one chat session. First call per repo had persistence=false (default). On the follow-up "let's persist them all" pass with persistence=true, only the one repo that already had an artifact from a previous session got refreshed; the other 5 silently produced nothing. The only workaround I found was delete_project followed by index_repository(persistence=true) per repo — which forces the full pipeline and works correctly.
Root cause
src/pipeline/pipeline_incremental.c::dump_and_persist():
/* Auto-update artifact if one already exists (persistence was enabled previously) */
if (repo_path && cbm_artifact_exists(repo_path)) {
cbm_artifact_export(db_path, repo_path, project, CBM_ARTIFACT_FAST);
}
The function does not take a persistence parameter and the caller (cbm_pipeline_run_incremental, line ~657) doesn't pass one. So the incremental path can only refresh an artifact that already exists — it can never create the first one.
The full-pipeline path in src/pipeline/pipeline.c::dump_and_persist_hashes() does honor it:
/* Export persistent artifact if enabled */
if (p->persistence) {
cbm_artifact_export(db_path, p->repo_path, p->project_name, CBM_ARTIFACT_BEST);
}
This asymmetry between the full and incremental paths is the bug.
persistence: trueis silently ignored on first artifact creationSummary
index_repository(persistence=true)only writes.codebase-memory/graph.db.zstwhen an artifact already exists beside the repo. After the local cache~/.cache/codebase-memory-mcp/<project>.dbis populated by an earlier call, every subsequentindex_repositoryruns through the incremental pipeline, which silently ignores thepersistenceflag. As a result, a repo that has never been persisted before never gets its first artifact — even though the user explicitly asked for one.The MCP response also gives no hint that the flag was a no-op:
"status":"indexed"(no error)"artifact_present":false(truthful, but easily misread as "indexing went fine, just no artifact yet")artifact_hint: "Persistent artifact written to .codebase-memory/graph.db.zst..."fieldReproduction
Expected:
.codebase-memory/graph.db.zstis written becausepersistence=truewas passed.Actual: the flag is dropped on the floor; no artifact is created.
Real-world impact
I hit this while indexing 6 sibling repos in one chat session. First call per repo had
persistence=false(default). On the follow-up "let's persist them all" pass withpersistence=true, only the one repo that already had an artifact from a previous session got refreshed; the other 5 silently produced nothing. The only workaround I found wasdelete_projectfollowed byindex_repository(persistence=true)per repo — which forces the full pipeline and works correctly.Root cause
src/pipeline/pipeline_incremental.c::dump_and_persist():The function does not take a
persistenceparameter and the caller (cbm_pipeline_run_incremental, line ~657) doesn't pass one. So the incremental path can only refresh an artifact that already exists — it can never create the first one.The full-pipeline path in
src/pipeline/pipeline.c::dump_and_persist_hashes()does honor it:This asymmetry between the full and incremental paths is the bug.