fix(memory): avoid destructive qmd collection rebinds

This commit is contained in:
Vignesh Natarajan
2026-03-05 16:04:07 -08:00
parent 688b72e158
commit f771ba8de9
3 changed files with 9 additions and 21 deletions

View File

@@ -369,7 +369,7 @@ describe("QmdMemoryManager", () => {
expect(addSessions?.[2]).toBe(path.join(stateDir, "agents", devAgentId, "qmd", "sessions"));
});
it("rebinds managed collections when qmd only reports collection names", async () => {
it("avoids destructive rebind when qmd only reports collection names", async () => {
cfg = {
...cfg,
memory: {
@@ -401,25 +401,11 @@ describe("QmdMemoryManager", () => {
await manager.close();
const commands = spawnMock.mock.calls.map((call: unknown[]) => call[1] as string[]);
const removeSessions = commands.find(
(args) =>
args[0] === "collection" && args[1] === "remove" && args[2] === sessionCollectionName,
);
expect(removeSessions).toBeDefined();
const removeWorkspace = commands.find(
(args) =>
args[0] === "collection" && args[1] === "remove" && args[2] === `workspace-${agentId}`,
);
expect(removeWorkspace).toBeDefined();
const removeCalls = commands.filter((args) => args[0] === "collection" && args[1] === "remove");
expect(removeCalls).toHaveLength(0);
const addSessions = commands.find((args) => {
if (args[0] !== "collection" || args[1] !== "add") {
return false;
}
const nameIdx = args.indexOf("--name");
return nameIdx >= 0 && args[nameIdx + 1] === sessionCollectionName;
});
expect(addSessions).toBeDefined();
const addCalls = commands.filter((args) => args[0] === "collection" && args[1] === "add");
expect(addCalls).toHaveLength(0);
});
it("migrates unscoped legacy collections before adding scoped names", async () => {

View File

@@ -568,8 +568,9 @@ export class QmdMemoryManager implements MemorySearchManager {
private shouldRebindCollection(collection: ManagedCollection, listed: ListedCollection): boolean {
if (!listed.path) {
// Older qmd versions may only return names from `collection list --json`.
// Rebind managed collections so stale path bindings cannot survive upgrades.
return true;
// Do not perform destructive rebinds when metadata is incomplete: remove+add
// can permanently drop collections if add fails (for example on timeout).
return false;
}
if (!this.pathsMatch(listed.path, collection.path)) {
return true;