Files
beads/.beads/issues.jsonl
Steve Yegge a6e28f7087 bd-411u: Document BEADS_DIR pattern for Gas Town integration
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 22:09:15 -08:00

236 lines
218 KiB
JSON
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"id":"bd-2au","title":"bd doctor: add SQLite integrity check (PRAGMA integrity_check)","description":"Add a database integrity check using SQLite's PRAGMA integrity_check to detect corruption. Currently bd doctor checks schema compatibility but not data integrity. This would help diagnose corrupted databases that pass schema checks but have internal inconsistencies.","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-12-02T12:52:17.5244-08:00","updated_at":"2025-12-03T22:14:02.580777-08:00","closed_at":"2025-12-03T22:14:02.580777-08:00"}
{"id":"bd-8f9","title":"Add bd migrate-tombstones command","description":"Create migration command to convert existing deletions.jsonl entries to tombstones. Support --dry-run and --verbose flags. Archive old file with .migrated suffix. Per design bd-dli.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-05T15:14:45.098831-08:00","updated_at":"2025-12-13T09:42:56.870081+11:00","closed_at":"2025-12-07T02:30:19.4741-08:00","dependencies":[{"issue_id":"bd-8f9","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-05T15:14:58.968329-08:00","created_by":"daemon"}]}
{"id":"bd-otf4","title":"Code Review: PR #481 - Context Engineering Optimizations","description":"Comprehensive code review of the merged context engineering PR (PR #481) that reduces MCP context usage by 80-90%.\n\n## Summary\nThe PR successfully implements lazy tool schema loading and minimal issue models to reduce context window usage. Overall implementation is solid and well-tested.\n\n## Positive Findings\n✅ Well-designed models (IssueMinimal, CompactedResult)\n✅ Comprehensive test coverage (28 tests, all passing)\n✅ Clear documentation and comments\n✅ Backward compatibility preserved (show() still returns full Issue)\n✅ Sensible defaults (COMPACTION_THRESHOLD=20, PREVIEW_COUNT=5)\n✅ Tool catalog complete with all 15 tools documented\n\n## Issues Identified\nSee linked issues for specific followup tasks.\n\n## Context Engineering Architecture\n- discover_tools(): List tool names only (~500 bytes vs ~15KB)\n- get_tool_info(name): Get specific tool details on-demand\n- IssueMinimal: Lightweight model for list views (~80 bytes vs ~400 bytes)\n- CompactedResult: Auto-compacts results with \u003e20 issues\n- _to_minimal(): Conversion function (efficient, no N+1 issues)","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-14T14:24:13.523532-08:00","updated_at":"2025-12-14T14:24:13.523532-08:00"}
{"id":"bd-9cdc","title":"Update docs for import bug fix","description":"Update AGENTS.md, README.md, TROUBLESHOOTING.md with import.orphan_handling config documentation. Document resurrection behavior, tombstones, config modes. Add troubleshooting section for import failures with deleted parents.","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-04T12:32:30.770415-08:00","updated_at":"2025-11-04T12:32:30.770415-08:00"}
{"id":"bd-qn5","title":"bd doctor: handle missing daemon registry gracefully","description":"When no daemon has ever been started, bd doctor shows an error parsing the registry: 'failed to parse registry: invalid character 0 after top-level value'. The doctor should handle the case where ~/.bd/daemon/registry.json doesn't exist, treating it as 'no daemon running' rather than an error.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-02T12:51:56.300983-08:00","updated_at":"2025-12-03T22:11:43.327235-08:00","closed_at":"2025-12-03T22:11:43.327235-08:00"}
{"id":"bd-91x","title":"Fix dependency naming inconsistencies (GH #440)","description":"Parent-child dependency documentation is backwards and UI labels are confusing.\\n\\nProblems:\\n1. DEPENDENCIES.md says 'bd dep add PARENT CHILD' but this is rejected\\n2. bd show displays epic children under 'Blocks' instead of 'Children'\\n3. bd dep tree EPIC shows nothing (need --direction=up)\\n4. Inconsistent with 'bd epic status' which uses 'children'\\n\\nSee: https://github.com/steveyegge/beads/issues/440","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-01T21:01:41.63295-08:00","updated_at":"2025-12-01T21:06:17.866688-08:00","closed_at":"2025-12-01T21:06:17.866688-08:00"}
{"id":"bd-077e","title":"Add close_reason field to CLI schema and documentation","description":"PR #551 persists close_reason, but the CLI documentation may not mention this field as part of the issue schema.\n\n## Current State\n- close_reason is now persisted in database\n- `bd show --json` will return close_reason in JSON output\n- Documentation may not reflect this new field\n\n## What's Missing\n- CLI reference documentation for close_reason field\n- Schema documentation showing close_reason is a top-level issue field\n- Example output showing close_reason in bd show --json\n- bd close command documentation should mention close_reason parameter is optional\n\n## Suggested Action\n1. Update README.md or CLI reference docs to list close_reason as an issue field\n2. Add example to bd close documentation\n3. Update any type definitions or schema specs\n4. Consider adding close_reason to verbose list output (bd list --verbose)","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-14T14:25:28.448654-08:00","updated_at":"2025-12-14T14:25:28.448654-08:00","dependencies":[{"issue_id":"bd-077e","depends_on_id":"bd-z86n","type":"discovered-from","created_at":"2025-12-14T14:25:28.449968-08:00","created_by":"stevey"}]}
{"id":"bd-52q","title":"Fix SyncJSONLToWorktree to merge instead of overwrite","description":"SyncJSONLToWorktree blindly copies local JSONL to worktree, overwriting remote issues.\n\n## Root Cause (GitHub #464)\nWhen Computer B syncs with fewer issues than remote:\n1. preemptiveFetchAndFastForward updates worktree (10 issues)\n2. SyncJSONLToWorktree overwrites with local (1 issue)\n3. Commit records deletion of 9 issues\n4. 3-way merge sees \"deletion in left\" → deletion wins\n\n## Fix\nBefore copying, check if worktree has more issues. If so:\n- Option A: Merge local into worktree (preferred)\n- Option B: Fail with helpful error message\n- Option C: Warn and require --force flag\n\n## Location\ninternal/syncbranch/worktree.go:107 - SyncJSONLToWorktree call\n\n## Test Case\n1. Clone repo with sync-branch containing issues\n2. bd init (starts empty since JSONL on sync-branch)\n3. bd create \"test\"\n4. bd sync\n5. Verify all issues preserved, not just \"test\"","status":"closed","issue_type":"bug","created_at":"2025-12-05T13:43:50.93096-08:00","updated_at":"2025-12-05T14:24:20.951645-08:00","closed_at":"2025-12-05T14:24:20.951645-08:00"}
{"id":"bd-dyy","title":"Review PR #513: fix hooks install docs","description":"Review and merge PR #513 from aspiers. This PR fixes incorrect docs for how to install git hooks - updates README to use bd hooks install instead of removed install.sh. Simple 1-line change. URL: https://github.com/anthropics/beads/pull/513","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-13T08:15:14.838772+11:00","updated_at":"2025-12-13T07:07:19.718544-08:00","closed_at":"2025-12-13T07:07:19.718544-08:00"}
{"id":"bd-zvg","title":"Design tombstone merge semantics","description":"Define how tombstones participate in 3-way merge. Key question: does tombstone always win over live issue (like current deletion-wins rule), or should we use updated_at comparison? Consider: tombstone with older timestamp vs live issue with newer edits. Recommendation: tombstone wins unless expired, matching current behavior but with longer TTL window.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T13:43:13.522002-08:00","updated_at":"2025-12-05T15:01:30.998256-08:00","closed_at":"2025-12-05T15:01:30.998256-08:00"}
{"id":"bd-cb64c226.9","title":"Remove Cache-Related Tests","description":"Delete or update tests that assume multi-repo caching","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T22:55:44.511897-07:00","updated_at":"2025-10-30T17:12:58.212659-07:00","closed_at":"2025-10-28T14:08:38.065118-07:00"}
{"id":"bd-cbed9619.5","title":"Add content-addressable identity to Issue type","description":"## Overview\nPhase 1: Add content hashing to enable global identification of issues regardless of their assigned IDs.\n\n## Current Problem\nThe system identifies issues only by ID (e.g., test-1, test-2). When multiple clones create the same ID with different content, there's no way to identify that these are semantically different issues without comparing all fields.\n\n## Solution\nAdd a ContentHash field to the Issue type that represents the canonical content fingerprint.\n\n## Implementation Tasks\n\n### 1. Add ContentHash field to Issue type\nFile: internal/types/types.go\n```go\ntype Issue struct {\n ID string\n ContentHash string // SHA256 of canonical content\n // ... existing fields\n}\n```\n\n### 2. Add content hash computation method\nUse existing hashIssueContent from collision.go:186 as foundation:\n```go\nfunc (i *Issue) ComputeContentHash() string {\n return hashIssueContent(i)\n}\n```\n\n### 3. Compute hash at creation time\n- Modify CreateIssue to compute and store ContentHash\n- Modify CreateIssues (batch) to compute hashes\n\n### 4. Compute hash at import time \n- Modify ImportIssues to compute ContentHash for all incoming issues\n- Store hash in database\n\n### 5. Add database column\n- Add migration to add content_hash column to issues table\n- Update SELECT/INSERT statements to include content_hash\n- Index on content_hash for fast lookups\n\n### 6. Populate existing issues\n- Add migration step to compute ContentHash for all existing issues\n- Use hashIssueContent function\n\n## Acceptance Criteria\n- Issue type has ContentHash field\n- Hash is computed automatically at creation time\n- Hash is computed for imported issues\n- Database stores content_hash column\n- All existing issues have non-empty ContentHash\n- Hash is deterministic (same content → same hash)\n- Hash excludes ID, timestamps (only semantic content)\n\n## Files to Modify\n- internal/types/types.go\n- internal/storage/sqlite/sqlite.go (schema, CreateIssue, CreateIssues)\n- internal/storage/sqlite/migrations.go (new migration)\n- internal/importer/importer.go (compute hash during import)\n- cmd/bd/create.go (compute hash at creation)\n\n## Testing\n- Unit test: same content produces same hash\n- Unit test: different content produces different hash \n- Unit test: hash excludes ID and timestamps\n- Integration test: hash persists in database\n- Migration test: existing issues get hashes populated","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T18:36:44.914967-07:00","updated_at":"2025-10-30T17:12:58.2279-07:00","closed_at":"2025-10-28T18:57:10.985198-07:00","dependencies":[{"issue_id":"bd-cbed9619.5","depends_on_id":"bd-325da116","type":"parent-child","created_at":"2025-10-28T18:39:20.547325-07:00","created_by":"daemon"}]}
{"id":"bd-zwtq","title":"Run bd doctor at end of bd init to verify setup","description":"Run bd doctor diagnostics at end of bd init (after line 398 in init.go). If issues found, warn user immediately: '⚠ Setup incomplete. Run bd doctor --fix to complete setup.' Catches configuration problems before user encounters them in normal workflow.","status":"open","priority":1,"issue_type":"feature","created_at":"2025-11-21T23:16:09.596778-08:00","updated_at":"2025-11-21T23:16:27.781976-08:00","dependencies":[{"issue_id":"bd-zwtq","depends_on_id":"bd-tbz3","type":"parent-child","created_at":"2025-11-21T23:16:09.597617-08:00","created_by":"daemon"}]}
{"id":"bd-cddj","title":"GH#520: Daemon sync-branch commit fails with pre-commit hooks (needs --no-verify)","description":"gitCommitInWorktree in daemon_sync_branch.go missing --no-verify flag, causing commit failures when pre-commit hooks installed. Library function in worktree.go:684 has correct impl. See: https://github.com/steveyegge/beads/issues/520","status":"in_progress","priority":1,"issue_type":"bug","created_at":"2025-12-14T16:31:33.151247-08:00","updated_at":"2025-12-14T16:52:49.801315-08:00"}
{"id":"bd-cb64c226.10","title":"Delete server_cache_storage.go","description":"Remove the entire cache implementation file (~286 lines)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T22:55:38.729299-07:00","updated_at":"2025-10-30T17:12:58.212391-07:00","closed_at":"2025-10-28T14:08:38.064592-07:00"}
{"id":"bd-4qfb","title":"Improve bd doctor output formatting for better readability","description":"The current bd doctor output is a wall of text that's hard to process. Consider improvements like:\n- Grouping related checks into collapsible sections\n- Using color/bold for section headers\n- Showing only failures/warnings by default with --verbose for full output\n- Better visual hierarchy between major sections\n- Summary line at top (e.g., '24 checks passed, 0 warnings, 0 errors')","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-13T09:29:27.557578+11:00","updated_at":"2025-12-13T09:29:27.557578+11:00"}
{"id":"bd-hlsw.1","title":"Pre-sync integrity check (bd sync --check)","description":"Add bd sync --check flag that detects problematic states before attempting sync: forced pushes on sync branch (via git reflog), prefix mismatches in JSONL, orphaned children with missing parents. Output combined diagnostic without modifying state.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-14T10:40:20.493608412-07:00","updated_at":"2025-12-14T10:40:20.493608412-07:00","dependencies":[{"issue_id":"bd-hlsw.1","depends_on_id":"bd-hlsw","type":"parent-child","created_at":"2025-12-14T10:40:20.494249154-07:00","created_by":"daemon"}]}
{"id":"bd-jgxi","title":"Auto-migrate database on CLI version bump","description":"When CLI is upgraded (e.g., 0.24.0 → 0.24.1), database version becomes stale. Add auto-migration in PersistentPreRun or daemon startup. Check dbVersion != CLIVersion and run bd migrate automatically. Fixes recurring UX issue where bd doctor shows version mismatch after every CLI upgrade.","status":"open","issue_type":"feature","created_at":"2025-11-21T23:16:09.004619-08:00","updated_at":"2025-11-21T23:16:27.229388-08:00","dependencies":[{"issue_id":"bd-jgxi","depends_on_id":"bd-tbz3","type":"parent-child","created_at":"2025-11-21T23:16:09.005513-08:00","created_by":"daemon"}]}
{"id":"bd-6rf","title":"bd doctor: detect and fix stale beads-sync branch","description":"## Problem\n\nWhen beads-sync diverges significantly from main (on source code, not just .beads/), it needs to be reset. After a force-push reset, other clones/contributors will have orphaned local beads-sync branches.\n\n## Symptoms\n- Local beads-sync is many commits behind main on source files\n- Local beads-sync doesn't share recent history with remote beads-sync (after force-push)\n- bd sync may behave unexpectedly\n\n## Proposed bd doctor checks\n\n1. **Check beads-sync alignment with main**\n - If beads-sync exists and is \u003eN commits behind main on non-.beads/ files, warn\n - Suggests: reset beads-sync to main\n\n2. **Check beads-sync alignment with remote**\n - If local beads-sync has diverged from origin/beads-sync (no common recent ancestor)\n - This happens after someone force-pushed a reset\n - Suggests: reset local beads-sync to origin/beads-sync\n\n## Proposed fixes (--fix)\n\n- Reset local beads-sync branch to origin/beads-sync or main\n- Handle worktree if present (git worktree remove, then recreate on next sync)\n\n## Context\nDiscovered when beads-sync drifted 126 commits behind main. Required manual reset and force-push. Contributors will need to reset their local branches too.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-12-02T23:45:40.607538-08:00","updated_at":"2025-12-03T22:13:21.727319-08:00","closed_at":"2025-12-03T22:13:21.727319-08:00"}
{"id":"bd-vs9","title":"Fix unparam unused parameter in cmd/bd/doctor.go:541","description":"Linting issue: checkHooksQuick - path is unused (unparam) at cmd/bd/doctor.go:541:22. Error: func checkHooksQuick(path string) string {","status":"open","issue_type":"bug","created_at":"2025-12-07T15:35:17.02177046-07:00","updated_at":"2025-12-07T15:35:17.02177046-07:00"}
{"id":"bd-mql4","title":"getLocalSyncBranch silently ignores YAML parse errors","description":"In autoimport.go:170-172, YAML parsing errors are silently ignored. If a user has malformed YAML in config.yaml, sync-branch will just silently be empty with no feedback.\n\nRecommendation: Add debug logging since this function is only called during auto-import, and debugging silent failures is painful.\n\nAdd: debug.Logf(\"Warning: failed to parse config.yaml: %v\", err)","status":"open","priority":4,"issue_type":"task","created_at":"2025-12-07T02:03:44.217728-08:00","updated_at":"2025-12-07T02:03:44.217728-08:00"}
{"id":"bd-9cc","title":"bd doctor: export diagnostics history for debugging","description":"Add ability to save doctor diagnostics to a file (e.g., diagnostics.json) for historical analysis and bug reporting. This would help track intermittent issues and provide context when filing bug reports. Could integrate with --perf output for comprehensive system snapshots.","status":"closed","priority":4,"issue_type":"feature","created_at":"2025-12-02T12:52:23.711572-08:00","updated_at":"2025-12-03T22:16:49.671517-08:00","closed_at":"2025-12-03T22:16:49.671517-08:00"}
{"id":"bd-0yzm","title":"GH#508: Orphan detection false positive when directory name contains dot","description":"Directory names with dots trigger orphan issue detection because dot is also used for orphan ID format. bd rename-prefix fixes it. See: https://github.com/steveyegge/beads/issues/508","status":"in_progress","priority":2,"issue_type":"bug","created_at":"2025-12-14T16:32:01.725196-08:00","updated_at":"2025-12-14T16:52:49.802533-08:00"}
{"id":"bd-53c","title":"bd sync corrupts issues.jsonl in multi-clone environments","description":"During parallel swarm operations on 2025-11-29, bd sync corrupted the issues database. Commit 93718056 purged all 80 issues from issues.jsonl.\n\nReproduction:\n1. Multiple clones of same repo (polecat swarm)\n2. Each clone runs bd sync in parallel\n3. One sync overwrites others, resulting in data loss\n\nEven in single-clone scenarios (~/src/beads), running bd sync after git pull seems to nuke the JSONL.\n\nWorkaround: Use bd import -i .beads/issues.jsonl --no-git-history instead of bd sync.\n\nRoot cause investigation needed. Options:\n1. Pessimistic locking (flock)\n2. Single point of merge (polecats on ephemeral branches)\n3. Beads-level locking (bd sync --lock)","status":"closed","issue_type":"bug","created_at":"2025-11-29T16:30:30.592507-08:00","updated_at":"2025-11-29T23:19:57.254217-08:00","closed_at":"2025-11-29T23:15:02.435084-08:00"}
{"id":"bd-6xfz","title":"GH#517: Fix Claude setting wrong priority syntax on new install","description":"Claude uses 'medium' instead of P2/2 for priority, causing infinite error loops. bd prime hook or docs not clear enough. See: https://github.com/steveyegge/beads/issues/517","status":"in_progress","priority":1,"issue_type":"bug","created_at":"2025-12-14T16:31:55.740197-08:00","updated_at":"2025-12-14T16:52:49.795747-08:00"}
{"id":"bd-aydr.3","title":"Add git operations for --hard reset","description":"Implement git integration for hard reset mode.\n\n## Operations Needed\n1. `git rm -rf .beads/*.jsonl` - remove data files from index\n2. `git commit -m 'beads: reset to clean state'` - commit removal\n3. After re-init: `git add .beads/` and commit fresh state\n\n## Edge Cases to Handle\n- Uncommitted changes in .beads/ - warn or error\n- Detached HEAD state - warn, maybe block\n- Git not initialized - skip git ops, warn\n- Git operations fail mid-way - clear error messaging\n\n## Interface\n```go\ntype GitState struct {\n IsRepo bool\n IsDirty bool // uncommitted changes in .beads/\n IsDetached bool // detached HEAD\n Branch string // current branch name\n}\n\nfunc CheckGitState(beadsDir string) (*GitState, error)\nfunc GitRemoveBeads(beadsDir string) error\nfunc GitCommitReset(message string) error\nfunc GitAddAndCommit(beadsDir, message string) error\n```\n\n## Location\n`internal/reset/git.go` - keep with reset package for now\n\nNote: Codebase has no central git package. internal/compact/git.go is compact-specific.\nFuture refactoring could extract shared git utilities, but YAGNI for now.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-13T08:44:52.798312+11:00","updated_at":"2025-12-13T10:13:32.611131+11:00","closed_at":"2025-12-13T09:17:40.785927+11:00","dependencies":[{"issue_id":"bd-aydr.3","depends_on_id":"bd-aydr","type":"parent-child","created_at":"2025-12-13T08:44:52.798715+11:00","created_by":"daemon"}]}
{"id":"bd-81x6","title":"Tombstone export includes tombstones even with --status filter","description":"In export.go, we set IncludeTombstones: true unconditionally. However, if a user runs:\n\n bd export --status=open\n\nThey might not expect tombstones in the output. The IncludeTombstones flag should probably only be set when no status filter is specified, or when --status=tombstone is explicitly requested.\n\nCurrent behavior: exports tombstones regardless of status filter\nExpected behavior: respect status filter, only include tombstones when explicitly requested or no filter","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-07T01:40:52.762758-08:00","updated_at":"2025-12-07T02:00:02.011512-08:00","closed_at":"2025-12-07T02:00:02.011512-08:00","dependencies":[{"issue_id":"bd-81x6","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-07T01:41:28.320845-08:00","created_by":"daemon"}]}
{"id":"bd-a5z","title":"bd doctor: add --dry-run flag to preview fixes without applying","description":"Currently bd doctor --fix applies all fixes. Add a --dry-run flag to preview what would be fixed without making changes. This helps users understand the impact before committing to repairs.","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-12-02T12:52:10.106929-08:00","updated_at":"2025-12-03T22:13:42.684052-08:00","closed_at":"2025-12-03T22:13:42.684052-08:00"}
{"id":"bd-73u","title":"Refactor daemon local-only sync functions to reduce duplication","description":"PR #433 added three new local-only sync functions (createLocalSyncFunc, createLocalExportFunc, createLocalAutoImportFunc) that are largely copy-paste of existing ones with git operations removed. Refactor to use a single implementation with a skipGit bool parameter or extract shared logic into helper functions to reduce ~200 lines of duplication.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-01T17:38:02.632264-08:00","updated_at":"2025-12-02T23:28:48.752202-08:00","closed_at":"2025-12-01T21:08:11.952459-08:00"}
{"id":"bd-2k5f","title":"GH#510: Document sync-branch worktree behavior","description":"User confused about beads creating worktree on main branch. Need docs explaining sync-branch worktree mechanism. See: https://github.com/steveyegge/beads/issues/510","status":"in_progress","priority":3,"issue_type":"task","created_at":"2025-12-14T16:31:58.800071-08:00","updated_at":"2025-12-14T16:52:49.802181-08:00"}
{"id":"bd-cb64c226.13","title":"Audit Current Cache Usage","description":"Understand exactly what code depends on the storage cache","notes":"AUDIT COMPLETE\n\ngetStorageForRequest() callers: 17 production + 11 test\n- server_issues_epics.go: 8 calls\n- server_labels_deps_comments.go: 4 calls \n- server_export_import_auto.go: 2 calls\n- server_compact.go: 2 calls\n- server_routing_validation_diagnostics.go: 1 call\n- server_eviction_test.go: 11 calls (DELETE entire file)\n\nPattern everywhere: store, err := s.getStorageForRequest(req) → store := s.storage\n\nreq.Cwd usage: Only for multi-repo routing. Local daemon always serves 1 repo, so routing is unused.\n\nMCP server: Uses separate daemons per repo (no req.Cwd usage found). NOT affected by cache removal.\n\nCache env vars to deprecate:\n- BEADS_DAEMON_MAX_CACHE_SIZE (used in server_core.go:63)\n- BEADS_DAEMON_CACHE_TTL (used in server_core.go:72)\n- BEADS_DAEMON_MEMORY_THRESHOLD_MB (used in server_cache_storage.go:47)\n\nServer struct fields to remove:\n- storageCache, cacheMu, maxCacheSize, cacheTTL, cleanupTicker, cacheHits, cacheMisses\n\nTests to delete:\n- server_eviction_test.go (entire file - 9 tests)\n- limits_test.go cache assertions\n\nSpecial consideration: ValidateDatabase endpoint uses findDatabaseForCwd() outside cache. Verify if used, then remove or inline.\n\nSafe to proceed with removal - cache always had 1 entry in local daemon model.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T22:55:19.3723-07:00","updated_at":"2025-10-30T17:12:58.211563-07:00","closed_at":"2025-10-28T14:08:38.060291-07:00"}
{"id":"bd-3852","title":"Add orphan detection migration","description":"Create migration to detect orphaned children in existing databases. Query: SELECT id FROM issues WHERE id LIKE '%.%' AND substr(id, 1, instr(id || '.', '.') - 1) NOT IN (SELECT id FROM issues). Log results, let user decide action (delete orphans or convert to top-level).","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-04T12:32:30.727044-08:00","updated_at":"2025-11-04T12:32:30.727044-08:00"}
{"id":"bd-7v3","title":"Add commit and branch to bd version output","description":"The 'bd version' command reports commit and branch correctly when built with 'go build' (thanks to Go 1.25+ automatic VCS info embedding), but NOT when installed with 'go install' or 'make install'. Need to either: 1) Update Makefile to use 'go build' instead of 'go install', or 2) Add explicit ldflags to both Makefile and .goreleaser.yml to ensure commit/branch are always set regardless of build method.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-09T05:56:13.642971756-07:00","updated_at":"2025-12-09T06:01:56.787528774-07:00","closed_at":"2025-12-09T06:01:56.787528774-07:00"}
{"id":"bd-0rh","title":"getLocalSyncBranch YAML parsing is fragile","description":"The getLocalSyncBranch() function in autoimport.go uses a simple line-by-line YAML parser that could fail on:\n- Indented sync-branch: (nested in a section)\n- Comments containing sync-branch:\n- Multi-line values\n- Values with special characters\n\nCurrent implementation at autoimport.go:161-172 does:\n```go\nfor _, line := range strings.Split(string(data), \"\\n\") {\n line = strings.TrimSpace(line)\n if strings.HasPrefix(line, \"sync-branch:\") {\n value := strings.TrimPrefix(line, \"sync-branch:\")\n ...\n }\n}\n```\n\nThe reason we can't use viper's cached config is that it's initialized at process startup from the main repo's CWD, not from the current directory at runtime. This causes issues in tests where t.Chdir() changes the directory.\n\nOptions:\n1. Accept the limitation (sync-branch must be top-level, unquoted)\n2. Use a proper YAML library (gopkg.in/yaml.v3) to parse just this value\n3. Refactor config package to support re-initialization per directory","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-05T14:50:57.547203-08:00","updated_at":"2025-12-07T01:44:31.444166-08:00","closed_at":"2025-12-07T01:44:31.444166-08:00"}
{"id":"bd-qvj","title":"Jira import/export integration","description":"Add ability to import issues from Jira and export beads issues to Jira. See GitHub discussion #430 for user request.\n\n**Background**: User @kaihendry configured jira.* settings but found bd sync doesn't sync with Jira - only with git. The config namespace exists but the integration doesn't.\n\n**Existing infrastructure**:\n- external_ref field for linking to external systems\n- Import logic matches by external_ref first (priority over ID matching)\n- Config namespace jira.* documented in CONFIG.md\n- GitHub import example (examples/github-import/gh2jsonl.py) provides pattern\n\n**Schema mapping challenges**:\n- Jira workflows are highly customizable (status mapping)\n- Jira has more field types (components, versions, custom fields)\n- Two-way sync needs conflict resolution\n- Jira Cloud vs Server/Data Center have different APIs\n\n**Approach**: Phased implementation starting with import, then export, then bidirectional sync.","status":"closed","priority":2,"issue_type":"epic","created_at":"2025-11-30T12:55:44.835009-08:00","updated_at":"2025-12-01T21:00:20.193271-08:00","closed_at":"2025-12-01T10:44:53.454483-08:00"}
{"id":"bd-aydr.8","title":"Respond to GitHub issue #479 with solution","description":"Once bd reset is implemented and released, respond to GitHub issue #479.\n\n## Response should include\n- Announce the new bd reset command\n- Show basic usage examples\n- Link to any documentation\n- Thank the user for the feedback\n\n## Example response\n```\nThanks for raising this! We've added a `bd reset` command to handle this case.\n\nUsage:\n- `bd reset` - Reset to clean state (prompts for confirmation)\n- `bd reset --backup` - Create backup first\n- `bd reset --hard` - Also clean up git history\n\nThis is available in version X.Y.Z.\n```\n\n## Notes\n- Wait until feature is merged and released\n- Consider if issue should be closed or left for user confirmation","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-13T08:45:00.112351+11:00","updated_at":"2025-12-13T06:24:29.562177-08:00","closed_at":"2025-12-13T10:18:06.646796+11:00","dependencies":[{"issue_id":"bd-aydr.8","depends_on_id":"bd-aydr","type":"parent-child","created_at":"2025-12-13T08:45:00.112732+11:00","created_by":"daemon"},{"issue_id":"bd-aydr.8","depends_on_id":"bd-aydr.7","type":"blocks","created_at":"2025-12-13T08:45:12.640243+11:00","created_by":"daemon"}]}
{"id":"bd-d3e5","title":"Test issue 2","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-14T11:21:13.878680387-07:00","updated_at":"2025-12-14T11:21:13.878680387-07:00","closed_at":"2025-12-14T00:32:13.890274-08:00"}
{"id":"bd-lxzx","title":"Add close_reason to JSONL export format documentation","description":"PR #551 now persists close_reason to the database, but there's a question about whether this field should be exported to JSONL format.\n\n## Current State\n- close_reason is stored in issues.close_reason column\n- close_reason is also stored in events table (audit trail)\n- The JSONL export format may or may not include close_reason\n\n## Questions\n1. Should close_reason be exported to JSONL format?\n2. If yes, where should it go (root level or nested in events)?\n3. Should there be any special handling to avoid duplication?\n4. How should close_reason be handled during JSONL import?\n\n## Why This Matters\n- JSONL is the git-friendly sync format\n- Other beads instances import from JSONL\n- close_reason is meaningful data that should be preserved across clones\n\n## Suggested Action\n- Check if close_reason is currently exported in JSONL\n- If not, add it to the export schema\n- Document the field in JSONL format spec\n- Add tests for round-trip (export -\u003e import -\u003e verify close_reason)","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-14T14:25:17.414916-08:00","updated_at":"2025-12-14T14:25:17.414916-08:00","dependencies":[{"issue_id":"bd-lxzx","depends_on_id":"bd-z86n","type":"discovered-from","created_at":"2025-12-14T14:25:17.416131-08:00","created_by":"stevey"}]}
{"id":"bd-z86n","title":"Code Review: PR #551 - Persist close_reason to issues table","description":"Code review of PR #551 which fixes close_reason persistence bug.\n\n## Summary\nThe PR correctly fixes a bug where close_reason was only stored in the events table, not in the issues.close_reason column. This caused `bd show --json` to return empty close_reason.\n\n## What Was Fixed\n- ✅ CloseIssue now updates both close_reason and closed_at\n- ✅ ReOpenIssue clears both close_reason and closed_at\n- ✅ Comprehensive tests added for both storage and CLI layers\n- ✅ Clear documentation in queries.go about dual storage strategy\n\n## Quality Assessment\n✅ Tests cover both storage layer and CLI JSON output\n✅ Handles reopen case (clearing close_reason)\n✅ Good comments explaining dual-storage design\n✅ No known issues\n\n## Potential Followups\nSee linked issues for suggestions.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-14T14:25:06.887069-08:00","updated_at":"2025-12-14T14:25:06.887069-08:00"}
{"id":"bd-c5m","title":"Safety check tests use string(rune()) which only works for single digits","status":"closed","priority":4,"issue_type":"bug","created_at":"2025-12-02T21:55:41.688857-08:00","updated_at":"2025-12-02T22:10:15.616882-08:00","closed_at":"2025-12-02T22:10:15.616882-08:00"}
{"id":"bd-xo9","title":"Document sync.require_confirmation_on_mass_delete config option","status":"closed","priority":4,"issue_type":"task","created_at":"2025-12-02T21:56:25.580287-08:00","updated_at":"2025-12-02T22:13:43.992387-08:00","closed_at":"2025-12-02T22:13:43.992387-08:00"}
{"id":"bd-7di","title":"worktree: any bd command is slow","description":"in a git worktree any bd command is slow, with a 2-3s pause before any results are shown. The identical command with `--no-daemon` is near instant.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-05T15:33:42.924618693-07:00","updated_at":"2025-12-05T15:33:42.924618693-07:00"}
{"id":"bd-au0.5","title":"Add date and priority filters to bd search","description":"Add filter parity with bd list for consistent querying.\n\n**Missing filters to add:**\n- --priority, --priority-min, --priority-max\n- --created-after, --created-before\n- --updated-after, --updated-before\n- --closed-after, --closed-before\n- --empty-description, --no-assignee, --no-labels\n- --desc-contains, --notes-contains\n\n**Files to modify:**\n- cmd/bd/search.go\n- internal/rpc/protocol.go (SearchArgs)\n- internal/storage/storage.go (Search method)\n\n**Testing:**\n- All filter combinations\n- Date format parsing\n- Daemon and direct mode","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-21T21:07:05.496726-05:00","updated_at":"2025-11-21T21:07:05.496726-05:00","dependencies":[{"issue_id":"bd-au0.5","depends_on_id":"bd-au0","type":"parent-child","created_at":"2025-11-21T21:07:05.497762-05:00","created_by":"daemon"}]}
{"id":"bd-3b4","title":"Update bd delete to create tombstones","description":"Modify delete command to create tombstone records instead of (or in addition to) deletions.jsonl entries. Phase 1: dual-write mode. Per design bd-dli.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T15:14:42.71246-08:00","updated_at":"2025-12-05T16:19:21.718607-08:00","closed_at":"2025-12-05T16:19:21.718607-08:00","dependencies":[{"issue_id":"bd-3b4","depends_on_id":"bd-fbj","type":"blocks","created_at":"2025-12-05T15:14:58.858679-08:00","created_by":"daemon"}]}
{"id":"bd-efm","title":"sync tries to create worktree in .git file","description":"example: bd sync --no-daemon\n→ Exporting pending changes to JSONL...\n→ Committing changes to sync branch 'worktree-db-fail'...\nError committing to sync branch: failed to create worktree: failed to create worktree parent directory: mkdir /var/home/matt/dev/beads/worktree-db-fail/.git: not a directory","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T15:43:38.086614222-07:00","updated_at":"2025-12-14T16:28:23.401844-08:00","closed_at":"2025-12-13T23:32:36.995519-08:00"}
{"id":"bd-au0.8","title":"Improve clean vs cleanup command naming/documentation","description":"Clarify the difference between bd clean and bd cleanup to reduce user confusion.\n\n**Current state:**\n- bd clean: Remove temporary artifacts (.beads/bd.sock, logs, etc.)\n- bd cleanup: Delete old closed issues from database\n\n**Options:**\n1. Rename for clarity:\n - bd clean → bd clean-temp\n - bd cleanup → bd cleanup-issues\n \n2. Keep names but improve help text and documentation\n\n3. Add prominent warnings in help output\n\n**Preferred approach:** Option 2 (improve documentation)\n- Update short/long descriptions in commands\n- Add examples to help text\n- Update README.md\n- Add cross-references in help output\n\n**Files to modify:**\n- cmd/bd/clean.go\n- cmd/bd/cleanup.go\n- README.md or ADVANCED.md","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-21T21:07:49.960534-05:00","updated_at":"2025-11-21T21:07:49.960534-05:00","dependencies":[{"issue_id":"bd-au0.8","depends_on_id":"bd-au0","type":"parent-child","created_at":"2025-11-21T21:07:49.962743-05:00","created_by":"daemon"}]}
{"id":"bd-0a43","title":"Split monolithic sqlite.go into focused files","description":"internal/storage/sqlite/sqlite.go is 1050 lines containing initialization, 20+ CRUD methods, query building, and schema management.\n\nSplit into:\n- store.go: Store struct \u0026 initialization (150 lines)\n- bead_queries.go: Bead CRUD (300 lines)\n- work_queries.go: Work queries (200 lines) \n- stats_queries.go: Statistics (150 lines)\n- schema.go: Schema \u0026 migrations (150 lines)\n- helpers.go: Common utilities (100 lines)\n\nImpact: Impossible to understand at a glance; hard to find specific functionality; high cognitive load\n\nEffort: 6-8 hours","status":"open","issue_type":"task","created_at":"2025-11-16T14:51:16.520465-08:00","updated_at":"2025-11-16T14:51:16.520465-08:00"}
{"id":"bd-1bu","title":"Exclude tombstones from SearchIssues by default","description":"SearchIssues() returns tombstones if they match search criteria. Per design, users generally shouldn't see deleted issues in search results.\n\nLocation: internal/storage/sqlite/queries.go:1155-1311 and transaction.go:887-1044\n\nOptions:\n1. Add default tombstone exclusion unless explicitly filtering for them\n2. Add IncludeTombstones field to IssueFilter\n\nRecommendation: Add 'status != tombstone' to WHERE clause unless filter.Status == StatusTombstone","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-05T15:35:36.398377-08:00","updated_at":"2025-12-05T15:48:07.595326-08:00","closed_at":"2025-12-05T15:48:07.595326-08:00","dependencies":[{"issue_id":"bd-1bu","depends_on_id":"bd-vw8","type":"parent-child","created_at":"2025-12-05T15:35:47.259641-08:00","created_by":"daemon"}]}
{"id":"bd-47tn","title":"Add bd daemon --stop-all command to kill all daemon processes","description":"Currently there's no easy way to stop all running bd daemon processes. Users must resort to pkill -f 'bd daemon' or similar shell commands.\n\nAdd a --stop-all flag to bd daemon that:\n1. Finds all running bd daemon processes (not just the current repo's daemon)\n2. Gracefully stops them all\n3. Reports how many were stopped\n\nThis is useful when:\n- Multiple daemons are running and causing race conditions\n- User wants a clean slate before running bd sync\n- Debugging daemon-related issues","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-13T06:34:45.080633-08:00","updated_at":"2025-12-13T06:34:52.983085-08:00"}
{"id":"bd-77gm","title":"Import reports misleading '0 created, 0 updated' when actually importing all issues","description":"When running 'bd import' on a fresh database (no existing issues), the command reports 'Import complete: 0 created, 0 updated' even though it successfully imported all issues from the JSONL file.\n\n**Steps to reproduce:**\n1. Delete .beads/beads.db\n2. Run: bd import .beads/issues.jsonl\n3. Observe output: 'Import complete: 0 created, 0 updated'\n4. Run: bd list\n5. Confirm: All issues are actually present in the database\n\n**Expected behavior:**\nReport the actual number of issues imported, e.g., 'Import complete: 523 created, 0 updated'\n\n**Actual behavior:**\n'Import complete: 0 created, 0 updated' (misleading - makes user think import failed)\n\n**Impact:**\n- Users think import failed when it succeeded\n- Confusing during database sync operations (e.g., after git pull)\n- Makes debugging harder (can't tell if import actually worked)\n\n**Context:**\nDiscovered during VC session when syncing database after git pull. The misleading message caused confusion about whether the database was properly synced with the canonical JSONL file.","status":"open","priority":2,"issue_type":"bug","created_at":"2025-11-09T16:20:13.191156-08:00","updated_at":"2025-11-09T16:20:13.191156-08:00"}
{"id":"bd-io0","title":"sync.branch config lost on clone - should be in config.yaml","description":"## Problem\n\nThe sync.branch configuration is stored in the SQLite database, which is gitignored. When contributors clone a repo that uses beads:\n\n1. They get .beads/issues.jsonl (tracked)\n2. They don't get .beads/beads.db (gitignored)\n3. They lose the sync.branch config\n\nWhen they run 'bd init' or 'bd doctor --fix', sync.branch gets auto-set to the current branch (usually 'main'), but if the project uses a dedicated sync branch like 'beads-sync', they'll be committing to the wrong branch.\n\n## Root Cause\n\nsyncbranch.Get() only checks:\n1. BEADS_SYNC_BRANCH env var\n2. Database config (store.GetConfig)\n\nIt never reads from config.yaml, which IS tracked in git and persists across clones.\n\n## Proposed Solution\n\nAdd sync-branch support to config.yaml with this precedence:\n1. BEADS_SYNC_BRANCH env var (highest)\n2. config.yaml sync-branch setting\n3. Database config (legacy/local override)\n4. Auto-detect from current branch (lowest)\n\nChanges needed:\n1. Update syncbranch.Get() to check config.GetString('sync-branch') between env and database\n2. Update config.yaml template in init.go to include sync-branch\n3. Update docs to recommend setting sync-branch in config.yaml for team projects\n4. Consider: bd init --branch should also write to config.yaml, not just database","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-30T10:51:29.594627-08:00","updated_at":"2025-11-30T10:54:14.198025-08:00","closed_at":"2025-11-30T10:54:14.198025-08:00"}
{"id":"bd-cbed9619.4","title":"Make DetectCollisions read-only (separate detection from modification)","description":"## Overview\nPhase 2: Separate collision detection from state modification to enable safe, composable collision resolution.\n\n## Current Problem\nDetectCollisions (collision.go:38-111) modifies database state during detection:\n- Line 83-86: Deletes issues when content matches but ID differs\n- This violates separation of concerns\n- Causes race conditions when processing multiple issues\n- Makes contentToDBIssue map stale after first deletion\n- Partial failures leave DB in inconsistent state\n\n## Solution\nMake DetectCollisions purely read-only. Move all modifications to a separate ApplyCollisionResolution function.\n\n## Implementation Tasks\n\n### 1. Add RenameDetail to CollisionResult\nFile: internal/storage/sqlite/collision.go\n```go\ntype CollisionResult struct {\n ExactMatches []string\n Collisions []*CollisionDetail\n NewIssues []string\n Renames []*RenameDetail // NEW\n}\n\ntype RenameDetail struct {\n OldID string // ID in database\n NewID string // ID in incoming\n Issue *types.Issue // The issue with new ID\n}\n```\n\n### 2. Remove deletion from DetectCollisions\nReplace lines 83-86:\n```go\n// OLD (DELETE THIS):\nif err := s.DeleteIssue(ctx, dbMatch.ID); err != nil {\n return nil, fmt.Errorf(\"failed to delete renamed issue...\")\n}\n\n// NEW (ADD THIS):\nresult.Renames = append(result.Renames, \u0026RenameDetail{\n OldID: dbMatch.ID,\n NewID: incoming.ID,\n Issue: incoming,\n})\ncontinue // Don't mark as NewIssue yet\n```\n\n### 3. Create ApplyCollisionResolution function\nNew function to apply all modifications atomically:\n```go\nfunc ApplyCollisionResolution(ctx context.Context, s *SQLiteStorage,\n result *CollisionResult, mapping map[string]string) error {\n \n // Phase 1: Handle renames (delete old IDs)\n for _, rename := range result.Renames {\n if err := s.DeleteIssue(ctx, rename.OldID); err != nil {\n return fmt.Errorf(\"failed to delete renamed issue %s: %w\", \n rename.OldID, err)\n }\n }\n \n // Phase 2: Create new IDs (from mapping)\n // Phase 3: Update references\n return nil\n}\n```\n\n### 4. Update callers to use two-phase approach\nFile: internal/importer/importer.go (handleCollisions)\n```go\n// Phase 1: Detect (read-only)\ncollisionResult, err := sqlite.DetectCollisions(ctx, sqliteStore, issues)\n\n// Phase 2: Resolve (compute mapping)\nmapping, err := sqlite.ResolveNWayCollisions(ctx, sqliteStore, collisionResult)\n\n// Phase 3: Apply (modify DB)\nerr = sqlite.ApplyCollisionResolution(ctx, sqliteStore, collisionResult, mapping)\n```\n\n### 5. Update tests\n- Verify DetectCollisions doesn't modify DB\n- Test ApplyCollisionResolution separately\n- Add test for rename detection without modification\n\n## Acceptance Criteria\n- DetectCollisions performs zero writes to database\n- DetectCollisions returns RenameDetail entries for content matches\n- ApplyCollisionResolution handles all modifications\n- All existing tests still pass\n- New test verifies read-only detection\n- contentToDBIssue map stays consistent throughout detection\n\n## Files to Modify\n- internal/storage/sqlite/collision.go (DetectCollisions, new function)\n- internal/importer/importer.go (handleCollisions caller)\n- internal/storage/sqlite/collision_test.go (add tests)\n\n## Testing\n- Unit test: DetectCollisions with content match doesn't delete DB issue\n- Unit test: RenameDetail correctly populated\n- Unit test: ApplyCollisionResolution applies renames\n- Integration test: Full flow still works end-to-end\n\n## Risk Mitigation\nThis is a significant refactor of core collision logic. Recommend:\n1. Add comprehensive tests before modifying\n2. Use feature flag to enable/disable new behavior\n3. Test thoroughly with TestTwoCloneCollision first","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T18:37:09.652326-07:00","updated_at":"2025-10-30T17:12:58.228266-07:00","closed_at":"2025-10-28T19:08:17.715416-07:00","dependencies":[{"issue_id":"bd-cbed9619.4","depends_on_id":"bd-325da116","type":"parent-child","created_at":"2025-10-28T18:39:20.570276-07:00","created_by":"daemon"},{"issue_id":"bd-cbed9619.4","depends_on_id":"bd-cbed9619.5","type":"blocks","created_at":"2025-10-28T18:39:28.285653-07:00","created_by":"daemon"}]}
{"id":"bd-cbed9619.1","title":"Fix multi-round convergence for N-way collisions","description":"## Problem\n\nN-way collision resolution is working (IDs get remapped correctly), but clones don't fully converge after a single final pull. Each clone is missing some issues that other clones have.\n\nFrom TestFiveCloneCollision results:\n- Clone A has: A, B\n- Clone B has: A, B \n- Clone C has: A, B, C\n- Clone D has: A, B, C, D\n- Clone E has: A, B, C, E\n\n**Expected**: All clones should have A, B, C, D, E after final pull.\n\n## Root Cause\n\nThe current sync workflow does:\n1. Each clone syncs in order (resolving collisions locally)\n2. Final pull to get all changes\n\nBut the final pull itself may need import with collision resolution, which creates new commits. These new commits aren't propagated to other clones, so they remain incomplete.\n\n## Proposed Solution\n\n**Option 1: Multi-round final sync**\n- After final pull, do additional sync rounds until all clones converge\n- Check convergence by comparing issue counts or content hashes\n- Maximum N rounds for N clones\n\n**Option 2: Iterative pull-import-push**\n- Each clone: pull → import with --resolve-collisions → push\n- Repeat until no new changes\n- Guaranteed convergence but may create commit spam\n\n**Option 3: Fix auto-import to be truly idempotent**\n- Ensure importing same JSONL multiple times produces no new commits\n- May require smarter content-based deduplication\n\n## Acceptance Criteria\n\n- TestFiveCloneCollision passes without t.Skip\n- All N clones have all N issues after convergence\n- Convergence happens in bounded rounds (≤ N)\n- No data loss or duplication\n- Works for arbitrary N (tested with 5, 10 clones)\n\n## Impact\n\nThis is the final blocker for bd-cbed9619 epic completion.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T21:22:21.486109-07:00","updated_at":"2025-10-30T17:12:58.180996-07:00","closed_at":"2025-10-29T11:02:40.756891-07:00"}
{"id":"bd-7r4l","title":"GH#488: Support claude.local.md for local-only config","description":"Allow CLAUDE.local.md for testing bd without committing to repo or overriding shared CLAUDE.md. Not every repo wants committed AI config. See: https://github.com/steveyegge/beads/issues/488","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2025-12-14T16:32:19.944847-08:00","updated_at":"2025-12-14T16:52:49.800832-08:00"}
{"id":"bd-tbz3","title":"bd init UX Improvements","description":"bd init leaves users with incomplete setup, requiring manual bd doctor --fix. Issues found: (1) git hooks not installed if user declines prompt, (2) no auto-migration when CLI is upgraded, (3) stale merge driver configs from old versions. Fix by making bd init more robust with better defaults and auto-migration.","status":"open","priority":1,"issue_type":"epic","created_at":"2025-11-21T23:16:00.333543-08:00","updated_at":"2025-11-21T23:16:37.811233-08:00"}
{"id":"bd-t4u1","title":"False positive detection by Kaspersky Antivirus (Trojan)","description":"Kaspersky Antivirus falsely detects beads (bd.exe v0.23.1) as a Trojan (PDM:Trojan.Win32.Generic) and removes it.\nEvent: Malicious object detected\nComponent: System Watcher\nObject name: bd.exe\n","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-20T18:56:12.498187-05:00","updated_at":"2025-11-20T18:56:12.498187-05:00"}
{"id":"bd-4ri","title":"Fix TestFallbackToDirectModeEnablesFlush deadlock causing 10min test timeout","description":"## Problem\n\nTestFallbackToDirectModeEnablesFlush in direct_mode_test.go deadlocks for 9m59s before timing out, causing the entire test suite to take 10+ minutes instead of \u003c10 seconds.\n\n## Root Cause\n\nDatabase lock contention between test cleanup and flushToJSONL():\n- Test cleanup (line 36) tries to close DB via defer\n- flushToJSONL() (line 132) is still accessing DB\n- Results in deadlock: database/sql.(*DB).Close() waits for mutex while GetJSONLFileHash() holds it\n\n## Stack Trace Evidence\n\n```\ngoroutine 512 [sync.Mutex.Lock, 9 minutes]:\ndatabase/sql.(*DB).Close(0x14000643790)\n .../database/sql/sql.go:927 +0x84\ngithub.com/steveyegge/beads/cmd/bd.TestFallbackToDirectModeEnablesFlush.func1()\n .../direct_mode_test.go:36 +0xf4\n\nWhile goroutine running flushToJSONL() holds DB connection via GetJSONLFileHash()\n```\n\n## Impact\n\n- Test suite: 10+ minutes → should be \u003c10 seconds\n- ALL other tests pass in ~4 seconds\n- This ONE test accounts for 99.9% of test runtime\n\n## Related\n\nThis is the EXACT same issue documented in MAIN_TEST_REFACTOR_NOTES.md for why main_test.go refactoring was deferred - global state manipulation + DB cleanup = deadlock.\n\n## Fix Approaches\n\n1. **Add proper cleanup sequencing** - stop flush goroutines BEFORE closing DB\n2. **Use test-specific DB lifecycle** - ensure flush completes before cleanup\n3. **Mock the flush mechanism** - avoid real DB for testing this code path \n4. **Add explicit timeout handling** - fail fast with clear error instead of hanging\n\n## Files\n\n- cmd/bd/direct_mode_test.go:36-132\n- cmd/bd/autoflush.go:353 (validateJSONLIntegrity)\n- cmd/bd/autoflush.go:508 (flushToJSONLWithState)\n\n## Acceptance\n\n- Test passes without timeout\n- Test suite completes in \u003c10 seconds\n- No deadlock between cleanup and flush operations","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-21T20:09:00.794372-05:00","updated_at":"2025-11-21T20:09:00.794372-05:00"}
{"id":"bd-lsa","title":"Mass deletion logging for forensics","description":"Log detailed information when the safety check triggers during auto-push.\n\nWhen \u003e50% issues vanish AND \u003e5 existed:\n- Log which issues vanished\n- Log the before/after counts\n- Log timestamp for forensic analysis\n\nThis gives users visibility into what happened if something goes wrong, without blocking the sync.\n\nLocation: internal/syncbranch/worktree.go\nParent issue: bd-3s8","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-02T19:30:59.835398-08:00","updated_at":"2025-12-03T22:17:33.866065-08:00","closed_at":"2025-12-03T22:17:33.866065-08:00","dependencies":[{"issue_id":"bd-lsa","depends_on_id":"bd-7ch","type":"blocks","created_at":"2025-12-02T19:31:08.254087-08:00","created_by":"daemon"}]}
{"id":"bd-aydr.1","title":"Implement core reset package (internal/reset)","description":"Create the core reset logic in internal/reset/ package.\n\n## Responsibilities\n- ResetOptions struct with all flag options\n- CountImpact() - count issues/tombstones that will be deleted\n- ValidateState() - check .beads/ exists, check git dirty state\n- ExecuteReset() - main reset logic (without CLI concerns)\n- Integrate with daemon killall\n\n## Interface Design\n```go\ntype ResetOptions struct {\n Hard bool // Include git operations (git rm, commit)\n Backup bool // Create backup before reset\n DryRun bool // Preview only, don't execute\n SkipInit bool // Don't re-initialize after reset\n}\n\ntype ResetResult struct {\n IssuesDeleted int\n TombstonesDeleted int\n BackupPath string // if backup was created\n DaemonsKilled int\n}\n\ntype ImpactSummary struct {\n IssueCount int\n OpenCount int\n ClosedCount int\n TombstoneCount int\n HasUncommitted bool // git dirty state\n}\n\nfunc Reset(opts ResetOptions) (*ResetResult, error)\nfunc CountImpact() (*ImpactSummary, error)\nfunc ValidateState() error\n```\n\n## IMPORTANT: CLI vs Core Separation\n- `Force` (skip confirmation) is NOT in ResetOptions - that's a CLI concern\n- Core always executes when called; CLI decides whether to prompt first\n- Keep CLI-agnostic: no prompts, no colored output, no user interaction\n- Return errors for CLI to handle with user-friendly messages\n- Unit testable in isolation\n\n## Dependencies\n- Uses daemon.KillAllDaemons() from internal/daemon/\n- Calls bd init logic after reset (unless SkipInit)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-13T08:44:50.145364+11:00","updated_at":"2025-12-13T10:13:32.610253+11:00","closed_at":"2025-12-13T09:20:06.184893+11:00","dependencies":[{"issue_id":"bd-aydr.1","depends_on_id":"bd-aydr","type":"parent-child","created_at":"2025-12-13T08:44:50.145775+11:00","created_by":"daemon"}]}
{"id":"bd-3sz0","title":"Auto-repair stale merge driver configs with invalid placeholders","description":"Old bd versions (\u003c0.24.0) installed merge driver with invalid placeholders %L %R instead of %A %B. Add detection to bd doctor --fix: check if git config merge.beads.driver contains %L or %R, auto-repair to 'bd merge %A %O %A %B'. One-time migration for users who initialized with old versions.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-21T23:16:10.762808-08:00","updated_at":"2025-11-21T23:16:28.892655-08:00","dependencies":[{"issue_id":"bd-3sz0","depends_on_id":"bd-tbz3","type":"parent-child","created_at":"2025-11-21T23:16:10.763612-08:00","created_by":"daemon"}]}
{"id":"bd-saa","title":"Add index on deleted_at for TTL queries","description":"Per bd-2m7 design: 'Index for efficient tombstone filtering' was recommended. The current implementation does NOT add an index on deleted_at.\n\nFor TTL cleanup queries like 'SELECT * FROM issues WHERE deleted_at \u003c datetime(now, -30 days)', this will require a full table scan.\n\nAdd to migration or new migration:\nCREATE INDEX IF NOT EXISTS idx_issues_deleted_at ON issues(deleted_at) WHERE deleted_at IS NOT NULL","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-05T15:35:33.842664-08:00","updated_at":"2025-12-05T15:48:07.584268-08:00","closed_at":"2025-12-05T15:48:07.584268-08:00","dependencies":[{"issue_id":"bd-saa","depends_on_id":"bd-vw8","type":"parent-child","created_at":"2025-12-05T15:35:47.222711-08:00","created_by":"daemon"}]}
{"id":"bd-4ec8","title":"Widespread double JSON encoding bug in daemon mode RPC calls","description":"Multiple CLI commands had the same double JSON encoding bug found in bd-1048. All commands that called ResolveID via RPC used string(resp.Data) instead of properly unmarshaling the JSON response. This caused IDs to retain JSON quotes (\"bd-1048\" instead of bd-1048), which then got double-encoded when passed to subsequent RPC calls.\n\nAffected commands:\n- bd show (3 instances)\n- bd dep add/remove/tree (5 instances)\n- bd label add/remove/list (3 instances)\n- bd reopen (1 instance)\n\nRoot cause: resp.Data is json.RawMessage (already JSON-encoded), so string() conversion preserves quotes.\n\nFix: Replace all string(resp.Data) with json.Unmarshal(resp.Data, \u0026id) for proper deserialization.\n\nAll commands now tested and working correctly with daemon mode.","status":"open","issue_type":"bug","created_at":"2025-11-02T22:33:01.632691-08:00","updated_at":"2025-11-02T22:33:01.632691-08:00"}
{"id":"bd-0is","title":"Fix bd init to bootstrap from sync-branch when configured","description":"When sync-branch is configured in config.yaml, bd init should import from that branch instead of HEAD. Currently it reads HEAD:.beads/issues.jsonl which may be empty or stale when issues are on the sync branch. Location: cmd/bd/autoimport.go:97 checkGitForIssues()","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-05T13:43:58.083186-08:00","updated_at":"2025-12-05T14:46:16.847836-08:00","closed_at":"2025-12-05T14:46:16.847836-08:00"}
{"id":"bd-iip5","title":"TestImportIssues_LegacyDeletionsConvertedToTombstones is failing","description":"The test TestImportIssues_LegacyDeletionsConvertedToTombstones in internal/importer/importer_test.go is failing:\n\nExpected 3 created (1 regular + 2 tombstones from deletions.jsonl), got 2\nExpected tombstone for test-deleted2 not found\n\nThe test expects legacy deletions.jsonl entries to be converted to tombstones during import, but test-deleted2 is not being converted.\n\nLocation: internal/importer/importer_test.go:1344","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-07T02:09:19.17774-08:00","updated_at":"2025-12-07T02:16:55.422522-08:00","closed_at":"2025-12-07T02:16:55.422522-08:00"}
{"id":"bd-6x5","title":"mergeTombstones does not handle empty DeletedAt timestamps","description":"The mergeTombstones() function uses isTimeAfter() to compare deleted_at timestamps, but does not handle the edge case where one or both tombstones have empty DeletedAt fields. Current behavior with isTimeAfter() semantics: empty string returns false when compared, which means if left.DeletedAt is empty, right wins. If both are empty, behavior depends on isTimeAfter tie-breaker. This should be explicitly handled with a comment or validation. Recommendation: Add explicit handling or documentation for invalid tombstones. Files: internal/merge/merge.go:448-456","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-05T16:36:43.002612-08:00","updated_at":"2025-12-05T17:15:57.633147-08:00","closed_at":"2025-12-05T17:15:57.633147-08:00"}
{"id":"bd-ig5","title":"Duplicate tombstone constants in merge and types packages","description":"## Problem\n\nThe tombstone constants are duplicated between two packages:\n\n**internal/types/types.go:**\n```go\nconst DefaultTombstoneTTL = 30 * 24 * time.Hour\nconst ClockSkewGrace = 1 * time.Hour\nconst StatusTombstone Status = \"tombstone\"\n```\n\n**internal/merge/merge.go:**\n```go\nconst StatusTombstone = \"tombstone\"\nconst DefaultTombstoneTTL = 30 * 24 * time.Hour\nconst ClockSkewGrace = 1 * time.Hour\n```\n\nThis violates DRY and creates risk of divergence if one is updated but not the other.\n\n## Root Cause\n\nThe merge package has its own `Issue` struct (for JSONL parsing) and cannot import types.Issue directly due to the different struct design. However, the constants could be shared.\n\n## Recommendation\n\nExport the constants from types package and import them in merge:\n\n```go\n// merge/merge.go\nimport \"github.com/steveyegge/beads/internal/types\"\n\n// Use types.StatusTombstone, types.DefaultTombstoneTTL, types.ClockSkewGrace\n```\n\nOr create a shared constants package if import cycles are a concern.\n\n## Files\n- internal/merge/merge.go:241-248\n- internal/types/types.go:77-84, 170","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-05T16:36:06.159443-08:00","updated_at":"2025-12-05T17:15:57.624376-08:00","closed_at":"2025-12-05T17:15:57.624376-08:00"}
{"id":"bd-k2n","title":"PushSyncBranch may fail if worktree was cleaned up","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-12-02T21:56:00.209253-08:00","updated_at":"2025-12-02T22:09:09.552051-08:00","closed_at":"2025-12-02T22:09:09.552051-08:00"}
{"id":"bd-fmo","title":"Missing test for IsExpiredTombstone edge cases","description":"## Problem\n\nThe `IsExpiredTombstone()` function has several edge cases that aren't directly tested:\n\n1. **Invalid DeletedAt timestamp** - Returns false (safety), but not tested\n2. **ttl=0 fallback to DefaultTombstoneTTL** - Not tested directly\n3. **Tombstone with empty DeletedAt** - Returns false, tested implicitly but not explicitly\n4. **Clock skew grace period effect** - Not tested (would need time mocking)\n\n## Current Test Coverage\n\nThe existing tests use `time.Now()` which makes them non-deterministic:\n```go\nDeletedAt: time.Now().Add(-24 * time.Hour).Format(time.RFC3339)\n```\n\nThis works but doesn't test the expiration boundary precisely.\n\n## Recommendation\n\nAdd explicit unit tests for `IsExpiredTombstone()`:\n\n```go\nfunc TestIsExpiredTombstone(t *testing.T) {\n tests := []struct {\n name string\n status string\n deletedAt string\n ttl time.Duration\n expected bool\n }{\n {\"non-tombstone returns false\", \"open\", \"2024-01-01T00:00:00Z\", 0, false},\n {\"empty deleted_at returns false\", \"tombstone\", \"\", 0, false},\n {\"invalid timestamp returns false\", \"tombstone\", \"not-a-date\", 0, false},\n {\"within TTL returns false\", \"tombstone\", time.Now().Add(-1*time.Hour).Format(time.RFC3339), 24*time.Hour, false},\n {\"beyond TTL returns true\", \"tombstone\", time.Now().Add(-48*time.Hour).Format(time.RFC3339), 24*time.Hour, true},\n }\n // ...\n}\n```\n\n## Files\n- internal/merge/merge.go:255-290\n- internal/merge/merge_test.go (add TestIsExpiredTombstone)","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-05T16:36:09.106135-08:00","updated_at":"2025-12-07T02:16:16.881654-08:00","closed_at":"2025-12-07T02:16:16.881654-08:00"}
{"id":"bd-6y5","title":"Add unit tests for getLocalSyncBranch","description":"The new getLocalSyncBranch() function in autoimport.go (bd-0is fix) has no dedicated unit tests.\n\nShould test:\n- Returns empty string when no config.yaml exists\n- Returns empty string when config.yaml has no sync-branch key\n- Returns value when sync-branch is set with double quotes\n- Returns value when sync-branch is set with single quotes\n- Returns value when sync-branch is set without quotes\n- Returns BEADS_SYNC_BRANCH env var when set (takes precedence)\n- Handles edge cases: empty file, whitespace-only lines, comments\n\nLocation: cmd/bd/autoimport_test.go","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-05T14:51:07.129329-08:00","updated_at":"2025-12-07T01:57:11.69579-08:00","closed_at":"2025-12-07T01:57:11.69579-08:00"}
{"id":"bd-k5kz","title":"Tombstone import creates duplicate entries when deletions.jsonl has entries already in JSONL","description":"In the tombstone import logic (bd-dve), when a non-tombstone issue is in both JSONL and deletions.jsonl, we:\n1. Skip the issue (line 149-155)\n2. Create a tombstone from deletions.jsonl (lines 161-171)\n\nThis means if the JSONL contains issue 'bd-abc' (non-tombstone) and deletions.jsonl also has 'bd-abc', we skip the JSONL version but then add a tombstone version from deletions.jsonl. This is intentional but the skipped issue count may be confusing.\n\nConsider: should we track converted-to-tombstone separately from skipped-deleted in the Result struct?","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-07T01:40:25.411613-08:00","updated_at":"2025-12-13T09:42:56.871484+11:00","closed_at":"2025-12-07T02:25:56.191188-08:00","dependencies":[{"issue_id":"bd-k5kz","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-07T01:41:28.205715-08:00","created_by":"daemon"}]}
{"id":"bd-0fvq","title":"bd doctor should recommend bd prime migration for existing repos","description":"bd doctor should detect old beads integration patterns and recommend migrating to bd prime approach.\n\n## Current behavior\n- bd doctor checks if Claude hooks are installed globally\n- Doesn't check project-level integration (AGENTS.md, CLAUDE.md)\n- Doesn't recommend migration for repos using old patterns\n\n## Desired behavior\nbd doctor should detect and suggest:\n\n1. **Old slash command pattern detected**\n - Check for /beads:* references in AGENTS.md, CLAUDE.md\n - Suggest: These slash commands are deprecated, use bd prime hooks instead\n \n2. **No agent documentation**\n - Check if AGENTS.md or CLAUDE.md exists\n - Suggest: Run 'bd onboard' or 'bd setup claude' to document workflow\n \n3. **Old MCP-only pattern**\n - Check for instructions to use MCP tools but no bd prime hooks\n - Suggest: Add bd prime hooks for better token efficiency\n\n4. **Migration path**\n - Show: 'Run bd setup claude to add SessionStart/PreCompact hooks'\n - Show: 'Update AGENTS.md to reference bd prime instead of slash commands'\n\n## Example output\n\n⚠ Warning: Old beads integration detected in CLAUDE.md\n Found: /beads:* slash command references (deprecated)\n Recommend: Migrate to bd prime hooks for better token efficiency\n Fix: Run 'bd setup claude' and update CLAUDE.md\n\n💡 Tip: bd prime + hooks reduces token usage by 80-99% vs slash commands\n MCP mode: ~50 tokens vs ~10.5k for full MCP scan\n CLI mode: ~1-2k tokens with automatic context recovery\n\n## Benefits\n- Helps existing repos adopt new best practices\n- Clear migration path for users\n- Better token efficiency messaging","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-12T03:20:25.567748-08:00","updated_at":"2025-11-12T03:20:25.567748-08:00"}
{"id":"bd-pdr2","title":"Consider backwards compatibility for ready() and list() return type change","description":"PR #481 changed the return types of `ready()` and `list()` from `list[Issue]` to `list[IssueMinimal] | CompactedResult`. This is a breaking change for MCP clients.\n\n## Impact Assessment\nBreaking change affects:\n- Any MCP client expecting `list[Issue]` from ready()\n- Any MCP client expecting `list[Issue]` from list()\n- Client code that accesses full Issue fields (description, design, acceptance_criteria, timestamps, dependencies, dependents)\n\n## Current Behavior\n- ready() returns `list[IssueMinimal] | CompactedResult`\n- list() returns `list[IssueMinimal] | CompactedResult`\n- show() still returns full `Issue` (good)\n\n## Considerations\n**Pros of current approach:**\n- Forces clients to use show() for full details (good for context efficiency)\n- Simple mental model (always use show for full data)\n- Documentation warns about this\n\n**Cons:**\n- Clients expecting list[Issue] will break\n- No graceful degradation option\n- No migration period\n\n## Potential Solutions\n1. Add optional parameter `full_details=false` to ready/list (would increase payload)\n2. Create separate tools: ready_minimal/list_minimal + ready_full/list_full\n3. Accept breaking change and document upgrade path (current approach)\n4. Version the MCP server and document migration guide\n\n## Recommendation\nCurrent approach (solution 3) is reasonable if:\n- Changelog clearly documents the breaking change\n- Migration guide provided to clients\n- Error handling is graceful for clients expecting specific fields","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-14T14:24:56.460465-08:00","updated_at":"2025-12-14T14:24:56.460465-08:00","dependencies":[{"issue_id":"bd-pdr2","depends_on_id":"bd-otf4","type":"discovered-from","created_at":"2025-12-14T14:24:56.461959-08:00","created_by":"stevey"}]}
{"id":"bd-ykd9","title":"Add bd doctor --fix flag to automatically repair issues","description":"Implement a --fix flag for bd doctor that can automatically repair detected issues.\n\nRequirements:\n- Add --fix flag to bd doctor command\n- Show all fixable issues and prompt for confirmation before applying fixes\n- Organize fix implementations under doctor/fix/\u003ctype_of_fix\u003e.go\n- Each fix type should have its own file (e.g., doctor/fix/hooks.go, doctor/fix/sync.go)\n- Display what will be fixed and ask user to confirm (Y/n) before proceeding\n- Support fixing issues like:\n - Missing or broken git hooks\n - Sync problems with remote\n - File permission issues\n - Any other auto-repairable issues doctor detects\n\nImplementation notes:\n- Maintain separation between detection (existing doctor code) and repair (new fix code)\n- Each fix should be idempotent and safe to run multiple times\n- Provide clear output about what was fixed\n- Log any fixes that fail with actionable error messages","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-14T18:17:48.411264-08:00","updated_at":"2025-11-14T18:17:58.88609-08:00"}
{"id":"bd-4pd","title":"Imperator lacks mail hooks for automatic notification","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-30T22:53:52.007971-08:00","updated_at":"2025-12-02T23:28:48.751957-08:00","closed_at":"2025-12-01T22:01:27.835516-08:00"}
{"id":"bd-ciu","title":"formatVanishedIssues output order is non-deterministic","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-12-02T21:55:32.897206-08:00","updated_at":"2025-12-02T22:07:23.677332-08:00","closed_at":"2025-12-02T22:07:23.677332-08:00"}
{"id":"bd-g9eu","title":"Investigate TestRoutingIntegration failure","description":"TestRoutingIntegration/maintainer_with_SSH_remote failed during pre-commit check with \"expected role maintainer, got contributor\".\nThis occurred while running `go test -short ./...` on darwin/arm64.\nThe failure appears unrelated to storage/sqlite changes.\nNeed to investigate if this is a flaky test or environmental issue.","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T15:55:19.337094-08:00","updated_at":"2025-11-20T15:55:19.337094-08:00"}
{"id":"bd-1sn","title":"Tombstone fields not merged in mergeIssue function","description":"The mergeIssue() function in merge.go does not handle tombstone fields (DeletedAt, DeletedBy, DeleteReason, OriginalType) when merging live issues. While tombstones are handled separately in merge3WayWithTTL(), if a tombstone ever reaches mergeIssue() via the mergeStatus safety fallback, the tombstone fields would be lost. The mergeIssue() function should either: 1) Copy tombstone fields when result.Status becomes tombstone, or 2) Assert that tombstones never reach mergeIssue() (defensive check). Files: internal/merge/merge.go:458-499","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-05T16:36:24.726818-08:00","updated_at":"2025-12-05T17:15:57.641091-08:00","closed_at":"2025-12-05T17:15:57.641091-08:00"}
{"id":"bd-e1085716","title":"bd validate - Comprehensive health check","description":"Run all validation checks in one command.\n\nChecks:\n- Duplicates\n- Orphaned dependencies\n- Test pollution\n- Git conflicts\n\nSupports --fix-all for auto-repair.\n\nDepends on bd-cbed9619.1, bd-0dcea000, bd-31aab707, bd-9826b69a.\n\nFiles: cmd/bd/validate.go (new)","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-29T23:05:13.980679-07:00","updated_at":"2025-10-30T17:12:58.19736-07:00"}
{"id":"bd-fi05","title":"bd sync fails with orphaned issues and duplicate ID conflict","description":"After fixing the deleted_at TEXT column scanning bug (commit 18b1eb2), bd sync still fails with two issues:\n\n1. Orphan Detection Warning: 12 orphaned child issues whose parents no longer exist (bd-cb64c226.* and bd-cbed9619.*)\n\n2. Import Failure: UNIQUE constraint failed for bd-360 - this tombstone exists in both DB and JSONL\n\nError: \"Import failed: error creating depth-0 issues: bulk insert issues: failed to insert issue bd-360: sqlite3: constraint failed: UNIQUE constraint failed: issues.id\"\n\nFix options:\n- Delete orphaned child issues with bd delete\n- Resolve bd-360 duplicate (in deletions.jsonl vs tombstone in DB)\n- Reset sync branch: git branch -f beads-sync main \u0026\u0026 git push --force-with-lease origin beads-sync","notes":"Fixed tombstone constraint violation bug. When deleting closed issues, the CHECK constraint (status = 'closed') = (closed_at IS NOT NULL) was violated because CreateTombstone didn't clear closed_at. Fix: set closed_at = NULL in tombstone creation SQL.\n\nThe sync data corruption (orphaned issues in beads-sync branch) requires manual cleanup: reset sync branch with 'git branch -f beads-sync main \u0026\u0026 git push --force-with-lease origin beads-sync'","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-13T07:14:33.831346-08:00","updated_at":"2025-12-13T10:50:48.545465-08:00","closed_at":"2025-12-13T07:30:33.843986-08:00"}
{"id":"bd-89f89fc0","title":"Remove unreachable RPC methods","description":"Several RPC server and client methods are unreachable and should be removed:\n\nServer methods (internal/rpc/server.go):\n- `Server.GetLastImportTime` (line 2116)\n- `Server.SetLastImportTime` (line 2123)\n- `Server.findJSONLPath` (line 2255)\n\nClient methods (internal/rpc/client.go):\n- `Client.Import` (line 311) - RPC import not used (daemon uses autoimport)\n\nEvidence:\n```bash\ngo run golang.org/x/tools/cmd/deadcode@latest -test ./...\n```\n\nImpact: Removes ~80 LOC of unused RPC code","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-28T16:20:02.432202-07:00","updated_at":"2025-10-30T17:12:58.222655-07:00"}
{"id":"bd-c3u","title":"Review PR #512: clarify bd ready docs","description":"Review and merge PR #512 from aspiers. This PR clarifies what bd ready does after git pull in README.md. Simple 1-line change. URL: https://github.com/anthropics/beads/pull/512","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-13T08:15:13.405161+11:00","updated_at":"2025-12-13T07:07:29.641265-08:00","closed_at":"2025-12-13T07:07:29.641265-08:00"}
{"id":"bd-lw0x","title":"Fix bd sync race condition with daemon causing dirty working directory","description":"After bd sync completes with sync.branch mode, subsequent bd commands or daemon file watcher would see a hash mismatch and trigger auto-import, which then schedules re-export, dirtying the working directory.\n\n**Root cause:**\n1. bd sync exports JSONL with NEW content (hash H1)\n2. bd sync updates jsonl_content_hash = H1 in DB\n3. bd sync restores JSONL from HEAD (OLD content, hash H0)\n4. Now: file hash = H0, DB hash = H1 (MISMATCH)\n5. Daemon or next CLI command sees mismatch, imports from OLD JSONL\n6. Import triggers re-export → file is dirty\n\n**Fix:**\nAfter restoreBeadsDirFromBranch(), update jsonl_content_hash to match the restored file's hash. This ensures daemon and CLI see file hash = DB hash → no spurious import/export cycle.\n\nRelated: bd-c83r (multiple daemon prevention)","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-13T06:42:17.130839-08:00","updated_at":"2025-12-13T06:43:33.329042-08:00","closed_at":"2025-12-13T06:43:33.329042-08:00"}
{"id":"bd-dvw8","title":"GH#523: Fix closed issues missing closed_at timestamp during db upgrade","description":"Old beads databases may have closed issues without closed_at timestamps, causing 'closed issues must have closed_at timestamp' validation errors on upgrade to 0.29.0. Need defensive handling during import. See: https://github.com/steveyegge/beads/issues/523","status":"in_progress","priority":1,"issue_type":"bug","created_at":"2025-12-14T16:31:30.421555-08:00","updated_at":"2025-12-14T16:52:49.796924-08:00"}
{"id":"bd-aydr.2","title":"Implement backup functionality for reset","description":"Add backup capability that can be used by reset command.\n\n## Functionality\n- Copy .beads/ to .beads-backup-{timestamp}/\n- Timestamp format: YYYYMMDD-HHMMSS\n- Preserve file permissions\n- Return backup path for user feedback\n\n## Location\n`internal/reset/backup.go` - keep with reset package for now (YAGNI)\n\n## Interface\n```go\nfunc CreateBackup(beadsDir string) (backupPath string, err error)\n```\n\n## Notes\n- Simple recursive file copy, no compression needed\n- Error if backup dir already exists (unlikely with timestamp)\n- Backup directories SHOULD be gitignored\n- Add `.beads-backup-*/` pattern to .beads/.gitignore template in doctor package\n- Consider: ListBackups() for future `bd backup list` command (not for this PR)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-13T08:44:51.306103+11:00","updated_at":"2025-12-13T10:13:32.610819+11:00","closed_at":"2025-12-13T09:20:20.590488+11:00","dependencies":[{"issue_id":"bd-aydr.2","depends_on_id":"bd-aydr","type":"parent-child","created_at":"2025-12-13T08:44:51.306474+11:00","created_by":"daemon"}]}
{"id":"bd-bxha","title":"Default to YES for git hooks and merge driver installation","description":"Currently bd init prompts user to install git hooks and merge driver, but setup is incomplete if user declines. Change to install by default unless --skip-hooks or --skip-merge-driver flags are passed. Better safe defaults. If installation fails, warn user and suggest bd doctor --fix.","status":"open","priority":1,"issue_type":"feature","created_at":"2025-11-21T23:16:10.172238-08:00","updated_at":"2025-11-21T23:16:28.369137-08:00","dependencies":[{"issue_id":"bd-bxha","depends_on_id":"bd-tbz3","type":"parent-child","created_at":"2025-11-21T23:16:10.173034-08:00","created_by":"daemon"}]}
{"id":"bd-bob","title":"Missing test: base is tombstone, both left and right are live","description":"The tombstone merge tests do not cover the case where the base version is a tombstone but both left and right have resurrected/live versions. This scenario could occur if: 1) Clone A deletes an issue, 2) Clone B and Clone C both sync from A (getting tombstone), 3) Both B and C independently recreate an issue with same ID. The current code would likely fall through to standard mergeIssue() which may not be correct. Need to add test and verify behavior. Files: internal/merge/merge_test.go, internal/merge/merge.go:347-387","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-05T16:36:34.895944-08:00","updated_at":"2025-12-13T09:42:56.871071+11:00","closed_at":"2025-12-07T02:27:40.788701-08:00"}
{"id":"bd-c83r","title":"Prevent multiple daemons from running on the same repo","description":"Multiple bd daemons running on the same repo clone causes race conditions and data corruption risks.\n\n**Problem:**\n- Nothing prevents spawning multiple daemons for the same repository\n- Multiple daemons watching the same files can conflict during sync operations\n- Observed: 4 daemons running simultaneously caused sync race condition\n\n**Solution:**\nImplement daemon singleton enforcement per repo:\n1. Use a lock file (e.g., .beads/.daemon.lock) with PID\n2. On daemon start, check if lock exists and process is alive\n3. If stale lock (dead PID), clean up and acquire lock\n4. If active daemon exists, either:\n - Exit with message 'daemon already running (PID xxx)'\n - Or offer --replace flag to kill existing and take over\n5. Release lock on graceful shutdown\n\n**Edge cases to handle:**\n- Daemon crashes without releasing lock (stale PID detection)\n- Multiple repos in same directory tree (each repo gets own lock)\n- Race between two daemons starting simultaneously (atomic lock acquisition)","status":"open","priority":2,"issue_type":"bug","created_at":"2025-12-13T06:37:23.377131-08:00","updated_at":"2025-12-13T06:37:23.377131-08:00"}
{"id":"bd-aydr.5","title":"Enhance bd doctor to suggest reset for broken states","description":"Update bd doctor to detect severely broken states and suggest reset.\n\n## Detection Criteria\nSuggest reset when:\n- Multiple unfixable errors detected\n- Corrupted JSONL that can't be repaired\n- Schema version mismatch that can't be migrated\n- Daemon state inconsistent and unkillable\n\n## Implementation\nAdd to doctor's check/fix flow:\n```go\nif unfixableErrors \u003e threshold {\n suggest('State may be too broken to fix. Consider: bd reset')\n}\n```\n\n## Output Example\n```\n✗ Found 5 unfixable errors\n \n Your beads state may be too corrupted to repair.\n Consider running 'bd reset' to start fresh.\n (Use 'bd reset --backup' to save current state first)\n```\n\n## Notes\n- Don't auto-run reset, just suggest\n- This is lower priority, can be done in parallel with main work","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-13T08:44:55.591986+11:00","updated_at":"2025-12-13T06:24:29.561624-08:00","closed_at":"2025-12-13T10:17:23.4522+11:00","dependencies":[{"issue_id":"bd-aydr.5","depends_on_id":"bd-aydr","type":"parent-child","created_at":"2025-12-13T08:44:55.59239+11:00","created_by":"daemon"}]}
{"id":"bd-k92d","title":"Critical: Beads deletes issues during sync (GH#464)","description":"# Findings\n\n## Root Cause 1: git-history-backfill deletes issues during repo ID mismatch\n\n**Location:** internal/importer/importer.go, purgeDeletedIssues()\n\nThe git-history-backfill mechanism checks git history to find deleted issues. When there's a repo ID mismatch (e.g., database from a different clone or after remote URL change), this can incorrectly treat local issues as deleted because they don't exist in the remote's git history.\n\n**Fix Applied:** Added safety guard at lines 971-987 in importer.go that:\n- Checks issue status before deletion via git-history-backfill\n- Prevents deletion of open/in_progress issues\n- Provides clear warning with actionable steps\n- Suggests using --no-git-history flag or bd delete for explicit deletion\n\n## Root Cause 2: Daemon sync race condition overwrites local unpushed changes\n\n**Location:** cmd/bd/daemon_sync.go, performAutoImport()\n\nThe daemon sync's auto-import function pulls from remote without checking for uncommitted local changes. This can overwrite local work that hasn't been pushed yet.\n\n**Fix Applied:** Added warning at lines 565-575 in daemon_sync.go that:\n- Checks for uncommitted changes before pulling\n- Warns user about potential overwrite\n- Suggests running 'bd sync' to commit/push first\n- Continues with pull but user is informed\n\n## Additional Safety Improvements\n\n1. Enhanced repo ID mismatch error message (daemon_sync.go:362-371)\n - Added warning about deletion risk\n - Clarified that mismatch can cause incorrect deletions\n\n2. Safety guard in deletions manifest processing (importer.go:886-902)\n - Prevents deletion of open/in_progress issues in deletions.jsonl\n - Provides diagnostic information\n - Suggests recovery options\n\n3. Updated tests (purge_test.go)\n - Changed test to use closed issue (safe to delete)\n - Verifies safety guard works correctly\n\n## Testing\n\nAll tests pass:\n- go test ./internal/importer/... ✓\n- go build ./cmd/bd/ ✓\n\nThe safety guards now prevent both root causes from deleting active work.","status":"closed","issue_type":"bug","created_at":"2025-12-14T23:00:19.36203-08:00","updated_at":"2025-12-14T23:07:43.311616-08:00","closed_at":"2025-12-14T23:07:43.311616-08:00"}
{"id":"bd-4u8","title":"Config option sync.require_confirmation_on_mass_delete","description":"Add config option for paranoid users who want confirmation before pushing after mass deletion.\n\nOption: sync.require_confirmation_on_mass_delete\nDefault: false\n\nWhen enabled AND safety check triggers:\n- Prompt user for confirmation before pushing\n- Show them what would be pushed\n\nFor users who have been burned and want extra safety. Most users will not need this.\n\nLocation: internal/config/ and internal/syncbranch/worktree.go\nParent issue: bd-3s8","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-02T19:31:00.927907-08:00","updated_at":"2025-12-03T22:17:49.4224-08:00","closed_at":"2025-12-03T22:17:49.4224-08:00","dependencies":[{"issue_id":"bd-4u8","depends_on_id":"bd-7ch","type":"blocks","created_at":"2025-12-02T19:31:09.134795-08:00","created_by":"daemon"}]}
{"id":"bd-tvu3","title":"Improve test coverage for internal/beads (48.1% → 70%)","description":"The beads package is a core package with 48.1% coverage. As the primary package for issue management, it should have at least 70% coverage.\n\nCurrent coverage: 48.1%\nTarget coverage: 70%","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-13T20:42:59.739142-08:00","updated_at":"2025-12-13T21:01:14.874359-08:00"}
{"id":"bd-7bbc4e6a","title":"Add MCP server functions for repair commands","description":"Expose new repair commands via MCP server for agent access:\n\nFunctions to add:\n- beads_repair_deps()\n- beads_detect_pollution()\n- beads_validate()\n- beads_resolve_conflicts() (when implemented)\n\nUpdate integrations/beads-mcp/src/beads_mcp/server.py\n\nSee repair_commands.md lines 803-884 for design.","notes":"Implemented all three MCP server functions:\n\n1. **repair_deps(fix=False)** - Find/fix orphaned dependencies\n2. **detect_pollution(clean=False)** - Detect/clean test issues \n3. **validate(checks=None, fix_all=False)** - Run comprehensive health checks\n\nChanges:\n- Added abstract methods to BdClientBase\n- Implemented in BdCliClient (CLI execution)\n- Added NotImplementedError stubs in BdDaemonClient (falls back to CLI)\n- Created wrapper functions in tools.py\n- Registered @mcp.tool decorators in server.py\n\nAll commands tested and working with --no-daemon flag.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-28T19:37:55.72639-07:00","updated_at":"2025-12-13T17:58:17.914638-08:00","closed_at":"2025-11-07T19:38:12.152437-08:00"}
{"id":"bd-hlsw.2","title":"Improve sync error messages","description":"When bd sync fails, immediately surface the actual root cause (prefix mismatch, orphaned children, forced push detected, etc.) instead of requiring multiple retries to discover it. Make errors actionable with specific recovery steps.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-14T10:40:20.545731796-07:00","updated_at":"2025-12-14T10:40:20.545731796-07:00","dependencies":[{"issue_id":"bd-hlsw.2","depends_on_id":"bd-hlsw","type":"parent-child","created_at":"2025-12-14T10:40:20.546686125-07:00","created_by":"daemon"}]}
{"id":"bd-2e0","title":"Add TTL to deletions manifest entries","description":"Deletions manifest entries should have a TTL (time-to-live) to automatically expire after a certain period. Stale deletion entries can poison beads installations when an agent gets out of sync, causing issues to remain deleted even when they shouldn't be. Adding expiration would limit the blast radius of stale deletions.","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-12-03T17:40:59.994296-08:00","updated_at":"2025-12-03T22:16:32.419289-08:00","closed_at":"2025-12-03T22:16:32.419289-08:00"}
{"id":"bd-abjw","title":"Consider consolidating config.yaml parsing into shared utility","description":"Multiple places parse config.yaml with custom structs:\n\n1. **autoimport.go:148** - `localConfig{SyncBranch}`\n2. **main.go:310** - strings.Contains for no-db (fragile, see bd-r6k2)\n3. **doctor.go:863** - strings.Contains for no-db (fragile, see bd-r6k2)\n4. **internal/config/config.go** - Uses viper (but caches at startup, problematic for tests)\n\nConsider creating a shared utility in `internal/configfile/` or extending the viper config:\n\n```go\n// internal/configfile/yaml.go\ntype YAMLConfig struct {\n SyncBranch string `yaml:\"sync-branch\"`\n NoDb bool `yaml:\"no-db\"`\n IssuePrefix string `yaml:\"issue-prefix\"`\n Author string `yaml:\"author\"`\n}\n\nfunc LoadYAML(beadsDir string) (*YAMLConfig, error) {\n // Parse config.yaml with proper YAML library\n}\n```\n\nBenefits:\n- Single source of truth for config.yaml structure\n- Proper YAML parsing everywhere\n- Easier to add new config fields\n\nTrade-off: May add complexity for simple one-off reads.","status":"open","priority":4,"issue_type":"task","created_at":"2025-12-07T02:03:26.067311-08:00","updated_at":"2025-12-07T02:03:26.067311-08:00"}
{"id":"bd-s2t","title":"wish: a 'continue' or similar cmd/flag which means alter last issue","description":"so many time I create an issue and then have another thought: 'oh, before I did X and it crashed there was ZZZ happening' or 'actually that is P4 not P2'. It would be nice if when `bd {cmd}` is used without a {title} or {id} it just adds or updates the most recently touched issue.","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-08T06:46:37.529160416-07:00","updated_at":"2025-12-08T06:46:37.529160416-07:00"}
{"id":"bd-6fe4622f","title":"Remove unreachable utility functions","description":"Several small utility functions are unreachable:\n\nFiles to clean:\n1. `internal/storage/sqlite/hash.go` - `computeIssueContentHash` (line 17)\n - Check if entire file can be deleted if only contains this function\n\n2. `internal/config/config.go` - `FileUsed` (line 151)\n - Delete unused config helper\n\n3. `cmd/bd/git_sync_test.go` - `verifyIssueOpen` (line 300)\n - Delete dead test helper\n\n4. `internal/compact/haiku.go` - `HaikuClient.SummarizeTier2` (line 81)\n - Tier 2 summarization not implemented\n - Options: implement feature OR delete method\n\nImpact: Removes 50-100 LOC depending on decisions","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-28T16:20:02.434573-07:00","updated_at":"2025-10-30T17:12:58.224957-07:00"}
{"id":"bd-cb64c226.8","title":"Update Metrics and Health Endpoints","description":"Remove cache-related metrics from health/metrics endpoints","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T22:55:49.212047-07:00","updated_at":"2025-10-30T17:12:58.212888-07:00","closed_at":"2025-10-28T14:08:38.06569-07:00"}
{"id":"bd-56x","title":"Review PR #514: fix plugin install docs","description":"Review and merge PR #514 from aspiers. This PR fixes incorrect docs for installing Claude Code plugin from source in docs/PLUGIN.md. Clarifies shell vs Claude Code commands and fixes the . vs ./beads argument issue. URL: https://github.com/anthropics/beads/pull/514","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-13T08:15:16.865354+11:00","updated_at":"2025-12-13T07:07:19.729213-08:00","closed_at":"2025-12-13T07:07:19.729213-08:00"}
{"id":"bd-7e7ddffa.1","title":"bd resolve-conflicts - Git merge conflict resolver","description":"Automatically resolve JSONL merge conflicts.\n\nModes:\n- Mechanical: ID remapping (no AI)\n- AI-assisted: Smart merge/keep decisions\n- Interactive: Review each conflict\n\nHandles \u003c\u003c\u003c\u003c\u003c\u003c\u003c conflict markers in .beads/beads.jsonl\n\nFiles: cmd/bd/resolve_conflicts.go (new)","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-28T14:48:30.083642-07:00","updated_at":"2025-10-30T17:12:58.220145-07:00","dependencies":[{"issue_id":"bd-7e7ddffa.1","depends_on_id":"bd-7e7ddffa","type":"parent-child","created_at":"2025-10-29T19:58:28.847736-07:00","created_by":"stevey"}]}
{"id":"bd-aydr.9","title":"Add .beads-backup-* pattern to gitignore template","description":"Update the gitignore template in doctor package to include backup directories.\n\n## Change\nAdd `.beads-backup-*/` to the GitignoreTemplate in `cmd/bd/doctor/gitignore.go`\n\n## Why\nBackup directories created by `bd reset --backup` should not be committed to git.\nThey are local-only recovery tools.\n\n## File\n`cmd/bd/doctor/gitignore.go` - look for GitignoreTemplate constant","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-13T08:49:42.453483+11:00","updated_at":"2025-12-13T09:16:44.201889+11:00","closed_at":"2025-12-13T09:16:44.201889+11:00","dependencies":[{"issue_id":"bd-aydr.9","depends_on_id":"bd-aydr","type":"parent-child","created_at":"2025-12-13T08:49:42.453886+11:00","created_by":"daemon"}]}
{"id":"bd-8g8","title":"Fix G304 potential file inclusion in cmd/bd/tips.go:259","description":"Linting issue: G304: Potential file inclusion via variable (gosec) at cmd/bd/tips.go:259:18. Error: if data, err := os.ReadFile(settingsPath); err == nil {","status":"open","issue_type":"bug","created_at":"2025-12-07T15:34:57.189730843-07:00","updated_at":"2025-12-07T15:34:57.189730843-07:00"}
{"id":"bd-yuv","title":"Add tests for tombstone edge cases","description":"Missing test coverage for tombstone implementation:\n\n1. Test tombstone validation (deleted_at requirement)\n2. Test GetReadyWork excludes tombstones\n3. Test SearchIssues behavior with tombstones\n4. Integration test for creating/retrieving a tombstone via the delete command\n5. Test that status=tombstone update is rejected","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-05T15:35:39.101881-08:00","updated_at":"2025-12-05T15:35:39.101881-08:00","dependencies":[{"issue_id":"bd-yuv","depends_on_id":"bd-vw8","type":"parent-child","created_at":"2025-12-05T15:35:47.335167-08:00","created_by":"daemon"}]}
{"id":"bd-y6t6","title":"GH#524: Package for Windows (winget)","description":"Request to publish beads on winget for easy Windows installation. See: https://github.com/steveyegge/beads/issues/524","status":"in_progress","priority":3,"issue_type":"feature","created_at":"2025-12-14T16:31:28.596258-08:00","updated_at":"2025-12-14T16:52:49.798255-08:00"}
{"id":"bd-c6w","title":"bd info whats-new missing releases","description":"Current release is v0.25.1 but `bd info --whats-new` stops at v0.23.0, indicating something is missing in the create new release workflow.","notes":"github issue #386","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-26T05:50:37.252394374-07:00","updated_at":"2025-11-26T06:28:21.974264087-07:00","closed_at":"2025-11-26T06:28:21.974264087-07:00"}
{"id":"bd-yck","title":"Fix checkExistingBeadsData to be worktree-aware","description":"The checkExistingBeadsData function in cmd/bd/init.go checks for .beads in the current working directory, but for worktrees it should check the main repository root instead. This prevents proper worktree compatibility.","status":"open","priority":2,"issue_type":"bug","created_at":"2025-12-07T16:48:32.082776345-07:00","updated_at":"2025-12-07T16:48:32.082776345-07:00"}
{"id":"bd-de6","title":"Fix FindBeadsDir to prioritize main repo .beads for worktrees","description":"The FindBeadsDir function should prioritize finding .beads in the main repository root when accessed from a worktree, rather than finding worktree-local .beads directories. This ensures proper sharing of the database across all worktrees.","status":"open","priority":2,"issue_type":"bug","created_at":"2025-12-07T16:48:36.883117467-07:00","updated_at":"2025-12-07T16:48:36.883117467-07:00"}
{"id":"bd-49kw","title":"Workaround for FastMCP outputSchema bug in Claude Code","description":"The beads MCP server (v0.23.1) successfully connects to Claude Code, but all tools fail to load with a schema validation error due to a bug in FastMCP 2.13.1.\n\nError: \"Invalid literal value, expected \\\"object\\\"\" in outputSchema.\n\nRoot Cause: FastMCP generates outputSchema with $ref at root level without \"type\": \"object\" for self-referential models (Issue).\n\nWorkaround: Use slash commands (/beads:ready) or wait for FastMCP fix.\n","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-20T18:55:39.041831-05:00","updated_at":"2025-11-20T18:55:39.041831-05:00"}
{"id":"bd-o4qy","title":"Improve CheckStaleness error handling","description":"## Problem\n\nCheckStaleness returns 'false' (not stale) for multiple error conditions instead of returning errors. This masks problems.\n\n**Location:** internal/autoimport/autoimport.go:253-285\n\n## Edge Cases That Return False\n\n1. **Invalid last_import_time format** (line 259-262)\n2. **No JSONL file found** (line 267-277) \n3. **JSONL stat fails** (line 279-282)\n\n## Fix\n\nReturn errors for abnormal conditions:\n\n```go\nlastImportTime, err := time.Parse(time.RFC3339, lastImportStr)\nif err != nil {\n return false, fmt.Errorf(\"corrupted last_import_time: %w\", err)\n}\n\nif jsonlPath == \"\" {\n return false, fmt.Errorf(\"no JSONL file found\")\n}\n\nstat, err := os.Stat(jsonlPath)\nif err != nil {\n return false, fmt.Errorf(\"cannot stat JSONL: %w\", err)\n}\n```\n\n## Impact\nMedium - edge cases are rare but should be handled\n\n## Effort \n30 minutes - requires updating callers in RPC server","status":"open","priority":2,"issue_type":"bug","created_at":"2025-11-20T20:17:27.606219-05:00","updated_at":"2025-11-20T20:17:27.606219-05:00","dependencies":[{"issue_id":"bd-o4qy","depends_on_id":"bd-2q6d","type":"blocks","created_at":"2025-11-20T20:18:26.81065-05:00","created_by":"stevey"}]}
{"id":"bd-llfl","title":"Improve test coverage for cmd/bd CLI (26.2% → 50%)","description":"The main CLI package (cmd/bd) has only 26.2% test coverage. CLI commands should have at least 50% coverage to ensure reliability.\n\nKey areas with low/no coverage:\n- daemon_autostart.go (multiple 0% functions)\n- compact.go (several 0% functions)\n- Various command handlers\n\nCurrent coverage: 26.2%\nTarget coverage: 50%","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-13T20:43:03.123341-08:00","updated_at":"2025-12-13T21:01:18.901944-08:00"}
{"id":"bd-hlsw.4","title":"Sync branch integrity guards","description":"Track sync branch parent commit. If sync branch was force-pushed, warn user and require confirmation before proceeding. Add option to reset to remote if user accepts rebase. Prevents silent corruption from forced pushes.","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-14T10:40:20.645402352-07:00","updated_at":"2025-12-14T10:40:20.645402352-07:00","dependencies":[{"issue_id":"bd-hlsw.4","depends_on_id":"bd-hlsw","type":"parent-child","created_at":"2025-12-14T10:40:20.646425761-07:00","created_by":"daemon"}]}
{"id":"bd-90v","title":"bd prime: AI context loading and Claude Code integration","description":"Implement `bd prime` command and Claude Code hooks for context recovery. Hooks work with BOTH MCP server and CLI approaches - they solve the context memory problem (keeping bd workflow fresh after compaction) not the tool access problem (MCP vs CLI).","status":"open","priority":2,"issue_type":"epic","created_at":"2025-11-11T23:31:12.119012-08:00","updated_at":"2025-11-12T00:11:07.743189-08:00"}
{"id":"bd-au0.6","title":"Add comprehensive filters to bd export","description":"Enhance bd export with filtering options for selective exports.\n\n**Currently only has:**\n- --status\n\n**Add filters:**\n- --label, --label-any\n- --assignee\n- --type\n- --priority, --priority-min, --priority-max\n- --created-after, --created-before\n- --updated-after, --updated-before\n\n**Use case:**\n- Export only open issues: bd export --status open\n- Export high-priority bugs: bd export --type bug --priority-max 1\n- Export recent issues: bd export --created-after 2025-01-01\n\n**Files to modify:**\n- cmd/bd/export.go\n- Reuse filter logic from list.go","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-21T21:07:19.431307-05:00","updated_at":"2025-11-21T21:07:19.431307-05:00","dependencies":[{"issue_id":"bd-au0.6","depends_on_id":"bd-au0","type":"parent-child","created_at":"2025-11-21T21:07:19.432983-05:00","created_by":"daemon"}]}
{"id":"bd-6ic","title":"Second worktree test","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-30T00:40:28.768125-08:00","updated_at":"2025-11-30T00:40:58.06615-08:00","closed_at":"2025-11-30T00:40:58.06615-08:00"}
{"id":"bd-fmc","title":"string(rune()) pattern in other test files still only works for single digits","description":"The bd-c5m fix only addressed worktree_divergence_test.go, but several other test files have the same issue:\n\n- cmd/bd/stale_test.go:218, 234\n- cmd/bd/export_integrity_integration_test.go:45-47, 279-280\n- internal/storage/sqlite/comments_test.go:146, 165\n- internal/storage/sqlite/blocked_cache_test.go:292\n- internal/storage/sqlite/compact_bench_test.go:117\n- internal/storage/sqlite/cycle_detection_test.go:418\n\nThese use string(rune('0'+i)) which produces wrong characters when i \u003e= 10.\nShould use strconv.Itoa(i) instead.","status":"closed","priority":4,"issue_type":"bug","created_at":"2025-12-02T22:29:12.355705-08:00","updated_at":"2025-12-02T22:39:51.844638-08:00","closed_at":"2025-12-02T22:39:51.844638-08:00"}
{"id":"bd-8q0","title":"Add Claude Code web installation docs to README","description":"GH #439 reported installation issues in Claude Code web environment. The go install fallback works, but users need guidance. Add a section to README documenting the workaround: go install + PATH export.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-01T21:02:24.511955-08:00","updated_at":"2025-12-01T21:10:10.587639-08:00","closed_at":"2025-12-01T21:10:10.587639-08:00"}
{"id":"bd-r9iq","title":"purgeDeletedIssues still writes to deletions.jsonl during git-history-backfill","description":"In purgeDeletedIssues (lines 929-939), when a deletion is recovered from git history, we:\n1. Append to deletions.jsonl (backfill)\n2. Create a tombstone in DB\n\nWith the tombstone approach, writing to deletions.jsonl is redundant since the tombstone will be exported to JSONL. Consider removing the deletions.jsonl backfill once we're confident in the tombstone approach.\n\nThis is related to the Phase 2 migration (bd-vw8) - we should stop writing to deletions.jsonl entirely.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-07T01:40:42.581876-08:00","updated_at":"2025-12-07T01:40:42.581876-08:00","dependencies":[{"issue_id":"bd-r9iq","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-07T01:41:28.285457-08:00","created_by":"daemon"}]}
{"id":"bd-ki14","title":"Implicit deletion cases do not check for tombstones in remaining side","description":"In merge3WayWithTTL(), the implicit deletion cases (lines 426-435) handle when an issue exists in base and one side but not the other. The current logic does not check if the remaining side is a tombstone:\n\nCase: inBase \u0026\u0026 inLeft \u0026\u0026 !inRight (deleted implicitly in right)\n- If leftIssue is a tombstone, we should keep it (tombstone propagation)\n- Currently: continue (drops the tombstone)\n\nCase: inBase \u0026\u0026 !inLeft \u0026\u0026 inRight (deleted implicitly in left)\n- If rightIssue is a tombstone, we should keep it\n- Currently: continue (drops the tombstone)\n\nThis could cause tombstones to be lost during merge if one side has a tombstone and the other side implicitly deleted. The tombstone should win since its an explicit deletion record.\n\nFiles: internal/merge/merge.go:426-435","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-05T16:37:22.584044-08:00","updated_at":"2025-12-05T17:15:57.61608-08:00","closed_at":"2025-12-05T17:15:57.61608-08:00"}
{"id":"bd-gmf","title":"Update flake.nix vendorHash after dependency bumps","description":"The Nix flake CI is failing due to stale vendorHash.\n\nError from CI:\n```\nerror: hash mismatch in fixed-output derivation beads-0.24.4-go-modules.drv\n```\n\nRoot cause: go.mod/go.sum was updated by dependabot (wazero, anthropic-sdk-go, etc.) but flake.nix vendorHash wasn't updated.\n\n## Immediate Fix\nRun `nix build` locally, get the correct hash from the error message, update flake.nix.\n\n## Long-term Fix\nAdd a GitHub Action that auto-updates vendorHash when go.mod/go.sum changes:\n1. Trigger on push to main when go.mod/go.sum changes\n2. Run `nix build` to get the new hash from the error\n3. Update flake.nix with the correct hash\n4. Commit and push","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-02T23:16:06.851696-08:00","updated_at":"2025-12-02T23:21:39.917239-08:00","closed_at":"2025-12-02T23:21:39.917239-08:00"}
{"id":"bd-dli","title":"Design migration path from deletions.jsonl to tombstones","description":"Plan the migration from current deletions manifest to inline tombstones. Steps: 1) Read existing deletions.jsonl and convert to tombstones during import, 2) Continue reading deletions.jsonl for backward compat, 3) Stop writing to deletions.jsonl, 4) Eventually remove deletions.jsonl support. Consider version flags and deprecation warnings.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T13:43:26.856406-08:00","updated_at":"2025-12-05T15:02:58.521601-08:00","closed_at":"2025-12-05T15:02:58.521601-08:00"}
{"id":"bd-7ch","title":"Auto-push after merge with safety check","description":"Make bd sync a true one-command solution by auto-pushing after successful content merge.\n\nBehavior:\n- After successful content merge, auto-push by default\n- Safety check: detect when \u003e50% issues vanished AND \u003e5 existed before\n- On safety check trigger: warn but still push (do not block happy path)\n\nVanished means issues removed from issues.jsonl entirely, NOT status=closed (closed is legitimate swarm completion).\n\nLocation: internal/syncbranch/worktree.go\nParent issue: bd-3s8","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-02T19:30:59.540636-08:00","updated_at":"2025-12-03T22:12:25.328091-08:00","closed_at":"2025-12-03T22:12:25.328091-08:00"}
{"id":"bd-hlsw","title":"Add sync resilience guardrails for forced pushes and prefix mismatches","description":"Beads can get into unrecoverable sync states when remote forces pushes occur (e.g., rebases) combined with prefix mismatches from multi-worker scenarios. Add detection, prevention, and auto-recovery features to handle this gracefully.","status":"open","priority":2,"issue_type":"epic","created_at":"2025-12-14T10:40:14.872875259-07:00","updated_at":"2025-12-14T10:40:14.872875259-07:00"}
{"id":"bd-zbyb","title":"GH#522: Add --type flag to bd update command","description":"Allow changing issue type (task/epic/bug/feature) via bd update --type. Storage layer already supports it. Needed for TUI tools like Abacus. See: https://github.com/steveyegge/beads/issues/522","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2025-12-14T16:31:31.71456-08:00","updated_at":"2025-12-14T16:52:49.797533-08:00"}
{"id":"bd-h5n1","title":"bd cleanup should also prune expired tombstones","description":"## Problem\n\n`bd cleanup` deletes closed issues (converting them to tombstones) but does NOT prune expired tombstones. Users expect 'cleanup' to do comprehensive cleanup.\n\n## Current Behavior\n\n1. `bd cleanup --force` → converts closed issues to tombstones\n2. Expired tombstones (\u003e30 days) remain in issues.jsonl\n3. User must separately run `bd compact` to prune tombstones\n4. `bd doctor` warns about expired tombstones: 'Run bd compact to prune'\n\n## Expected Behavior\n\n`bd cleanup` should also prune expired tombstones from issues.jsonl.\n\n## Impact\n\nWith v0.30.0 making tombstones the default migration path, this UX gap becomes more visible. Users cleaning up their database shouldn't need to know about a separate `bd compact` command.\n\n## Proposed Solution\n\nCall `pruneExpiredTombstones()` at the end of the cleanup command (same function used by compact). Report results:\n\n```\n✓ Deleted 15 closed issue(s)\n✓ Pruned 3 expired tombstone(s) (older than 30 days)\n```\n\n## Files to Modify\n\n- `cmd/bd/cleanup.go` - Add call to pruneExpiredTombstones after deleteBatch\n- May need to move pruneExpiredTombstones to shared location if not already accessible\n\n## Acceptance Criteria\n\n- [ ] `bd cleanup --force` prunes expired tombstones after deleting closed issues\n- [ ] `bd cleanup --dry-run` shows what tombstones would be pruned\n- [ ] JSON output includes tombstone prune results","status":"open","priority":1,"issue_type":"bug","created_at":"2025-12-13T23:49:35.963356-08:00","updated_at":"2025-12-14T00:26:19.763556-08:00"}
{"id":"bd-bw6","title":"Fix G104 errors unhandled in internal/storage/sqlite/queries.go:1181","description":"Linting issue: G104: Errors unhandled (gosec) at internal/storage/sqlite/queries.go:1181:4. Error: rows.Close()","status":"open","issue_type":"bug","created_at":"2025-12-07T15:35:09.008444133-07:00","updated_at":"2025-12-07T15:35:09.008444133-07:00"}
{"id":"bd-iq7n","title":"Audit and fix JSONL filename mismatches across all repo clones","description":"## Problem\n\nMultiple clones of repos are configured with different JSONL filenames (issues.jsonl vs beads.jsonl), causing:\n1. JSONL files to be resurrected after deletion (one clone pushes issues.jsonl, another pushes beads.jsonl)\n2. Agents unable to see issues filed by other agents after sync\n3. Merge conflicts and data inconsistencies\n\n## Root Cause\n\nWhen repos were \"bd doctored\" or initialized at different times, some got issues.jsonl (old default) and others got beads.jsonl (Beads repo specific). These clones push their respective files, creating duplicates.\n\n## Task\n\nScan all repo clones under ~/src/ (1-2 levels deep) and standardize their JSONL configuration.\n\n### Step 1: Find all beads-enabled repos\n\n```bash\n# Find all directories named 'beads' at levels 1-2 under ~/src/\nfind ~/src -maxdepth 2 -type d -name beads\n```\n\n### Step 2: For each repo found, check configuration\n\nFor each directory from Step 1, check:\n- Does `.beads/metadata.json` exist?\n- What is the `jsonl_export` value?\n- What JSONL files actually exist in `.beads/`?\n- Are there multiple JSONL files (problem!)?\n\n### Step 3: Create audit report\n\nGenerate a report showing:\n```\nRepo Path | Config | Actual Files | Status\n----------------------------------- | ------------- | ---------------------- | --------\n~/src/beads | beads.jsonl | beads.jsonl | OK\n~/src/dave/beads | issues.jsonl | issues.jsonl | MISMATCH\n~/src/emma/beads | issues.jsonl | issues.jsonl, beads.jsonl | DUPLICATE!\n```\n\n### Step 4: Determine canonical name for each repo\n\nFor repos that are the SAME git repository (check `git remote -v`):\n- Group them together\n- Determine which JSONL filename should be canonical (majority wins, or beads.jsonl for the beads repo itself)\n- List which clones need to be updated\n\n### Step 5: Generate fix script\n\nCreate a script that for each mismatched clone:\n1. Updates `.beads/metadata.json` to use the canonical name\n2. If JSONL file needs renaming: `git mv .beads/old.jsonl .beads/new.jsonl`\n3. Removes any duplicate JSONL files: `git rm .beads/duplicate.jsonl`\n4. Commits the change\n5. Syncs: `bd sync`\n\n### Expected Output\n\n1. Audit report showing all repos and their config status\n2. List of repos grouped by git remote (same repository)\n3. Fix script or manual instructions for standardizing each repo\n4. Verification that after fixes, all clones of the same repo use the same JSONL filename\n\n### Edge Cases\n\n- Handle repos without metadata.json (use default discovery)\n- Handle repos with no git remote (standalone/local)\n- Handle repos that are not git repositories\n- Don't modify repos with uncommitted changes (warn instead)\n\n### Success Criteria\n\n- All clones of the same git repository use the same JSONL filename\n- No duplicate JSONL files in any repo\n- All configurations documented in metadata.json\n- bd doctor passes on all repos","status":"open","issue_type":"task","created_at":"2025-11-21T23:58:35.044762-08:00","updated_at":"2025-11-21T23:58:35.044762-08:00"}
{"id":"bd-fl4","title":"Test sync branch setup","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-30T00:26:47.520507-08:00","updated_at":"2025-11-30T00:33:23.105998-08:00","closed_at":"2025-11-30T00:33:23.105998-08:00"}
{"id":"bd-y68","title":"Block direct status update to tombstone in UpdateIssue","description":"Per bd-2m7 design: 'Should we support tombstone as valid input to bd update --status? Recommendation: No, tombstones only created via bd delete'\n\nCurrently nothing prevents 'bd update \u003cid\u003e --status=tombstone', which would create an invalid tombstone (missing deleted_at, deleted_by, etc.).\n\nLocation: internal/storage/sqlite/queries.go:500-664 UpdateIssue\n\nAdd validation to reject status=tombstone in updates.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-05T15:35:31.5176-08:00","updated_at":"2025-12-05T15:41:14.813862-08:00","closed_at":"2025-12-05T15:41:14.813862-08:00","dependencies":[{"issue_id":"bd-y68","depends_on_id":"bd-vw8","type":"parent-child","created_at":"2025-12-05T15:35:47.181896-08:00","created_by":"daemon"}]}
{"id":"bd-35o","title":"Add --yes flag to bd doctor --fix","description":"bd doctor --fix prompts for confirmation, which blocks automation (CI/CD, scripts, hooks).\n\nRequirements:\n1. Add --yes or -y flag to bd doctor command\n2. When --yes is passed, skip confirmation prompts\n3. Still log what's being fixed (don't go completely silent)","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-30T21:14:08.696905-08:00","updated_at":"2025-11-30T21:14:49.867041-08:00","closed_at":"2025-11-30T21:14:49.867041-08:00"}
{"id":"bd-zsle","title":"GH#516: Automate 'landing the plane' setup in AGENTS.md","description":"bd init or /beads:init should auto-add landing-the-plane instructions to AGENTS.md (and @AGENTS.md for web Claude). Reduces manual setup. See: https://github.com/steveyegge/beads/issues/516","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2025-12-14T16:31:57.541154-08:00","updated_at":"2025-12-14T16:52:49.79956-08:00"}
{"id":"bd-ola6","title":"Implement transaction retry logic for SQLITE_BUSY","description":"BEGIN IMMEDIATE fails immediately on SQLITE_BUSY instead of retrying with exponential backoff.\n\nLocation: internal/storage/sqlite/sqlite.go:223-225\n\nProblem:\n- Under concurrent write load, BEGIN IMMEDIATE can fail with SQLITE_BUSY\n- Current implementation fails immediately instead of retrying\n- Results in spurious failures under normal concurrent usage\n\nSolution: Implement exponential backoff retry:\n- Retry up to N times (e.g., 5)\n- Backoff: 10ms, 20ms, 40ms, 80ms, 160ms\n- Check for context cancellation between retries\n- Only retry on SQLITE_BUSY/database locked errors\n\nImpact: Spurious failures under concurrent write load\n\nEffort: 3 hours","status":"open","priority":1,"issue_type":"feature","created_at":"2025-11-16T14:51:31.247147-08:00","updated_at":"2025-11-16T14:51:31.247147-08:00"}
{"id":"bd-4uoc","title":"Code Review Followup Summary: PR #481 + PR #551","description":"## Merged PRs Summary\n\n### PR #551: Persist close_reason to issues table\n- ✅ Merged successfully\n- ✅ Bug fix: close_reason now persisted in database column (not just events table)\n- ✅ Comprehensive test coverage added\n- ✅ Handles reopen case (clearing close_reason)\n\n**Followup Issues Filed:**\n- bd-lxzx: Document close_reason in JSONL export format\n- bd-077e: Update CLI documentation for close_reason field\n\n---\n\n### PR #481: Context Engineering Optimizations (80-90% context reduction)\n- ✅ Merged successfully \n- ✅ Lazy tool discovery: discover_tools() + get_tool_info()\n- ✅ Minimal issue models: IssueMinimal (~80% smaller than full Issue)\n- ✅ Result compaction: Auto-compacts results \u003e20 items\n- ✅ All 28 tests passing\n- ⚠️ Breaking change: ready() and list() return type changed\n\n**Followup Issues Filed:**\n- bd-b318: Add integration tests for CompactedResult\n- bd-4u2b: Make compaction settings configurable (THRESHOLD, PREVIEW_COUNT)\n- bd-2kf8: Document CompactedResult response format in CONTEXT_ENGINEERING.md\n- bd-pdr2: Document backwards compatibility considerations\n\n---\n\n## Overall Assessment\n\nBoth PRs are production-ready with solid implementations. All critical functionality works and tests pass. Followup issues focus on:\n1. Documentation improvements (5 issues)\n2. Integration test coverage (1 issue)\n3. Configuration flexibility (1 issue)\n4. Backwards compatibility guidance (1 issue)\n\nNo critical bugs or design issues found.\n\n## Review Completed By\nCode review process completed. Issues auto-created for tracking improvements.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-14T14:25:59.214886-08:00","updated_at":"2025-12-14T14:25:59.214886-08:00","dependencies":[{"issue_id":"bd-4uoc","depends_on_id":"bd-otf4","type":"discovered-from","created_at":"2025-12-14T14:25:59.216884-08:00","created_by":"stevey"},{"issue_id":"bd-4uoc","depends_on_id":"bd-z86n","type":"discovered-from","created_at":"2025-12-14T14:25:59.217296-08:00","created_by":"stevey"}]}
{"id":"bd-bwk2","title":"Centralize error handling patterns in storage layer","description":"80+ instances of inconsistent error handling across sqlite.go with mix of %w, %v, and no wrapping.\n\nLocation: internal/storage/sqlite/sqlite.go (throughout)\n\nProblem:\n- Some use fmt.Errorf(\"op failed: %w\", err) - correct wrapping\n- Some use fmt.Errorf(\"op failed: %v\", err) - loses error chain\n- Some return err directly - no context\n- Hard to debug production issues\n- Can't distinguish error types\n\nSolution: Create internal/storage/sqlite/errors.go:\n- Define sentinel errors (ErrNotFound, ErrInvalidID, etc.)\n- Create wrapDBError(op string, err error) helper\n- Convert sql.ErrNoRows to ErrNotFound\n- Always wrap with operation context\n\nImpact: Lost error context; inconsistent messages; hard to debug\n\nEffort: 5-7 hours","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-16T14:51:54.974909-08:00","updated_at":"2025-11-16T14:51:54.974909-08:00"}
{"id":"bd-tm2p","title":"Polecats get stuck on interactive shell prompts (cp/mv/rm -i)","description":"During swarm operations, polecats frequently get stuck waiting for interactive prompts from shell commands like:\n- cp prompting 'overwrite file? (y/n)'\n- mv prompting 'overwrite file? (y/n)' \n- rm prompting 'remove file?'\n\nThis happens because macOS aliases or shell configs may have -i flags set by default.\n\nRoot cause: Claude Code runs commands that trigger interactive confirmation prompts, but cannot respond to them, causing the agent to hang indefinitely.\n\nObserved in: Multiple polecats during GH issues swarm (Dec 2024)\n- Derrick, Roustabout, Prospector, Warboy all got stuck on y/n prompts\n\nSuggested fixes:\n1. AGENTS.md should instruct agents to always use -f flag with cp/mv/rm\n2. Polecat startup could set shell aliases to use non-interactive versions\n3. bd prime hook could include guidance about non-interactive commands\n4. Consider detecting stuck prompts and auto-recovering","status":"open","priority":1,"issue_type":"bug","created_at":"2025-12-14T16:51:24.572271-08:00","updated_at":"2025-12-14T16:51:24.572271-08:00"}
{"id":"bd-5we","title":"Use RAM disk for Windows CI tests","description":"Windows CI tests time out due to slow filesystem I/O. Even with splitting into parallel jobs, each package set takes \u003e30 minutes.\n\nImplement a RAM disk solution using ImDisk or similar on Windows GitHub Actions runners to speed up tests.\n\nReferences:\n- https://github.com/actions/runner-images/issues/intlharry has examples\n- ImDisk can create RAM disks on Windows\n- Alternative: use D: drive which may be faster on some runners","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-04T20:30:23.877831-08:00","updated_at":"2025-12-13T12:54:00.045208828-05:00","closed_at":"2025-12-13T07:28:44.636222-08:00"}
{"id":"bd-cb64c226.6","title":"Verify MCP Server Compatibility","description":"Ensure MCP server works with cache-free daemon","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T22:56:03.241615-07:00","updated_at":"2025-10-30T17:12:58.213372-07:00","closed_at":"2025-10-28T14:08:38.059615-07:00"}
{"id":"bd-6sm6","title":"Improve test coverage for internal/export (37.1% → 60%)","description":"The export package has only 37.1% test coverage. Export functionality needs good coverage to ensure data integrity.\n\nCurrent coverage: 37.1%\nTarget coverage: 60%","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-13T20:43:06.802277-08:00","updated_at":"2025-12-13T21:01:19.08088-08:00"}
{"id":"bd-2m7","title":"Design tombstone storage format","description":"Define the JSON schema for tombstone records. Options: minimal (id, deleted_at, deleted_by, expires_at) vs full preservation (keep all original fields). Trade-offs: storage size vs audit trail. Consider: should tombstones be distinguishable from regular issues by status field or separate record type?","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T13:43:20.384642-08:00","updated_at":"2025-12-05T15:00:18.61323-08:00","closed_at":"2025-12-05T15:00:18.61323-08:00"}
{"id":"bd-cbed9619.3","title":"Implement global N-way collision resolution algorithm","description":"## Overview\nPhase 3: Replace pairwise collision resolution with global N-way resolution that produces deterministic results regardless of sync order.\n\n## Current Problem\nScoreCollisions (collision.go:228) compares issues pairwise:\n```go\ncollision.RemapIncoming = existingHash \u003c incomingHash\n```\n\nThis works for 2-way but fails for 3+ way because:\n- Each clone makes local decisions without global context\n- No guarantee intermediate states are consistent\n- Remapping decisions depend on sync order\n- Can't detect transitive remap chains (test-1 → test-2 → test-3)\n\n## Solution\nImplement global resolution that:\n1. Collects ALL versions of same logical issue\n2. Sorts by content hash (deterministic)\n3. Assigns sequential IDs based on sorted order\n4. All clones converge to same assignments\n\n## Implementation Tasks\n\n### 1. Create ResolveNWayCollisions function\nFile: internal/storage/sqlite/collision.go\n\nReplace ScoreCollisions with:\n```go\n// ResolveNWayCollisions handles N-way collisions deterministically.\n// Groups all versions with same base ID, sorts by content hash,\n// assigns sequential IDs. Returns mapping of old ID → new ID.\nfunc ResolveNWayCollisions(ctx context.Context, s *SQLiteStorage,\n collisions []*CollisionDetail, incoming []*types.Issue) (map[string]string, error) {\n \n if len(collisions) == 0 {\n return make(map[string]string), nil\n }\n \n // Group by base ID pattern (e.g., test-1, test-2 → base \"test-1\")\n groups := groupCollisionsByBaseID(collisions)\n \n idMapping := make(map[string]string)\n \n for baseID, versions := range groups {\n // 1. Collect all unique versions by content hash\n uniqueVersions := deduplicateVersionsByContentHash(versions)\n \n // 2. Sort by content hash (deterministic!)\n sort.Slice(uniqueVersions, func(i, j int) bool {\n return uniqueVersions[i].ContentHash \u003c uniqueVersions[j].ContentHash\n })\n \n // 3. Assign sequential IDs based on sorted order\n prefix := extractPrefix(baseID)\n baseNum := extractNumber(baseID)\n \n for i, version := range uniqueVersions {\n targetID := fmt.Sprintf(\"%s-%d\", prefix, baseNum+i)\n \n // Map this version to its deterministic ID\n if version.ID != targetID {\n idMapping[version.ID] = targetID\n }\n }\n }\n \n return idMapping, nil\n}\n```\n\n### 2. Implement helper functions\n\n```go\n// groupCollisionsByBaseID groups collisions by their logical base ID\nfunc groupCollisionsByBaseID(collisions []*CollisionDetail) map[string][]*types.Issue {\n groups := make(map[string][]*types.Issue)\n for _, c := range collisions {\n baseID := c.ID // All share same ID (that's why they collide)\n groups[baseID] = append(groups[baseID], c.ExistingIssue, c.IncomingIssue)\n }\n return groups\n}\n\n// deduplicateVersionsByContentHash keeps one issue per unique content hash\nfunc deduplicateVersionsByContentHash(issues []*types.Issue) []*types.Issue {\n seen := make(map[string]*types.Issue)\n for _, issue := range issues {\n if _, found := seen[issue.ContentHash]; !found {\n seen[issue.ContentHash] = issue\n }\n }\n result := make([]*types.Issue, 0, len(seen))\n for _, issue := range seen {\n result = append(result, issue)\n }\n return result\n}\n```\n\n### 3. Update handleCollisions in importer\nFile: internal/importer/importer.go\n\nReplace ScoreCollisions call with:\n```go\n// OLD:\nif err := sqlite.ScoreCollisions(ctx, sqliteStore, collisionResult.Collisions, allExistingIssues); err != nil {\n return nil, fmt.Errorf(\"failed to score collisions: %w\", err)\n}\n\n// NEW:\nidMapping, err := sqlite.ResolveNWayCollisions(ctx, sqliteStore, \n collisionResult.Collisions, issues)\nif err != nil {\n return nil, fmt.Errorf(\"failed to resolve collisions: %w\", err)\n}\n```\n\n### 4. Update RemapCollisions\nRemapCollisions currently uses collision.RemapIncoming field. Update to use idMapping directly:\n- Remove RemapIncoming logic\n- Use idMapping to determine what to remap\n- Simplify to just apply the computed mapping\n\n### 5. Add comprehensive tests\n\nTest cases:\n1. 3-way collision with different content → 3 sequential IDs\n2. 3-way collision with 2 identical content → 2 IDs (dedupe works)\n3. Sync order independence (A→B→C vs C→A→B produce same result)\n4. Content hash ordering is respected\n5. Works with 5+ clones\n\n## Acceptance Criteria\n- ResolveNWayCollisions implemented and replaces ScoreCollisions\n- Groups all versions of same ID together\n- Deduplicates by content hash\n- Sorts by content hash deterministically\n- Assigns sequential IDs starting from base ID\n- Returns complete mapping (old ID → new ID)\n- All clones converge to same ID assignments\n- Works for arbitrary N-way collisions\n- TestThreeCloneCollision passes (or gets much closer)\n\n## Files to Modify\n- internal/storage/sqlite/collision.go (new function, helpers)\n- internal/importer/importer.go (call new function)\n- internal/storage/sqlite/collision_test.go (comprehensive tests)\n\n## Testing Strategy\n\n### Unit Tests\n- groupCollisionsByBaseID correctly groups\n- deduplicateVersionsByContentHash removes duplicates\n- Sorting by hash is stable and deterministic\n- Sequential ID assignment is correct\n\n### Integration Tests\n- 3-way collision resolves to 3 issues\n- Sync order doesn't affect final IDs\n- Content hash ordering determines winner\n\n### Property Tests\n- For any N clones with same content, all converge to same IDs\n- Idempotent: running resolution twice produces same result\n\n## Dependencies\n- Requires bd-cbed9619.5 (ContentHash field) to be completed first\n- Requires bd-cbed9619.4 (read-only detection) for clean integration\n\n## Notes\nThis is the core algorithm that enables convergence. The key insight:\n**Sort by content hash globally, not pairwise comparison.**","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T18:37:42.85616-07:00","updated_at":"2025-10-30T17:12:58.228707-07:00","closed_at":"2025-10-28T20:03:26.675257-07:00","dependencies":[{"issue_id":"bd-cbed9619.3","depends_on_id":"bd-325da116","type":"parent-child","created_at":"2025-10-28T18:39:20.593102-07:00","created_by":"daemon"},{"issue_id":"bd-cbed9619.3","depends_on_id":"bd-cbed9619.5","type":"blocks","created_at":"2025-10-28T18:39:28.30886-07:00","created_by":"daemon"},{"issue_id":"bd-cbed9619.3","depends_on_id":"bd-cbed9619.4","type":"blocks","created_at":"2025-10-28T18:39:28.336312-07:00","created_by":"daemon"}]}
{"id":"bd-fx7v","title":"Improve test coverage for cmd/bd/doctor/fix (23.9% → 50%)","description":"The doctor/fix package has only 23.9% test coverage. The doctor fix functionality is important for troubleshooting.\n\nCurrent coverage: 23.9%\nTarget coverage: 50%","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-13T20:43:05.67127-08:00","updated_at":"2025-12-13T21:01:20.839298-08:00"}
{"id":"bd-83xx","title":"bd cleanup fails with CHECK constraint on status/closed_at mismatch","description":"## Problem\n\nRunning `bd cleanup --force` fails with:\n\n```\nError: failed to create tombstone for bd-okh: sqlite3: constraint failed: CHECK constraint failed: (status = 'closed') = (closed_at IS NOT NULL)\n```\n\n## Root Cause\n\nThe database has a CHECK constraint ensuring closed issues have `closed_at` set and non-closed issues don't. When `bd cleanup` tries to convert a closed issue to a tombstone, this constraint fails if:\n1. The issue has status='closed' but closed_at is NULL, OR\n2. The issue is being converted but the tombstone creation doesn't properly handle the closed_at field\n\n## Impact\n\n- `bd cleanup --force` cannot complete\n- 722 closed issues cannot be cleaned up\n- Blocks routine maintenance\n\n## Investigation Needed\n\n1. Check the bd-okh record in the database:\n ```sql\n SELECT id, status, closed_at, deleted_at FROM issues WHERE id = 'bd-okh';\n ```\n2. Determine if this is data corruption or a bug in tombstone creation\n\n## Proposed Solutions\n\n1. **If data corruption**: Add a `bd doctor --fix` check that repairs status/closed_at mismatches\n2. **If code bug**: Fix the tombstone creation to properly handle the constraint\n\n## Files to Investigate\n\n- `internal/storage/sqlite/sqlite.go` - DeleteIssue / tombstone creation\n- Schema CHECK constraint definition\n\n## Acceptance Criteria\n\n- [ ] Identify root cause (data vs code bug)\n- [ ] `bd cleanup --force` completes successfully\n- [ ] `bd doctor` detects status/closed_at mismatches","status":"open","priority":1,"issue_type":"bug","created_at":"2025-12-13T23:49:54.012806-08:00","updated_at":"2025-12-14T00:26:19.76258-08:00"}
{"id":"bd-vw8","title":"Switch from deletions manifest to inline tombstones","description":"Replace the current deletions.jsonl manifest with inline tombstone records in issues.jsonl.\n\n## Problem Statement\n\nThe current deletions manifest approach has several issues:\n\n1. **Wild poisoning** - A stale clone's deletions manifest can poison fresh databases when synced\n2. **Two-level merge inconsistency** - Git content merge and beads snapshot merge use different bases\n3. **SyncJSONLToWorktree overwrites** - Blindly copies local JSONL to worktree, losing remote issues\n4. **3-day TTL too aggressive** - Deletions expire before dormant branches get merged\n\n## Proposed Solution: Inline Tombstones\n\nInstead of a separate deletions.jsonl file, embed deletion records directly in issues.jsonl:\n\n```json\n{\"id\":\"beads-abc\",\"status\":\"tombstone\",\"title\":\"Original title\",\"deleted_at\":\"2025-12-01T...\",\"deleted_by\":\"user\",\"expires_at\":\"2025-12-31T...\"}\n```\n\n### Benefits\n\n1. **Single source of truth** - No separate manifest to sync/merge\n2. **Participates in normal 3-way merge** - Deletion conflicts resolved same as other fields\n3. **Atomic with issue data** - Can't have orphaned deletions or missing tombstones\n4. **Preserves metadata** - Can optionally keep title/type for audit trail\n\n### Design Decisions Needed\n\n1. **TTL duration** - 30 days default? Configurable via config.yaml?\n2. **Tombstone content** - Minimal (just ID + timestamps) vs. full issue preservation?\n3. **Migration path** - How to handle existing deletions.jsonl files?\n4. **Status value** - Use \"tombstone\" or \"deleted\"? (tombstone clearer, deleted more intuitive)\n5. **Merge semantics** - Does tombstone always win, or use updated_at like other fields?\n\n### Migration Strategy\n\n1. On import, convert deletions.jsonl entries to tombstones in JSONL\n2. Deprecate but still read deletions.jsonl for backward compatibility\n3. Stop writing to deletions.jsonl after N versions\n\n## Related Issues\n\n- GitHub #464: Beads deletes issues (fresh clone sync problem)\n- bd-2e0: Add TTL to deletions manifest entries (current 3-day TTL)\n- bd-53c: bd sync corrupts issues.jsonl in multi-clone environments","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-12-05T13:42:24.384792-08:00","updated_at":"2025-12-13T13:26:00.767546-08:00","closed_at":"2025-12-13T07:25:56.968329-08:00","dependencies":[{"issue_id":"bd-vw8","depends_on_id":"bd-1r5","type":"blocks","created_at":"2025-12-05T14:57:31.111259-08:00","created_by":"daemon"},{"issue_id":"bd-vw8","depends_on_id":"bd-2m7","type":"blocks","created_at":"2025-12-05T14:57:33.57722-08:00","created_by":"daemon"},{"issue_id":"bd-vw8","depends_on_id":"bd-dli","type":"blocks","created_at":"2025-12-05T14:57:34.902784-08:00","created_by":"daemon"},{"issue_id":"bd-vw8","depends_on_id":"bd-zvg","type":"blocks","created_at":"2025-12-05T14:57:36.665817-08:00","created_by":"daemon"},{"issue_id":"bd-vw8","depends_on_id":"bd-fbj","type":"blocks","created_at":"2025-12-05T15:14:59.081452-08:00","created_by":"daemon"},{"issue_id":"bd-vw8","depends_on_id":"bd-olt","type":"blocks","created_at":"2025-12-05T15:14:59.118268-08:00","created_by":"daemon"},{"issue_id":"bd-vw8","depends_on_id":"bd-0ih","type":"blocks","created_at":"2025-12-05T15:14:59.155689-08:00","created_by":"daemon"},{"issue_id":"bd-vw8","depends_on_id":"bd-3b4","type":"blocks","created_at":"2025-12-05T15:14:59.192575-08:00","created_by":"daemon"},{"issue_id":"bd-vw8","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-05T15:14:59.227233-08:00","created_by":"daemon"},{"issue_id":"bd-vw8","depends_on_id":"bd-8f9","type":"blocks","created_at":"2025-12-05T15:14:59.262816-08:00","created_by":"daemon"},{"issue_id":"bd-vw8","depends_on_id":"bd-s3v","type":"blocks","created_at":"2025-12-05T15:14:59.299481-08:00","created_by":"daemon"},{"issue_id":"bd-vw8","depends_on_id":"bd-okh","type":"blocks","created_at":"2025-12-05T15:14:59.337656-08:00","created_by":"daemon"}]}
{"id":"bd-1kf","title":"mergePriority: negative priorities not handled consistently","status":"closed","priority":4,"issue_type":"bug","created_at":"2025-12-02T21:56:17.99534-08:00","updated_at":"2025-12-02T22:12:28.396719-08:00","closed_at":"2025-12-02T22:12:28.396719-08:00"}
{"id":"bd-93d","title":"Jira export script (jsonl2jira.py)","description":"Create a Python script to push beads issues to Jira.\n\n**Requires**: Jira import script to be complete first (need external_ref matching logic working)\n\n**Features needed**:\n- Create new Jira issues from beads issues without external_ref\n- Update existing Jira issues matched by external_ref\n- Map beads fields back to Jira fields\n- Handle Jira workflow transitions (status changes may need transitions)\n- Support custom field mapping for design/acceptance_criteria/notes\n\n**Challenges**:\n- Jira status changes often require workflow transitions, not direct updates\n- Need to discover valid transitions via API\n- Custom fields vary by Jira instance\n\n**Usage**:\n```bash\nbd export | python jsonl2jira.py --create-only # Only create, don't update\nbd export | python jsonl2jira.py # Create and update\n```\n\n**After creation**: Sets external_ref on beads issue to link back","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-30T12:56:14.266357-08:00","updated_at":"2025-11-30T15:19:40.264737-08:00","closed_at":"2025-11-30T15:19:40.264737-08:00","dependencies":[{"issue_id":"bd-93d","depends_on_id":"bd-qvj","type":"parent-child","created_at":"2025-11-30T12:56:44.652391-08:00","created_by":"stevey"},{"issue_id":"bd-93d","depends_on_id":"bd-tjn","type":"blocks","created_at":"2025-11-30T12:56:54.941116-08:00","created_by":"stevey"}]}
{"id":"bd-cb64c226.12","title":"Remove Storage Cache from Server Struct","description":"Eliminate cache fields and use s.storage directly","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T22:55:25.474412-07:00","updated_at":"2025-10-30T17:12:58.211812-07:00","closed_at":"2025-10-28T14:08:38.061444-07:00"}
{"id":"bd-hp0m","title":"Add test for legacy deletions.jsonl to tombstone conversion","description":"The importer now converts legacy deletions.jsonl entries to tombstones (bd-dve), but there's no dedicated test that:\n1. Creates a deletions.jsonl with entries\n2. Imports issues (some in deletions, some not)\n3. Verifies the converted tombstones have correct fields from the deletion record\n\nThe existing TestImportIssues_TombstoneNotFilteredByDeletionsManifest tests that tombstones bypass the filter, but doesn't verify the conversion of legacy deletions to tombstones.\n\nAdd a test: TestImportIssues_LegacyDeletionsConvertedToTombstones","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T01:41:12.976726-08:00","updated_at":"2025-12-07T02:16:16.882286-08:00","closed_at":"2025-12-07T02:16:16.882286-08:00","dependencies":[{"issue_id":"bd-hp0m","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-07T01:41:28.391366-08:00","created_by":"daemon"}]}
{"id":"bd-y2v","title":"Refactor duplicate JSONL-from-git parsing code","description":"Both readFirstIssueFromGit() in init.go and importFromGit() in autoimport.go have similar code patterns for:\n1. Running git show \u003cref\u003e:\u003cpath\u003e\n2. Scanning the output with bufio.Scanner\n3. Parsing JSON lines\n\nCould be refactored to share a helper like:\n- readJSONLFromGit(gitRef, path string) ([]byte, error)\n- Or a streaming version: streamJSONLFromGit(gitRef, path string) (io.Reader, error)\n\nFiles:\n- cmd/bd/autoimport.go:225-256 (importFromGit)\n- cmd/bd/init.go:1212-1243 (readFirstIssueFromGit)\n\nPriority is low since code duplication is minimal and both functions work correctly.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-05T14:51:18.41124-08:00","updated_at":"2025-12-05T14:51:18.41124-08:00"}
{"id":"bd-1a6j","title":"Test issue 2","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-07T19:07:12.24632-08:00","updated_at":"2025-12-13T23:29:56.877225-08:00","closed_at":"2025-12-13T23:29:56.877225-08:00"}
{"id":"bd-0yt","title":"Plugin should provide hooks instead of requiring global install","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-12-04T22:38:58.173423-08:00","updated_at":"2025-12-04T22:44:13.35077-08:00","closed_at":"2025-12-04T22:44:13.35077-08:00"}
{"id":"bd-bscs","title":"GH#518: Document bd setup command","description":"bd setup (e.g. bd setup cursor) is undocumented. Users only find it by grepping source. Need proper docs. See: https://github.com/steveyegge/beads/issues/518","status":"in_progress","priority":2,"issue_type":"task","created_at":"2025-12-14T16:31:35.881408-08:00","updated_at":"2025-12-14T16:52:49.796464-08:00"}
{"id":"bd-r46","title":"Support --reason flag in daemon mode for reopen command","description":"The reopen.go command has a TODO at line 61 to add reason as a comment once RPC supports AddComment. Currently --reason flag is ignored in daemon mode with a warning.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-21T18:55:10.773626-05:00","updated_at":"2025-11-21T18:55:10.773626-05:00"}
{"id":"bd-co0","title":"Imperator does not know its own mail identity","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-30T22:53:49.963803-08:00","updated_at":"2025-12-02T23:28:48.752455-08:00","closed_at":"2025-12-01T22:01:26.953199-08:00"}
{"id":"bd-xoyh","title":"GH#519: bd sync fails when sync.branch equals current branch","description":"bd sync tries to create worktree when sync.branch matches current checkout, fails with 'already used by worktree'. Should detect and commit directly. See: https://github.com/steveyegge/beads/issues/519","status":"in_progress","priority":2,"issue_type":"bug","created_at":"2025-12-14T16:31:34.574414-08:00","updated_at":"2025-12-14T16:52:49.800357-08:00"}
{"id":"bd-xxal","title":"bd ready includes blocked issues (GH#544)","description":"Issues with 'blocks' dependencies still appear in bd ready. The ready query should exclude issues that have unresolved blockers.\n\nFix in: cmd/bd/ready.go or internal query logic.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-14T23:00:26.048532-08:00","updated_at":"2025-12-14T23:07:43.312979-08:00","closed_at":"2025-12-14T23:07:43.312979-08:00"}
{"id":"bd-thgk","title":"Improve test coverage for internal/compact (18.2% → 70%)","description":"The compact package has only 18.2% test coverage. This is a core package handling issue compaction and should have at least 70% coverage.\n\nKey functions needing tests:\n- runCompactSingle (0%)\n- runCompactAll (0%)\n- runCompactRPC (0%)\n- runCompactStatsRPC (0%)\n- runCompactAnalyze (0%)\n- runCompactApply (0%)\n- pruneDeletionsManifest (0%)\n\nCurrent coverage: 18.2%\nTarget coverage: 70%","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-13T20:42:58.455767-08:00","updated_at":"2025-12-13T21:01:15.070551-08:00"}
{"id":"bd-5qim","title":"Optimize GetReadyWork performance - 752ms on 10K database (target: \u003c50ms)","notes":"# Performance Analysis (10K Issue Database)\n\nAnalyzed using CPU profiles from benchmark suite on Apple M2 Pro.\n\n## Operation Performance\n\n| Operation | Time | Allocations | Memory |\n|----------------------------------|---------|-------------|--------|\n| bd ready (GetReadyWork) | ~752ms | 167,466 | 16MB |\n| bd list (SearchIssues no filter) | ~11.6ms | 89,214 | 5.8MB |\n| bd list (SearchIssues filtered) | ~9.2ms | 62,365 | 3.5MB |\n| bd create (CreateIssue) | ~2.6ms | 146 | 8.6KB |\n| bd update (UpdateIssue) | ~0.32ms | 364 | 15KB |\n| bd close (UpdateIssue) | ~0.32ms | 364 | 15KB |\n\n**Target: \u003c50ms for all operations on 10K database**\n\n**Current issue: GetReadyWork is 15x over target (752ms vs 50ms)**\n\n## Root Cause\n\nGetReadyWork (internal/storage/sqlite/ready.go:90-128) uses recursive CTE to propagate blocking:\n- 65x slower than SearchIssues\n- Recalculates entire blocked issue tree on every call\n- Algorithm:\n 1. Find directly blocked issues via 'blocks' dependencies\n 2. Recursively propagate blockage to descendants (max depth: 50)\n 3. Exclude all blocked issues from results\n\n## CPU Profile Analysis\n\n- Database syscalls (pthread_cond_signal, syscall6): ~75%\n- SQLite engine overhead: inherent to recursive CTE\n- Application code (query construction): \u003c1%\n\n**Bottleneck is the recursive CTE query execution, not application code.**\n\n## Optimization Recommendations\n\n### High Impact (Likely to achieve \u003c50ms target)\n\n1. **Cache blocked issue calculation**\n - Add `blocked_issues` table updated on dependency changes\n - Trade write complexity for read speed (ready called \u003e\u003e dependency changes)\n - Eliminates recursive CTE on every read\n\n2. **Add/verify database indexes**\n ```sql\n CREATE INDEX IF NOT EXISTS idx_dependencies_blocked \n ON dependencies(issue_id, type, depends_on_id);\n CREATE INDEX IF NOT EXISTS idx_issues_status \n ON issues(status);\n ```\n\n### Medium Impact\n\n3. **Reduce allocations** (167K allocations for GetReadyWork)\n - Profile `scanIssues()` for object pooling opportunities\n - Reuse slice capacity for repeated calls\n\n### Low Impact (Not recommended)\n- Query optimization for CRUD operations (already \u003c3ms)\n- Connection pooling tuning (not showing in profiles)\n\n## Verification\n\nRun benchmarks to validate optimization:\n```bash\nmake bench-quick\ngo tool pprof -http=:8080 internal/storage/sqlite/bench-cpu-*.prof\n```\n\nProfile files automatically generated in `internal/storage/sqlite/`.","status":"open","issue_type":"bug","created_at":"2025-11-14T09:02:46.507526-08:00","updated_at":"2025-11-14T09:03:44.073236-08:00"}
{"id":"bd-hm8","title":"Add uninstall documentation (GH #445)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-01T21:04:30.313637-08:00","updated_at":"2025-12-01T21:04:57.943192-08:00","closed_at":"2025-12-01T21:04:57.943192-08:00"}
{"id":"bd-aydr.6","title":"Add unit tests for reset package","description":"Comprehensive unit tests for internal/reset package.\n\n## Test Cases\n\n### ValidateState tests\n- .beads/ exists → success\n- .beads/ missing → appropriate error\n- git dirty state detection\n\n### CountImpact tests \n- Empty .beads/ → zero counts\n- With issues → correct count (open vs closed)\n- With tombstones → correct count\n- Returns HasUncommitted correctly\n\n### Backup tests\n- Creates backup with correct timestamp format\n- Preserves all files and permissions\n- Returns correct path\n- Handles missing .beads/ gracefully\n- Errors on pre-existing backup dir\n\n### Git operation tests\n- CheckGitState detects dirty, detached, not-a-repo\n- GitRemoveBeads removes correct files\n- GitCommitReset creates commit with message\n- Operations skip gracefully when not in git repo\n\n### Reset tests (with mocks/temp dirs)\n- Soft reset removes files, calls init\n- Hard reset includes git operations\n- Dry run doesn't modify anything\n- SkipInit flag prevents re-initialization\n- Daemon killall is called\n- Backup is created when requested\n\n## Approach\n- Can start with interface definitions (TDD style)\n- Use testify for assertions\n- Create temp directories for isolation\n- Mock git operations where needed\n- Test completion depends on implementation tasks\n\n## File Location\n`internal/reset/reset_test.go`\n`internal/reset/backup_test.go`\n`internal/reset/git_test.go`","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-13T08:44:57.01739+11:00","updated_at":"2025-12-13T10:13:32.611698+11:00","closed_at":"2025-12-13T09:59:20.820314+11:00","dependencies":[{"issue_id":"bd-aydr.6","depends_on_id":"bd-aydr","type":"parent-child","created_at":"2025-12-13T08:44:57.017813+11:00","created_by":"daemon"}]}
{"id":"bd-au0.10","title":"Add global verbosity flags (--verbose, --quiet)","description":"Add consistent verbosity controls across all commands.\n\n**Current state:**\n- bd init has --quiet flag\n- No other commands have verbosity controls\n- Debug output controlled by BD_VERBOSE env var\n\n**Proposal:**\nAdd persistent flags:\n- --verbose / -v: Enable debug output\n- --quiet / -q: Suppress non-essential output\n\n**Implementation:**\n- Add to rootCmd.PersistentFlags()\n- Replace BD_VERBOSE checks with flag checks\n- Standardize output levels:\n * Quiet: Errors only\n * Normal: Errors + success messages\n * Verbose: Errors + success + debug info\n\n**Files to modify:**\n- cmd/bd/main.go (add flags)\n- internal/debug/debug.go (respect flags)\n- Update all commands to respect quiet mode\n\n**Testing:**\n- Verify --verbose shows debug output\n- Verify --quiet suppresses normal output\n- Ensure errors always show regardless of mode","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-21T21:08:21.600209-05:00","updated_at":"2025-11-21T21:08:21.600209-05:00","dependencies":[{"issue_id":"bd-au0.10","depends_on_id":"bd-au0","type":"parent-child","created_at":"2025-11-21T21:08:21.602557-05:00","created_by":"daemon"}]}
{"id":"bd-l0pg","title":"GH#483: Pre-commit hook should not fail when .beads exists but bd sync fails","description":"Pre-commit hook exit 1 on bd sync --flush-only failure blocks commits even when user removed beads but .beads dir reappears. Should warn not fail. See: https://github.com/steveyegge/beads/issues/483","status":"in_progress","priority":2,"issue_type":"bug","created_at":"2025-12-14T16:32:22.759225-08:00","updated_at":"2025-12-14T16:52:49.799074-08:00"}
{"id":"bd-au0.9","title":"Review and document rarely-used commands","description":"Document use cases or consider deprecation for infrequently-used commands.\n\n**Commands to review:**\n1. bd rename-prefix - How often is this used? Document use cases\n2. bd detect-pollution - Consider integrating into bd validate\n3. bd migrate-hash-ids - One-time migration, keep but document as legacy\n\n**For each command:**\n- Document typical use cases\n- Add examples to help text\n- Consider if it should be a subcommand instead\n- Add deprecation warning if appropriate\n\n**Not changing:**\n- duplicates ✓ (useful for data quality)\n- repair-deps ✓ (useful for fixing broken refs)\n- restore ✓ (critical for compacted issues)\n- compact ✓ (performance feature)\n\n**Deliverable:**\n- Updated help text\n- Documentation in ADVANCED.md\n- Deprecation plan if needed","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-21T21:08:05.588275-05:00","updated_at":"2025-11-21T21:08:05.588275-05:00","dependencies":[{"issue_id":"bd-au0.9","depends_on_id":"bd-au0","type":"parent-child","created_at":"2025-11-21T21:08:05.59003-05:00","created_by":"daemon"}]}
{"id":"bd-dtm","title":"Inconsistent stderr printing: bd-feh warning still prints directly","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-12-02T21:55:25.212867-08:00","updated_at":"2025-12-02T22:05:53.14012-08:00","closed_at":"2025-12-02T22:05:53.14012-08:00"}
{"id":"bd-6l8","title":"Auto-resolve all field conflicts in merge.go","description":"Eliminate manual conflict resolution by adding deterministic auto-resolve rules for all fields:\n\n- Priority: higher priority wins (lower number = more urgent)\n- IssueType: local wins\n- Notes: concatenate both sides with separator\n- Title: side with latest updated_at on the issue wins\n- Description: side with latest updated_at on the issue wins\n\nCurrently true conflicts (both sides changed same field to different values) fail sync. With this change, NO conflicts ever require manual resolution.\n\nLocation: internal/merge/merge.go\nParent issue: bd-3s8","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-02T19:30:59.244181-08:00","updated_at":"2025-12-02T19:49:51.570143-08:00","closed_at":"2025-12-02T19:49:51.570143-08:00"}
{"id":"bd-n3v","title":"Error committing to sync branch: failed to create worktree","description":"\u003e bd sync --no-daemon\n→ Exporting pending changes to JSONL...\n→ Committing changes to sync branch 'beads-sync'...\nError committing to sync branch: failed to create worktree: failed to create worktree parent directory: mkdir /var/home/matt/dev/beads/fix-ci/.git: not a directory","notes":"**Problem Diagnosed**: The `bd sync` command was failing with \"mkdir /var/home/matt/dev/beads/fix-ci/.git: not a directory\" because it was being executed from the wrong directory.\n\n**Root Cause**: The command was run from `/var/home/matt/dev/beads` (where the `fix-ci` worktree exists) instead of the main repository directory `/var/home/matt/dev/beads/main`. Since `fix-ci` is a git worktree with a `.git` file (not directory), the worktree creation logic failed when trying to create `\u003ccurrent_dir\u003e/.git/beads-worktrees/\u003cbranch\u003e`.\n\n**Solution Verified**: Execute `bd sync` from the main repository directory:\n```bash\ncd main \u0026\u0026 bd sync --dry-run\n```\n","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-05T15:25:24.514998248-07:00","updated_at":"2025-12-05T15:42:32.910166956-07:00"}
{"id":"bd-nl2","title":"No logging/debugging for tombstone resurrection events","description":"Per the design document bd-zvg Open Question 1: Should resurrection log a warning? Recommendation was Yes. Currently, when an expired tombstone loses to a live issue (resurrection), there is no logging or debugging output. This makes it hard to understand why an issue reappeared. Recommendation: Add optional debug logging when resurrection occurs, e.g., Issue bd-abc resurrected (tombstone expired). Files: internal/merge/merge.go:359-366, 371-378, 400-405, 410-415","status":"open","priority":4,"issue_type":"feature","created_at":"2025-12-05T16:36:52.27525-08:00","updated_at":"2025-12-05T16:36:52.27525-08:00"}
{"id":"bd-m8ro","title":"Improve test coverage for internal/rpc (47.5% → 60%)","description":"The RPC package has only 47.5% test coverage. RPC is the communication layer for daemon operations.\n\nCurrent coverage: 47.5%\nTarget coverage: 60%","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-13T20:43:09.515299-08:00","updated_at":"2025-12-13T21:01:17.17404-08:00"}
{"id":"bd-581b80b3","title":"bd find-duplicates - AI-powered duplicate detection","description":"Find semantically duplicate issues.\n\nApproaches:\n1. Mechanical: Exact title/description matching\n2. Embeddings: Cosine similarity (cheap, scalable)\n3. AI: LLM-based semantic comparison (expensive, accurate)\n\nUses embeddings by default for \u003e100 issues.\n\nFiles: cmd/bd/find_duplicates.go (new)","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-29T20:49:49.126801-07:00","updated_at":"2025-10-30T17:12:58.218673-07:00"}
{"id":"bd-n386","title":"Improve test coverage for internal/daemon (27.3% → 60%)","description":"The daemon package has only 27.3% test coverage. The daemon is critical for background operations and reliability.\n\nKey areas needing tests:\n- Daemon autostart logic\n- Socket handling\n- PID file management\n- Health checks\n\nCurrent coverage: 27.3%\nTarget coverage: 60%","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-13T20:43:00.895238-08:00","updated_at":"2025-12-13T21:01:17.274438-08:00"}
{"id":"bd-sh4c","title":"Improve test coverage for cmd/bd/setup (28.4% → 50%)","description":"The setup package has only 28.4% test coverage. Setup commands are critical for first-time user experience.\n\nCurrent coverage: 28.4%\nTarget coverage: 50%","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-13T20:43:04.409346-08:00","updated_at":"2025-12-13T21:01:18.98833-08:00"}
{"id":"bd-au0.7","title":"Audit and standardize JSON output across all commands","description":"Ensure consistent JSON format and error handling when --json flag is used.\n\n**Scope:**\n1. Verify all commands respect --json flag\n2. Standardize success response format\n3. Standardize error response format\n4. Document JSON schemas\n\n**Commands to audit:**\n- Core CRUD: create, update, delete, show, list, search ✓\n- Queries: ready, blocked, stale, count, stats, status\n- Deps: dep add/remove/tree/cycles\n- Labels: label commands\n- Comments: comments add/list/delete\n- Epics: epic status/close-eligible\n- Export/import: already support --json ✓\n\n**Testing:**\n- Success cases return valid JSON\n- Error cases return valid JSON (not plain text)\n- Consistent field naming (snake_case vs camelCase)\n- Array vs object wrapping consistency","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-21T21:07:35.304424-05:00","updated_at":"2025-11-21T21:07:35.304424-05:00","dependencies":[{"issue_id":"bd-au0.7","depends_on_id":"bd-au0","type":"parent-child","created_at":"2025-11-21T21:07:35.305663-05:00","created_by":"daemon"}]}
{"id":"bd-kig","title":"Test worktree sync branch commit","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-30T00:38:13.906936-08:00","updated_at":"2025-11-30T00:40:23.609537-08:00","closed_at":"2025-11-30T00:40:23.609537-08:00"}
{"id":"bd-411u","title":"Document BEADS_DIR pattern for multi-agent workspaces (Gas Town)","description":"Gas Town and similar multi-agent systems need to configure separate beads databases per workspace/rig, distinct from any project-level beads.\n\n## Use Case\n\nIn Gas Town:\n- Each 'rig' (managed project) has multiple agents (polecats, refinery, witness)\n- All agents in a rig should share a single beads database at the rig level\n- This should be separate from any .beads/ the project itself uses\n- The BEADS_DIR env var enables this\n\n## Documentation Needed\n\n1. Add a section to docs explaining BEADS_DIR for multi-agent setups\n2. Example: setting BEADS_DIR in agent startup scripts/hooks\n3. Clarify interaction with project-level .beads/ (BEADS_DIR takes precedence)\n\n## Current Support\n\nAlready implemented in internal/beads/beads.go:FindDatabasePath():\n- BEADS_DIR env var is checked first (preferred)\n- BEADS_DB env var still supported (deprecated)\n- Falls back to .beads/ search in tree\n\nJust needs documentation for the multi-agent workspace pattern.","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-15T22:08:22.158027-08:00","updated_at":"2025-12-15T22:08:22.158027-08:00"}
{"id":"bd-au0","title":"Command Set Standardization \u0026 Flag Consistency","description":"Comprehensive improvements to bd command set based on 2025 audit findings.\n\n## Background\nSee docs/command-audit-2025.md for detailed analysis.\n\n## Goals\n1. Standardize flag naming and behavior across all commands\n2. Add missing flags for feature parity\n3. Fix naming confusion\n4. Improve consistency in JSON output\n\n## Success Criteria\n- All mutating commands support --dry-run (no --preview variants)\n- bd update supports label operations\n- bd search has filter parity with bd list\n- Priority flags accept both int and P0-P4 format everywhere\n- JSON output is consistent across all commands","status":"open","priority":2,"issue_type":"epic","created_at":"2025-11-21T21:05:55.672749-05:00","updated_at":"2025-11-21T21:05:55.672749-05:00"}
{"id":"bd-hy9p","title":"Add --body-file flag to bd create for reading descriptions from files","description":"## Problem\n\nCreating issues with long/complex descriptions via CLI requires shell escaping gymnastics:\n\n```bash\n# Current workaround - awkward heredoc quoting\nbd create --title=\"...\" --description=\"$(cat \u003c\u003c'EOF'\n...markdown...\nEOF\n)\"\n\n# Often fails with quote escaping errors in eval context\n# Agents resort to writing temp files then reading them\n```\n\n## Proposed Solution\n\nAdd `--body-file` and `--description-file` flags to read description from a file, matching `gh` CLI pattern.\n\n```bash\n# Natural pattern that aligns with training data\ncat \u003e /tmp/desc.md \u003c\u003c 'EOF'\n...markdown content...\nEOF\n\nbd create --title=\"...\" --body-file=/tmp/desc.md\n```\n\n## Implementation\n\n### 1. Add new flags to `bd create`\n\n```go\ncreateCmd.Flags().String(\"body-file\", \"\", \"Read description from file (use - for stdin)\")\ncreateCmd.Flags().String(\"description-file\", \"\", \"Alias for --body-file\")\n```\n\n### 2. Flag precedence\n\n- If `--body-file` or `--description-file` is provided, read from file\n- If value is `-`, read from stdin\n- Otherwise fall back to `--body` or `--description` flag\n- If neither provided, description is empty (current behavior)\n\n### 3. Error handling\n\n- File doesn't exist → clear error message\n- File not readable → clear error message\n- stdin specified but not available → clear error message\n\n## Benefits\n\n✅ **Matches training data**: `gh issue create --body-file file.txt` is a common pattern\n✅ **No shell escaping issues**: File content is read directly\n✅ **Works with any content**: Markdown, special characters, quotes, etc.\n✅ **Agent-friendly**: Agents already write complex content to temp files\n✅ **User-friendly**: Easier for humans too when pasting long descriptions\n\n## Related Commands\n\nConsider adding similar support to:\n- `bd update --body-file` (for updating descriptions)\n- `bd comment --body-file` (if/when we add comments)\n\n## Examples\n\n```bash\n# From file\nbd create --title=\"Add new feature\" --body-file=feature.md\n\n# From stdin\necho \"Quick description\" | bd create --title=\"Bug fix\" --body-file=-\n\n# With other flags\nbd create \\\n --title=\"Security issue\" \\\n --type=bug \\\n --priority=0 \\\n --body-file=security-report.md \\\n --label=security\n```\n\n## Testing\n\n- Test with normal files\n- Test with stdin (`-`)\n- Test with non-existent files (error handling)\n- Test with binary files (should handle gracefully)\n- Test with empty files (valid - empty description)\n- Test that `--description-file` and `--body-file` are equivalent aliases","status":"open","priority":1,"issue_type":"feature","created_at":"2025-11-22T00:02:08.762684-08:00","updated_at":"2025-11-22T00:02:08.762684-08:00"}
{"id":"bd-er7r","title":"GH#509: bd fails to find .beads from nested worktrees","description":"findDatabaseInTree stops at worktree git root, missing .beads in parent repo. Should check git-common-dir and search past worktree root. See: https://github.com/steveyegge/beads/issues/509","status":"in_progress","priority":2,"issue_type":"bug","created_at":"2025-12-14T16:32:00.082813-08:00","updated_at":"2025-12-14T16:52:49.8029-08:00"}
{"id":"bd-dve","title":"Update import/export to handle tombstones","description":"Modify importer to read tombstones from issues.jsonl and legacy deletions.jsonl. Modify exporter to write tombstones. Filter tombstoned issues during import. Per design bd-dli.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T15:14:43.797468-08:00","updated_at":"2025-12-07T01:32:27.980549-08:00","closed_at":"2025-12-07T01:32:27.980549-08:00","dependencies":[{"issue_id":"bd-dve","depends_on_id":"bd-fbj","type":"blocks","created_at":"2025-12-05T15:14:58.895531-08:00","created_by":"daemon"},{"issue_id":"bd-dve","depends_on_id":"bd-0ih","type":"blocks","created_at":"2025-12-05T15:14:58.931808-08:00","created_by":"daemon"}]}
{"id":"bd-clg","title":"bd jira sync command","description":"Add a built-in bd command for Jira synchronization.\n\n**Requires**: Both import and export scripts working\n\n**Features**:\n- `bd jira sync --pull` - Import from Jira to beads\n- `bd jira sync --push` - Export from beads to Jira\n- `bd jira sync` - Bidirectional (pull then push, with conflict resolution)\n- `bd jira status` - Show sync status and last sync time\n\n**Conflict resolution**:\n- Timestamp-based: newer update wins\n- Option for --prefer-local or --prefer-jira to override\n- Interactive mode for manual conflict resolution (optional)\n\n**Integration**:\n- Uses jira.* config settings from bd config\n- Stores last sync timestamp in config\n- Logs sync activity for audit\n\n**Stretch goals**:\n- Webhook integration for real-time sync\n- Selective sync by JQL filter","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-11-30T12:56:27.716537-08:00","updated_at":"2025-11-30T15:25:37.896045-08:00","closed_at":"2025-11-30T15:25:37.896045-08:00","dependencies":[{"issue_id":"bd-clg","depends_on_id":"bd-qvj","type":"parent-child","created_at":"2025-11-30T12:56:49.796568-08:00","created_by":"stevey"},{"issue_id":"bd-clg","depends_on_id":"bd-tjn","type":"blocks","created_at":"2025-11-30T12:57:00.075288-08:00","created_by":"stevey"},{"issue_id":"bd-clg","depends_on_id":"bd-93d","type":"blocks","created_at":"2025-11-30T12:57:05.206431-08:00","created_by":"stevey"}]}
{"id":"bd-a6m","title":"isLikelyHash rejects 3-char all-letter base36 hashes","description":"ExtractIssuePrefix fails for multi-hyphen prefixes when the 3-char hash suffix has no digits.\n\nExample: `xa-adt-bat` returns prefix `xa` instead of `xa-adt`.\n\nRoot cause: `isLikelyHash()` requires at least one digit to distinguish hashes from English words, but base36 hashes can be all-letters by chance.\n\nAffected: 20 issues in xa-adapt with suffixes like bat, dev, fbi, oil, etc.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-02T17:11:19.783336327-05:00","updated_at":"2025-12-02T17:12:37.634260315-05:00","closed_at":"2025-12-02T17:12:37.634260315-05:00"}
{"id":"bd-tjn","title":"Jira import script (jira2jsonl.py)","description":"Create a Python script to import Jira issues into beads JSONL format.\n\n**Pattern**: Follow examples/github-import/gh2jsonl.py\n\n**Features needed**:\n- Fetch issues via Jira REST API with JQL queries\n- Pagination handling (100 issues per request)\n- Map Jira fields to beads fields (see schema mapping in epic)\n- Set external_ref to Jira issue URL for re-sync\n- Support both Jira Cloud and Server/Data Center APIs\n- Read config from bd config (jira.url, jira.project, jira.api_token)\n\n**Config-driven mapping**:\n- jira.status_map.* for status conversion\n- jira.type_map.* for issue type conversion\n- jira.priority_map.* for priority conversion\n\n**Usage**:\n```bash\npython jira2jsonl.py --project PROJ | bd import\n# or\npython jira2jsonl.py --jql 'project=PROJ AND status\\!=Done' | bd import\n```\n\n**Output**: JSONL with external_ref set to Jira issue URL","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-30T12:55:59.517985-08:00","updated_at":"2025-11-30T15:11:56.692594-08:00","closed_at":"2025-11-30T15:11:56.692594-08:00","dependencies":[{"issue_id":"bd-tjn","depends_on_id":"bd-qvj","type":"parent-child","created_at":"2025-11-30T12:56:39.507643-08:00","created_by":"stevey"}]}
{"id":"bd-1r5","title":"Design tombstone TTL and expiration semantics","description":"Design the TTL and expiration behavior for tombstone records. Key decisions: default TTL (recommend 30 days), configuration via config.yaml, expiration semantics (remove vs keep expired), merge behavior when tombstone expires (live issue wins), clock skew handling.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T13:42:57.242067-08:00","updated_at":"2025-12-05T14:59:11.461169-08:00","closed_at":"2025-12-05T14:59:11.461169-08:00"}
{"id":"bd-4hn","title":"wish: list \u0026 ready show issues as hierarchy tree","description":"`bd ready` and `bd list` just show a flat list, and it's up to the reader to parse which ones are dependent or sub-issues of others. It would be much easier to understand if they were shown in a tree format","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-08T06:38:24.016316945-07:00","updated_at":"2025-12-08T06:39:04.065882225-07:00"}
{"id":"bd-f2f","title":"CRITICAL: bd sync exports before pull, allowing stale DB to corrupt JSONL statuses","description":"## Root Cause\n\nThe fix in bd-53c (reverse ZFC check) only checks COUNTS, not content. The real corruption happens when:\n\n1. Polecat A has stale DB with old status values (e.g., status=closed for issues that are now open on remote)\n2. Polecat A runs bd sync:\n - **Export FIRST**: DB (status=closed) → JSONL (overwrites correct status=open)\n - Commit: Stale JSONL committed\n - Pull: 3-way merge with remote\n - Merge uses 'closed wins' rule → status stays closed\n3. Polecat A pushes → Remote now corrupted with status=closed\n\n## Why bd-53c didn't fix it\n\nThe reverse ZFC check compares COUNTS:\n```go\nif jsonlCount \u003e dbCount // Only catches count mismatch\n```\n\nBut in the corruption scenario:\n- JSONL count = 5, DB count = 5 (same count!)\n- Only the STATUS field differs\n\n## The Real Fix\n\n**PULL BEFORE EXPORT**. The sync order must be:\n1. Pull from remote (get latest state)\n2. Import merged JSONL to DB\n3. THEN export DB changes (if any)\n\nCurrent order is: Export → Commit → Pull → Import → Push\n\nThis is a fundamental architecture change to the sync flow.\n\n## Workaround\n\nUse --no-auto-flush and manually control the sync order, or disable daemon auto-export.\n\n## Evidence\n\nFrom user investigation:\n- At 595b7943 (13:20:30): 5 open issues\n- At 10239812 (13:28:39): 0 open issues\n- All 5 issues had their status changed from open to closed\n- Count stayed at 5 (not a deletion issue)","status":"closed","issue_type":"bug","created_at":"2025-11-29T17:33:26.744766-08:00","updated_at":"2025-11-29T19:24:31.010075-08:00","closed_at":"2025-11-29T19:24:31.010075-08:00"}
{"id":"bd-cb64c226.1","title":"Performance Validation","description":"Confirm no performance regression from cache removal","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T10:50:15.126019-07:00","updated_at":"2025-10-30T17:12:58.216721-07:00","closed_at":"2025-10-28T10:49:45.021037-07:00"}
{"id":"bd-28db","title":"Add 'bd status' command for issue database overview","description":"Implement a bd status command that provides a quick snapshot of the issue database state, similar to how git status shows working tree state.\n\nExpected output: Show summary including counts by state (open, in-progress, blocked, closed), recent activity (last 7 days), and quick overview without needing multiple queries.\n\nExample output showing issue counts, recent activity stats, and pointer to bd list for details.\n\nProposed options: --all (show all issues), --assigned (show issues assigned to current user), --json (JSON format output)\n\nUse cases: Quick project health check, onboarding for new contributors, integration with shell prompts or CI/CD, daily standup reference","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-02T17:25:59.203549-08:00","updated_at":"2025-11-02T17:25:59.203549-08:00"}
{"id":"bd-2q6d","title":"Beads commands operate on stale database without warning","description":"All beads read operations should validate database is in sync with JSONL before proceeding.\n\n**Current Behavior:**\n- Commands can query/read from stale database\n- Only mutation operations (like 'bd sync') check if JSONL is newer\n- User gets incorrect results without realizing database is out of sync\n\n**Expected Behavior:**\n- All beads commands should have pre-flight check for database freshness\n- If JSONL is newer than database, refuse to operate with error: \"Database out of sync. Run 'bd import' first.\"\n- Same safety check that exists for 'bd sync' should apply to ALL operations\n\n**Impact:**\n- Users make decisions based on incomplete/outdated data\n- Silent failures lead to confusion (e.g., thinking issues don't exist when they do)\n- Similar to running git commands on stale repo without being warned to pull\n\n**Example:**\n- Searched for bd-g9eu issue file: not found\n- Issue exists in .beads/issues.jsonl (in git)\n- Database was stale, but no warning was given\n- Led to incorrect conclusion that issue was already closed/deleted","notes":"## Implementation Complete\n\n**Phase 1: Created staleness check (cmd/bd/staleness.go)**\n- ensureDatabaseFresh() function checks JSONL mtime vs last_import_time\n- Returns error with helpful message when database is stale\n- Auto-skips in daemon mode (daemon has auto-import)\n\n**Phase 2: Added to all read commands**\n- list, show, ready, status, stale, info, duplicates, validate\n- Check runs before database queries in direct mode\n- Daemon mode already protected via checkAndAutoImportIfStale()\n\n**Phase 3: Code Review Findings**\nSee follow-up issues:\n- bd-XXXX: Add warning when staleness check errors\n- bd-YYYY: Improve CheckStaleness error handling\n- bd-ZZZZ: Refactor redundant daemon checks (low priority)\n\n**Testing:**\n- Build successful: go build ./cmd/bd\n- Binary works: ./bd --version\n- Ready for manual testing\n\n**Next Steps:**\n1. Test with stale database scenario\n2. Implement review improvements\n3. Close issue when tests pass","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-20T19:33:40.019297-05:00","updated_at":"2025-11-22T14:57:44.481917204-05:00"}
{"id":"bd-3s8","title":"Imperator clone on beads-sync branch causes bd sync failures","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-30T22:53:51.056763-08:00","updated_at":"2025-12-02T23:28:48.751447-08:00","closed_at":"2025-12-02T18:05:16.968092-08:00"}
{"id":"bd-umbf","title":"Design contributor namespace isolation for beads pollution prevention","description":"## Problem\n\nWhen contributors work on beads-the-project using beads-the-tool, their personal work-tracking issues leak into PRs. The .beads/issues.jsonl is intentionally tracked (it's the project's issue database), but contributors' local issues pollute the diff.\n\nThis is a recursion problem unique to self-hosting projects.\n\n## Possible Solutions to Explore\n\n1. **Contributor namespaces** - Each contributor gets a private prefix (e.g., `bd-steve-xxxx`) that's gitignored or filtered\n2. **Separate database** - Contributors use BEADS_DIR pointing elsewhere for personal tracking\n3. **Issue ownership/visibility flags** - Mark issues as \"local-only\" vs \"project\"\n4. **Prefix-based filtering** - Configure which prefixes are committed vs ignored\n\n## Design Considerations\n\n- Should be zero-friction for contributors (no manual setup)\n- Must not break existing workflows\n- Needs to work with sync/collaboration features\n- Consider: what if a \"personal\" issue graduates to \"project\" issue?\n\n## Expansion Needed\n\nThis is a placeholder. Needs detailed design exploration before implementation.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-13T18:00:29.638743-08:00","updated_at":"2025-12-13T18:00:41.345673-08:00"}
{"id":"bd-379","title":"Implement `bd setup cursor` for Cursor IDE integration","description":"Create a `bd setup cursor` command that integrates Beads workflow into Cursor IDE via .cursorrules file. Unlike Claude Code (which has hooks), Cursor uses a static rules file to provide context to its AI.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-11-11T23:32:22.170083-08:00","updated_at":"2025-11-11T23:32:22.170083-08:00"}
{"id":"bd-bgm","title":"Fix unparam unused parameter in cmd/bd/doctor.go:1879","description":"Linting issue: checkGitHooks - path is unused (unparam) at cmd/bd/doctor.go:1879:20. Error: func checkGitHooks(path string) doctorCheck {","status":"open","issue_type":"bug","created_at":"2025-12-07T15:35:25.270293252-07:00","updated_at":"2025-12-07T15:35:25.270293252-07:00"}
{"id":"bd-wucl","title":"Add Result.ConvertedToTombstone counter for import statistics","description":"The import Result struct has SkippedDeleted but doesn't distinguish between:\n1. Issues skipped because they're in deletions manifest (old behavior)\n2. Issues converted from deletions.jsonl to tombstones (new bd-dve behavior)\n\nAdd a new ConvertedToTombstone counter to track legacy deletions converted to tombstones during import. This provides better visibility into the migration process.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T01:40:34.097611-08:00","updated_at":"2025-12-07T02:18:09.466608-08:00","closed_at":"2025-12-07T02:18:09.466608-08:00","dependencies":[{"issue_id":"bd-wucl","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-07T01:41:28.242971-08:00","created_by":"daemon"}]}
{"id":"bd-8ib","title":"Update git hooks to be sync.branch aware","description":"## Problem\n\nThe pre-push hook blocks pushes when .beads/issues.jsonl has uncommitted changes. But with sync.branch configured, those changes are intentionally NOT committed to main - they go to the sync branch via worktree.\n\n## Current Behavior\n\n1. User configures sync.branch=beads-sync\n2. bd sync commits changes to beads-sync via worktree \n3. Local .beads/issues.jsonl is updated (needed for import)\n4. git push to main triggers pre-push hook\n5. Hook sees uncommitted .beads changes and blocks push\n6. User must use --no-verify to push\n\n## Expected Behavior\n\nWhen sync.branch is configured, the pre-push hook should:\n1. Check if sync.branch is set (bd config get sync.branch)\n2. If set, skip the .beads uncommitted check OR\n3. Verify changes are committed to the sync branch instead\n\n## Affected Files\n\n- examples/git-hooks/pre-push\n- examples/git-hooks/pre-commit (may also need update)\n\n## Workaround\n\nUse git push --no-verify","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-30T00:43:40.991951-08:00","updated_at":"2025-11-30T11:12:09.91242-08:00","closed_at":"2025-11-30T11:12:09.91242-08:00"}
{"id":"bd-9auw","title":"convertDeletionToTombstone uses hardcoded default values","description":"The convertDeletionToTombstone helper (importer.go:1114-1130) uses hardcoded defaults:\n- Priority: 2\n- IssueType: types.TypeTask\n- Title: \"(deleted)\"\n\nThese defaults work but could be improved:\n1. Consider using Priority: 0 (unset) to distinguish from user-set priority\n2. OriginalType is empty string - consider setting IssueType to empty to be consistent\n3. Title could include the original ID for debugging: \"(deleted: bd-xyz)\"\n\nLow priority cleanup for consistency.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T01:41:02.390816-08:00","updated_at":"2025-12-07T02:19:52.824918-08:00","closed_at":"2025-12-07T02:19:52.824918-08:00","dependencies":[{"issue_id":"bd-9auw","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-07T01:41:28.35551-08:00","created_by":"daemon"}]}
{"id":"bd-tok","title":"Upgrade notification persists after running suggested commands","description":"The upgrade notification kept showing even after running 'bd upgrade review' and 'bd doctor' as suggested.\n\nExpected: Notification should be dismissed after running either/both commands\nActual: Notification persisted on every bd command\n\nInvestigation findings:\n- metadata.json correctly shows last_bd_version=0.28.0\n- The notification stopped appearing after a few more invocations\n- May be related to daemon caching or a race condition\n- The 'upgradeAcknowledged' flag in version_tracking.go:115 only persists per-session (in-memory)\n\nPossible causes:\n1. Daemon vs direct mode inconsistency - daemon may have stale version info\n2. The version is checked/updated before daemon connection, but daemon has cached state\n3. Race between trackBdVersion() and daemon startup\n\nStatus: May have resolved itself, but root cause unclear. Close if no longer reproducible.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-02T23:23:04.652453-08:00","updated_at":"2025-12-02T23:38:09.310731-08:00","closed_at":"2025-12-02T23:38:09.310731-08:00"}
{"id":"bd-n4td","title":"Add warning when staleness check errors","description":"## Problem\n\nWhen ensureDatabaseFresh() calls CheckStaleness() and it errors (corrupted metadata, permission issues, etc.), we silently proceed with potentially stale data.\n\n**Location:** cmd/bd/staleness.go:27-32\n\n**Scenarios:**\n- Corrupted metadata table\n- Database locked by another process \n- Permission issues reading JSONL file\n- Invalid last_import_time format in DB\n\n## Current Code\n\n```go\nisStale, err := autoimport.CheckStaleness(ctx, store, dbPath)\nif err \\!= nil {\n // If we can't determine staleness, allow operation to proceed\n // (better to show potentially stale data than block user)\n return nil\n}\n```\n\n## Fix\n\n```go\nisStale, err := autoimport.CheckStaleness(ctx, store, dbPath)\nif err \\!= nil {\n fmt.Fprintf(os.Stderr, \"Warning: Could not verify database freshness: %v\\n\", err)\n fmt.Fprintf(os.Stderr, \"Proceeding anyway. Data may be stale.\\n\\n\")\n return nil\n}\n```\n\n## Impact\nMedium - users should know when staleness check fails\n\n## Effort\nEasy - 5 minutes","status":"open","priority":2,"issue_type":"bug","created_at":"2025-11-20T20:16:34.889997-05:00","updated_at":"2025-11-20T20:16:34.889997-05:00","dependencies":[{"issue_id":"bd-n4td","depends_on_id":"bd-2q6d","type":"blocks","created_at":"2025-11-20T20:18:20.154723-05:00","created_by":"stevey"}]}
{"id":"bd-d0t","title":"Priority 0 in merge may incorrectly win over set priorities","description":"In mergePriority(), priority 0 (which may mean 'unset' due to Go's zero value) beats any explicitly set priority like P1, P2, etc. Should probably treat 0 as 'no priority set' and not let it win conflicts.","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-12-02T20:14:58.906543-08:00","updated_at":"2025-12-03T22:16:02.66552-08:00","closed_at":"2025-12-03T22:16:02.66552-08:00"}
{"id":"bd-8nz","title":"Merge timestamp tie-breaker should prefer local (left)","description":"In mergeFieldByUpdatedAt, when timestamps are exactly equal, right wins. For consistency with IssueType (where local/left wins), equal timestamps should prefer left. Minor inconsistency.","status":"closed","priority":4,"issue_type":"task","created_at":"2025-12-02T20:14:59.898345-08:00","updated_at":"2025-12-03T22:18:17.242011-08:00","closed_at":"2025-12-03T22:18:17.242011-08:00"}
{"id":"bd-7yg","title":"Git merge driver uses invalid placeholders (%L, %R instead of %A, %B)","description":"## Problem\n\nThe beads git merge driver is configured with invalid Git placeholders:\n\n```\ngit config merge.beads.driver \"bd merge %A %O %L %R\"\n```\n\nGit doesn't recognize `%L` or `%R` as valid merge driver placeholders. The valid placeholders are:\n- `%O` = base (common ancestor)\n- `%A` = current version (ours)\n- `%B` = other version (theirs)\n\n## Impact\n\n- Affects ALL users when they have `.beads/beads.jsonl` merge conflicts\n- Automatic JSONL merge fails with error: \"error reading left file: failed to open file: open 7: no such file or directory\"\n- Users must manually resolve conflicts instead of getting automatic merge\n\n## Root Cause\n\nThe `bd init` command (or wherever the merge driver is configured) is using non-standard placeholders. When Git encounters `%L` and `%R`, it either passes them literally or interprets them incorrectly.\n\n## Fix\n\nUpdate the merge driver configuration to:\n```\ngit config merge.beads.driver \"bd merge %A %O %A %B\"\n```\n\nWhere:\n- 1st `%A` = output file (current file, will be overwritten)\n- `%O` = base (common ancestor)\n- 2nd `%A` = left/current version\n- `%B` = right/other version\n\n## Action Items\n\n1. Fix `bd init` (or equivalent setup command) to use correct placeholders\n2. Add migration/warning for existing users with misconfigured merge driver\n3. Update documentation with correct merge driver setup\n4. Consider adding validation when `bd init` is run","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-21T19:51:55.747608-05:00","updated_at":"2025-11-21T19:51:55.747608-05:00"}
{"id":"bd-lfak","title":"bd preflight: PR readiness checks for contributors","description":"## Vision\n\nEncode project-specific institutional knowledge into executable checks. CONTRIBUTING.md is documentation that's read once and forgotten; `bd preflight` is documentation that runs at exactly the right moment.\n\n## Problem Statement\n\nContributors face a \"last mile\" problem - they do the work but stumble on project-specific gotchas at PR time:\n- Nix vendorHash gets stale when go.sum changes\n- Beads artifacts leak into PRs (see bd-umbf for namespace solution)\n- Version mismatches between version.go and default.nix\n- Tests/lint not run locally before pushing\n- Other project-specific checks that only surface when CI fails\n\nThese are too obscure to remember, exist in docs nobody reads end-to-end, and waste CI round-trips.\n\n## Why beads?\n\nBeads already has a foothold in the contributor workflow. It knows:\n- Git state (staged files, branch, dirty status)\n- Project structure\n- The specific issue being worked on\n- Project-specific configuration\n\n## Proposed Interface\n\n### Tier 1: Checklist Mode (v1)\n\n $ bd preflight\n PR Readiness Checklist:\n\n [ ] Tests pass: go test -short ./...\n [ ] Lint passes: golangci-lint run ./...\n [ ] No beads pollution: check .beads/issues.jsonl diff\n [ ] Nix hash current: go.sum unchanged or vendorHash updated\n [ ] Version sync: version.go matches default.nix\n\n Run 'bd preflight --check' to validate automatically.\n\n### Tier 2: Check Mode (v2)\n\n $ bd preflight --check\n ✓ Tests pass\n ✓ Lint passes\n ⚠ Beads pollution: 3 issues in diff - are these project issues or personal?\n ✗ Nix hash stale: go.sum changed, vendorHash needs update\n Fix: sha256-KRR6dXzsSw8OmEHGBEVDBOoIgfoZ2p0541T9ayjGHlI=\n ✓ Version sync\n\n 1 error, 1 warning. Run 'bd preflight --fix' to auto-fix where possible.\n\n### Tier 3: Fix Mode (v3)\n\n $ bd preflight --fix\n ✓ Updated vendorHash in default.nix\n ⚠ Cannot auto-fix beads pollution - manual review needed\n\n## Checks to Implement\n\n| Check | Description | Auto-fixable |\n|-------|-------------|--------------|\n| tests | Run go test -short ./... | No |\n| lint | Run golangci-lint | Partial (gofmt) |\n| beads-pollution | Detect personal issues in diff | No (see bd-umbf) |\n| nix-hash | Detect stale vendorHash | Yes (if nix available) |\n| version-sync | version.go matches default.nix | Yes |\n| no-debug | No TODO/FIXME/console.log | Warn only |\n| clean-stage | No unintended files staged | Warn only |\n\n## Future: Configuration\n\nMake checks configurable per-project via .beads/preflight.yaml:\n\n preflight:\n checks:\n - name: tests\n run: go test -short ./...\n required: true\n - name: no-secrets\n pattern: \"**/*.env\"\n staged: deny\n - name: custom-check\n run: ./scripts/validate.sh\n\nThis lets any project using beads define their own preflight checks.\n\n## Implementation Phases\n\n### Phase 1: Static Checklist\n- Implement bd preflight with hardcoded checklist for beads\n- No execution, just prints what to check\n- Update CONTRIBUTING.md to reference it\n\n### Phase 2: Automated Checks\n- Implement bd preflight --check\n- Run tests, lint, detect stale hashes\n- Clear pass/fail/warn output\n\n### Phase 3: Auto-fix\n- Implement bd preflight --fix\n- Fix vendorHash, version sync\n- Integrate with bd-umbf solution for pollution\n\n### Phase 4: Configuration\n- .beads/preflight.yaml support\n- Make it useful for other projects using beads\n- Plugin/hook system for custom checks\n\n## Dependencies\n\n- bd-umbf: Namespace isolation for beads pollution (blocking for full solution)\n\n## Success Metrics\n\n- Fewer CI failures on first PR push\n- Reduced \"fix nix hash\" commits\n- Contributors report preflight caught issues before CI","status":"open","priority":2,"issue_type":"epic","created_at":"2025-12-13T18:01:39.587078-08:00","updated_at":"2025-12-13T18:01:39.587078-08:00","dependencies":[{"issue_id":"bd-lfak","depends_on_id":"bd-umbf","type":"blocks","created_at":"2025-12-13T18:01:46.059901-08:00","created_by":"daemon"}]}
{"id":"bd-e0o7","title":"Refactor: extract common helpers in sync-branch hook checks","description":"Code review of #532 fix identified duplication between checkSyncBranchHookCompatibility and checkSyncBranchHookQuick.\n\nSuggested refactoring:\n1. Extract getPrePushHookPath(path string) helper for git dir + hook path resolution\n2. Extract extractHookVersion(hookContent string) helper for version parsing\n3. Consider whether Warning for custom hooks is appropriate (vs OK with info message)\n4. Document the intentional behavior difference between full check (Warning for custom) and quick check (OK for custom)","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-13T18:04:04.220868-08:00","updated_at":"2025-12-13T18:04:04.220868-08:00"}
{"id":"bd-8uk","title":"Missing test for PullResult.SafetyWarnings population","status":"closed","priority":4,"issue_type":"task","created_at":"2025-12-02T21:56:08.413387-08:00","updated_at":"2025-12-02T22:11:17.630494-08:00","closed_at":"2025-12-02T22:11:17.630494-08:00"}
{"id":"bd-alz","title":"bd doctor: add configuration value validation","description":"Currently bd doctor checks for missing config files but doesn't validate config values. Add validation for: invalid priority values, malformed sync intervals, invalid branch names, unsupported storage backends, etc. This would catch misconfigurations before they cause runtime errors.","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-12-02T12:52:31.852532-08:00","updated_at":"2025-12-03T22:15:23.137554-08:00","closed_at":"2025-12-03T22:15:23.137554-08:00"}
{"id":"bd-j3il","title":"Add bd reset command for clean slate restart","description":"Implement a command to reset beads to a clean starting state.\n\n**Context:** GitHub issue #479 - users sometimes get beads into an invalid state after updates, and there's no clean way to start fresh. The git backup/restore mechanism that protects against accidental deletion also makes it hard to intentionally reset.\n\n**Current workaround** (from maphew):\n```bash\nbd daemons killall\ngit rm .beads/*.jsonl\ngit commit -m 'remove old issues'\nrm .beads/*\nbd init\nbd onboard\n```\n\n**Desired:** A proper `bd reset` command that handles this cleanly and safely.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-12-13T08:41:34.956552+11:00","updated_at":"2025-12-13T08:43:49.970591+11:00","closed_at":"2025-12-13T08:43:49.970591+11:00"}
{"id":"bd-io8c","title":"Improve test coverage for internal/syncbranch (33.0% → 70%)","description":"The syncbranch package has only 33.0% test coverage. This package handles git sync operations and is critical for data integrity.\n\nCurrent coverage: 33.0%\nTarget coverage: 70%","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-13T20:43:02.079145-08:00","updated_at":"2025-12-13T21:01:14.972533-08:00"}
{"id":"bd-nhkh","title":"bd blocked shows empty (GH#545)","description":"bd blocked only shows dependency-blocked issues, not status=blocked issues.\n\nEither:\n- Include status=blocked issues, OR\n- Document/rename to clarify behavior\n\nFix in: cmd/bd/blocked.go","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-14T23:00:33.19049-08:00","updated_at":"2025-12-14T23:07:43.313267-08:00","closed_at":"2025-12-14T23:07:43.313267-08:00"}
{"id":"bd-e3w","title":"bd sync: use worktree for sync.branch commits (non-daemon mode)","description":"## Summary\n\nWhen `sync.branch` is configured (e.g., `beads-sync`), `bd sync` should commit beads changes to that branch via git worktree, even when the user's working directory is on a different branch (e.g., `main`).\n\nCurrently:\n- `bd sync` always commits to the current branch\n- Daemon with `--auto-commit` uses worktrees to commit to sync branch\n- Gap: `bd sync` ignores sync.branch config\n\n## Goal\n\nWorkers stay on `main` (or feature branches) while beads metadata automatically flows to `beads-sync` branch. No daemon required.\n\n## Design Considerations\n\n1. **Worktree lifecycle**: Create on first use, reuse thereafter\n2. **Daemon interaction**: Ensure daemon and bd sync don't conflict\n3. **MCP server**: Uses daemon or direct mode - needs same behavior\n4. **Pull semantics**: Pull from sync branch, not current branch\n5. **Push semantics**: Push to sync branch remote\n6. **Error handling**: Worktree corruption, missing branch, etc.\n\n## Affected Components\n\n- `cmd/bd/sync.go` - Main changes\n- `cmd/bd/daemon_sync_branch.go` - Reuse existing functions\n- `internal/git/worktree.go` - Already implemented\n- MCP server (if it bypasses daemon)\n\n## Edge Cases\n\n- Fresh clone (no sync branch exists yet)\n- Worktree exists but is corrupted\n- Concurrent bd sync from multiple processes\n- sync.branch configured but remote doesn't have that branch\n- User switches sync.branch config mid-session","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-30T00:31:20.026356-08:00","updated_at":"2025-12-07T21:25:07.141293+11:00","closed_at":"2025-11-30T00:41:35.335791-08:00"}
{"id":"bd-bwdd","title":"GH#497: bd onboard copilot-instructions.md is beads-specific, not generic","description":"bd onboard outputs beads repo specific content (Go/SQLite/Cobra) for copilot-instructions.md instead of a generic template. AGENTS.md output is correct. See: https://github.com/steveyegge/beads/issues/497","status":"in_progress","priority":2,"issue_type":"bug","created_at":"2025-12-14T16:32:18.599655-08:00","updated_at":"2025-12-14T16:52:49.794787-08:00"}
{"id":"bd-5b6e","title":"Add tests for helper functions (GetDirtyIssueHash, GetAllDependencyRecords, export hashes)","description":"Several utility functions have 0% coverage:\n- GetDirtyIssueHash (dirty.go)\n- GetAllDependencyRecords (dependencies.go)\n- GetExportHash, SetExportHash, ClearAllExportHashes (hash.go)\n\nThese are lower priority but should have basic coverage.","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-01T22:40:58.989976-07:00","updated_at":"2025-11-01T22:40:58.989976-07:00"}
{"id":"bd-1tw","title":"Fix G104 errors unhandled in internal/storage/sqlite/queries.go:1186","description":"Linting issue: G104: Errors unhandled (gosec) at internal/storage/sqlite/queries.go:1186:2. Error: rows.Close()","status":"open","issue_type":"bug","created_at":"2025-12-07T15:35:13.051671889-07:00","updated_at":"2025-12-07T15:35:13.051671889-07:00"}
{"id":"bd-fbj","title":"Implement tombstone types and schema migration","description":"Add tombstone fields to Issue struct (deleted_at, deleted_by, delete_reason, original_type), add StatusTombstone constant, create SQLite migration for new columns. Per design bd-2m7.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T15:14:38.250106-08:00","updated_at":"2025-12-05T15:28:50.361654-08:00","closed_at":"2025-12-05T15:28:50.361654-08:00"}
{"id":"bd-dmd","title":"Duplicate safety check message when confirmation required","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-12-02T21:55:50.204007-08:00","updated_at":"2025-12-02T22:08:09.569984-08:00","closed_at":"2025-12-02T22:08:09.569984-08:00"}
{"id":"bd-aydr.4","title":"Implement CLI command (cmd/bd/reset.go)","description":"Wire up the reset command with Cobra CLI.\n\n## Responsibilities\n- Define command and all flags\n- User confirmation prompt (unless --force)\n- Display impact summary before confirmation\n- Colored output and progress indicators\n- Call core reset package\n- Handle errors with user-friendly messages\n- Register command with rootCmd in init()\n\n## Flags\n```go\n--hard bool \"Also remove from git and commit\"\n--force bool \"Skip confirmation prompt\"\n--backup bool \"Create backup before reset\"\n--dry-run bool \"Preview what would happen\"\n--skip-init bool \"Do not re-initialize after reset\"\n--verbose bool \"Show detailed progress output\"\n```\n\n## Output Format\n```\n⚠ This will reset beads to a clean state.\n\nWill be deleted:\n • 47 issues (23 open, 24 closed)\n • 12 tombstones\n\nContinue? [y/N] y\n\n→ Stopping daemons... ✓\n→ Removing .beads/... ✓\n→ Initializing fresh... ✓\n\n✓ Reset complete. Run 'bd onboard' to set up hooks.\n```\n\n## Implementation Notes\n- Confirmation logic lives HERE, not in core package\n- Use color package (github.com/fatih/color) for output\n- Follow patterns from other commands (init.go, doctor.go)\n- Add to rootCmd in init() function\n\n## File Location\n`cmd/bd/reset.go`","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-13T08:44:54.318854+11:00","updated_at":"2025-12-13T10:13:32.611434+11:00","closed_at":"2025-12-13T09:59:41.72638+11:00","dependencies":[{"issue_id":"bd-aydr.4","depends_on_id":"bd-aydr","type":"parent-child","created_at":"2025-12-13T08:44:54.319237+11:00","created_by":"daemon"},{"issue_id":"bd-aydr.4","depends_on_id":"bd-aydr.1","type":"blocks","created_at":"2025-12-13T08:45:09.762138+11:00","created_by":"daemon"},{"issue_id":"bd-aydr.4","depends_on_id":"bd-aydr.2","type":"blocks","created_at":"2025-12-13T08:45:09.817854+11:00","created_by":"daemon"},{"issue_id":"bd-aydr.4","depends_on_id":"bd-aydr.3","type":"blocks","created_at":"2025-12-13T08:45:09.883658+11:00","created_by":"daemon"}]}
{"id":"bd-20j","title":"sync branch not match config","description":"./bd sync\n→ Exporting pending changes to JSONL...\n→ No changes to commit\n→ Pulling from sync branch 'gh-386'...\nError pulling from sync branch: failed to create worktree: failed to create worktree parent directory: mkdir /var/home/matt/dev/beads/worktree-db-fail/.git: not a directory\nmatt@blufin-framation ~/d/b/worktree-db-fail (worktree-db-fail) [1]\u003e bd config list\n\nConfiguration:\n auto_compact_enabled = false\n compact_batch_size = 50\n compact_model = claude-3-5-haiku-20241022\n compact_parallel_workers = 5\n compact_tier1_days = 30\n compact_tier1_dep_levels = 2\n compact_tier2_commits = 100\n compact_tier2_days = 90\n compact_tier2_dep_levels = 5\n compaction_enabled = false\n issue_prefix = worktree-db-fail\n sync.branch = worktree-db-fail","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-08T06:49:04.449094018-07:00","updated_at":"2025-12-08T06:49:04.449094018-07:00"}
{"id":"bd-a0cp","title":"Consider using types.Status in merge package for type safety","description":"The merge package uses string for status comparison (e.g., result.Status == closed, issue.Status == StatusTombstone). The types package defines Status as a type alias with validation. While the merge package needs its own Issue struct for JSONL flexibility, it could import and use types.Status for constants to get compile-time type checking. Current code: if left == closed || right == closed. Could be: if left == string(types.StatusClosed). This is low priority since string comparison works correctly. Files: internal/merge/merge.go:44, 488, 501-521","status":"open","priority":4,"issue_type":"task","created_at":"2025-12-05T16:37:10.690424-08:00","updated_at":"2025-12-05T16:37:10.690424-08:00"}
{"id":"bd-0ih","title":"Update 3-way merge to handle tombstones","description":"Modify internal/merge/merge.go to detect tombstones, implement tombstone-wins-unless-expired logic, add TTL parameter to merge functions. Per design bd-zvg.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T15:14:41.367004-08:00","updated_at":"2025-12-05T16:33:16.722162-08:00","closed_at":"2025-12-05T16:33:16.722162-08:00","dependencies":[{"issue_id":"bd-0ih","depends_on_id":"bd-fbj","type":"blocks","created_at":"2025-12-05T15:14:58.784343-08:00","created_by":"daemon"},{"issue_id":"bd-0ih","depends_on_id":"bd-olt","type":"blocks","created_at":"2025-12-05T15:14:58.82323-08:00","created_by":"daemon"}]}
{"id":"bd-cbed9619.2","title":"Implement content-first idempotent import","description":"## Overview\nPhase 4: Refactor import to be content-first and idempotent, ensuring importing same JSONL multiple times always converges correctly.\n\n## Current Problem\nCurrent import is ID-first:\n1. Look up by ID\n2. If exists, update\n3. If not exists, create\n\nThis causes issues when:\n- Same content arrives with different IDs (renames not detected)\n- Multiple rounds of import needed for convergence\n- Import order affects final state\n\n## Solution\nMake import content-first and idempotent:\n1. Hash all incoming and existing issues\n2. Match by content hash first (detect renames)\n3. Handle ID conflicts second (using global resolution)\n4. Ensure importing same data multiple times = no-op\n\n## Implementation Tasks\n\n### 1. Refactor ImportIssues to be content-first\nFile: internal/importer/importer.go\n\n```go\nfunc ImportIssues(ctx context.Context, dbPath string, store storage.Storage, \n issues []*types.Issue, opts Options) (*Result, error) {\n \n result := \u0026Result{...}\n \n sqliteStore, needCloseStore, err := getOrCreateStore(ctx, dbPath, store)\n if err != nil {\n return nil, err\n }\n if needCloseStore {\n defer func() { _ = sqliteStore.Close() }()\n }\n \n // Phase 1: Compute content hashes for all incoming issues\n for _, issue := range issues {\n issue.ContentHash = issue.ComputeContentHash()\n }\n \n // Phase 2: Build content hash maps\n incomingByHash := buildHashMap(issues)\n dbIssues, _ := sqliteStore.SearchIssues(ctx, \"\", types.IssueFilter{})\n dbByHash := buildHashMap(dbIssues)\n dbByID := buildIDMap(dbIssues)\n \n // Phase 3: Content-first matching\n var newIssues []*types.Issue\n var idConflicts []*CollisionDetail\n \n for hash, incoming := range incomingByHash {\n if existing, found := dbByHash[hash]; found {\n // Same content exists\n if existing.ID == incoming.ID {\n // Exact match - idempotent case\n result.Unchanged++\n } else {\n // Same content, different ID - rename detected\n // Delete old ID, keep new ID (incoming is canonical)\n if err := handleRename(ctx, sqliteStore, existing, incoming); err != nil {\n return nil, err\n }\n result.Updated++\n }\n } else {\n // New content - check for ID collision\n if existingWithID, found := dbByID[incoming.ID]; found {\n // ID exists but different content - collision\n idConflicts = append(idConflicts, \u0026CollisionDetail{\n ID: incoming.ID,\n IncomingIssue: incoming,\n ExistingIssue: existingWithID,\n })\n } else {\n // Truly new issue\n newIssues = append(newIssues, incoming)\n }\n }\n }\n \n // Phase 4: Resolve ID conflicts using global algorithm\n if len(idConflicts) \u003e 0 {\n if !opts.ResolveCollisions {\n return nil, fmt.Errorf(\"collision detected\")\n }\n \n idMapping, err := sqlite.ResolveNWayCollisions(ctx, sqliteStore, \n idConflicts, issues)\n if err != nil {\n return nil, err\n }\n \n if err := applyIDMapping(ctx, sqliteStore, idMapping); err != nil {\n return nil, err\n }\n \n result.IDMapping = idMapping\n result.Collisions = len(idConflicts)\n }\n \n // Phase 5: Create new issues\n if len(newIssues) \u003e 0 {\n if err := sqliteStore.CreateIssues(ctx, newIssues, \"import\"); err != nil {\n return nil, err\n }\n result.Created = len(newIssues)\n }\n \n // Phase 6: Import dependencies, labels, comments (existing logic)\n // ...\n \n return result, nil\n}\n```\n\n### 2. Implement helper functions\n\n```go\n// buildHashMap creates a map of content hash → issue\nfunc buildHashMap(issues []*types.Issue) map[string]*types.Issue {\n result := make(map[string]*types.Issue)\n for _, issue := range issues {\n result[issue.ContentHash] = issue\n }\n return result\n}\n\n// buildIDMap creates a map of ID → issue\nfunc buildIDMap(issues []*types.Issue) map[string]*types.Issue {\n result := make(map[string]*types.Issue)\n for _, issue := range issues {\n result[issue.ID] = issue\n }\n return result\n}\n\n// handleRename handles content match with different IDs\nfunc handleRename(ctx context.Context, s *SQLiteStorage, \n existing *types.Issue, incoming *types.Issue) error {\n \n // Delete old ID\n if err := s.DeleteIssue(ctx, existing.ID); err != nil {\n return fmt.Errorf(\"failed to delete old ID %s: %w\", existing.ID, err)\n }\n \n // Create with new ID\n if err := s.CreateIssue(ctx, incoming, \"import-rename\"); err != nil {\n return fmt.Errorf(\"failed to create renamed issue %s: %w\", \n incoming.ID, err)\n }\n \n // Update references from old ID to new ID\n idMapping := map[string]string{existing.ID: incoming.ID}\n return updateReferences(ctx, s, idMapping)\n}\n```\n\n### 3. Add idempotency tests\n\nTest cases:\n1. Import same JSONL twice → second import reports all Unchanged\n2. Import, modify DB, import again → reports Updated\n3. Import with rename, import again → idempotent\n4. Import with collision resolution, import again → idempotent\n\n### 4. Update handleCollisions to use new flow\nCurrent handleCollisions in importer.go needs to be updated to:\n- Use content-first matching\n- Call new ResolveNWayCollisions\n- Apply results using ApplyCollisionResolution\n\n## Acceptance Criteria\n- Import matches by content hash before checking IDs\n- Importing same JSONL multiple times is idempotent (reports Unchanged)\n- Rename detection works (same content, different ID)\n- ID conflicts resolved using global algorithm\n- Result.Unchanged correctly tracks idempotent imports\n- TestThreeCloneCollision passes\n- All existing import tests still pass\n\n## Testing Strategy\n\n### Unit Tests\n- buildHashMap correctly indexes by content hash\n- buildIDMap correctly indexes by ID\n- handleRename deletes old, creates new, updates references\n\n### Integration Tests\n- Import same data twice → idempotent\n- Import renamed issue → handled correctly\n- Import with collision → resolved globally\n- Final pull after 3-way collision → all clones converge\n\n### Property Tests\n- Idempotency: Import(x); Import(x) ≡ Import(x)\n- Commutativity: Import(a); Import(b) ≡ Import(b); Import(a) (for non-colliding issues)\n- Convergence: After N rounds of sync, all clones identical\n\n## Files to Modify\n- internal/importer/importer.go (major refactor of ImportIssues)\n- internal/importer/importer_test.go (new tests)\n- cmd/bd/import_bug_test.go (update for new behavior)\n\n## Dependencies\n- Requires bd-cbed9619.5 (ContentHash field)\n- Requires bd-cbed9619.4 (read-only detection)\n- Requires bd-cbed9619.3 (global resolution)\n\n## Risk Mitigation\nMajor refactor of import logic. Recommend:\n1. Comprehensive tests before modifying\n2. Feature flag to enable/disable\n3. Keep old import code path for rollback\n4. Test with all existing import tests\n5. Manual testing with real repositories\n\n## Success Metrics\nAfter this phase:\n- TestThreeCloneCollision should PASS\n- All clones converge after final pull\n- Import is demonstrably idempotent\n- No data loss in N-way scenarios","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T18:38:25.671302-07:00","updated_at":"2025-10-30T17:12:58.229134-07:00","closed_at":"2025-10-28T20:21:39.529971-07:00","dependencies":[{"issue_id":"bd-cbed9619.2","depends_on_id":"bd-325da116","type":"parent-child","created_at":"2025-10-28T18:39:20.616846-07:00","created_by":"daemon"},{"issue_id":"bd-cbed9619.2","depends_on_id":"bd-cbed9619.5","type":"blocks","created_at":"2025-10-28T18:39:28.360026-07:00","created_by":"daemon"},{"issue_id":"bd-cbed9619.2","depends_on_id":"bd-cbed9619.4","type":"blocks","created_at":"2025-10-28T18:39:28.383624-07:00","created_by":"daemon"},{"issue_id":"bd-cbed9619.2","depends_on_id":"bd-cbed9619.3","type":"blocks","created_at":"2025-10-28T18:39:28.407157-07:00","created_by":"daemon"}]}
{"id":"bd-hlsw.3","title":"Auto-recovery mode (bd sync --auto-recover)","description":"Add bd sync --auto-recover flag that: detects problematic sync state, backs up .beads/issues.db with timestamp, rebuilds DB from JSONL atomically, verifies consistency, reports what was fixed. Provides safety valve when sync integrity fails.","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-14T10:40:20.599836875-07:00","updated_at":"2025-12-14T10:40:20.599836875-07:00","dependencies":[{"issue_id":"bd-hlsw.3","depends_on_id":"bd-hlsw","type":"parent-child","created_at":"2025-12-14T10:40:20.600435888-07:00","created_by":"daemon"}]}
{"id":"bd-eyto","title":"Time-dependent tests may be flaky near TTL boundary","description":"Several tombstone merge tests use time.Now() to create test data: time.Now().Add(-24 * time.Hour), time.Now().Add(-60 * 24 * time.Hour), etc. While these work reliably in practice (24h vs 30d TTL has large margin), they could theoretically be flaky if: 1) Tests run slowly, 2) System clock changes during test, 3) TTL constants change. Recommendation: Consider using a fixed reference time or time injection for deterministic tests. Lower priority since current margin is large. Files: internal/merge/merge_test.go:1337-1338, 1352-1353, 1548-1549, 1590-1591","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-05T16:37:02.348143-08:00","updated_at":"2025-12-05T16:37:02.348143-08:00"}
{"id":"bd-aydr","title":"Add bd reset command for clean slate restart","description":"Implement a `bd reset` command to reset beads to a clean starting state.\n\n## Context\nGitHub issue #479 - users sometimes get beads into an invalid state after updates, and there's no clean way to start fresh. The git backup/restore mechanism that protects against accidental deletion also makes it hard to intentionally reset.\n\n## Design\n\n### Command Interface\n```\nbd reset [--hard] [--force] [--backup] [--dry-run] [--no-init]\n```\n\n| Flag | Effect |\n|------|--------|\n| `--hard` | Also remove from git index and commit |\n| `--force` | Skip confirmation prompt |\n| `--backup` | Create `.beads-backup-{timestamp}/` first |\n| `--dry-run` | Preview what would happen |\n| `--no-init` | Don't re-initialize after clearing |\n\n### Reset Levels\n1. **Soft Reset (default)** - Kill daemons, clear .beads/, re-init. Git history unchanged.\n2. **Hard Reset (`--hard`)** - Also git rm and commit the removal, then commit fresh state.\n\n### Implementation Flow\n1. Validate .beads/ exists\n2. If not --force: show impact summary, prompt confirmation\n3. If --backup: copy .beads/ to .beads-backup-{timestamp}/\n4. Kill daemons\n5. If --hard: git rm + commit\n6. rm -rf .beads/*\n7. If not --no-init: bd init (and git add+commit if --hard)\n8. Print summary\n\n### Safety Mechanisms\n- Confirmation prompt (skip with --force)\n- Impact summary (issue/tombstone counts)\n- Backup option\n- Dry-run preview\n- Git dirty check warning\n\n### Code Structure\n- `cmd/bd/reset.go` - CLI command\n- `internal/reset/` - Core logic package","status":"closed","priority":2,"issue_type":"epic","created_at":"2025-12-13T08:44:01.38379+11:00","updated_at":"2025-12-13T06:24:29.561294-08:00","closed_at":"2025-12-13T10:18:19.965287+11:00"}
{"id":"bd-6rl","title":"Merge3Way public API does not expose TTL parameter","description":"The public Merge3Way() function in merge.go does not allow callers to configure the tombstone TTL. It hard-codes the default via merge3WayWithTTL(). While merge3WayWithTTL() exists, it is unexported (lowercase). This means the CLI and tests cannot configure TTL at merge time. Use cases: testing with different TTL values, per-repository TTL configuration, debugging with short TTL, supporting --ttl flag in bd merge command (mentioned in design doc bd-zvg). Recommendation: Export Merge3WayWithTTL (rename to uppercase). Files: internal/merge/merge.go:77, 292-298","status":"open","priority":3,"issue_type":"feature","created_at":"2025-12-05T16:36:15.756814-08:00","updated_at":"2025-12-05T16:36:15.756814-08:00"}
{"id":"bd-eeqf","title":"GH#486: Claude forgets beads workflow mid-session","description":"Claude progressively reverts to TodoWrite or skips tracking despite CLAUDE.md instructions. Happens after context resets or long sessions. Need stronger prompting or hooks. See: https://github.com/steveyegge/beads/issues/486","status":"in_progress","priority":2,"issue_type":"bug","created_at":"2025-12-14T16:32:21.544338-08:00","updated_at":"2025-12-14T16:52:49.797933-08:00"}
{"id":"bd-nyt","title":"Update GetStatistics to report tombstone count separately","description":"Per bd-2m7 design: 'Should tombstones appear in bd stats? Recommendation: Yes, as separate counter: 5 deleted (tombstones)'\n\nCurrently GetStatistics counts tombstones in TotalIssues without distinguishing them.\n\nLocation: internal/storage/sqlite/events.go:114-121\n\nAdd to Statistics struct and query:\n- DeletedIssues (tombstone count)\n- Exclude tombstones from TotalIssues or document that it includes them","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-05T15:35:38.007301-08:00","updated_at":"2025-12-05T15:48:07.605518-08:00","closed_at":"2025-12-05T15:48:07.605518-08:00","dependencies":[{"issue_id":"bd-nyt","depends_on_id":"bd-vw8","type":"parent-child","created_at":"2025-12-05T15:35:47.297871-08:00","created_by":"daemon"}]}
{"id":"bd-okh","title":"Update bd compact to prune expired tombstones","description":"Modify compaction to identify and remove expired tombstones from issues.jsonl. Report count of removed tombstones. Per design bd-1r5.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-05T15:14:48.133062-08:00","updated_at":"2025-12-13T09:42:56.870704+11:00","closed_at":"2025-12-07T02:33:32.02985-08:00","dependencies":[{"issue_id":"bd-okh","depends_on_id":"bd-olt","type":"blocks","created_at":"2025-12-05T15:14:59.042761-08:00","created_by":"daemon"}]}
{"id":"bd-2rfr","title":"GH#505: Add bd reset command to wipe database","description":"Users struggle to fully reset beads (local + remote). Need bd reset command with safety confirmation. Currently requires manual hook/dir removal. See: https://github.com/steveyegge/beads/issues/505","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2025-12-14T16:32:02.919494-08:00","updated_at":"2025-12-14T16:52:49.799898-08:00"}
{"id":"bd-aydr.7","title":"Add integration tests for bd reset command","description":"End-to-end integration tests for the reset command.\n\n## Test Scenarios\n\n### Basic reset\n1. Init beads, create some issues\n2. Run bd reset --force\n3. Verify .beads/ is fresh, issues gone\n\n### Hard reset\n1. Init beads, create issues, commit\n2. Run bd reset --hard --force \n3. Verify git history has reset commits\n\n### Backup functionality\n1. Init beads, create issues\n2. Run bd reset --backup --force\n3. Verify backup exists with correct contents\n4. Verify main .beads/ is reset\n\n### Dry run\n1. Init beads, create issues\n2. Run bd reset --dry-run\n3. Verify nothing changed\n\n### Confirmation prompt\n1. Init beads\n2. Run bd reset (no --force)\n3. Verify prompts for confirmation\n4. Test both y and n responses\n\n## Location\ntests/integration/reset_test.go or similar","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-13T08:44:58.479282+11:00","updated_at":"2025-12-13T06:24:29.561908-08:00","closed_at":"2025-12-13T10:15:59.221637+11:00","dependencies":[{"issue_id":"bd-aydr.7","depends_on_id":"bd-aydr","type":"parent-child","created_at":"2025-12-13T08:44:58.479686+11:00","created_by":"daemon"},{"issue_id":"bd-aydr.7","depends_on_id":"bd-aydr.4","type":"blocks","created_at":"2025-12-13T08:45:11.15972+11:00","created_by":"daemon"}]}
{"id":"bd-aec5439f","title":"Update LINTING.md with current baseline","description":"After cleanup, document the remaining acceptable baseline in LINTING.md so we can track regression.","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-27T18:53:10.38679-07:00","updated_at":"2025-10-30T17:12:58.194901-07:00"}
{"id":"bd-in6","title":"CONFIG.md docs for sync.require_confirmation_on_mass_delete missing threshold detail","description":"The docs say 'if \u003e50% of issues vanish' but the actual code (worktree.go:380) also requires '\u003e5 issues existed before'. The docs should mention both conditions for completeness.","status":"closed","priority":4,"issue_type":"task","created_at":"2025-12-02T22:29:56.753032-08:00","updated_at":"2025-12-02T22:40:37.385126-08:00","closed_at":"2025-12-02T22:40:37.385126-08:00"}
{"id":"bd-bx9","title":"bd init --contributor should configure sync.remote=upstream for fork workflows","description":"When running `bd init --contributor` in a fork workflow (where `upstream` remote points to the original repo), the wizard should configure beads to sync from `upstream/main` rather than `origin/main`.\n\n**Current behavior:**\n- Contributor mode detects the fork setup (upstream remote exists)\n- Sets up planning repo and auto-routing\n- Does NOT configure sync remote\n- `bd sync` on feature branches shows \"No upstream configured, using --from-main mode\" and syncs from `origin/main`\n\n**Expected behavior:**\n- Contributor mode should also set `sync.remote = upstream` (or similar config)\n- `bd sync` should pull beads from `upstream/main` (source of truth)\n\n**Why this matters:**\n- The fork's `origin/main` may be behind `upstream/main`\n- Contributors want the latest issues from the source repo\n- Code PRs go: local -\u003e origin -\u003e upstream, but beads should come FROM upstream\n\n**Suggested fix:**\nAdd to `runContributorWizard()` after detecting fork:\n```go\nif isFork {\n store.SetConfig(ctx, \"sync.remote\", \"upstream\")\n}\n```","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-29T00:39:05.137488727-05:00","updated_at":"2025-11-29T23:23:01.219117-08:00","closed_at":"2025-11-29T23:22:57.631519-08:00"}
{"id":"bd-md2","title":"Add tombstone validation: require deleted_at for tombstone status","description":"ValidateWithCustomStatuses() doesn't enforce that tombstones must have deleted_at set. Per bd-2m7 design: 'If status == tombstone, then deleted_at MUST be set'. Also should validate that non-tombstones cannot have deleted_at set.\n\nLocation: internal/types/types.go:109-114\n\nAdd validation:\n- if i.Status == StatusTombstone \u0026\u0026 i.DeletedAt == nil: error\n- if i.Status != StatusTombstone \u0026\u0026 i.DeletedAt != nil: error","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-05T15:35:29.458545-08:00","updated_at":"2025-12-05T15:41:14.804544-08:00","closed_at":"2025-12-05T15:41:14.804544-08:00","dependencies":[{"issue_id":"bd-md2","depends_on_id":"bd-vw8","type":"parent-child","created_at":"2025-12-05T15:35:47.141085-08:00","created_by":"daemon"}]}
{"id":"bd-3xl","title":"bd doctor: per-fix confirmation mode","description":"Add an interactive mode where users can approve/reject each fix individually rather than all-or-nothing. Currently --fix prompts once for all fixes. This would give users more control over which repairs to apply, especially useful when some fixes may have side effects.","status":"closed","priority":4,"issue_type":"feature","created_at":"2025-12-02T12:52:38.137201-08:00","updated_at":"2025-12-03T22:17:11.405848-08:00","closed_at":"2025-12-03T22:17:11.405848-08:00"}
{"id":"bd-yk8w","title":"Add export test verifying tombstones are included in JSONL output","description":"The export now includes tombstones (bd-dve) but there's no test that:\n1. Creates issues in DB including a tombstone\n2. Runs export\n3. Verifies the JSONL contains the tombstone with all fields\n\nAdd a test: TestExportIncludesTombstones","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T01:41:19.987907-08:00","updated_at":"2025-12-07T02:16:16.882688-08:00","closed_at":"2025-12-07T02:16:16.882688-08:00","dependencies":[{"issue_id":"bd-yk8w","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-07T01:41:28.426945-08:00","created_by":"daemon"}]}
{"id":"bd-29c128e8","title":"Update AGENTS.md with event-driven mode","description":"Document BEADS_DAEMON_MODE env var. Explain opt-in during Phase 1. Add troubleshooting for watcher failures.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-28T16:20:02.433145-07:00","updated_at":"2025-10-30T17:12:58.223058-07:00","closed_at":"2025-10-29T15:53:24.019613-07:00"}
{"id":"bd-s3v","title":"Add tombstone doctor checks","description":"Add bd doctor checks for: unmigrated deletions.jsonl, stale deletions.jsonl in Phase 3, tombstones expiring soon. Per design bd-dli.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-05T15:14:46.733558-08:00","updated_at":"2025-12-13T13:26:00.765736-08:00","closed_at":"2025-12-13T10:15:38.981577-08:00","dependencies":[{"issue_id":"bd-s3v","depends_on_id":"bd-8f9","type":"blocks","created_at":"2025-12-05T15:14:59.006029-08:00","created_by":"daemon"}]}
{"id":"bd-r6k2","title":"Fragile no-db detection uses strings.Contains instead of YAML parsing","description":"Two locations use `strings.Contains(string(configData), \"no-db: true\")` to detect JSONL-only mode:\n\n1. **cmd/bd/main.go:310** - Auto-enabling no-db mode\n2. **cmd/bd/doctor.go:863** - Database status check\n\nThis is fragile because it could match:\n- Comments: `# no-db: true for testing`\n- Nested keys: `settings:\\n no-db: true`\n- String values: `note: \"set no-db: true to disable\"`\n\nShould use proper YAML parsing like we did for sync-branch in bd-0rh:\n\n```go\ntype noDbConfig struct {\n NoDb bool `yaml:\"no-db\"`\n}\n\nvar cfg noDbConfig\nif err := yaml.Unmarshal(configData, \u0026cfg); err == nil {\n isNoDbMode = cfg.NoDb\n}\n```\n\nRelated: bd-0rh (fixed similar issue for sync-branch)","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-12-07T02:03:12.120296-08:00","updated_at":"2025-12-07T02:09:30.628372-08:00","closed_at":"2025-12-07T02:09:30.628372-08:00","dependencies":[{"issue_id":"bd-r6k2","depends_on_id":"bd-0rh","type":"discovered-from","created_at":"2025-12-07T02:03:50.599423-08:00","created_by":"daemon"}]}
{"id":"bd-olt","title":"Implement tombstone TTL and expiration logic","description":"Add IsExpired() method to tombstones, implement TTL config reading from config.yaml, add clock skew grace period. Per design bd-1r5.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T15:14:40.074707-08:00","updated_at":"2025-12-05T16:19:21.727851-08:00","closed_at":"2025-12-05T16:19:21.727851-08:00","dependencies":[{"issue_id":"bd-olt","depends_on_id":"bd-fbj","type":"blocks","created_at":"2025-12-05T15:14:58.744319-08:00","created_by":"daemon"}]}
{"id":"bd-a15d","title":"Add test files for internal/storage","description":"The internal/storage package has no test files at all. This package provides the storage interface abstraction.\n\nCurrent coverage: N/A (no test files)\nTarget: Add basic interface tests","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-13T20:43:11.363017-08:00","updated_at":"2025-12-13T21:01:20.925779-08:00"}