Document merge command and AI duplicate detection workflow (bd-29)

- Add comprehensive merge command documentation to README.md
- Add AI agent duplicate detection workflow to AGENTS.md
- Include command syntax, examples, and best practices
- Close bd-29

Amp-Thread-ID: https://ampcode.com/threads/T-95a37593-fd67-4e99-bc84-ace580b4776d
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Steve Yegge
2025-10-22 11:48:12 -07:00
parent a7ce986555
commit 4ef995b0e4
3 changed files with 127 additions and 1 deletions

View File

@@ -19,7 +19,7 @@
{"id":"bd-26","title":"Make merge command idempotent for safe retry after partial failures","description":"The merge command currently performs 3 operations without an outer transaction:\n1. Migrate dependencies from source → target\n2. Update text references across all issues\n3. Close source issues\n\nIf merge fails mid-operation (network issue, daemon crash, etc.), a retry will fail or produce incorrect results because some operations already succeeded.\n\n**Goal:** Make merge idempotent so retrying after partial failure is safe and completes the remaining work.\n\n**Idempotency checks needed:**\n- Skip dependency migration if target already has the dependency\n- Skip text reference updates if already updated\n- Skip closing source issues if already closed\n- Report which operations were skipped vs performed\n\n**Example output:**\n```\n✓ Merged 2 issue(s) into bd-78\n - Dependencies: 3 migrated, 2 already existed\n - Text references: 5 updated, 0 already correct\n - Source issues: 1 closed, 1 already closed\n```\n\n**Related:** bd-23 originally requested transaction support, but idempotency is a better solution for this use case since individual operations are already atomic.","design":"Current merge code already has some idempotency:\n- Dependency migration checks `alreadyExists` before adding (line ~145-151 in merge.go)\n- Text reference updates are naturally idempotent (replacing bd-X with bd-Y twice has same result)\n\nMissing idempotency:\n- CloseIssue fails if source already closed\n- Error messages don't distinguish \"already done\" from \"real failure\"\n\nImplementation:\n1. Check source issue status before closing - skip if already closed\n2. Track which operations succeeded/skipped\n3. Return detailed results for user visibility\n4. Consider adding --dry-run output showing what would be done vs skipped","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-21T23:53:44.31362-07:00","updated_at":"2025-10-22T01:03:24.905087-07:00"}
{"id":"bd-27","title":"bd sync crashes with nil pointer when daemon is running","description":"The 'bd sync' command crashes with a nil pointer dereference when the daemon is running.\n\n**Reproduction:**\n```bash\n# With daemon running\n./bd sync\n```\n\n**Error:**\n```\npanic: runtime error: invalid memory address or nil pointer dereference\n[signal SIGSEGV: segmentation violation code=0x2 addr=0x120 pc=0x1012314ac]\n\ngoroutine 1 [running]:\nmain.exportToJSONL({0x1014ec2e0, 0x101a49900}, {0x14000028db0, 0x30})\n /Users/stevey/src/fred/beads/cmd/bd/sync.go:245 +0x4c\n```\n\n**Root cause:**\nThe sync command's `exportToJSONL` function directly accesses `store.SearchIssues()` at line 245, but when daemon mode is active, the global `store` variable is nil. The sync command should either:\n1. Use daemon RPC when daemon is running, or\n2. Force direct mode for sync operations\n\n**Workaround:**\nUse `--no-daemon` flag: `bd sync --no-daemon`","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-21T23:53:44.31362-07:00","updated_at":"2025-10-22T01:03:24.90534-07:00","closed_at":"2025-10-22T00:09:12.615536-07:00"}
{"id":"bd-28","title":"Add cross-repo issue references (future enhancement)","description":"Support referencing issues across different beads repositories. Useful for tracking dependencies between separate projects.\n\nProposed syntax:\n- Local reference: bd-78 (current behavior)\n- Cross-repo by path: ~/src/other-project#bd-456\n- Cross-repo by workspace name: @project2:bd-789\n\nUse cases:\n1. Frontend project depends on backend API issue\n2. Shared library changes blocking multiple projects\n3. System administrator tracking work across machines\n4. Monorepo with separate beads databases per component\n\nImplementation challenges:\n- Storage layer needs to query external databases\n- Dependency resolution across repos\n- What if external repo not available?\n- How to handle in JSONL export/import?\n- Security: should repos be able to read others?\n\nDesign questions to resolve first:\n1. Read-only references vs full cross-repo dependencies?\n2. How to handle repo renames/moves?\n3. Absolute paths vs workspace names vs git remotes?\n4. Should bd-77 auto-discover related repos?\n\nRecommendation: \n- Gather user feedback first\n- Start with read-only references\n- Implement as plugin/extension?\n\nContext: This is mentioned in bd-77 as approach #2. Much more complex than daemon multi-repo approach. Only implement if there's strong user demand.\n\nPriority: Backlog (4) - wait for user feedback before designing","status":"closed","priority":4,"issue_type":"feature","created_at":"2025-10-21T23:53:44.31362-07:00","updated_at":"2025-10-22T01:03:24.905617-07:00","closed_at":"2025-10-20T22:00:31.966891-07:00"}
{"id":"bd-29","title":"Document merge command and AI integration","description":"Update README, AGENTS.md with merge command examples. Document AI agent duplicate detection workflow.","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-21T23:53:44.31362-07:00","updated_at":"2025-10-22T01:03:24.905923-07:00"}
{"id":"bd-29","title":"Document merge command and AI integration","description":"Update README, AGENTS.md with merge command examples. Document AI agent duplicate detection workflow.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T23:53:44.31362-07:00","updated_at":"2025-10-22T11:37:41.104918-07:00","closed_at":"2025-10-22T11:37:41.104918-07:00"}
{"id":"bd-3","title":"Add godoc comments for auto-flush functions","description":"Add comprehensive godoc comments for findJSONLPath(), markDirtyAndScheduleFlush(), and flushToJSONL() explaining behavior, concurrency considerations, and error handling. Include notes about debouncing behavior (timer resets on each write, flush occurs 5s after LAST operation) and flush-on-exit guarantees. Located in cmd/bd/main.go:188-307.","status":"closed","priority":4,"issue_type":"chore","created_at":"2025-10-21T23:53:44.31362-07:00","updated_at":"2025-10-22T01:03:24.906177-07:00","closed_at":"2025-10-19T19:22:19.172983-07:00"}
{"id":"bd-30","title":"Optimize export dependency queries (N+1 problem)","description":"Export triggers separate GetDependencyRecords() per issue. For large DBs (1000+ issues), this is N+1 queries. Add GetAllDependencyRecords() to fetch all dependencies in one query. Location: cmd/bd/export.go:52-59, import.go:138-142","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-21T23:53:44.31362-07:00","updated_at":"2025-10-22T01:03:24.906463-07:00","closed_at":"2025-10-14T02:51:52.19905-07:00"}
{"id":"bd-31","title":"Add workspace config file for multi-repo management (optional enhancement)","description":"For users who want explicit control over multi-repo setup without daemon, add optional workspace config file.\n\nConfig file: ~/.beads/workspaces.toml\n\nExample:\n[workspaces]\ncurrent = \"global\"\n\n[workspace.global]\ndb = \"~/.beads/global.db\"\ndescription = \"System-wide tasks\"\n\n[workspace.project1] \ndb = \"~/src/project1/.beads/db.sqlite\"\ndescription = \"Main product\"\n\n[workspace.project2]\ndb = \"~/src/project2/.beads/db.sqlite\"\ndescription = \"Internal tools\"\n\nCommands:\nbd workspace list # Show all workspaces\nbd workspace add NAME PATH # Add workspace\nbd workspace remove NAME # Remove workspace \nbd workspace use NAME # Switch active workspace\nbd workspace current # Show current workspace\nbd --workspace NAME \u003ccommand\u003e # Override for single command\n\nImplementation:\n- Load config in PersistentPreRun\n- Override dbPath based on current workspace\n- Store workspace state in config file\n- Support both workspace config AND auto-discovery\n- Workspace config takes precedence over auto-discovery\n\nPriority rationale:\n- Priority 3 (low) because daemon approach already solves this\n- Only implement if users request explicit workspace management\n- Adds complexity vs daemon's automatic discovery\n\nAlternative: Users can use BEADS_DB env var for manual workspace switching today.","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-10-21T23:53:44.31362-07:00","updated_at":"2025-10-22T01:03:24.906689-07:00","closed_at":"2025-10-20T16:04:27.216482-07:00"}

