diff --git a/cmd/bd/daemon_sync.go b/cmd/bd/daemon_sync.go index cf5b7a7c..9e3155d2 100644 --- a/cmd/bd/daemon_sync.go +++ b/cmd/bd/daemon_sync.go @@ -598,6 +598,18 @@ func performAutoImport(ctx context.Context, store storage.Storage, skipGit bool, return } + // Update jsonl_content_hash after successful import to prevent repeated imports + // Uses repoKey for multi-repo support (bd-ar2.10, bd-ar2.11) + hashKey := "jsonl_content_hash" + if repoKey != "" { + hashKey += ":" + repoKey + } + if currentHash, err := computeJSONLHash(jsonlPath); err == nil { + if err := store.SetMetadata(importCtx, hashKey, currentHash); err != nil { + log.log("Warning: failed to update %s after import: %v", hashKey, err) + } + } + if skipGit { log.log("Local auto-import complete") } else { diff --git a/cmd/bd/sync.go b/cmd/bd/sync.go index ec370b07..ec03f150 100644 --- a/cmd/bd/sync.go +++ b/cmd/bd/sync.go @@ -666,6 +666,15 @@ Use --merge to merge the sync branch back to main branch.`, if err := restoreBeadsDirFromBranch(ctx); err != nil { // Non-fatal - just means git status will show modified files debug.Logf("sync: failed to restore .beads/ from branch: %v", err) + } else { + // Update jsonl_content_hash to match the restored file + // This prevents daemon/CLI from seeing a hash mismatch and re-importing + // which would trigger re-export and dirty the working directory (bd-c83r race fix) + if restoredHash, err := computeJSONLHash(jsonlPath); err == nil { + if err := store.SetMetadata(ctx, "jsonl_content_hash", restoredHash); err != nil { + debug.Logf("sync: failed to update hash after restore: %v", err) + } + } } // Skip final flush in PersistentPostRun - we've already exported to sync branch // and restored the working directory to match the current branch