From 1c5dc7fc937f28ec1a3700d4d5e9d764b0e7a59d Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Sun, 2 Nov 2025 11:17:39 -0800 Subject: [PATCH] bd sync: 2025-11-02 11:17:39 --- .beads/beads.jsonl | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.beads/beads.jsonl b/.beads/beads.jsonl index b5e2d2d5..2fa433ca 100644 --- a/.beads/beads.jsonl +++ b/.beads/beads.jsonl @@ -1,7 +1,7 @@ {"id":"bd-0134cc5a","content_hash":"d45c0e44c01c5855f14f07693bd800f4bfeac3084e10ceb17970ff54c58f6a40","title":"Fix auto-import creating duplicates instead of updating issues","description":"ROOT CAUSE: server_export_import_auto.go line 221 uses ResolveCollisions: true for ALL auto-imports. This is wrong.\n\nProblem:\n- ResolveCollisions is for branch merges (different issues with same ID)\n- Auto-import should UPDATE existing issues, not create duplicates\n- Every git pull creates NEW duplicate issues with different IDs\n- Two agents ping-pong creating endless duplicates\n\nEvidence:\n- 31 duplicate groups found (bd duplicates)\n- bd-236-246 are duplicates of bd-224-235\n- Both agents keep pulling and creating more duplicates\n- JSONL file grows endlessly with duplicates\n\nThe Fix:\nChange checkAndAutoImportIfStale in server_export_import_auto.go:\n- Remove ResolveCollisions: true (line 221)\n- Use normal import logic that updates existing issues by ID\n- Only use ResolveCollisions for explicit bd import --resolve-collisions\n\nImpact: Critical - makes beads unusable for multi-agent workflows","acceptance_criteria":"- Auto-import does NOT create duplicates when pulling git changes\n- Existing issues are updated in-place by ID match\n- No ping-pong commits between agents\n- Test: two agents updating same issue should NOT create duplicates\n- bd duplicates shows 0 groups after fix","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-27T21:48:57.733846-07:00","updated_at":"2025-10-30T17:12:58.21084-07:00","closed_at":"2025-10-27T22:26:40.627239-07:00"} {"id":"bd-0447029c","content_hash":"f32f7d8f0b07aaaeb9d07d8a1d000eef8fc79cf864e8aa20ebb899f6e359ebda","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":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T16:43:28.182327-07:00","updated_at":"2025-10-30T17:12:58.188016-07:00","closed_at":"2025-10-29T16:15:10.64719-07:00"} -{"id":"bd-0458","content_hash":"7503fa7f4b0b10c9b22e20ee8e0b8d691397979e89275d8e2efd3c0c0f7cbcb6","title":"Consolidate export/import/commit/push into sync.go","description":"Create internal/daemonrunner/sync.go with Syncer type. Add ExportOnce, ImportOnce, CommitAndMaybePush methods. Replace createExportFunc/createAutoImportFunc with thin closures calling Syncer.","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-01T11:41:14.874539-07:00","updated_at":"2025-11-01T11:41:14.874539-07:00"} -{"id":"bd-05a1","content_hash":"ffa9764c3c65d13af6d9c54b691b57541a66bf3d266b1e11c5172cd09a32e1f5","title":"Isolate RPC server startup into rpc_server.go","description":"Create internal/daemonrunner/rpc_server.go with StartRPC function. Move startRPCServer logic here and return typed handle.","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-01T11:41:14.876839-07:00","updated_at":"2025-11-01T11:41:14.876839-07:00"} +{"id":"bd-0458","content_hash":"7503fa7f4b0b10c9b22e20ee8e0b8d691397979e89275d8e2efd3c0c0f7cbcb6","title":"Consolidate export/import/commit/push into sync.go","description":"Create internal/daemonrunner/sync.go with Syncer type. Add ExportOnce, ImportOnce, CommitAndMaybePush methods. Replace createExportFunc/createAutoImportFunc with thin closures calling Syncer.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T11:41:14.874539-07:00","updated_at":"2025-11-01T22:56:08.364335-07:00","closed_at":"2025-11-01T22:56:08.364335-07:00"} +{"id":"bd-05a1","content_hash":"ffa9764c3c65d13af6d9c54b691b57541a66bf3d266b1e11c5172cd09a32e1f5","title":"Isolate RPC server startup into rpc_server.go","description":"Create internal/daemonrunner/rpc_server.go with StartRPC function. Move startRPCServer logic here and return typed handle.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T11:41:14.876839-07:00","updated_at":"2025-11-01T22:56:08.362581-07:00","closed_at":"2025-11-01T22:56:08.362581-07:00"} {"id":"bd-0650a73b","content_hash":"a596aa8d6114d4938471e181ebc30da5d0315f74fd711a92dbbb83f5d0e7af88","title":"Create cmd/bd/daemon_debouncer.go (~60 LOC)","description":"Implement Debouncer to batch rapid events into single action. Default 500ms, configurable via BEADS_DEBOUNCE_MS. Thread-safe with mutex.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T16:20:02.431118-07:00","updated_at":"2025-10-30T17:12:58.221711-07:00","closed_at":"2025-10-28T12:03:35.614191-07:00"} {"id":"bd-06aec0c3","content_hash":"330e69cf6ca40209948559b453ed5242c15a71b5c949a858ad6854488b12dca2","title":"Integration Testing","description":"Verify cache removal doesn't break any workflows","acceptance_criteria":"- All test cases pass\n- No stale data observed\n- Performance is same or better\n- MCP works as before\n\nTest cases:\n1. Basic daemon operations (bd daemon --stop, bd daemon, bd list, bd create, bd show)\n2. Auto-import/export cycle (edit beads.jsonl externally, bd list auto-imports)\n3. Git workflow (git pull updates beads.jsonl, bd list shows pulled issues)\n4. Concurrent operations (multiple bd commands simultaneously)\n5. Daemon health (bd daemon --health, bd daemon --metrics)\n6. MCP operations (test MCP server with multiple repos, verify project switching)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T10:50:15.126668-07:00","updated_at":"2025-10-30T17:12:58.217214-07:00","closed_at":"2025-10-28T10:49:20.471129-07:00"} {"id":"bd-0702","content_hash":"7d338a7ecc544ac818bb49f32654bba946e34383a8e27e2cb8181be0fcf93282","title":"Consolidate ID generation and validation into ids.go","description":"Extract ID logic into ids.go: ValidateIssueIDPrefix, GenerateIssueID, EnsureIDs. Move GetAdaptiveIDLength here. Unify single and bulk ID generation flows.","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-01T11:41:14.877886-07:00","updated_at":"2025-11-01T11:41:14.877886-07:00"} @@ -12,7 +12,7 @@ {"id":"bd-0dcea000","content_hash":"a6fc218b07d270e3498957525c39a869f7c850d687339b6d758a246be20c9591","title":"Add tests for internal/importer package","description":"Currently 0.0% coverage. Need tests for JSONL import logic including collision detection and resolution.","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-29T14:06:21.071024-07:00","updated_at":"2025-10-30T17:12:58.183211-07:00","dependencies":[{"issue_id":"bd-0dcea000","depends_on_id":"bd-cbed9619.5","type":"blocks","created_at":"2025-10-29T19:52:05.531279-07:00","created_by":"import-remap"},{"issue_id":"bd-0dcea000","depends_on_id":"bd-cbed9619.4","type":"blocks","created_at":"2025-10-29T19:52:05.53166-07:00","created_by":"import-remap"}]} {"id":"bd-0e1f2b1b","content_hash":"c0b1677fe3f4aa3f395ae4d79bff5362632d5db26477bf571c09f9177b8741ef","title":"Event-driven daemon architecture","description":"Replace 5-second polling sync loop with event-driven architecture that reacts instantly to changes. Eliminates stale data issues while reducing CPU ~60%. Key components: FileWatcher (fsnotify), Debouncer (500ms), RPC mutation events, optional git hooks. Target latency: \u003c500ms (vs 5000ms). See event_driven_daemon.md for full design.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-28T16:20:02.430479-07:00","updated_at":"2025-10-30T17:12:58.221424-07:00","closed_at":"2025-10-28T16:30:26.631191-07:00"} {"id":"bd-11e0","content_hash":"591db3f5674cf7f79b1f50d6b8d83fe60e495f02a21e181c9c63d8da88308d58","title":"Database import silently fails when daemon version != CLI version","description":"","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-31T21:08:09.096749-07:00","updated_at":"2025-11-01T19:29:35.267817-07:00","closed_at":"2025-11-01T19:29:35.267817-07:00"} -{"id":"bd-1231","content_hash":"c9545032de3b8fb5da54edc4951253d7ac47e5c96677fc412b8c785e56ec8f32","title":"CI failing on all 3/4 test jobs despite individual tests passing","description":"CI has been broken for a day+ with mysterious test failures. Issue #173 on GitHub tracks this.\n\n## Current Status\n- **Lint job**: ✅ PASSING\n- **Test (Linux)**: ❌ FAILING (exit code 1)\n- **Test (Windows)**: ❌ FAILING (exit code 1)\n- **Test Nix Flake**: ❌ FAILING (exit code 1)\n\n## Key Observations\nAll three failing jobs show identical pattern:\n- Individual test output shows PASS for every test\n- Final result: `FAIL github.com/steveyegge/beads/cmd/bd`\n- Exit code 1 despite no visible test failures\n- Last visible test output before failure: \"No Reason Issue\" test (TestCloseCommand/close_without_reason)\n\n## Investigation So Far\n1. All tests appear to pass when examined individually\n2. Likely causes:\n - Race detector finding data races during test cleanup (`-race` flag)\n - Panic/error occurring after main tests complete\n - Test harness issue not reporting actual failure\n - Possible regression from PR #203 (dependency_type changes)\n\n## Recent CI Runs\n- Run 19015040655 (latest): 3/4 failing\n- Multiple recent commits tried to fix Windows/lint issues\n- Agent on rrnewton/beads fork attempting fixes (2/4 passing there)\n\n## Next Steps\n1. Run tests locally with `-race -v` to see full output\n2. Check for unreported test failures or panics\n3. Examine test cleanup/teardown code\n4. Review recent changes around close command tests\n5. Consider if race detector is too sensitive or catching real issues","notes":"## Progress Update\n\n### ✅ Fixed (commits 09bd4d3, 21a29bc)\n1. **Daemon auto-import** - Always recompute content_hash in importer to avoid stale hashes\n2. **TestScripts failures** - Added bd binary to PATH for shell subprocess tests\n3. **Test infrastructure** - Added .gitignore to test repos, fixed last_import_time metadata\n\n### ✅ CI Status (Run 19015638968)\n- **Test (Linux)**: ✅ SUCCESS - All tests passing\n- **Test (Windows)**: ❌ FAILURE - Pre-existing Windows test failures\n- **Test Nix Flake**: ❌ FAILURE - Build fails with same test errors\n- **Lint**: ❌ FAILURE - Pre-existing issue in migrate.go:647\n\n### ❌ Remaining Issues (not related to original bd-1231)\n\n**Windows failures:**\n- TestFindDatabasePathEnvVar\n- TestHashIDs_MultiCloneConverge \n- TestHashIDs_IdenticalContentDedup\n- TestDatabaseReinitialization (5 subtests)\n- TestFindBeadsDir_NotFound\n- TestMetricsSnapshot/uptime\n\n**Lint failure:**\n- cmd/bd/migrate.go:647:37: cleanupWALFiles - result 0 (error) is always nil (unparam)\n\n**Nix failure:**\n- Build fails during test phase with same test errors\n\n### Next Steps\n1. Investigate Windows-specific test failures\n2. Fix linting issue in migrate.go\n3. Debug Nix build test failures","status":"open","priority":0,"issue_type":"bug","created_at":"2025-11-02T08:42:16.142128-08:00","updated_at":"2025-11-02T09:29:15.199328-08:00","external_ref":"https://github.com/steveyegge/beads/issues/173"} +{"id":"bd-1231","content_hash":"c9545032de3b8fb5da54edc4951253d7ac47e5c96677fc412b8c785e56ec8f32","title":"CI failing on all 3/4 test jobs despite individual tests passing","description":"CI has been broken for a day+ with mysterious test failures. Issue #173 on GitHub tracks this.\n\n## Current Status\n- **Lint job**: ✅ PASSING\n- **Test (Linux)**: ❌ FAILING (exit code 1)\n- **Test (Windows)**: ❌ FAILING (exit code 1)\n- **Test Nix Flake**: ❌ FAILING (exit code 1)\n\n## Key Observations\nAll three failing jobs show identical pattern:\n- Individual test output shows PASS for every test\n- Final result: `FAIL github.com/steveyegge/beads/cmd/bd`\n- Exit code 1 despite no visible test failures\n- Last visible test output before failure: \"No Reason Issue\" test (TestCloseCommand/close_without_reason)\n\n## Investigation So Far\n1. All tests appear to pass when examined individually\n2. Likely causes:\n - Race detector finding data races during test cleanup (`-race` flag)\n - Panic/error occurring after main tests complete\n - Test harness issue not reporting actual failure\n - Possible regression from PR #203 (dependency_type changes)\n\n## Recent CI Runs\n- Run 19015040655 (latest): 3/4 failing\n- Multiple recent commits tried to fix Windows/lint issues\n- Agent on rrnewton/beads fork attempting fixes (2/4 passing there)\n\n## Next Steps\n1. Run tests locally with `-race -v` to see full output\n2. Check for unreported test failures or panics\n3. Examine test cleanup/teardown code\n4. Review recent changes around close command tests\n5. Consider if race detector is too sensitive or catching real issues","notes":"## Progress Update\n\n### ✅ Fixed (commits 09bd4d3, 21a29bc)\n1. **Daemon auto-import** - Always recompute content_hash in importer to avoid stale hashes\n2. **TestScripts failures** - Added bd binary to PATH for shell subprocess tests\n3. **Test infrastructure** - Added .gitignore to test repos, fixed last_import_time metadata\n\n### ✅ CI Status (Run 19015638968)\n- **Test (Linux)**: ✅ SUCCESS - All tests passing\n- **Test (Windows)**: ❌ FAILURE - Pre-existing Windows test failures\n- **Test Nix Flake**: ❌ FAILURE - Build fails with same test errors\n- **Lint**: ❌ FAILURE - Pre-existing issue in migrate.go:647\n\n### ❌ Remaining Issues (not related to original bd-1231)\n\n**Windows failures:**\n- TestFindDatabasePathEnvVar\n- TestHashIDs_MultiCloneConverge \n- TestHashIDs_IdenticalContentDedup\n- TestDatabaseReinitialization (5 subtests)\n- TestFindBeadsDir_NotFound\n- TestMetricsSnapshot/uptime\n\n**Lint failure:**\n- cmd/bd/migrate.go:647:37: cleanupWALFiles - result 0 (error) is always nil (unparam)\n\n**Nix failure:**\n- Build fails during test phase with same test errors\n\n### Next Steps\n1. Investigate Windows-specific test failures\n2. Fix linting issue in migrate.go\n3. Debug Nix build test failures","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-02T08:42:16.142128-08:00","updated_at":"2025-11-02T11:17:39.073861-08:00","closed_at":"2025-11-02T11:17:39.073861-08:00","external_ref":"https://github.com/steveyegge/beads/issues/173"} {"id":"bd-12c2","content_hash":"caa7a5f6e61a9b1c872f5462e53ed0ecdedc8835265ba6b7c7ef2100fa6448ae","title":"Add comprehensive tests for show.go commands (show, update, edit, close)","description":"Need to add tests for cmd/bd/show.go which contains show, update, edit, and close commands.\n\n**Challenge**: The existing test patterns use rootCmd.SetArgs() and rootCmd.Execute(), but the global `store` variable needs to match what the commands use. Initial attempt created tests that failed with \"no issue found\" because the test's store instance wasn't the same as the command's store.\n\n**Files to test**:\n- show.go (contains showCmd, updateCmd, editCmd, closeCmd)\n\n**Coverage needed**:\n- show command (single issue, multiple issues, JSON output, with dependencies, with labels, with compaction)\n- update command (status, priority, title, assignee, description, multiple fields, multiple issues)\n- edit command (requires $EDITOR, may need mocking)\n- close command (single issue, multiple issues, with reason, JSON output)\n\n**Test approach**:\n1. Study working test patterns in init_test.go, list_test.go, etc.\n2. Ensure BEADS_NO_DAEMON=1 is set\n3. Properly initialize database with bd init\n4. Use the command's global store, not a separate instance\n5. May need to reset global state between tests\n\n**Success criteria**: \n- All test functions pass\n- Coverage for show.go increases significantly\n- Tests follow existing patterns in cmd/bd/*_test.go","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T20:08:40.545173-07:00","updated_at":"2025-10-31T20:19:22.411066-07:00","closed_at":"2025-10-31T20:19:22.411066-07:00"} {"id":"bd-1445","content_hash":"20fa939366a39e352f5c2ddad5705ab13559440366eebcb4f32db42a5660dfdc","title":"Create shared insert/event/dirty helpers","description":"Create issues.go (insertIssue/insertIssues), events.go (recordCreatedEvent/recordCreatedEvents), dirty.go (markDirty/markDirtyBatch). Refactor single and bulk create paths to use these.","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-01T11:41:14.882142-07:00","updated_at":"2025-11-01T11:41:14.882142-07:00"} {"id":"bd-17fa2d21","content_hash":"139511c299c2fa977d11d5496245b23f4c27fe785fd4fc94470a35b0e4a01a0a","title":"Batch test 2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T15:29:01.877052-07:00","updated_at":"2025-10-31T12:00:43.183657-07:00","closed_at":"2025-10-31T12:00:43.183657-07:00"} @@ -48,7 +48,7 @@ {"id":"bd-373c","content_hash":"2ee54c4542489d8d254d17a6fc2e2d581e99badd7a166b36799cdca4be94bcc6","title":"Daemon crashes silently when multiple .db files exist in .beads/","description":"When daemon detects multiple .db files (after filtering out .backup and vc.db files), it writes error details to .beads/daemon-error file before exiting.\n\nThe error file is checked when:\n1. Daemon discovery fails to connect (internal/daemon/discovery.go)\n2. Auto-start fails to yield a running daemon (cmd/bd/main.go)\n3. Daemon list shows 'daemon not responding' error\n\nThis makes the error immediately visible to users without requiring them to check daemon logs.\n\nFile created: cmd/bd/daemon.go (writes daemon-error on multiple .db detection)\nFiles modified: \n- internal/daemon/discovery.go (reads daemon-error and surfaces in DaemonInfo.Error)\n- cmd/bd/main.go (displays daemon-error when auto-start fails)\n\nTesting: Create multiple .db files in .beads/, start daemon, verify error file created and shown in bd daemons list","notes":"Root cause: Daemon exits with os.Exit(1) when multiple .db files detected (daemon.go:1381), but error only goes to daemon log file. User sees 'daemon not responding' without knowing why.\n\nCurrent detection:\n- daemon.go filters out .backup and vc.db files\n- bd doctor detects multiple databases\n- Error message tells user to run 'bd init' or manually remove\n\nProblem: Error is not user-visible unless they check daemon logs.\n\nProposed fix options:\n1. Surface the error in 'bd info' and 'bd daemons list' output\n2. Add a hint in error messages to run 'bd doctor' when daemon fails\n3. Make daemon write error to a .beads/daemon-error file that gets checked\n4. Improve 'bd doctor' to run automatically when daemon is unhealthy","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-31T21:08:03.389259-07:00","updated_at":"2025-11-01T11:13:48.029427-07:00","closed_at":"2025-11-01T11:13:48.029427-07:00","dependencies":[{"issue_id":"bd-373c","depends_on_id":"bd-2752a7a2","type":"discovered-from","created_at":"2025-10-31T21:08:03.390022-07:00","created_by":"stevey"}]} {"id":"bd-381d7f6c","content_hash":"24b00d276bd245aec3e6dfb6378457e785ac6a01538eba05450dd65dba993178","title":"Audit Current Cache Usage","description":"Understand exactly what code depends on the storage cache","acceptance_criteria":"- Document showing all cache dependencies\n- Confirmation that removing cache won't break MCP\n- List of tests that need updating\n\nFiles to examine:\n- internal/rpc/server_cache_storage.go (cache implementation)\n- internal/rpc/client.go (how req.Cwd is set)\n- internal/rpc/server_*.go (all getStorageForRequest calls)\n- integrations/beads-mcp/ (MCP multi-repo logic)\n\nTasks:\n- Document all callers of getStorageForRequest()\n- Verify req.Cwd is only set by RPC client for database discovery\n- Confirm MCP server doesn't rely on multi-repo cache behavior\n- Check if any tests assume multi-repo routing\n- Review environment variables: BEADS_DAEMON_MAX_CACHE_SIZE, BEADS_DAEMON_CACHE_TTL, BEADS_DAEMON_MEMORY_THRESHOLD_MB","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T23:01:15.172045-07:00","updated_at":"2025-10-30T17:12:58.214409-07:00","closed_at":"2025-10-28T10:47:37.87529-07:00"} {"id":"bd-3b2fe268","content_hash":"60b24230230cb6c49c45d7439787ee8a748164dfc9629946653814d447ea8c1a","title":"Add fsnotify dependency to go.mod","description":"","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-28T16:20:02.429763-07:00","updated_at":"2025-10-31T20:36:49.310833-07:00"} -{"id":"bd-3b7f","content_hash":"08bd6769475661b3916ba86a366e869bf0b0d5c3efe228cf42ff953264449119","title":"Add tests for extracted modules","description":"Create tests for migrations.go, hash_ids.go, batch_ops.go, and validators.go","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T19:28:54.88933-07:00","updated_at":"2025-11-01T23:00:37.751004-07:00","closed_at":"2025-11-01T23:00:37.751004-07:00"} +{"id":"bd-3b7f","content_hash":"24c22ea6863edee2b6269e178a9966e68295baa265595b4ba813b68fc67020ac","title":"Add tests for extracted modules","description":"Create tests for migrations.go, hash_ids.go, batch_ops.go, and validators.go","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T19:28:54.88933-07:00","updated_at":"2025-11-01T23:32:00.722607-07:00","closed_at":"2025-11-01T23:32:00.722613-07:00"} {"id":"bd-3d844c58","content_hash":"92be620ba7d89a256decb33cefd8ba8a12f40413a27e4d92dca9b6189b48665b","title":"Implement content-hash based collision resolution for deterministic convergence","description":"The current collision resolution uses creation timestamps to decide which issue to keep vs. remap. This is non-deterministic when two clones create issues at nearly the same time.\n\nRoot cause of bd-71107098:\n- Clone A creates test-1=\"Issue from clone A\" at T0\n- Clone B creates test-1=\"Issue from clone B\" at T0+30ms\n- Clone B syncs first, remaps Clone A's to test-2\n- Clone A syncs second, sees collision, remaps Clone B's to test-2\n- Result: titles are swapped between clones\n\nSolution:\n- Use content-based hashing (title + description + priority + type)\n- Deterministic winner: always keep issue with lower hash\n- Same collision on different clones produces same result (idempotent)\n\nImplementation:\n- Modify ScoreCollisions in internal/storage/sqlite/collision.go\n- Replace timestamp-based scoring with content hash comparison\n- Ensure hash function is stable across platforms","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-28T17:04:06.145646-07:00","updated_at":"2025-10-30T17:12:58.225476-07:00","closed_at":"2025-10-28T19:20:09.943023-07:00","dependencies":[{"issue_id":"bd-3d844c58","depends_on_id":"bd-71107098","type":"blocks","created_at":"2025-10-31T19:38:09.203365-07:00","created_by":"stevey"}]} {"id":"bd-3e307cd4","content_hash":"2d95ea3b6835139e1fd266bbdcd0f683b5b4d26a1041516c4883beeb37b11ede","title":"File change test issue","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T19:11:28.425601-07:00","updated_at":"2025-10-31T12:00:43.176605-07:00","closed_at":"2025-10-31T12:00:43.176605-07:00"} {"id":"bd-3e3b","content_hash":"db612c737d8f330bb1ff1bbda043835d1318bb806970677ed768a69e15287653","title":"Add circular dependency detection to bd doctor","description":"Added cycle detection as Check #10 in bd doctor command. Uses same recursive CTE query as DetectCycles() to find circular dependencies. Reports error status with count and fix suggestion if cycles found.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-01T20:18:23.416056-07:00","updated_at":"2025-11-01T20:18:26.76113-07:00","closed_at":"2025-11-01T20:18:26.76113-07:00"} @@ -63,7 +63,7 @@ {"id":"bd-4d80b7b1","content_hash":"0cad3e22d722ff045a29f218962fb00bd8265a1cfc82c5b70f29ffe1a40e4088","title":"Investigate and upgrade to modernc.org/sqlite 1.39.1+","description":"We had to pin modernc.org/sqlite to v1.38.2 due to a FOREIGN KEY constraint regression in v1.39.1 (SQLite 3.50.4).\n\n**Issue:** [deleted:bd-cb64c226.2], GH #144\n\n**Symptom:** CloseIssue fails with \"FOREIGN KEY constraint failed (787)\" when called via MCP/daemon, but works fine via CLI.\n\n**Root Cause:** Unknown - likely stricter FK enforcement in SQLite 3.50.4 or modernc.org wrapper changes.\n\n**Workaround:** Pinned to v1.38.2 (SQLite 3.49.x)\n\n**TODO:**\n1. Monitor modernc.org/sqlite releases for fixes\n2. Check SQLite 3.50.5+ changelogs for FK-related fixes\n3. Investigate why daemon mode fails but CLI succeeds (connection reuse? transaction isolation?)\n4. Consider filing upstream issue with reproducible test case\n5. Upgrade when safe","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-24T11:49:12.836292-07:00","updated_at":"2025-10-30T17:12:58.211344-07:00"} {"id":"bd-4e21b5ad","content_hash":"8029d0c5b14261648d3d17d8bc26413183962eab2875772cd2585db92c0104a6","title":"Add test case for symmetric collision (both clones create same ID simultaneously)","description":"TestTwoCloneCollision demonstrates the problem, but we need a simpler unit test for the collision resolver itself.\n\nTest should verify:\n- Two issues with same ID, different content\n- Content hash determines winner deterministically \n- Result is same regardless of which clone imports first\n- No title swapping occurs\n\nThis can be a simpler test than the full integration test.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T17:46:10.046999-07:00","updated_at":"2025-10-31T12:00:43.196705-07:00","closed_at":"2025-10-31T12:00:43.196705-07:00"} {"id":"bd-4f582ec8","content_hash":"02e00868aecbd17486f988a5927a68a07bc309978b33568361559a182eadb2cc","title":"Test auto-start in fred","description":"","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-30T17:46:16.668088-07:00","updated_at":"2025-10-31T12:00:43.185723-07:00","closed_at":"2025-10-31T12:00:43.185723-07:00"} -{"id":"bd-4ff2","content_hash":"c245bd7fec00b7a899ace53a6f7f518252c93692fd2b74e5adf2a8b1c90f87b5","title":"Fix CI failures before 0.21.3 release","description":"CI is failing on multiple jobs:\n1. Nix flake: Tests fail due to missing git in build environment\n2. Windows tests: Need to check what's failing\n3. Linux tests: Need to check what's failing\n4. Linter errors: Many unchecked errors need fixing\n\nNeed to fix before tagging v0.21.3 release.","notes":"Fixed linter errors (errcheck, misspell), Nix flake git dependency, and import database discovery bug. Tests still failing - need to investigate further.","status":"in_progress","priority":0,"issue_type":"bug","created_at":"2025-11-01T23:52:09.244763-07:00","updated_at":"2025-11-02T10:42:12.114426-08:00"} +{"id":"bd-4ff2","content_hash":"c245bd7fec00b7a899ace53a6f7f518252c93692fd2b74e5adf2a8b1c90f87b5","title":"Fix CI failures before 0.21.3 release","description":"CI is failing on multiple jobs:\n1. Nix flake: Tests fail due to missing git in build environment\n2. Windows tests: Need to check what's failing\n3. Linux tests: Need to check what's failing\n4. Linter errors: Many unchecked errors need fixing\n\nNeed to fix before tagging v0.21.3 release.","notes":"Fixed linter errors (errcheck, misspell), Nix flake git dependency, and import database discovery bug. Tests still failing - need to investigate further.","status":"in_progress","priority":0,"issue_type":"bug","created_at":"2025-11-01T23:52:09.244763-07:00","updated_at":"2025-11-02T00:21:14.149364-07:00"} {"id":"bd-5314bddf","content_hash":"bbaf3bd26766fb78465900c455661a3608ab1d1485cb964d12229badf138753a","title":"bd detect-pollution - Test pollution detector","description":"Detect test issues that leaked into production DB.\n\nPattern matching for:\n- Titles starting with 'test', 'benchmark', 'sample'\n- Sequential numbering (test-1, test-2)\n- Generic descriptions\n- Created in rapid succession\n\nOptional AI scoring for confidence.\n\nFiles: cmd/bd/detect_pollution.go (new)","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-28T14:48:17.466906-07:00","updated_at":"2025-10-30T17:12:58.219307-07:00"} {"id":"bd-5599","content_hash":"c48839a6f7f5ca4083ced2f0f47cd250046146032555a14864ac3469a42bb76b","title":"Fix TestListCommand duplicate dependency constraint violation","description":"","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-10-31T21:27:05.557548-07:00","updated_at":"2025-10-31T21:27:11.429018-07:00","closed_at":"2025-10-31T21:27:11.429018-07:00"} {"id":"bd-581b80b3","content_hash":"04c4d952852ae2673e551d9776698c52b0189754ac5f9ca295bed464a5b86a43","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"} @@ -73,7 +73,7 @@ {"id":"bd-5b6e","content_hash":"f82a86b4aae21311f23c8511a242f16e96d03836300995fadd43b8bea945cefa","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-5dae5504","content_hash":"4f2b5a203d6a7b5e38176dd6ef68afb4b7d0e11889718381e28bf006f4e83a16","title":"Export deduplication breaks when JSONL and export_hashes table diverge","description":"## Problem\n\nThe export deduplication feature (timestamp-only skipping) breaks when the JSONL file and export_hashes table get out of sync, causing exports to skip issues that aren't actually in the file.\n\n## Symptoms\n\n- `bd export` reports \"Skipped 128 issue(s) with timestamp-only changes\"\n- JSONL file only has 38 lines but DB has 149 issues\n- export_hashes table has 149 entries\n- Auto-import doesn't trigger (hash matches despite missing data)\n- Two repos on same commit show different issue counts\n\n## Root Cause\n\nshouldSkipExport() in autoflush.go compares current issue hash with stored export_hashes entry. If they match, it skips export assuming the issue is already in the JSONL.\n\nThis assumption fails when:\n1. Git operations (pull, reset, checkout) change JSONL without clearing export_hashes\n2. Manual JSONL edits or corruption\n3. Import operations that modify DB but don't update export_hashes\n4. Partial exports that update export_hashes but don't complete\n\n## Impact\n\n- **Critical data loss risk**: Issues appear to be tracked but aren't persisted to git\n- Breaks multi-repo sync (root cause of today's debugging session)\n- Auto-import fails to detect staleness (hash matches despite missing data)\n- Silent data corruption (no error messages, just missing issues)\n\n## Reproduction\n\n1. Have DB with 149 issues, all in export_hashes table\n2. Truncate JSONL to 38 lines (simulate git reset or corruption)\n3. Run `bd export` - it skips 128 issues\n4. JSONL still has only 38 lines but export thinks it succeeded\n\n## Current Workaround\n\n```bash\nsqlite3 .beads/beads.db \"DELETE FROM export_hashes\"\nbd export -o .beads/beads.jsonl\n```\n\n## Proposed Solutions\n\n**Option 1: Verify JSONL integrity before skipping**\n- Count lines in JSONL, compare with export_hashes count\n- If mismatch, clear export_hashes and force full export\n- Safe but adds I/O overhead\n\n**Option 2: Hash-based JSONL validation**\n- Store hash of entire JSONL file in metadata\n- Before export, check if JSONL hash matches\n- If mismatch, clear export_hashes\n- More efficient, detects any JSONL corruption\n\n**Option 3: Disable timestamp-only deduplication**\n- Remove the feature entirely\n- Always export all issues\n- Simplest and safest, but creates larger git commits\n\n**Option 4: Clear export_hashes on git operations**\n- Add post-merge hook to clear export_hashes\n- Clear on any import operation\n- Defensive approach but may over-clear\n\n## Recommended Fix\n\nCombination of Options 2 + 4:\n1. Store JSONL file hash in metadata after export\n2. Check hash before export, clear export_hashes if mismatch \n3. Clear export_hashes on import operations\n4. Add `bd validate` check for JSONL/export_hashes sync\n\n## Files Involved\n\n- cmd/bd/autoflush.go (shouldSkipExport)\n- cmd/bd/export.go (export with deduplication)\n- internal/storage/sqlite/metadata.go (export_hashes table)","notes":"## Recovery Session (2025-10-29 21:30)\n\n### What Happened\n- Created 14 new hash ID issues (bd-f8b764c9 through bd-f8b764c9.1) \n- bd sync appeared to succeed\n- Canonical repo (~/src/beads): 162 issues in DB + JSONL ✓\n- Secondary repo (fred/beads): Only 145 issues vs 162 in canonical ✗\n- Both repos on same git commit but different issue counts!\n\n### Bug Manifestation During Recovery\n\n1. **Initial state**: fred/beads had 145 issues, 145 lines in JSONL, 145 export_hashes entries\n\n2. **After git reset --hard origin/main**: \n - JSONL: 162 lines (from git)\n - DB: 150 issues (auto-import partially worked)\n - Auto-import failed with UNIQUE constraint error\n\n3. **After manual import --resolve-collisions**:\n - DB: 160 issues\n - JSONL: Still 162 lines\n - export_hashes: 159 entries\n\n4. **After bd export**: \n - **JSONL reduced to 17 lines!** ← The bug in action\n - export_hashes: 159 entries (skipped exporting 142 issues)\n - Silent data loss - no error message\n\n5. **After clearing export_hashes and re-export**:\n - JSONL: 159 lines (missing 3 issues still)\n - DB: 159 issues\n - Still diverged from canonical\n\n### The Bug Loop\nOnce export_hashes and JSONL diverge:\n- Export skips issues already in export_hashes\n- But those issues aren't actually in JSONL\n- This creates corrupt JSONL with missing issues\n- Auto-import can't detect the problem (file hash matches what was exported)\n- Data is lost with no error messages\n\n### Recovery Solution\nCouldn't break the loop with export alone. Had to:\n1. Copy .beads/beads.db from canonical repo\n2. Clear export_hashes\n3. Full re-export\n4. Finally converged to 162 issues\n\n### Key Learnings\n\n1. **The bug is worse than we thought**: It can create corrupt exports (17 lines instead of 162!)\n\n2. **Auto-import can't save you**: Once export is corrupt, auto-import just imports the corrupt data\n\n3. **Silent failure**: No warnings, no errors, just missing issues\n\n4. **Git operations trigger it**: git reset, git pull, etc. change JSONL without clearing export_hashes\n\n5. **Import operations populate export_hashes**: Even manual imports update export_hashes, setting up future export failures\n\n### Immediate Action Required\n\n**DISABLE EXPORT DEDUPLICATION NOW**\n\nThis feature is fundamentally broken and causes data loss. Should be disabled until properly fixed.\n\nQuick fix options:\n- Set environment variable to disable feature\n- Comment out shouldSkipExport check\n- Always clear export_hashes before export\n- Add validation that DB count == JSONL line count before allowing export\n\n### Long-term Fix\n\nNeed Option 2 + 4 from proposed solutions:\n1. Store JSONL file hash after every successful export\n2. Before export, verify JSONL hash matches expected\n3. If mismatch, log WARNING and clear export_hashes\n4. Clear export_hashes on every import operation\n5. Add git post-merge hook to clear export_hashes\n6. Add `bd validate` command to detect divergence\n","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-29T23:05:13.959435-07:00","updated_at":"2025-10-30T17:12:58.207148-07:00","closed_at":"2025-10-29T21:57:03.06641-07:00"} {"id":"bd-5e1f","content_hash":"3e3467773e73eb9dbb8dd8f213be7157c27d72b53c6cc9776616154db96c3864","title":"Issue with desc","description":"This is a description","status":"open","priority":2,"issue_type":"bug","created_at":"2025-10-31T21:41:11.128718-07:00","updated_at":"2025-10-31T21:41:11.128718-07:00"} -{"id":"bd-5f26","content_hash":"75bc96be4d465a5eb39bdf0b636c42cdd7b8ac7daf90b47b7b2a015991b87512","title":"Refactor daemon.go into internal/daemonrunner","description":"Extract daemon runtime from daemon.go (1,565 lines) into internal/daemonrunner with focused modules: config.go, daemon.go, process.go, rpc_server.go, sync.go, git.go. Keep cobra command thin.","design":"New structure:\n- internal/daemonrunner/config.go: Config struct\n- internal/daemonrunner/daemon.go: Daemon struct + Start/Stop\n- internal/daemonrunner/process.go: PID/lock/socket handling\n- internal/daemonrunner/rpc_server.go: RPC lifecycle\n- internal/daemonrunner/sync.go: Export/import/commit/push logic\n- internal/daemonrunner/git.go: Git operations interface\n- cmd/bd/daemon.go: Thin cobra command","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-01T11:41:14.821017-07:00","updated_at":"2025-11-01T21:44:44.507747-07:00","closed_at":"2025-11-01T21:44:44.507747-07:00"} +{"id":"bd-5f26","content_hash":"75bc96be4d465a5eb39bdf0b636c42cdd7b8ac7daf90b47b7b2a015991b87512","title":"Refactor daemon.go into internal/daemonrunner","description":"Extract daemon runtime from daemon.go (1,565 lines) into internal/daemonrunner with focused modules: config.go, daemon.go, process.go, rpc_server.go, sync.go, git.go. Keep cobra command thin.","design":"New structure:\n- internal/daemonrunner/config.go: Config struct\n- internal/daemonrunner/daemon.go: Daemon struct + Start/Stop\n- internal/daemonrunner/process.go: PID/lock/socket handling\n- internal/daemonrunner/rpc_server.go: RPC lifecycle\n- internal/daemonrunner/sync.go: Export/import/commit/push logic\n- internal/daemonrunner/git.go: Git operations interface\n- cmd/bd/daemon.go: Thin cobra command","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-01T11:41:14.821017-07:00","updated_at":"2025-11-01T22:34:00.944402-07:00","closed_at":"2025-11-01T22:34:00.944402-07:00"} {"id":"bd-5f483051","content_hash":"d69f64f7f0bdc46a539dfe0b699a8977309c9c8d59f3e9beffbbe4484275a16b","title":"Implement bd resolve-conflicts (git merge conflicts in JSONL)","description":"Automatically detect and resolve git merge conflicts in .beads/issues.jsonl file.\n\nFeatures:\n- Detect conflict markers in JSONL\n- Parse conflicting issues from HEAD and BASE\n- Provide mechanical resolution (remap duplicate IDs)\n- Support AI-assisted resolution (requires internal/ai package)\n\nSee repair_commands.md lines 125-353 for design.","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-28T19:37:55.722827-07:00","updated_at":"2025-10-30T17:12:58.179718-07:00"} {"id":"bd-6214875c","content_hash":"d4d20e71bbf5c08f1fe1ed07f67b7554167aa165d4972ea51b5cacc1b256c4c1","title":"Split internal/rpc/server.go into focused modules","description":"The file `internal/rpc/server.go` is 2,273 lines with 50+ methods, making it difficult to navigate and prone to merge conflicts. Split into 8 focused files with clear responsibilities.\n\nCurrent structure: Single 2,273-line file with:\n- Connection handling\n- Request routing\n- All 40+ RPC method implementations\n- Storage caching\n- Health checks \u0026 metrics\n- Cleanup loops\n\nTarget structure:\n```\ninternal/rpc/\n├── server.go # Core server, connection handling (~300 lines)\n├── methods_issue.go # Issue operations (~400 lines)\n├── methods_deps.go # Dependency operations (~200 lines)\n├── methods_labels.go # Label operations (~150 lines)\n├── methods_ready.go # Ready work queries (~150 lines)\n├── methods_compact.go # Compaction operations (~200 lines)\n├── methods_comments.go # Comment operations (~150 lines)\n├── storage_cache.go # Storage caching logic (~300 lines)\n└── health.go # Health \u0026 metrics (~200 lines)\n```\n\nMigration strategy:\n1. Create new files with appropriate methods\n2. Keep `server.go` as main file with core server logic\n3. Test incrementally after each file split\n4. Final verification with full test suite","acceptance_criteria":"- All 50 methods split into appropriate files\n- Each file \u003c500 LOC\n- All methods remain on `*Server` receiver (no behavior change)\n- All tests pass: `go test ./internal/rpc/...`\n- Verify daemon works: start daemon, run operations, check health\n- Update internal documentation if needed\n- No change to public API","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T14:21:37.51524-07:00","updated_at":"2025-10-30T17:12:58.2179-07:00","closed_at":"2025-10-28T14:11:04.399811-07:00"} {"id":"bd-6221bdcd","content_hash":"3bf15bc9e418180e1e91691261817c872330e182dbc1bcb756522faa42416667","title":"Improve cmd/bd test coverage (currently 20.2%)","description":"CLI commands need better test coverage. Focus on:\n- Command argument parsing\n- Error handling paths\n- Edge cases in create, update, close commands\n- Daemon commands\n- Import/export workflows","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-29T14:06:27.951656-07:00","updated_at":"2025-10-30T17:12:58.185819-07:00","dependencies":[{"issue_id":"bd-6221bdcd","depends_on_id":"bd-4d7fca8a","type":"blocks","created_at":"2025-10-29T19:52:05.532391-07:00","created_by":"import-remap"}]} @@ -112,9 +112,9 @@ {"id":"bd-8900f145","content_hash":"4a07f36a9e5d24aaffb092c89e2273cb58f9de357d24eeb01fcde6a4079ba775","title":"Testing event-driven mode!","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T15:28:33.564871-07:00","updated_at":"2025-10-30T17:12:58.186325-07:00","closed_at":"2025-10-29T19:12:54.43368-07:00"} {"id":"bd-89e2","content_hash":"ddf4626e586440f379ff19872eac29941cecb925d0a4aae8a6f9c08c969ca05d","title":"Daemon race condition: stale export overwrites recent DB changes","description":"**Symptom:**\nMerged bd-fc2d into bd-fb05 in ~/src/beads (commit ce4d756), pushed to remote. The ~/src/fred/beads daemon then exported its stale DB state and committed (8cc1bb4), reverting bd-fc2d back to \"open\" status.\n\n**Timeline:**\n1. 21:45:12 - Merge committed from ~/src/beads (ce4d756): bd-fc2d closed\n2. 21:49:42 - Daemon in ~/src/fred/beads exported stale state (8cc1bb4): bd-fc2d open again\n\n**Root cause:**\nThe fred/beads daemon had a stale database (bd-fc2d still open) and didn't auto-import the newer JSONL before exporting. When it exported, it overwrote the merge with its stale state.\n\n**Expected behavior:**\nDaemon should detect that JSONL is newer than its last export and import before exporting.\n\n**Actual behavior:**\nDaemon exported stale DB state, creating a conflicting commit that reverted upstream changes.\n\n**Impact:**\nMulti-workspace setups with daemons can silently lose changes if one daemon has stale state and exports.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-01T21:53:07.930819-07:00","updated_at":"2025-11-01T22:01:25.54126-07:00","closed_at":"2025-11-01T22:01:25.54126-07:00"} {"id":"bd-89f89fc0","content_hash":"235c3bdeb45e3069167f81e7b4e798fc98547478bb16df40556100478c5e505a","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","acceptance_criteria":"- Remove the 4 unreachable methods (~80 LOC total)\n- Verify no callers: `grep -r \"GetLastImportTime\\|SetLastImportTime\\|findJSONLPath\" .`\n- All tests pass: `go test ./internal/rpc/...`\n- Daemon functionality works: test daemon start/stop/operations","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-8a39","content_hash":"77554ff8b92731806d997c37a7f624b8ea5204e69a6ed3db82449dd8658ba1fd","title":"Fix Windows-specific test failures in CI","description":"Several tests are failing on Windows but passing on Linux:\n\n**Failing tests:**\n- TestFindDatabasePathEnvVar\n- TestHashIDs_MultiCloneConverge\n- TestHashIDs_IdenticalContentDedup\n- TestDatabaseReinitialization (all 5 subtests):\n - fresh_clone_auto_import\n - database_removal_scenario\n - legacy_filename_support\n - precedence_test\n - init_safety_check\n- TestFindBeadsDir_NotFound\n- TestMetricsSnapshot/uptime (in internal/rpc)\n\n**CI Run:** https://github.com/steveyegge/beads/actions/runs/19015638968\n\nThese are likely path separator or filesystem behavior differences between Windows and Linux.","notes":"Fixed all Windows path issues:\n1. TestFindDatabasePathEnvVar - expects canonicalized paths ✅\n2. TestHashIDs tests - use platform-specific bd.exe command ✅ \n3. TestMetricsSnapshot/uptime - enforce minimum 1 second uptime ✅\n4. TestFindBeadsDir_NotFound - allow finding .beads in parent dirs ✅\n5. TestDatabaseReinitialization - fix git path conversion on Windows (git returns /c/Users/... but filepath needs C:\\Users\\...) ✅\n\nCI run in progress to verify all fixes.","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-02T09:29:37.274103-08:00","updated_at":"2025-11-02T10:01:48.259245-08:00","dependencies":[{"issue_id":"bd-8a39","depends_on_id":"bd-1231","type":"blocks","created_at":"2025-11-02T09:29:37.276579-08:00","created_by":"stevey"}]} +{"id":"bd-8a39","content_hash":"77554ff8b92731806d997c37a7f624b8ea5204e69a6ed3db82449dd8658ba1fd","title":"Fix Windows-specific test failures in CI","description":"Several tests are failing on Windows but passing on Linux:\n\n**Failing tests:**\n- TestFindDatabasePathEnvVar\n- TestHashIDs_MultiCloneConverge\n- TestHashIDs_IdenticalContentDedup\n- TestDatabaseReinitialization (all 5 subtests):\n - fresh_clone_auto_import\n - database_removal_scenario\n - legacy_filename_support\n - precedence_test\n - init_safety_check\n- TestFindBeadsDir_NotFound\n- TestMetricsSnapshot/uptime (in internal/rpc)\n\n**CI Run:** https://github.com/steveyegge/beads/actions/runs/19015638968\n\nThese are likely path separator or filesystem behavior differences between Windows and Linux.","notes":"Fixed all Windows path issues:\n1. TestFindDatabasePathEnvVar - expects canonicalized paths ✅\n2. TestHashIDs tests - use platform-specific bd.exe command ✅ \n3. TestMetricsSnapshot/uptime - enforce minimum 1 second uptime ✅\n4. TestFindBeadsDir_NotFound - allow finding .beads in parent dirs ✅\n5. TestDatabaseReinitialization - fix git path conversion on Windows (git returns /c/Users/... but filepath needs C:\\Users\\...) ✅\n\nCI run in progress to verify all fixes.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-02T09:29:37.274103-08:00","updated_at":"2025-11-02T11:17:39.074618-08:00","closed_at":"2025-11-02T11:17:39.074618-08:00","dependencies":[{"issue_id":"bd-8a39","depends_on_id":"bd-1231","type":"blocks","created_at":"2025-11-02T09:29:37.276579-08:00","created_by":"stevey"}]} {"id":"bd-9063acda","content_hash":"572a9f35c6b6a74f5d1ff1bb6851881ca6991de48c2238e21bea48752a323ea4","title":"Clean up linter errors (914 total issues)","description":"The codebase has 914 linter issues reported by golangci-lint. While many are documented as baseline in LINTING.md, we should clean these up systematically to improve code quality and maintainability.","design":"Break down by linter category, prioritizing high-impact issues:\n1. dupl (7) - Code duplication\n2. goconst (12) - Repeated strings\n3. gocyclo (11) - High complexity functions\n4. revive (78) - Style issues\n5. gosec (102) - Security warnings\n6. errcheck (683) - Unchecked errors (many in tests)","acceptance_criteria":"All linter categories reduced to acceptable levels, with remaining baseline documented in LINTING.md","notes":"Reduced from 56 to 41 issues locally, then to 0 issues.\n\n**Fixed in commits:**\n- c2c7eda: Fixed 15 actual errors (dupl, gosec, revive, staticcheck, unparam)\n- 963181d: Configured exclusions to get to 0 issues locally\n\n**Current status:**\n- ✅ Local: golangci-lint reports 0 issues\n- ❌ CI: Still failing (see [deleted:bd-cb64c226.1])\n\n**Problem:**\nConfig v2 format or golangci-lint-action@v8 compatibility issue causing CI to fail despite local success.\n\n**Next:** Debug [deleted:bd-cb64c226.1] to fix CI/local discrepancy","status":"open","priority":2,"issue_type":"epic","created_at":"2025-10-24T01:01:12.997982-07:00","updated_at":"2025-10-31T20:36:49.404022-07:00"} -{"id":"bd-90a5","content_hash":"0c47eb0e3250e98727c52f6fa700b535a7e4bf4cdbd33df8857a55d6c107ed5c","title":"Extract hash ID generation functions to hash_ids.go","description":"Move generateHashID, getNextChildNumber, GetNextChildID to hash_ids.go","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-01T19:28:54.890883-07:00","updated_at":"2025-11-01T19:28:54.890883-07:00"} +{"id":"bd-90a5","content_hash":"0c47eb0e3250e98727c52f6fa700b535a7e4bf4cdbd33df8857a55d6c107ed5c","title":"Extract hash ID generation functions to hash_ids.go","description":"Move generateHashID, getNextChildNumber, GetNextChildID to hash_ids.go","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T19:28:54.890883-07:00","updated_at":"2025-11-01T23:39:19.427561-07:00","closed_at":"2025-11-01T23:39:19.427561-07:00"} {"id":"bd-942469b8","content_hash":"be178337752bf9a94ac06f13d6c36752c9104585b9aef43ade971ed50437a39e","title":"Rapid 5","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-29T19:11:57.508166-07:00","updated_at":"2025-10-30T17:12:58.189947-07:00"} {"id":"bd-96142dec","content_hash":"ba00d412efdb156e0449b304096f3e075df4c66606e6283b6501e8a29acb7b28","title":"Add fallback to polling on watcher failure","description":"Detect fsnotify.NewWatcher() errors and log warning. Auto-switch to polling mode with 5s ticker. Add BEADS_WATCHER_FALLBACK env var to control behavior.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T16:20:02.428439-07:00","updated_at":"2025-10-30T17:12:58.220378-07:00","closed_at":"2025-10-28T19:23:43.595916-07:00"} {"id":"bd-9826b69a","content_hash":"d7e67e9b28e525705562e3f81e9112f3882c20d726c6e0f57062153f0e6bf3b9","title":"CRDT-based architecture for guaranteed convergence (v2.0)","description":"## Vision\nRedesign beads around Conflict-Free Replicated Data Types (CRDTs) to provide mathematical guarantees for N-way collision resolution at arbitrary scale.\n\n## Current Limitations\n- Content-hash based collision resolution fails at 5+ clones\n- Non-deterministic convergence in multi-round scenarios\n- UNIQUE constraint violations during rename operations\n- No formal proof of convergence properties\n\n## CRDT Benefits\n- Provably convergent (Strong Eventual Consistency)\n- Commutative/Associative/Idempotent operations\n- No coordination required between clones\n- Scales to 100+ concurrent workers\n- Well-understood mathematical foundations\n\n## Proposed Architecture\n\n### 1. UUID-Based IDs\nReplace sequential IDs with UUIDs:\n- Current: bd-1c63eb84, bd-9063acda, bd-4d80b7b1\n- CRDT: bd-a1b2c3d4-e5f6-7890-abcd-ef1234567890\n- Human aliases maintained separately: #42 maps to UUID\n\n### 2. Last-Write-Wins (LWW) Elements\nEach field becomes an LWW register:\n- title: (timestamp, clone_id, value)\n- status: (timestamp, clone_id, value)\n- Deterministic conflict resolution via Lamport timestamp + clone_id tiebreaker\n\n### 3. Operation Log\nTrack all operations as CRDT ops:\n- CREATE(uuid, timestamp, clone_id, fields)\n- UPDATE(uuid, field, timestamp, clone_id, value)\n- DELETE(uuid, timestamp, clone_id) - tombstone, not hard delete\n\n### 4. Sync as Merge\nSyncing becomes merging two CRDT states:\n- No merge conflicts possible\n- Deterministic merge function\n- Guaranteed convergence\n\n## Implementation Phases\n\n### Phase 1: Research \u0026 Design (4 weeks)\n- Study existing CRDT implementations (Automerge, Yjs, Loro)\n- Design schema for CRDT-based issue tracking\n- Prototype LWW-based Issue CRDT\n- Benchmark performance vs current system\n\n### Phase 2: Parallel Implementation (6 weeks)\n- Implement CRDT storage layer alongside SQLite\n- Build conversion tools: SQLite ↔ CRDT\n- Maintain backward compatibility with v1.x format\n- Migration path for existing databases\n\n### Phase 3: Testing \u0026 Validation (4 weeks)\n- Formal verification of convergence properties\n- Stress testing with 100+ clone scenario\n- Performance profiling and optimization\n- Documentation and examples\n\n### Phase 4: Migration \u0026 Rollout (4 weeks)\n- Release v2.0-beta with CRDT backend\n- Gradual migration from v1.x\n- Monitoring and bug fixes\n- Final v2.0 release\n\n## Risks \u0026 Mitigations\n\n**Risk 1: Performance overhead**\n- Mitigation: Benchmark early, optimize hot paths\n- CRDTs can be slower than append-only logs\n- May need compaction strategy\n\n**Risk 2: Storage bloat**\n- Mitigation: Implement operation log compaction\n- Tombstone garbage collection for deleted issues\n- Periodic snapshots to reduce log size\n\n**Risk 3: Breaking changes**\n- Mitigation: Maintain v1.x compatibility layer\n- Gradual migration tools\n- Dual-mode operation during transition\n\n**Risk 4: Complexity**\n- Mitigation: Use battle-tested CRDT libraries\n- Comprehensive documentation\n- Clear migration guide\n\n## Success Criteria\n- 100-clone collision test passes without failures\n- Formal proof of convergence properties\n- Performance within 2x of current system\n- Zero manual conflict resolution required\n- Backward compatible with v1.x databases\n\n## Timeline\n18-20 weeks total (4-5 months)\n\n## References\n- Automerge: https://automerge.org\n- Yjs: https://docs.yjs.dev\n- Loro: https://loro.dev\n- CRDT theory: Shapiro et al, A comprehensive study of CRDTs\n- Related issues: bd-0dcea000, bd-4d7fca8a, bd-6221bdcd","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-10-29T20:48:00.267736-07:00","updated_at":"2025-10-31T20:06:44.60536-07:00","closed_at":"2025-10-31T20:06:44.60536-07:00"} @@ -141,7 +141,7 @@ {"id":"bd-bc2c6191","content_hash":"533e56b8628e24229a4beb52f8683355f6ca699e34a73650bf092003d73c2957","title":"Audit Current Cache Usage","description":"Understand exactly what code depends on the storage cache","acceptance_criteria":"- Document showing all cache dependencies\n- Confirmation that removing cache won't break MCP\n- List of tests that need updating\n\nFiles to examine:\n- internal/rpc/server_cache_storage.go (cache implementation)\n- internal/rpc/client.go (how req.Cwd is set)\n- internal/rpc/server_*.go (all getStorageForRequest calls)\n- integrations/beads-mcp/ (MCP multi-repo logic)\n\nTasks:\n- Document all callers of getStorageForRequest()\n- Verify req.Cwd is only set by RPC client for database discovery\n- Confirm MCP server doesn't rely on multi-repo cache behavior\n- Check if any tests assume multi-repo routing\n- Review environment variables: BEADS_DAEMON_MAX_CACHE_SIZE, BEADS_DAEMON_CACHE_TTL, BEADS_DAEMON_MEMORY_THRESHOLD_MB","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-27T23:02:43.506373-07:00","updated_at":"2025-10-31T20:36:49.334214-07:00"} {"id":"bd-bdaf24d5","content_hash":"6ccdbf2362d22fbbe854fdc666695a7488353799e1a5c49e6095b34178c9bcb4","title":"Final validation test","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T18:27:28.310533-07:00","updated_at":"2025-10-31T12:00:43.184995-07:00","closed_at":"2025-10-31T12:00:43.184995-07:00"} {"id":"bd-c01f","content_hash":"b183cc4d99f74e9314f67d927f1bd1255608632b47ce0352af97af5872275fec","title":"Implement bd stale command to find abandoned/forgotten issues","description":"Add bd stale command to surface issues that haven't been updated recently and may need attention.\n\nUse cases:\n- In-progress issues with no recent activity (may be abandoned)\n- Open issues that have been forgotten\n- Issues that might be outdated or no longer relevant\n\nQuery logic should find non-closed issues where updated_at exceeds a time threshold.\n\nShould support:\n- --days N flag (default 30-90 days)\n- --status filter (e.g., only in_progress)\n- --json output for automation\n\nReferences GitHub issue #184 where user expected this command to exist.","design":"Implementation approach:\n1. Add new command in cmd/bd/stale.go\n2. Query issues with: status != 'closed' AND updated_at \u003c (now - N days)\n3. Support filtering by status (open, in_progress, blocked)\n4. Default threshold: 30 days (configurable via --days)\n5. JSON output for agent consumption\n6. Order by updated_at ASC (oldest first)","status":"closed","priority":2,"issue_type":"epic","created_at":"2025-10-31T22:48:46.85435-07:00","updated_at":"2025-10-31T22:54:33.704492-07:00","closed_at":"2025-10-31T22:54:33.704492-07:00"} -{"id":"bd-c796","content_hash":"7231785c8ce4d15ce296f7e2d22d03b9d6610ed73dcc5501773f86782ffeaf03","title":"Extract batch operations to batch_ops.go","description":"Move validateBatchIssues, generateBatchIDs, bulkInsertIssues, bulkRecordEvents, bulkMarkDirty, CreateIssues to batch_ops.go","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T19:28:54.887487-07:00","updated_at":"2025-11-02T08:09:51.579971-08:00","closed_at":"2025-11-02T08:09:51.579978-08:00"} +{"id":"bd-c796","content_hash":"3d36861edfa65fd43101c2ac0a2ec0a6bf931c84fcb2d6468a2e14f3fac367df","title":"Extract batch operations to batch_ops.go","description":"Move validateBatchIssues, generateBatchIDs, bulkInsertIssues, bulkRecordEvents, bulkMarkDirty, CreateIssues to batch_ops.go","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T19:28:54.887487-07:00","updated_at":"2025-11-01T23:38:31.841775-07:00","closed_at":"2025-11-01T23:38:31.841775-07:00"} {"id":"bd-c825f867","content_hash":"27cecaa2dc6cdabb2ae77fd65fbf8dca8f4c536bdf140a13b25cdd16376c9845","title":"Add docs/architecture/event_driven.md","description":"Copy event_driven_daemon.md into docs/ folder. Add to documentation index.","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-28T16:20:02.431399-07:00","updated_at":"2025-10-30T17:12:58.221939-07:00"} {"id":"bd-c947dd1b","content_hash":"79bd51b46b28bc16cfc19cd19a4dd4f57f45cd1e902b682788d355b03ec00b2a","title":"Remove Daemon Storage Cache","description":"The daemon's multi-repo storage cache is the root cause of stale data bugs. Since global daemon is deprecated, we only ever serve one repository, making the cache unnecessary complexity. This epic removes the cache entirely for simpler, more reliable direct storage access.","design":"For local daemon (single repository), eliminate the cache entirely:\n- Use s.storage field directly (opened at daemon startup)\n- Remove getStorageForRequest() routing logic\n- Remove server_cache_storage.go entirely (~300 lines)\n- Remove cache-related tests\n- Simplify Server struct\n\nBenefits:\n✅ No staleness bugs: Always using live SQLite connection\n✅ Simpler code: Remove ~300 lines of cache management\n✅ Easier debugging: Direct storage access, no cache indirection\n✅ Same performance: Cache was always 1 entry for local daemon anyway","acceptance_criteria":"- Daemon has no storage cache code\n- All tests pass\n- MCP integration works\n- No stale data bugs\n- Documentation updated\n- Performance validated","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-28T10:50:15.126939-07:00","updated_at":"2025-10-30T17:12:58.21743-07:00","closed_at":"2025-10-28T10:49:53.612049-07:00"} {"id":"bd-c9a482db","content_hash":"35c1ad124187c21b4e8dae7db46ea5d00173d33234a9b815ded7dcf0ab51078e","title":"Add internal/ai package for AI-assisted repairs","description":"Add AI integration package to support AI-powered repair commands.\n\nProviders:\n- Anthropic (Claude)\n- OpenAI\n- Ollama (local)\n\nFeatures:\n- Conflict resolution analysis\n- Duplicate detection via embeddings\n- Configuration via env vars (BEADS_AI_PROVIDER, BEADS_AI_API_KEY, etc.)\n\nSee repair_commands.md lines 357-425 for design.","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-28T19:37:55.722841-07:00","updated_at":"2025-10-30T17:12:58.180177-07:00"} @@ -160,13 +160,13 @@ {"id":"bd-cdf7","content_hash":"ebe962c7eb6dba6d112f7ccf59a8920e0354ea9cd8b039974a8fc4a58373809b","title":"Add tests for DetectCycles to improve coverage from 29.6%","description":"DetectCycles currently has 29.6% coverage. Need comprehensive tests for:\n- Simple cycles (A-\u003eB-\u003eA)\n- Complex multi-node cycles\n- Acyclic graphs (should not detect cycles)\n- Self-loops\n- Multiple independent cycles\n- Edge cases (empty graph, single node)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-01T22:40:58.977156-07:00","updated_at":"2025-11-01T22:52:02.243223-07:00","closed_at":"2025-11-01T22:52:02.243223-07:00"} {"id":"bd-ce37850f","content_hash":"3ef2872c3fcb1e5acc90d33fd5a76291742cbcecfbf697b611aa5b4d8ce80078","title":"Add embedding generation for duplicate detection","description":"Use embeddings for scalable duplicate detection.\n\nModel: text-embedding-3-small (OpenAI) or all-MiniLM-L6-v2 (local)\nStorage: SQLite vector extension or in-memory\nCost: ~/bin/bash.0002 per 100 issues\n\nMuch cheaper than LLM comparisons for large databases.\n\nFiles: internal/embeddings/ (new package)","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-28T14:48:29.072913-07:00","updated_at":"2025-10-30T17:12:58.219921-07:00"} {"id":"bd-cf349eb3","content_hash":"1b42289a0cb1da0626a69c6f004bf62fc9ba6e3a0f8eb70159c5f1446497020b","title":"Update LINTING.md with current baseline","description":"After cleanup, document the remaining acceptable baseline in LINTING.md so we can track regression.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T23:20:10.39272-07:00","updated_at":"2025-10-30T17:12:58.215471-07:00","closed_at":"2025-10-27T23:05:31.945614-07:00"} -{"id":"bd-d33c","content_hash":"0c3eb277be0ec16edae305156aa8824b6bc9c37fbd6151477f235e859e9b6181","title":"Separate process/lock/PID concerns into process.go","description":"Create internal/daemonrunner/process.go with: acquireDaemonLock, PID file read/write, stopDaemon, isDaemonRunning, getPIDFilePath, socket path helpers, version check.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T11:41:14.871122-07:00","updated_at":"2025-11-01T23:43:55.66159-07:00","closed_at":"2025-11-01T23:43:55.66159-07:00"} +{"id":"bd-d33c","content_hash":"0c3eb277be0ec16edae305156aa8824b6bc9c37fbd6151477f235e859e9b6181","title":"Separate process/lock/PID concerns into process.go","description":"Create internal/daemonrunner/process.go with: acquireDaemonLock, PID file read/write, stopDaemon, isDaemonRunning, getPIDFilePath, socket path helpers, version check.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T11:41:14.871122-07:00","updated_at":"2025-11-01T22:56:08.368079-07:00","closed_at":"2025-11-01T22:56:08.368079-07:00"} {"id":"bd-d355a07d","content_hash":"b4f98403e209eadf33dd4913660c1538fd922c89339a9ed034ef504aac358662","title":"Import validation falsely reports data loss on collision resolution","description":"## Problem\n\nPost-import validation reports 'data loss detected!' when import count reduces due to legitimate collision resolution.\n\n## Example\n\n```\nImport complete: 1 created, 8 updated, 142 unchanged, 19 skipped, 1 issues remapped\nPost-import validation failed: import reduced issue count: 165 → 164 (data loss detected!)\n```\n\nThis was actually successful collision resolution (bd-70419816 duplicated → remapped to-70419816), not data loss.\n\n## Impact\n\n- False alarms waste investigation time\n- Undermines confidence in import validation\n- Confuses users/agents about sync health\n\n## Solution\n\nImprove validation to distinguish:\n- Collision-resolution merges (expected count reduction)\n- Actual data loss (unexpected disappearance)\n\nTrack remapped issue count and adjust expected post-import count accordingly.","status":"open","priority":2,"issue_type":"bug","created_at":"2025-10-29T23:15:00.815227-07:00","updated_at":"2025-10-31T19:38:09.19996-07:00"} {"id":"bd-d3e5","content_hash":"16f978c58b9988457aeb1eaff37fb17f12e91325549b38be10362a08923e9a2d","title":"Test issue 2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-02T09:44:17.116768539Z","updated_at":"2025-11-02T09:45:20.780838695Z","closed_at":"2025-11-02T09:45:20.780838695Z"} {"id":"bd-d4ec5a82","content_hash":"872448809bfa26d39d68ba6cac5071379756c30bcd3b08dc75de6da56c133956","title":"Add MCP functions for repair commands","description":"Add repair commands to beads-mcp for agent access:\n- beads_resolve_conflicts()\n- beads_find_duplicates()\n- beads_detect_pollution()\n- beads_validate()\n\nFiles: integrations/beads-mcp/src/beads_mcp/server.py","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-28T14:48:29.071495-07:00","updated_at":"2025-10-30T17:12:58.219499-07:00"} {"id":"bd-d68f","content_hash":"4b5b5340749fba1c419c22f9937717b363ee8a49e4c5e0a5e0066a24b652a936","title":"Add tests for Comments API (AddIssueComment, GetIssueComments)","description":"Comments API currently has 0% coverage. Need tests for:\n- AddIssueComment - adding comments to issues\n- GetIssueComments - retrieving comments\n- Comment ordering and pagination\n- Edge cases (non-existent issues, empty comments)","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-01T22:40:58.980688-07:00","updated_at":"2025-11-01T22:53:42.124391-07:00","closed_at":"2025-11-01T22:53:42.124391-07:00"} {"id":"bd-d7e88238","content_hash":"b69ec861618b03129fad7807b085ee6365860cfd2e9901b49eb846e192b95a0d","title":"Rapid 3","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-29T19:11:57.459655-07:00","updated_at":"2025-10-30T17:12:58.189494-07:00"} -{"id":"bd-d9e0","content_hash":"67a706abbb956ca078d37d718b8f4d2d6c0c1b71f7a2267c64a67dab4938f433","title":"Extract validation functions to validators.go","description":"Move validatePriority, validateStatus, validateIssueType, validateTitle, validateEstimatedMinutes, validateFieldUpdate to validators.go","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-01T19:28:54.915909-07:00","updated_at":"2025-11-01T19:28:54.915909-07:00"} +{"id":"bd-d9e0","content_hash":"67a706abbb956ca078d37d718b8f4d2d6c0c1b71f7a2267c64a67dab4938f433","title":"Extract validation functions to validators.go","description":"Move validatePriority, validateStatus, validateIssueType, validateTitle, validateEstimatedMinutes, validateFieldUpdate to validators.go","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T19:28:54.915909-07:00","updated_at":"2025-11-01T23:37:07.480417-07:00","closed_at":"2025-11-01T23:37:07.480417-07:00"} {"id":"bd-da4d8951","content_hash":"a4e81b23d88d41c8fd3fe31fb7ef387f99cb54ea42a6baa210ede436ecce3288","title":"Replace getStorageForRequest with Direct Access","description":"Replace all getStorageForRequest(req) calls with s.storage","acceptance_criteria":"- No references to getStorageForRequest() in codebase (except in deleted file)\n- All handlers use s.storage directly\n- Code compiles without errors\n\nFiles to update:\n- internal/rpc/server_issues_epics.go (~8 calls)\n- internal/rpc/server_labels_deps_comments.go (~4 calls)\n- internal/rpc/server_compact.go (~2 calls)\n- internal/rpc/server_export_import_auto.go (~2 calls)\n- internal/rpc/server_routing_validation_diagnostics.go (~1 call)\n\nPattern: store, err := s.getStorageForRequest(req) → store := s.storage","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T16:20:02.430127-07:00","updated_at":"2025-10-30T17:12:58.22099-07:00","closed_at":"2025-10-28T19:20:58.312809-07:00"} {"id":"bd-dcd6f14b","content_hash":"efc3565abad1605a8bc16b151fa067d0584a36e3e86e0baa2fb5e5a470c64444","title":"Batch test 4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T15:29:02.053523-07:00","updated_at":"2025-10-31T12:00:43.182861-07:00","closed_at":"2025-10-31T12:00:43.182861-07:00"} {"id":"bd-dd6f6d26","content_hash":"dbcecb8b95f9f2939d97c61bd8cbe331bea866f47600bded213d3122e311c356","title":"Fix autoimport tests for content-hash collision scoring","description":"## Overview\nThree autoimport tests are failing after bd-cbed9619.4 because they expect behavior based on the old reference-counting collision resolution, but the system now uses deterministic content-hash scoring.\n\n## Failing Tests\n1. `TestAutoImportMultipleCollisionsRemapped` - expects local versions preserved\n2. `TestAutoImportAllCollisionsRemapped` - expects local versions preserved \n3. `TestAutoImportCollisionRemapMultipleFields` - expects specific collision resolution behavior\n\n## Root Cause\nThese tests were written when ScoreCollisions used reference counting to determine which version to keep. Now it uses content-hash comparison (introduced in commit 2e87329), which produces different but deterministic results.\n\n## Example\nOld behavior: Issue with more references would be kept\nNew behavior: Issue with lexicographically lower content hash is kept\n\n## Solution\nUpdate each test to:\n1. Verify the new content-hash based behavior is correct\n2. Check that the remapped issue (not necessarily local/remote) has the expected content\n3. Ensure dependencies are preserved on the correct remapped issue\n\n## Acceptance Criteria\n- All three autoimport tests pass\n- Tests verify content-hash determinism (same collision always resolves the same way)\n- Tests check dependency preservation on remapped issues\n- Test documentation explains content-hash scoring expectations\n\n## Files to Modify\n- `cmd/bd/autoimport_collision_test.go`\n\n## Testing\nRun: `go test ./cmd/bd -run \"TestAutoImport.*Collision\" -v`","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-28T19:12:56.344193-07:00","updated_at":"2025-10-30T17:12:58.178703-07:00","closed_at":"2025-10-28T19:18:35.106895-07:00","dependencies":[{"issue_id":"bd-dd6f6d26","depends_on_id":"bd-cbed9619.4","type":"discovered-from","created_at":"2025-10-28T19:12:56.345276-07:00","created_by":"daemon"}]} @@ -197,7 +197,7 @@ {"id":"bd-f8b764c9.7","content_hash":"0cd1edbd677f73f3a21e571709eca026db7c6e0d158a3d41d7c4e37deb8bc4c2","title":"CLI accepts both hash IDs and aliases","description":"Update all CLI commands to accept both hash IDs (bd-af78e9a2) and aliases (#42, or just 42).\n\n## Parsing Logic\n```go\n// internal/utils/id_parser.go\nfunc ParseIssueID(input string) (issueID string, err error) {\n // Hash ID: bd-af78e9a2\n if strings.HasPrefix(input, \"bd-\") {\n return input, nil\n }\n \n // Alias: #42 or 42\n aliasStr := strings.TrimPrefix(input, \"#\")\n alias, err := strconv.Atoi(aliasStr)\n if err != nil {\n return \"\", fmt.Errorf(\"invalid issue ID: %s\", input)\n }\n \n // Resolve alias to hash ID\n return storage.GetIssueIDByAlias(alias)\n}\n```\n\n## Commands to Update\nAll commands that accept issue IDs:\n\n### 1. bd show\n```bash\nbd show bd-af78e9a2 # Hash ID\nbd show #42 # Alias\nbd show 42 # Alias (shorthand)\nbd show bd-af78e9a2 #42 # Mixed (multiple IDs)\n```\n\n### 2. bd update\n```bash\nbd update #42 --status in_progress\nbd update bd-af78e9a2 --priority 1\n```\n\n### 3. bd close\n```bash\nbd close #42 --reason \"Done\"\n```\n\n### 4. bd dep add/tree\n```bash\nbd dep add #42 #1 --type blocks\nbd dep tree bd-af78e9a2\n```\n\n### 5. bd label add/remove\n```bash\nbd label add #42 critical\n```\n\n### 6. bd merge\n```bash\nbd merge #42 #43 --into #41\n```\n\n## Display Format\nDefault to showing aliases in output:\n```bash\n$ bd list\n#1 Fix authentication bug P1 open\n#2 Add logging to daemon P2 open \n#42 Investigate jujutsu integration P3 open\n```\n\nWith `--format=hash` flag:\n```bash\n$ bd list --format=hash\nbd-af78e9a2 Fix authentication bug P1 open\nbd-e5f6a7b8 Add logging to daemon P2 open\nbd-1a2b3c4d Investigate jujutsu integration P3 open\n```\n\n## Files to Modify\n- internal/utils/id_parser.go (new)\n- cmd/bd/show.go\n- cmd/bd/update.go\n- cmd/bd/close.go\n- cmd/bd/reopen.go\n- cmd/bd/dep.go\n- cmd/bd/label.go\n- cmd/bd/merge.go\n- cmd/bd/list.go (add --format flag)\n\n## Testing\n- Test hash ID parsing\n- Test alias parsing (#42, 42)\n- Test mixed IDs in single command\n- Test error on invalid ID\n- Test alias resolution failure","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T21:25:06.256317-07:00","updated_at":"2025-10-31T12:32:32.609634-07:00","closed_at":"2025-10-31T12:32:32.609634-07:00","dependencies":[{"issue_id":"bd-f8b764c9.7","depends_on_id":"bd-f8b764c9","type":"parent-child","created_at":"2025-10-29T21:25:06.257796-07:00","created_by":"stevey"},{"issue_id":"bd-f8b764c9.7","depends_on_id":"bd-f8b764c9.10","type":"blocks","created_at":"2025-10-29T21:25:06.258307-07:00","created_by":"stevey"},{"issue_id":"bd-f8b764c9.7","depends_on_id":"bd-f8b764c9.8","type":"blocks","created_at":"2025-10-29T21:29:45.993274-07:00","created_by":"stevey"}]} {"id":"bd-f8b764c9.8","content_hash":"d047b706654f9e5b0cc59fde73e88fed242932c3c024d90af22327a5c2f2fced","title":"Update JSONL format to use hash IDs","description":"Update JSONL import/export to use hash IDs, store aliases separately.\n\n## Current JSONL Format\n```jsonl\n{\"id\":\"bd-1c63eb84\",\"title\":\"Fix bug\",\"status\":\"open\",...}\n{\"id\":\"bd-9063acda\",\"title\":\"Add test\",\"status\":\"open\",...}\n```\n\n## New JSONL Format (Option A: Include Alias)\n```jsonl\n{\"id\":\"bd-af78e9a2\",\"alias\":1,\"title\":\"Fix bug\",\"status\":\"open\",...}\n{\"id\":\"bd-e5f6a7b8\",\"alias\":2,\"title\":\"Add test\",\"status\":\"open\",...}\n```\n\n## New JSONL Format (Option B: Hash ID Only)\n```jsonl\n{\"id\":\"bd-af78e9a2\",\"title\":\"Fix bug\",\"status\":\"open\",...}\n{\"id\":\"bd-e5f6a7b8\",\"title\":\"Add test\",\"status\":\"open\",...}\n```\n\nStore aliases in separate .beads/aliases.jsonl (local only, git-ignored):\n```jsonl\n{\"hash\":\"bd-af78e9a2\",\"alias\":1}\n{\"hash\":\"bd-e5f6a7b8\",\"alias\":2}\n```\n\n**Recommendation**: Option B (hash only in main JSONL)\n- Cleaner git diffs (no alias conflicts)\n- Aliases are workspace-local preference\n- Main JSONL is canonical, portable\n\n## Export Changes\nFile: cmd/bd/export.go\n```go\n// Export issues with hash IDs\nfor _, issue := range issues {\n json := marshalIssue(issue) // Uses issue.ID (hash)\n // Don't include alias in JSONL\n}\n\n// Separately export aliases to .beads/aliases.jsonl\nexportAliases(issues)\n```\n\n## Import Changes \nFile: cmd/bd/import.go, internal/importer/importer.go\n```go\n// Import issues by hash ID\nissue := unmarshalIssue(line)\n// Assign new alias on import (don't use incoming alias)\nissue.Alias = getNextAlias()\n\n// No collision detection needed! Hash IDs are globally unique\n```\n\n## Dependency Reference Format\nNo change needed - already uses issue IDs:\n```json\n{\"depends_on_id\":\"bd-af78e9a2\",\"type\":\"blocks\"}\n```\n\n## Files to Modify\n- cmd/bd/export.go (use hash IDs)\n- cmd/bd/import.go (import hash IDs, assign aliases)\n- internal/importer/importer.go (remove collision detection!)\n- .gitignore (add .beads/aliases.jsonl)\n\n## Testing\n- Test export produces hash IDs\n- Test import assigns new aliases\n- Test dependencies preserved with hash IDs\n- Test no collision detection triggered","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T21:24:47.408106-07:00","updated_at":"2025-10-31T12:32:32.609925-07:00","closed_at":"2025-10-31T12:32:32.609925-07:00","dependencies":[{"issue_id":"bd-f8b764c9.8","depends_on_id":"bd-f8b764c9","type":"parent-child","created_at":"2025-10-29T21:24:47.409489-07:00","created_by":"stevey"},{"issue_id":"bd-f8b764c9.8","depends_on_id":"bd-f8b764c9.9","type":"blocks","created_at":"2025-10-29T21:24:47.409977-07:00","created_by":"stevey"},{"issue_id":"bd-f8b764c9.8","depends_on_id":"bd-f8b764c9.10","type":"blocks","created_at":"2025-10-29T21:29:45.975499-07:00","created_by":"stevey"}]} {"id":"bd-f8b764c9.9","content_hash":"5b040bec47ef5353a04d90d73ac8237f0302137c27ef7f6bfc84379b84cbb7ec","title":"Implement hash ID generation in CreateIssue","description":"Replace sequential ID generation with hash-based IDs in CreateIssue function.\n\n## Current Behavior (internal/storage/sqlite/sqlite.go)\n```go\nfunc (s *SQLiteStorage) CreateIssue(ctx context.Context, issue *types.Issue) error {\n // ID comes from auto-increment counter\n // Collisions possible across clones\n}\n```\n\n## New Behavior\n```go\nfunc (s *SQLiteStorage) CreateIssue(ctx context.Context, issue *types.Issue) error {\n // Generate hash ID if not provided\n if issue.ID == \"\" {\n issue.ID = idgen.GenerateHashID(\n issue.Title,\n issue.Description,\n time.Now(),\n s.workspaceID,\n )\n }\n \n // Assign next alias\n issue.Alias = s.getNextAlias()\n \n // Insert with hash ID + alias\n // ...\n}\n```\n\n## Workspace ID Generation\nAdd to database initialization:\n```go\n// Generate stable workspace ID (persisted in .beads/workspace_id)\nworkspaceID := getOrCreateWorkspaceID()\n```\n\nOptions for workspace ID:\n1. Hostname + random suffix\n2. UUID (random)\n3. Git remote URL hash (deterministic per repo)\n\nRecommended: Option 3 (git remote hash) for reproducibility\n\n## Hash Collision Detection\n```go\n// On insert, check for collision (unlikely but possible)\nexisting, err := s.GetIssue(ctx, issue.ID)\nif err == nil {\n // Hash collision! Add random suffix and retry\n issue.ID = issue.ID + \"-\" + randomSuffix(4)\n}\n```\n\n## Files to Create/Modify\n- internal/types/id_generator.go (new)\n- internal/storage/sqlite/sqlite.go (CreateIssue)\n- internal/storage/sqlite/workspace.go (new - workspace ID management)\n- .beads/workspace_id (new file, git-ignored)\n\n## Testing\n- Test hash ID generation is deterministic\n- Test collision detection and retry\n- Test workspace ID persistence\n- Benchmark: hash generation performance (\u003c1μs)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T21:24:29.412237-07:00","updated_at":"2025-10-31T12:32:32.610403-07:00","closed_at":"2025-10-31T12:32:32.610403-07:00","dependencies":[{"issue_id":"bd-f8b764c9.9","depends_on_id":"bd-f8b764c9","type":"parent-child","created_at":"2025-10-29T21:24:29.413417-07:00","created_by":"stevey"},{"issue_id":"bd-f8b764c9.9","depends_on_id":"bd-f8b764c9.11","type":"blocks","created_at":"2025-10-29T21:24:29.413823-07:00","created_by":"stevey"}]} -{"id":"bd-fb05","content_hash":"d8c34c8c2f87c9c726a9a5f90d451e65583bd3269180a9ca30d0864bc960aa99","title":"Refactor sqlite.go into focused modules","description":"Split sqlite.go (2,298 lines) into focused modules: migrations.go, ids.go, issues.go, events.go, dirty.go, db.go. This will improve maintainability and reduce cognitive load.","design":"Files to create:\n- migrations.go: Migration registry + runner\n- ids.go: ID generation/validation \n- issues.go: CRUD helpers\n- events.go: Event helpers\n- dirty.go: dirty_issues helpers\n- db.go: New/open, DSN construction\n- tx.go: Transaction helper","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-01T11:41:14.805895-07:00","updated_at":"2025-11-01T22:30:09.833675-07:00","closed_at":"2025-11-01T22:30:09.833675-07:00"} +{"id":"bd-fb05","content_hash":"1d99061e4ac1564982acc5e141674adf3bb7db789d546c12deb9108435af6450","title":"Refactor sqlite.go into focused modules","description":"Split sqlite.go (2,298 lines) into focused modules: migrations.go, ids.go, issues.go, events.go, dirty.go, db.go. This will improve maintainability and reduce cognitive load.","design":"Files to create:\n- migrations.go: Migration registry + runner\n- ids.go: ID generation/validation \n- issues.go: CRUD helpers\n- events.go: Event helpers\n- dirty.go: dirty_issues helpers\n- db.go: New/open, DSN construction\n- tx.go: Transaction helper","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-01T11:41:14.805895-07:00","updated_at":"2025-11-01T22:56:21.902164-07:00","closed_at":"2025-11-01T22:56:21.90217-07:00"} {"id":"bd-fb95094c","content_hash":"99f456d7a5d3a4288c3f60dd65212480c54d3b0161e57d7eccffe01875d2eb5e","title":"Code Health \u0026 Technical Debt Cleanup","description":"Comprehensive codebase cleanup to remove dead code, refactor monolithic files, deduplicate utilities, and improve maintainability. Based on ultrathink code health analysis conducted 2025-10-27.\n\nGoals:\n- Remove ~1,500 LOC of dead/unreachable code\n- Split 2 monolithic files (server.go 2,273 LOC, sqlite.go 2,136 LOC) into focused modules\n- Deduplicate scattered utility functions (normalizeLabels, BD_DEBUG checks)\n- Consolidate test coverage (2,019 LOC of collision tests)\n- Improve code navigation and reduce merge conflicts\n\nImpact: Reduces codebase by ~6-8%, improves maintainability, faster CI/CD\n\nEstimated Effort: 11 days across 4 phases","acceptance_criteria":"- All unreachable code identified by `deadcode` analyzer is removed\n- RPC server split into \u003c500 LOC files with clear responsibilities\n- Duplicate utility functions centralized\n- Test coverage maintained or improved\n- All tests passing\n- Documentation updated","status":"open","priority":2,"issue_type":"epic","created_at":"2025-10-27T20:39:22.22227-07:00","updated_at":"2025-10-30T17:12:58.210295-07:00","labels":["cleanup","epic"]} {"id":"bd-fb95094c.1","content_hash":"d28bd9b00ae5586a782aec012344d1c29eec3bc9fdfa06d5804984a3b3c78e4f","title":"Run final validation and cleanup checks","description":"Final validation pass to ensure all cleanup objectives met and no regressions introduced.\n\nValidation checklist:\n1. Dead code verification: `go run golang.org/x/tools/cmd/deadcode@latest -test ./...`\n2. Test coverage: `go test -cover ./...`\n3. Build verification: `go build ./cmd/bd/`\n4. Linting: `golangci-lint run`\n5. Integration tests\n6. Metrics verification\n7. Git clean check\n\nFinal metrics to report:\n- LOC removed: ~____\n- Files deleted: ____\n- Files created: ____\n- Test coverage: ____%\n- Build time: ____ (before/after)\n- Test run time: ____ (before/after)\n\nImpact: Confirms all cleanup objectives achieved successfully","acceptance_criteria":"- Zero unreachable functions per deadcode analyzer\n- All tests pass: `go test ./...`\n- Test coverage maintained or improved\n- Builds cleanly: `go build ./...`\n- Linting shows improvements\n- Integration tests all pass\n- LOC reduction target achieved (~2,500 LOC)\n- No unintended behavior changes\n- Git commit messages document all changes","notes":"Validation completed:\n- LOC: 52,372 lines total\n- Dead code: 4 functions in import_shared.go (tracked in bd-6fe4622f)\n- Build: ✓ Successful\n- Test coverage: ~20-82% across packages\n- Test failure: TestTwoCloneCollision (timeout issue)\n- Linting: errcheck warnings present (defer close, fmt errors)\n- Test time: ~20s\n\nIssues found:\n1. bd-6fe4622f: Remove unreachable import functions (renameImportedIssuePrefixes, etc)\n2. TestTwoCloneCollision: Daemon killall timeout causing test failure\n3. Linting: errcheck violations need fixing","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T20:32:00.14166-07:00","updated_at":"2025-10-30T17:12:58.209988-07:00","closed_at":"2025-10-28T14:11:25.218801-07:00","labels":["phase-4","validation"],"dependencies":[{"issue_id":"bd-fb95094c.1","depends_on_id":"bd-fb95094c","type":"parent-child","created_at":"2025-10-27T20:32:00.144113-07:00","created_by":"daemon"}]} {"id":"bd-fb95094c.10","content_hash":"0d499f79a6336ca36c7e459e3393cd7cfe471d184e5e443fa9757a22740744ab","title":"Consider central serialization package for JSON handling","description":"Multiple parts of the codebase handle JSON serialization of issues with slightly different approaches. Consider creating a centralized serialization package to ensure consistency.\n\nCurrent serialization locations:\n- `cmd/bd/export.go` - JSONL export (issues to file)\n- `cmd/bd/import.go` - JSONL import (file to issues)\n- `internal/rpc/protocol.go` - RPC JSON marshaling\n- `internal/storage/memory/memory.go` - In-memory marshaling\n\nPotential benefits:\n- Single source of truth for JSON format\n- Consistent field naming\n- Easier to add new fields\n- Centralized validation\n\nNote: This is marked **optional** because:\n- Current serialization mostly works\n- May not provide enough benefit to justify refactor\n- Risk of breaking compatibility\n\nDecision point: Evaluate if benefits outweigh refactoring cost\n\nImpact: TBD based on investigation - may defer to future work","acceptance_criteria":"- Create serialization package with documented JSON format\n- Migrate export/import to use centralized serialization\n- All existing JSONL files can be read with new code\n- All tests pass: `go test ./...`\n- Export/import round-trip works perfectly\n- RPC protocol unchanged (or backwards compatible)","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-27T20:31:19.090608-07:00","updated_at":"2025-10-30T17:12:58.208871-07:00","labels":["deduplication","optional","phase-3","refactor","serialization"],"dependencies":[{"issue_id":"bd-fb95094c.10","depends_on_id":"bd-fb95094c","type":"parent-child","created_at":"2025-10-27T20:31:19.092328-07:00","created_by":"daemon"}]} @@ -209,6 +209,6 @@ {"id":"bd-fb95094c.7","content_hash":"af7f41ff73c3aaba006d9cfbf8e35332e25d5b42f9e620b5e94d41c05550ea81","title":"Extract SQLite migrations into separate files","description":"The file `internal/storage/sqlite/sqlite.go` is 2,136 lines and contains 11 sequential migrations alongside core storage logic. Extract migrations into a versioned system.\n\nCurrent issues:\n- 11 migration functions mixed with core logic\n- Hard to see migration history\n- Sequential migrations slow database open\n- No clear migration versioning\n\nMigration functions to extract:\n- `migrateDirtyIssuesTable()`\n- `migrateIssueCountersTable()`\n- `migrateExternalRefColumn()`\n- `migrateCompositeIndexes()`\n- `migrateClosedAtConstraint()`\n- `migrateCompactionColumns()`\n- `migrateSnapshotsTable()`\n- `migrateCompactionConfig()`\n- `migrateCompactedAtCommitColumn()`\n- `migrateExportHashesTable()`\n- Plus 1 more (11 total)\n\nTarget structure:\n```\ninternal/storage/sqlite/\n├── sqlite.go # Core storage (~800 lines)\n├── schema.go # Table definitions (~200 lines)\n├── migrations.go # Migration orchestration (~200 lines)\n└── migrations/ # Individual migrations\n ├── 001_initial_schema.go\n ├── 002_dirty_issues.go\n ├── 003_issue_counters.go\n [... through 011_export_hashes.go]\n```\n\nBenefits:\n- Clear migration history\n- Each migration self-contained\n- Easier to review migration changes in PRs\n- Future migrations easier to add","acceptance_criteria":"- All 11 migrations extracted to separate files\n- Migration version tracking in database\n- Migrations run in order on fresh database\n- Existing databases upgrade correctly\n- All tests pass: `go test ./internal/storage/sqlite/...`\n- Database initialization time unchanged or improved\n- Add migration rollback capability (optional, nice-to-have)","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-27T20:30:47.870671-07:00","updated_at":"2025-10-30T17:12:58.207682-07:00","labels":["database","phase-2","refactor"],"dependencies":[{"issue_id":"bd-fb95094c.7","depends_on_id":"bd-fb95094c","type":"parent-child","created_at":"2025-10-27T20:30:47.875564-07:00","created_by":"daemon"}]} {"id":"bd-fb95094c.8","content_hash":"8a8df680150f73fef6ac9cede6a1b2b0033406b35553a8a3795b13a542cd62f1","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","acceptance_criteria":"- Remove unreachable functions\n- If entire files can be deleted (like hash.go), delete them\n- For SummarizeTier2: decide to implement or delete, document decision\n- All tests pass: `go test ./...`\n- Verify no callers exist for each function","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T20:30:19.963392-07:00","updated_at":"2025-10-30T17:12:58.206334-07:00","closed_at":"2025-10-28T14:14:55.724226-07:00","labels":["cleanup","dead-code","phase-1"],"dependencies":[{"issue_id":"bd-fb95094c.8","depends_on_id":"bd-fb95094c","type":"parent-child","created_at":"2025-10-27T20:30:19.968126-07:00","created_by":"daemon"}]} {"id":"bd-fb95094c.9","content_hash":"404b82a19dde2fdece7eb6bb3b816db7906e81a03a5a05341ed631af7a2a8e87","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","acceptance_criteria":"- Remove the 4 unreachable methods (~80 LOC total)\n- Verify no callers: `grep -r \"GetLastImportTime\\|SetLastImportTime\\|findJSONLPath\" .`\n- All tests pass: `go test ./internal/rpc/...`\n- Daemon functionality works: test daemon start/stop/operations","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T20:30:19.962209-07:00","updated_at":"2025-10-30T17:12:58.201466-07:00","closed_at":"2025-10-28T16:07:26.103703-07:00","labels":["cleanup","dead-code","phase-1","rpc"],"dependencies":[{"issue_id":"bd-fb95094c.9","depends_on_id":"bd-fb95094c","type":"parent-child","created_at":"2025-10-27T20:30:19.965239-07:00","created_by":"daemon"}]} -{"id":"bd-fc2d","content_hash":"f3677662a3659a99c69bfaaa3fa019a3c525ce9a8c2d25ae3cd786e05eb1098f","title":"Refactor sqlite.go (2298 lines)","description":"Break down internal/storage/sqlite/sqlite.go into smaller, more focused modules. The file is currently 2298 lines and should be split into logical components.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-01T19:28:40.899111-07:00","updated_at":"2025-11-01T22:21:01.729379-07:00","closed_at":"2025-11-01T22:21:01.729379-07:00"} -{"id":"bd-fd56","content_hash":"71946aa48a3fa7836f905d340f73428416aeb8a190069ff3bb737eafbeed0d5e","title":"Wrap git operations in GitClient interface","description":"Create internal/daemonrunner/git.go with GitClient interface (HasUpstream, HasChanges, Commit, Push, Pull). Default implementation using os/exec. Use in Syncer and Run loop for testability.","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-01T11:41:14.88734-07:00","updated_at":"2025-11-01T11:41:14.88734-07:00"} +{"id":"bd-fc2d","content_hash":"f3677662a3659a99c69bfaaa3fa019a3c525ce9a8c2d25ae3cd786e05eb1098f","title":"Refactor sqlite.go (2298 lines)","description":"Break down internal/storage/sqlite/sqlite.go into smaller, more focused modules. The file is currently 2298 lines and should be split into logical components.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-01T19:28:40.899111-07:00","updated_at":"2025-11-01T21:43:55.870724-07:00","closed_at":"2025-11-01T21:43:55.870724-07:00"} +{"id":"bd-fd56","content_hash":"71946aa48a3fa7836f905d340f73428416aeb8a190069ff3bb737eafbeed0d5e","title":"Wrap git operations in GitClient interface","description":"Create internal/daemonrunner/git.go with GitClient interface (HasUpstream, HasChanges, Commit, Push, Pull). Default implementation using os/exec. Use in Syncer and Run loop for testability.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T11:41:14.88734-07:00","updated_at":"2025-11-01T22:56:08.354697-07:00","closed_at":"2025-11-01T22:56:08.354697-07:00"} {"id":"bd-fd8753d9","content_hash":"ae13fc833baa7d586a48ca62648dd4f0ee61fcc96aa1f238fb2639b6657b07da","title":"Document bd edit command and verify MCP exclusion","description":"Follow-up from PR #152:\n1. Add \"bd edit\" to AGENTS.md with \"Humans only\" note\n2. Verify MCP server doesn't expose bd edit command\n3. Consider adding test for command registration","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-26T13:23:47.982295-07:00","updated_at":"2025-10-30T17:12:58.226229-07:00"}