View File

@@ -151,6 +151,10 @@ bd restore <id> # View full history at time of compaction
# Import with collision detection
bd import -i .beads/issues.jsonl --dry-run # Preview only
bd import -i .beads/issues.jsonl --resolve-collisions # Auto-resolve
# Merge duplicate issues
bd merge <source-id...> --into <target-id> --json # Consolidate duplicates
bd merge bd-42 bd-43 --into bd-41 --dry-run # Preview merge
```
### Workflow
@@ -189,6 +193,69 @@ bd import -i .beads/issues.jsonl --resolve-collisions # Auto-resolve
Only `blocks` dependencies affect the ready work queue.
### Duplicate Detection & Merging
AI agents should proactively detect and merge duplicate issues to keep the database clean:
**Detection strategies:**
1. **Before creating new issues**: Search for similar existing issues
```bash
bd list --json | grep -i "authentication"
bd show bd-41 bd-42 --json # Compare candidates
```
2. **Periodic duplicate scans**: Review issues by type or priority
```bash
bd list --status open --priority 1 --json # High-priority issues
bd list --issue-type bug --json # All bugs
```
3. **During work discovery**: Check for duplicates when filing discovered-from issues
```bash
# Before: bd create "Fix auth bug" --deps discovered-from:bd-100
# First: bd list --json | grep -i "auth bug"
# Then decide: create new or link to existing
```
**Merge workflow:**
```bash
# Step 1: Identify duplicates (bd-42 and bd-43 duplicate bd-41)
bd show bd-41 bd-42 bd-43 --json
# Step 2: Preview merge to verify
bd merge bd-42 bd-43 --into bd-41 --dry-run
# Step 3: Execute merge
bd merge bd-42 bd-43 --into bd-41 --json
# Step 4: Verify result
bd dep tree bd-41 # Check unified dependency tree
bd show bd-41 --json # Verify merged content
```
**What gets merged:**
- ✅ All dependencies from source → target
- ✅ Text references updated across ALL issues (descriptions, notes, design, acceptance criteria)
- ✅ Source issues closed with "Merged into bd-X" reason
- ❌ Source issue content NOT copied (target keeps its original content)
**Important notes:**
- Merge preserves target issue completely; only dependencies/references migrate
- If source issues have valuable content, manually copy it to target BEFORE merging
- Cannot merge in daemon mode yet (bd-190); use `--no-daemon` flag
- Operation cannot be undone (but git history preserves the original)
**Best practices:**
- Merge early to prevent dependency fragmentation
- Choose the oldest or most complete issue as merge target
- Add labels like `duplicate` to source issues before merging (for tracking)
- File a discovered-from issue if you found duplicates during work:
```bash
bd create "Found duplicates during bd-X" -p 2 --deps discovered-from:bd-X --json
```
## Development Guidelines
### Code Standards

View File

@@ -445,6 +445,65 @@ bd rename-prefix kw-
bd list # Shows kw-* issues
```
### Merging Duplicate Issues
Consolidate duplicate issues into a single issue while preserving dependencies and references:
```bash
# Merge bd-42 and bd-43 into bd-41
bd merge bd-42 bd-43 --into bd-41
# Merge multiple duplicates at once
bd merge bd-10 bd-11 bd-12 --into bd-10
# Preview merge without making changes
bd merge bd-42 bd-43 --into bd-41 --dry-run
# JSON output
bd merge bd-42 bd-43 --into bd-41 --json
```
**What the merge command does:**
1. **Validates** all issues exist and prevents self-merge
2. **Closes** source issues with reason `Merged into bd-X`
3. **Migrates** all dependencies from source issues to target
4. **Updates** text references across all issue descriptions, notes, design, and acceptance criteria
**Example workflow:**
```bash
# You discover bd-42 and bd-43 are duplicates of bd-41
bd show bd-41 bd-42 bd-43
# Preview the merge
bd merge bd-42 bd-43 --into bd-41 --dry-run
# Execute the merge
bd merge bd-42 bd-43 --into bd-41
# ✓ Merged 2 issue(s) into bd-41
# Verify the result
bd show bd-41 # Now has dependencies from bd-42 and bd-43
bd dep tree bd-41 # Shows unified dependency tree
```
**Important notes:**
- Source issues are permanently closed (status: `closed`)
- All dependencies pointing to source issues are redirected to target
- Text references like "see bd-42" are automatically rewritten to "see bd-41"
- Operation cannot be undone (but git history preserves the original state)
- Not yet supported in daemon mode (use `--no-daemon` flag)
**AI Agent Workflow:**
When agents discover duplicate issues, they should:
1. Search for similar issues: `bd list --json | grep "similar text"`
2. Compare issue details: `bd show bd-41 bd-42 --json`
3. Merge duplicates: `bd merge bd-42 --into bd-41`
4. File a discovered-from issue if needed: `bd create "Found duplicates during bd-X" --deps discovered-from:bd-X`
See [AGENTS.md](#ai-agent-integration) for complete AI integration workflow.
### Labels
Add flexible metadata to issues for filtering and organization: