Skip to content

bug: projects consolidate reports 'Merged: 0' without merging + mem_update does not persist project rename #179

@yeerliin

Description

@yeerliin

Pre-flight Checks

  • I have searched existing issues and this is not a duplicate
  • I understand this issue needs status:approved before a PR can be opened

Bug Description

Two related bugs that cause project name fragmentation to be unrecoverable through engram's built-in tools:

Bug 1 — projects consolidate does nothing:
Running engram projects consolidate --all correctly detects groups of similar project names, but when selecting all to merge, it always reports Merged: 0 obs, 0 sessions, 0 prompts and no rows are actually updated in the database.

Bug 2 — mem_update does not persist project changes:
Calling mem_update(id, project="new_name") via MCP returns Memory updated: #ID "title" but the project column is not changed in the database. Subsequent queries still show the old project name.

Root cause of the fragmentation:
Engram MCP's mem_save normalizes project names to lowercase (e.g. Stack_Ecokeystack_ecokey), but other code paths (CLI, older binary versions) may store the original case from the git remote. This creates duplicates like Stack_Ecokey (499 obs) and stack_ecokey (11 obs) that cannot be merged with the built-in tools.

Steps to Reproduce

  1. Have a git repo with a mixed-case remote name (e.g. Stack_Ecokey)
  2. Use engram across sessions — some memories end up as Stack_Ecokey, others as stack_ecokey
  3. Run engram projects list — see two entries for the same project
  4. Run engram projects consolidate --all and type all for the group
  5. See Merged: 0 obs, 0 sessions, 0 prompts
  6. Run engram projects list again — nothing changed
  7. Try MCP: mem_update(id=1546, project="stack_ecokey") — returns success but project is unchanged

Expected Behavior

  • projects consolidate should update all rows in sessions, observations, user_prompts, prompts_fts, sync_mutations, and observations_fts tables to the canonical project name.
  • mem_update(project=...) should persist the project name change in the database.

Actual Behavior

`
$ engram projects consolidate --all
Found 2 group(s) of similar project names:

Group 2:
→ [1] Stack_Ecokey 499 obs
[2] stack_ecokey 11 obs
Suggested canonical: "Stack_Ecokey" (→)
Choice: all
Merged: 0 obs, 0 sessions, 0 prompts

$ engram projects list
Stack_Ecokey 499 obs 289 sessions 459 prompts
stack_ecokey 11 obs 6 sessions 38 prompts ← still there
`

Environment

  • OS: Windows 11
  • Engram Version: 1.12.0
  • Agent/Client: Claude Code + OpenCode (both affected)

Workaround

Direct SQLite UPDATE against ~/.engram/engram.db:

`python
import sqlite3, shutil
from pathlib import Path

DB = Path.home() / ".engram" / "engram.db"
shutil.copy2(DB, DB.with_suffix(".db.backup"))

conn = sqlite3.connect(str(DB))
conn.execute("PRAGMA journal_mode=WAL")

TABLES = [
"sessions", "observations", "user_prompts",
"prompts_fts", "sync_mutations", "observations_fts",
]

canonical must be lowercase (engram MCP normalizes to lowercase)

MERGES = {"stack_ecokey": ["Stack_Ecokey"]}

for canonical, variants in MERGES.items():
for variant in variants:
for table in TABLES:
conn.execute(
f"UPDATE {table} SET project = ? WHERE project = ?",
(canonical, variant),
)

conn.commit()
conn.close()
`

Important: The canonical name must be lowercase because mem_save normalizes to lowercase. If you merge into the uppercase variant, fragmentation will recur on the next save.

Additional Context

  • Related to feat(store): add project aliasing system to group related projects #104 (project aliasing) but this is a concrete bug in existing functionality, not a feature request.
  • The fragmentation is especially common when using multiple agents (Claude Code + OpenCode) that may point to different engram binary versions with different project name detection heuristics.
  • Unifying all agent configs to use the same engram binary from PATH (instead of absolute paths to different versions) prevents future fragmentation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions