diff --git a/.beads/beads.jsonl b/.beads/beads.jsonl index 67c1870d..64f0a56f 100644 --- a/.beads/beads.jsonl +++ b/.beads/beads.jsonl @@ -1,7 +1,7 @@ {"id":"bd-0088","content_hash":"7449088a4560a2a2821eeda8dca1e44c0017667314236a13df8d8112cda20101","title":"Create npm package structure for bd-wasm","description":"Set up npm package for distribution:\n- Create package.json with bd-wasm name\n- Bundle bd.wasm + wasm_exec.js\n- Create CLI wrapper (bin/bd) that invokes WASM\n- Add installation scripts if needed\n- Configure package for Claude Code Web sandbox compatibility","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-02T21:58:07.295058-08:00","updated_at":"2025-11-03T20:56:22.700641-08:00","closed_at":"2025-11-03T20:56:22.700641-08:00","source_repo":".","dependencies":[{"issue_id":"bd-0088","depends_on_id":"bd-44d0","type":"parent-child","created_at":"2025-11-02T22:23:49.475356-08:00","created_by":"stevey"}]} {"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","source_repo":"."} {"id":"bd-02a4","content_hash":"fbaca84d9502239656f05a14f62e8e6adec8f8dd492b1e91694fefcd0bdf310c","title":"Modify CreateIssue to support parent resurrection","description":"Update internal/storage/sqlite/sqlite.go:182-196 to call TryResurrectParent before failing on missing parent. Coordinate with EnsureIDs changes for consistent behavior. Handle edge case where parent never existed in JSONL (fail gracefully).","status":"closed","priority":0,"issue_type":"task","created_at":"2025-11-04T12:31:59.701571-08:00","updated_at":"2025-11-05T00:08:42.811436-08:00","closed_at":"2025-11-05T00:08:42.81144-08:00","source_repo":"."} -{"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-11-20T12:40:11.705915-05:00","updated_at":"2025-11-20T12:40:11.705915-05:00","closed_at":"2025-10-29T16:15:10.64719-07:00","source_repo":"."} +{"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-11-22T15:18:47.42617776-07:00","updated_at":"2025-11-22T15:18:47.42617776-07:00","closed_at":"2025-10-29T16:15:10.64719-07:00","source_repo":"."} {"id":"bd-0458","content_hash":"c4427da2aec84621525f7f286c626f6c94365a7e6ff8e35e9676b184c85e1adb","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-02T12:32:00.157369-08:00","closed_at":"2025-11-02T12:32:00.157375-08:00","source_repo":"."} {"id":"bd-05a1","content_hash":"b79b0efa41b4eca8d7e5ab9738d5ecaa403c35497877a056a502efe0583ca251","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-02T12:32:00.158054-08:00","closed_at":"2025-11-02T12:32:00.158057-08:00","source_repo":"."} {"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","source_repo":"."} @@ -15,7 +15,7 @@ {"id":"bd-0a43","content_hash":"36ff43c769f6b0d227c892b20c3af9b1092b38e06cc0f31c0d7c313528be716e","title":"Split monolithic sqlite.go into focused files","description":"internal/storage/sqlite/sqlite.go is 1050 lines containing initialization, 20+ CRUD methods, query building, and schema management.\n\nSplit into:\n- store.go: Store struct \u0026 initialization (150 lines)\n- bead_queries.go: Bead CRUD (300 lines)\n- work_queries.go: Work queries (200 lines) \n- stats_queries.go: Statistics (150 lines)\n- schema.go: Schema \u0026 migrations (150 lines)\n- helpers.go: Common utilities (100 lines)\n\nImpact: Impossible to understand at a glance; hard to find specific functionality; high cognitive load\n\nEffort: 6-8 hours","status":"open","priority":0,"issue_type":"task","created_at":"2025-11-16T14:51:16.520465-08:00","updated_at":"2025-11-16T14:51:16.520465-08:00","source_repo":"."} {"id":"bd-0a90","content_hash":"8f19f9a9e01ccf3a4dd42673a84610f2550db9a9e744806105dc3b9e070f4e46","title":"bd show --json doesn't include dependency type field","description":"Fix GitHub issue #202. The JSON output from bd show and bd list commands should include the dependency type field (and optionally created_at, created_by) to match internal storage format and enable better tooling integration.","notes":"PR #203 updated with cleaner implementation: https://github.com/steveyegge/beads/pull/203\n\n## Final Implementation\n\nCleanest possible approach - no internal helper methods needed:\n\n**Design:**\n- `GetDependenciesWithMetadata()` / `GetDependentsWithMetadata()` - canonical implementations with full SQL query\n- `GetDependencies()` / `GetDependents()` - thin wrappers that strip metadata for backward compat\n- `scanIssuesWithDependencyType()` - shared helper for scanning rows with dependency type\n\n**Benefits:**\n- Single source of truth - the `...WithMetadata()` methods ARE the implementation\n- Eliminated ~139 lines of duplicated SQL and scanning code\n- All tests passing (14 dependency-related tests)\n- Backward compatible\n- dependency_type field appears correctly in JSON output\n\n**Note on scan helpers:**\nThe duplication between `scanIssues()` and `scanIssuesWithDependencyType()` is necessary because they handle different SQL result shapes (16 vs 17 columns). This is justified as they serve fundamentally different purposes based on query structure.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-02T09:42:08.712725096Z","updated_at":"2025-11-02T11:50:54.292546-08:00","closed_at":"2025-11-02T11:50:54.292546-08:00","external_ref":"https://github.com/steveyegge/beads/issues/202","source_repo":"."} {"id":"bd-0d9c","content_hash":"a61ba371d6c50f21a92e4debeaaa00a4c3eb77ef96fbcdfa89f80e9b13ffff7a","title":"YABB: Spurious issue updates during normal operations","description":"Issue bd-627d was updated during config refactoring session without any actual changes to it. Only timestamps and content_hash changed.\n\nObserved: Running various bd commands (list, create, etc.) caused bd-627d updated_at to change from 14:14 to 14:31.\n\nExpected: Issues should only be updated when explicitly modified.\n\nThis causes:\n- Dirty JSONL after every session\n- False conflicts in git\n- Confusing git history\n\nLikely culprit: Daemon auto-import/export cycle or database migration touching all issues.","notes":"Investigated thoroughly - unable to reproduce. The import logic has IssueDataChanged() checks before calling UpdateIssue (importer/importer.go:458). All tests pass. May have been fixed by recent refactorings. Closing as cannot reproduce - please reopen with specific repro steps if it occurs again.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-02T14:36:31.023552-08:00","updated_at":"2025-11-02T16:27:39.023535-08:00","closed_at":"2025-11-02T16:27:39.023539-08:00","source_repo":"."} -{"id":"bd-0dcea000","content_hash":"5f3eccf8635195729691e83818486c31c81e608d939e03a2241f944f645ce90d","title":"Add tests for internal/importer package","description":"Currently 0.0% coverage. Need tests for JSONL import logic including collision detection and resolution.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T14:06:21.071024-07:00","updated_at":"2025-11-08T22:42:08.859374-08:00","closed_at":"2025-11-08T18:06:20.150657-08:00","source_repo":".","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-0dcea000","content_hash":"5f3eccf8635195729691e83818486c31c81e608d939e03a2241f944f645ce90d","title":"Add tests for internal/importer package","description":"Currently 0.0% coverage. Need tests for JSONL import logic including collision detection and resolution.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T14:06:21.071024-07:00","updated_at":"2025-11-11T08:42:34.990591143-07:00","closed_at":"2025-11-08T18:06:20.150657-08:00","source_repo":".","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-0do3","content_hash":"e6d85ab6360e5704e3d6792eade15bbec8d19d13b878c15e4021f3375cb3d515","title":"Test issue 0","description":"","status":"closed","priority":0,"issue_type":"task","created_at":"2025-11-07T19:00:15.156832-08:00","updated_at":"2025-11-07T22:07:17.340826-08:00","closed_at":"2025-11-07T21:55:09.425092-08:00","source_repo":"."} {"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","source_repo":"."} {"id":"bd-0e74","content_hash":"d8ab25b7a6ac1ba0e5012677cac3ac1320d3ca1059df97c979aab8c43ecb579d","title":"Comprehensive testing for separate branch workflow","description":"Comprehensive testing for separate branch workflow including unit tests, integration tests, and performance testing.\n\nTasks:\n- Unit tests for worktree management\n- Unit tests for config parsing\n- Integration tests: create/update/close → beads branch\n- Integration test: merge beads → main\n- Integration test: protected branch scenario\n- Integration test: network failure recovery\n- Integration test: config change handling\n- Manual testing guide\n- Performance testing (worktree overhead)\n\nTest scenarios: fresh setup, issue operations, merge workflow, protected branch, error handling, migration, multiple workspaces, sparse checkout\n\nEstimated effort: 4-5 days","acceptance_criteria":"- All unit tests pass\n- All integration tests pass\n- Manual testing guide works\n- No data loss in any scenario\n- Performance acceptable (\u003c 100ms overhead per commit)","notes":"Completed comprehensive test coverage. Added 4 new integration tests: config change handling, multiple concurrent clones (3-way), performance testing (avg 77ms \u003c 150ms target), and network failure recovery. All tests pass. Coverage includes fresh setup, issue ops, error handling, multiple workspaces, sparse checkout, config changes, network failures, and performance.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-02T15:22:35.580741-08:00","updated_at":"2025-11-02T21:40:35.337464-08:00","closed_at":"2025-11-02T21:40:35.337468-08:00","source_repo":".","dependencies":[{"issue_id":"bd-0e74","depends_on_id":"bd-a101","type":"parent-child","created_at":"2025-11-02T15:22:51.348226-08:00","created_by":"stevey"}]} @@ -47,7 +47,7 @@ {"id":"bd-1f4086c5.1","content_hash":"ba5173c61613a29786641ba06a93427de87bed65ce39dbc3c3ddd2b6900f827e","title":"Integration test: mutation to export latency","description":"Measure time from bd create to JSONL update. Verify \u003c500ms latency. Test with multiple rapid mutations to verify batching.","notes":"Test added to daemon_test.go as TestMutationToExportLatency().\n\nCurrently skipped with note that it should be enabled once bd-146 (event-driven daemon) is fully implemented and enabled by default.\n\nThe test structure is complete:\n1. Sets up test environment with fast debounce (500ms)\n2. SingleMutationLatency: measures latency from mutation to JSONL update\n3. RapidMutationBatching: verifies multiple mutations batch into single export\n\nOnce event-driven mode is default, remove the t.Skip() line and the test will validate \u003c500ms latency.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T20:49:49.103759-07:00","updated_at":"2025-10-30T17:12:58.195867-07:00","closed_at":"2025-10-29T14:19:19.808139-07:00","source_repo":".","dependencies":[{"issue_id":"bd-1f4086c5.1","depends_on_id":"bd-1f4086c5","type":"parent-child","created_at":"2025-10-29T20:49:49.107244-07:00","created_by":"import-remap"}]} {"id":"bd-1f64","content_hash":"80f404d7c0f06c7f4bc6d52ac02c1a002a95ac7cb60c6485b2ceed5e013dad75","title":"Add comprehensive tests for config.yaml issue-prefix migration","description":"The GH #209 config.yaml migration lacks test coverage:\n\nMissing tests:\n- config.SetIssuePrefix() edge cases (empty file, comments, malformed YAML)\n- config.GetIssuePrefix() with various config states\n- MigrateConfigToYAML() automatic migration logic\n- bd init writing to config.yaml instead of DB\n- bd migrate DB→config.yaml migration path\n\nTest scenarios needed:\n1. SetIssuePrefix with empty config.yaml\n2. SetIssuePrefix with existing config.yaml (preserves other settings)\n3. SetIssuePrefix with commented issue-prefix line\n4. SetIssuePrefix atomic write (temp file cleanup)\n5. GetIssuePrefix fallback behavior\n6. MigrateConfigToYAML when config.yaml missing prefix but DB has it\n7. MigrateConfigToYAML when both missing (detect from issues)\n8. MigrateConfigToYAML when config.yaml already has prefix (no-op)\n9. Integration test: fresh bd init writes to config.yaml only\n10. Integration test: upgrade from v0.21 DB migrates to config.yaml\n\nPriority 1 because this is a user-facing migration affecting all users upgrading to v0.22.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-03T22:33:43.08753-08:00","updated_at":"2025-11-03T22:46:16.306565-08:00","closed_at":"2025-11-03T22:46:16.306565-08:00","source_repo":"."} {"id":"bd-1fkr","content_hash":"ad8fd9d0254ef9f4ff430253234569af0a606b5d813ee98995dc5a6a2cbf897b","title":"bd-hv01: Storage backend extensibility broken by type assertion","description":"Problem: deletion_tracking.go:69-82 uses type assertion for DeleteIssue which breaks if someone adds a new storage backend.\n\nFix: Check capability before starting merge or add DeleteIssue to Storage interface.\n\nFiles: cmd/bd/deletion_tracking.go:69-82, internal/storage/storage.go","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-06T18:16:20.770662-08:00","updated_at":"2025-11-06T18:55:08.666253-08:00","closed_at":"2025-11-06T18:55:08.666253-08:00","source_repo":".","dependencies":[{"issue_id":"bd-1fkr","depends_on_id":"bd-rbxi","type":"parent-child","created_at":"2025-11-06T18:19:14.925961-08:00","created_by":"daemon"}]} -{"id":"bd-1h8","content_hash":"10db44963b46b664cb6c20b76a6a06eac7295767799f2bff4c27c28c80889c19","title":"Fix compact --analyze/--apply error messages to clarify direct mode requirement","description":"**Problem:**\nWhen users run `bd compact --analyze` with daemon running, they get:\n```\nError: compact requires SQLite storage\n```\n\nThis is misleading because they ARE using SQLite (via daemon), but the command needs DIRECT SQLite access.\n\n**Current behavior:**\n- Error message suggests they don't have SQLite\n- No hint about using --no-daemon flag\n- Related to issue #349 item #1\n\n**Proposed fix:**\n1. Update error messages in cmd/bd/compact.go lines 106-114 (analyze) and 121-137 (apply)\n2. Add explicit hint: \"Use --no-daemon flag to bypass daemon\"\n3. Change SQLite check error from \"requires SQLite storage\" to \"failed to open database in direct mode\"\n\n**Files to modify:**\n- cmd/bd/compact.go (lines ~106-137)\n\n**Testing:**\n- Run with daemon: `bd compact --analyze` should show clear error + hint\n- Run with --no-daemon: `bd compact --analyze --no-daemon` should work\n- Verify error message is actionable","design":"Change error messages to be explicit about direct mode requirement:\n\n```go\nif err := ensureDirectMode(\"compact --analyze requires direct database access\"); err != nil {\n fmt.Fprintf(os.Stderr, \"Error: %v\\n\", err)\n fmt.Fprintf(os.Stderr, \"Hint: Use --no-daemon flag to bypass daemon and access database directly\\n\")\n os.Exit(1)\n}\n```\n\nFor SQLite check failure:\n```go\nif !ok {\n fmt.Fprintf(os.Stderr, \"Error: failed to open database in direct mode\\n\")\n fmt.Fprintf(os.Stderr, \"Hint: Ensure .beads/beads.db exists and is readable\\n\")\n os.Exit(1)\n}\n```","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-20T20:47:45.606924-05:00","updated_at":"2025-11-20T20:59:13.406952-05:00","closed_at":"2025-11-20T20:59:13.406952-05:00","source_repo":".","labels":["bug","documentation","ux"],"comments":[{"id":33,"issue_id":"bd-1h8","author":"stevey","text":"Addresses GitHub issue #349 item 1: https://github.com/steveyegge/beads/issues/349\n\nUser reported misleading error when running 'bd compact --analyze' with daemon active. Error says 'requires SQLite storage' but user IS using SQLite via daemon - the real issue is that --analyze mode needs DIRECT database access.","created_at":"2025-11-22T07:53:00Z"}]} +{"id":"bd-1h8","content_hash":"10db44963b46b664cb6c20b76a6a06eac7295767799f2bff4c27c28c80889c19","title":"Fix compact --analyze/--apply error messages to clarify direct mode requirement","description":"**Problem:**\nWhen users run `bd compact --analyze` with daemon running, they get:\n```\nError: compact requires SQLite storage\n```\n\nThis is misleading because they ARE using SQLite (via daemon), but the command needs DIRECT SQLite access.\n\n**Current behavior:**\n- Error message suggests they don't have SQLite\n- No hint about using --no-daemon flag\n- Related to issue #349 item #1\n\n**Proposed fix:**\n1. Update error messages in cmd/bd/compact.go lines 106-114 (analyze) and 121-137 (apply)\n2. Add explicit hint: \"Use --no-daemon flag to bypass daemon\"\n3. Change SQLite check error from \"requires SQLite storage\" to \"failed to open database in direct mode\"\n\n**Files to modify:**\n- cmd/bd/compact.go (lines ~106-137)\n\n**Testing:**\n- Run with daemon: `bd compact --analyze` should show clear error + hint\n- Run with --no-daemon: `bd compact --analyze --no-daemon` should work\n- Verify error message is actionable","design":"Change error messages to be explicit about direct mode requirement:\n\n```go\nif err := ensureDirectMode(\"compact --analyze requires direct database access\"); err != nil {\n fmt.Fprintf(os.Stderr, \"Error: %v\\n\", err)\n fmt.Fprintf(os.Stderr, \"Hint: Use --no-daemon flag to bypass daemon and access database directly\\n\")\n os.Exit(1)\n}\n```\n\nFor SQLite check failure:\n```go\nif !ok {\n fmt.Fprintf(os.Stderr, \"Error: failed to open database in direct mode\\n\")\n fmt.Fprintf(os.Stderr, \"Hint: Ensure .beads/beads.db exists and is readable\\n\")\n os.Exit(1)\n}\n```","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-20T20:47:45.606924-05:00","updated_at":"2025-11-20T21:51:31.7997-05:00","closed_at":"2025-11-20T20:59:13.406952-05:00","source_repo":".","labels":["bug","documentation","ux"],"comments":[{"id":8,"issue_id":"bd-1h8","author":"stevey","text":"Addresses GitHub issue #349 item 1: https://github.com/steveyegge/beads/issues/349\n\nUser reported misleading error when running 'bd compact --analyze' with daemon active. Error says 'requires SQLite storage' but user IS using SQLite via daemon - the real issue is that --analyze mode needs DIRECT database access.","created_at":"2025-11-21T13:58:10Z"}]} {"id":"bd-1ls","content_hash":"af79708476d560abaac3cbe9c537bcf43c2100dcb1d676954ea604486f75d199","title":"Override test","description":"## Overview\n\n[Describe the high-level goal and scope of this epic]\n\n## Success Criteria\n\n- [ ] Criteria 1\n- [ ] Criteria 2\n- [ ] Criteria 3\n\n## Background\n\n[Provide context and motivation]\n\n## Scope\n\n**In Scope:**\n- Item 1\n- Item 2\n\n**Out of Scope:**\n- Item 1\n- Item 2\n","design":"## Architecture\n\n[Describe the overall architecture and approach]\n\n## Components\n\n- Component 1: [description]\n- Component 2: [description]\n\n## Dependencies\n\n[List external dependencies or constraints]\n","acceptance_criteria":"- [ ] All child issues are completed\n- [ ] Integration tests pass\n- [ ] Documentation is updated\n- [ ] Code review completed\n","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-03T20:15:10.01471-08:00","updated_at":"2025-11-03T22:07:10.946574-08:00","closed_at":"2025-11-03T22:07:10.946574-08:00","source_repo":".","labels":["epic"]} {"id":"bd-1mzt","content_hash":"3dffe5c0934f51c6fa526a952a975e808665d80e7c69dffbe910aabc87d32a7b","title":"Client self-heal: remove stale pid when lock free + socket missing","description":"When client detects:\n- Socket is missing AND\n- tryDaemonLock shows lock NOT held\n\nThen automatically:\n1. Remove stale daemon.pid file\n2. Optionally auto-start daemon (behind BEADS_AUTO_START_DAEMON=1 env var)\n\nThis prevents stale artifacts from accumulating after daemon crashes.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-07T16:42:12.75205-08:00","updated_at":"2025-11-07T22:07:17.342845-08:00","closed_at":"2025-11-07T21:21:15.317562-08:00","source_repo":".","dependencies":[{"issue_id":"bd-1mzt","depends_on_id":"bd-ndyz","type":"discovered-from","created_at":"2025-11-07T16:42:12.753099-08:00","created_by":"daemon"}]} {"id":"bd-1pj6","content_hash":"de1c1195b29d9a70c88b5f2b05ca1c3497469d1802f9c0be415d5a44b0575deb","title":"Proposal: Custom status states via config","description":"Proposal to add 'custom status states' via `bd config`.\nUsers could define an optional issue status enum (e.g., awaiting_review, review_in_progress) in the config.\nThis would enable multi-step pipelines to process issues where each step correlates to a specific status.\n\nExamples:\n- awaiting_verification\n- awaiting_docs\n- awaiting_testing\n","status":"open","priority":3,"issue_type":"feature","created_at":"2025-11-20T18:55:48.670499-05:00","updated_at":"2025-11-20T18:55:48.670499-05:00","source_repo":"."} @@ -56,7 +56,7 @@ {"id":"bd-1vv","content_hash":"1db907ddb55edaf7a4c06a566c4e1b8244fcd9ba5d7e2fca4d5c053e424ac515","title":"Add WebSocket support","description":"## Feature Request\n\n[Describe the desired feature]\n\n## Motivation\n\n[Why is this feature needed? What problem does it solve?]\n\n## Use Cases\n\n1. **Use Case 1**: [description]\n2. **Use Case 2**: [description]\n\n## Proposed Solution\n\n[High-level approach to implementing this feature]\n\n## Alternatives Considered\n\n- **Alternative 1**: [description and why not chosen]\n- **Alternative 2**: [description and why not chosen]\n","design":"## Technical Design\n\n[Detailed technical approach]\n\n## API Changes\n\n[New commands, flags, or APIs]\n\n## Data Model Changes\n\n[Database schema changes if any]\n\n## Implementation Notes\n\n- Note 1\n- Note 2\n\n## Testing Strategy\n\n- Unit tests: [scope]\n- Integration tests: [scope]\n- Manual testing: [steps]\n","acceptance_criteria":"- [ ] Feature implements all described use cases\n- [ ] All tests pass\n- [ ] Documentation updated (README, commands)\n- [ ] Examples added if applicable\n- [ ] No performance regressions\n","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-03T19:56:41.271215-08:00","updated_at":"2025-11-03T19:56:41.271215-08:00","source_repo":".","labels":["feature"]} {"id":"bd-1yi5","content_hash":"11044802d32a77f8ca574ca5902939bcc7e252880437bea7281aaf445db8db84","title":"Use -short flag in CI for PR checks","description":"Update CI configuration to use -short flag for PR checks, run full tests nightly.\n\nThe slow tests already support testing.Short() and will be skipped.\n\nExpected savings: ~20 seconds for PR checks (fast tests only)\n\nImplementation:\n- Update .github/workflows/ci.yml to add -short flag for PR tests\n- Create/update nightly workflow for full test runs\n- Update README/docs about test strategy\n\nFile: .github/workflows/ci.yml:30","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-04T01:24:17.279618-08:00","updated_at":"2025-11-04T10:25:10.616119-08:00","closed_at":"2025-11-04T10:25:10.616119-08:00","source_repo":".","dependencies":[{"issue_id":"bd-1yi5","depends_on_id":"bd-l5gq","type":"blocks","created_at":"2025-11-04T01:24:17.280453-08:00","created_by":"daemon"}]} {"id":"bd-22e0bde9","content_hash":"532c3b7af57bcf046114e2a3e9519fd07729251b3e81450a772d75d920d63e5d","title":"Add TestNWayCollision for 5+ clones","description":"## Overview\nAdd comprehensive tests for N-way (5+) collision resolution to verify the solution scales beyond 3 clones.\n\n## Purpose\nWhile TestThreeCloneCollision validates the basic N-way case, we need to verify:\n1. Solution scales to arbitrary N\n2. Performance is acceptable with more clones\n3. Convergence time is bounded\n4. No edge cases in larger collision groups\n\n## Implementation Tasks\n\n### 1. Create TestFiveCloneCollision\nFile: beads_twoclone_test.go (or new beads_nway_test.go)\n\n```go\nfunc TestFiveCloneCollision(t *testing.T) {\n // Test with 5 clones creating same ID with different content\n // Verify all 5 clones converge after sync rounds\n \n t.Run(\"SequentialSync\", func(t *testing.T) {\n testNCloneCollision(t, 5, \"A\", \"B\", \"C\", \"D\", \"E\")\n })\n \n t.Run(\"ReverseSync\", func(t *testing.T) {\n testNCloneCollision(t, 5, \"E\", \"D\", \"C\", \"B\", \"A\")\n })\n \n t.Run(\"RandomSync\", func(t *testing.T) {\n testNCloneCollision(t, 5, \"C\", \"A\", \"E\", \"B\", \"D\")\n })\n}\n```\n\n### 2. Implement generalized testNCloneCollision\nGeneralize the 3-clone test to handle arbitrary N:\n\n```go\nfunc testNCloneCollision(t *testing.T, numClones int, syncOrder ...string) {\n t.Helper()\n \n if len(syncOrder) != numClones {\n t.Fatalf(\"syncOrder length (%d) must match numClones (%d)\", \n len(syncOrder), numClones)\n }\n \n tmpDir := t.TempDir()\n \n // Setup remote and N clones\n remoteDir := setupBareRepo(t, tmpDir)\n cloneDirs := make(map[string]string)\n \n for i := 0; i \u003c numClones; i++ {\n name := string(rune('A' + i))\n cloneDirs[name] = setupClone(t, tmpDir, remoteDir, name)\n }\n \n // Each clone creates issue with same ID but different content\n for name, dir := range cloneDirs {\n createIssue(t, dir, fmt.Sprintf(\"Issue from clone %s\", name))\n }\n \n // Sync in specified order\n for _, name := range syncOrder {\n syncClone(t, cloneDirs[name], name)\n }\n \n // Final pull for convergence\n for name, dir := range cloneDirs {\n finalPull(t, dir, name)\n }\n \n // Verify all clones have all N issues\n expectedTitles := make(map[string]bool)\n for i := 0; i \u003c numClones; i++ {\n name := string(rune('A' + i))\n expectedTitles[fmt.Sprintf(\"Issue from clone %s\", name)] = true\n }\n \n for name, dir := range cloneDirs {\n titles := getTitles(t, dir)\n if !compareTitleSets(titles, expectedTitles) {\n t.Errorf(\"Clone %s missing issues: expected %v, got %v\", \n name, expectedTitles, titles)\n }\n }\n \n t.Log(\"✓ All\", numClones, \"clones converged successfully\")\n}\n```\n\n### 3. Add performance benchmarks\nTest convergence time and memory usage:\n\n```go\nfunc BenchmarkNWayCollision(b *testing.B) {\n for _, n := range []int{3, 5, 10, 20} {\n b.Run(fmt.Sprintf(\"N=%d\", n), func(b *testing.B) {\n for i := 0; i \u003c b.N; i++ {\n // Run N-way collision and measure time\n testNCloneCollisionBench(b, n)\n }\n })\n }\n}\n```\n\n### 4. Add convergence time tests\nVerify bounded convergence:\n\n```go\nfunc TestConvergenceTime(t *testing.T) {\n // Test that convergence happens within expected rounds\n // For N clones, should converge in at most N-1 sync rounds\n \n for n := 3; n \u003c= 10; n++ {\n t.Run(fmt.Sprintf(\"N=%d\", n), func(t *testing.T) {\n rounds := measureConvergenceRounds(t, n)\n maxExpected := n - 1\n if rounds \u003e maxExpected {\n t.Errorf(\"Convergence took %d rounds, expected ≤ %d\", \n rounds, maxExpected)\n }\n })\n }\n}\n```\n\n### 5. Add edge case tests\nTest boundary conditions:\n- All N clones have identical content (dedup works)\n- N-1 clones have same content, 1 differs\n- All N clones have unique content\n- Mix of collisions and non-collisions\n\n## Acceptance Criteria\n- TestFiveCloneCollision passes with all sync orders\n- All 5 clones converge to identical content\n- Performance is acceptable (\u003c 5 seconds for 5 clones)\n- Convergence time is bounded (≤ N-1 rounds)\n- Edge cases handled correctly\n- Benchmarks show scalability to 10+ clones\n\n## Files to Create/Modify\n- beads_twoclone_test.go or beads_nway_test.go\n- Add helper functions for N-clone setup\n\n## Testing Strategy\n\n### Test Matrix\n| N Clones | Sync Orders | Expected Result |\n|----------|-------------|-----------------|\n| 3 | A→B→C | Pass |\n| 3 | C→B→A | Pass |\n| 5 | A→B→C→D→E | Pass |\n| 5 | E→D→C→B→A | Pass |\n| 5 | Random | Pass |\n| 10 | Sequential | Pass |\n\n### Performance Targets\n- 3 clones: \u003c 2 seconds\n- 5 clones: \u003c 5 seconds\n- 10 clones: \u003c 15 seconds\n\n## Dependencies\n- Requires bd-cbed9619.5, bd-cbed9619.4, bd-cbed9619.3, bd-cbed9619.2 to be completed\n- TestThreeCloneCollision must pass first\n\n## Success Metrics\n- All tests pass for N ∈ {3, 5, 10}\n- Convergence time scales linearly (O(N))\n- Memory usage reasonable (\u003c 100MB for 10 clones)\n- No data corruption or loss in any scenario","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T23:05:13.974702-07:00","updated_at":"2025-10-31T12:00:43.197709-07:00","closed_at":"2025-10-31T12:00:43.197709-07:00","source_repo":"."} -{"id":"bd-23a8","content_hash":"7c54bea4624429ff0842a192489979e0a1eafdd872027a0934b1a1d9b0e80d33","title":"Test simple issue","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-02T17:11:04.464726-08:00","updated_at":"2025-11-04T11:10:23.529727-08:00","closed_at":"2025-11-04T11:10:23.529731-08:00","source_repo":".","comments":[{"id":24,"issue_id":"bd-23a8","author":"stevey","text":"Testing the new bd comment alias!","created_at":"2025-11-22T07:09:48Z"},{"id":25,"issue_id":"bd-23a8","author":"stevey","text":"Another test with JSON output","created_at":"2025-11-22T07:09:48Z"},{"id":26,"issue_id":"bd-23a8","author":"stevey","text":"Test comment from file\n","created_at":"2025-11-22T07:09:48Z"}]} +{"id":"bd-23a8","content_hash":"7c54bea4624429ff0842a192489979e0a1eafdd872027a0934b1a1d9b0e80d33","title":"Test simple issue","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-02T17:11:04.464726-08:00","updated_at":"2025-11-04T11:10:23.529727-08:00","closed_at":"2025-11-04T11:10:23.529731-08:00","source_repo":".","comments":[{"id":1,"issue_id":"bd-23a8","author":"stevey","text":"Testing the new bd comment alias!","created_at":"2025-11-08T20:26:48Z"},{"id":2,"issue_id":"bd-23a8","author":"stevey","text":"Another test with JSON output","created_at":"2025-11-08T20:26:48Z"},{"id":3,"issue_id":"bd-23a8","author":"stevey","text":"Test comment from file\n","created_at":"2025-11-08T20:26:48Z"}]} {"id":"bd-248bdc3e","content_hash":"85c98bac3b48e3cc8466d1b60e4a690fe198c4f795160cf175d7add4691749b5","title":"Add optional post-merge git hook example for bd sync","description":"Create example git hook that auto-runs bd sync after git pull/merge.\n\nAdd to examples/git-hooks/:\n- post-merge hook that checks if .beads/issues.jsonl changed\n- If changed: run `bd sync` automatically\n- Make it optional/documented (not auto-installed)\n\nBenefits:\n- Zero-friction sync after git pull\n- Complements auto-detection as belt-and-suspenders\n\nNote: post-merge hook already exists for pre-commit/post-merge. Extend it to support sync.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-25T22:47:14.668842-07:00","updated_at":"2025-11-06T20:06:49.217298-08:00","closed_at":"2025-11-06T19:51:37.787964-08:00","source_repo":"."} {"id":"bd-2530","content_hash":"ac8bc0c4d75082ac76200d092b3c1c476fd1523c9e83b890f829ee3dd7dcbb3d","title":"Issue with labels","description":"This is a description","design":"Use MVC pattern","acceptance_criteria":"All tests pass","status":"closed","priority":0,"issue_type":"feature","created_at":"2025-10-31T21:40:34.630173-07:00","updated_at":"2025-11-01T11:11:57.93151-07:00","closed_at":"2025-11-01T11:11:57.93151-07:00","source_repo":".","labels":["bug","critical"]} {"id":"bd-2752a7a2","content_hash":"064b1ae28914d2cfcca93724e60636c13a6818883dbbb13322772ec93d814170","title":"Create cmd/bd/daemon_watcher.go (~150 LOC)","description":"Implement FileWatcher using fsnotify to watch JSONL file and git refs. Handle platform differences (inotify/FSEvents/ReadDirectoryChangesW). Include edge case handling for file rename, event storm, watcher failure.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T23:05:13.887269-07:00","updated_at":"2025-10-31T18:30:24.131535-07:00","closed_at":"2025-10-31T18:30:24.131535-07:00","source_repo":"."} @@ -83,7 +83,7 @@ {"id":"bd-2ifg","content_hash":"1a32ca6b21a14e121fc8e1026d83d85683cd3ff3b500f56eb8a05398b89ebf51","title":"bd-hv01: Silent partial deletion failures cause DB inconsistency","description":"Problem: deletion_tracking.go:76-77 logs deletion errors as warnings but continues. If deletion fails midway (database locked, disk full), some issues delete but others don't. System thinks all deletions succeeded.\n\nImpact: Database diverges from JSONL, silent corruption, issues may resurrect on next sync.\n\nFix: Collect errors and fail the operation:\nvar deletionErrors []error\nfor _, id := range acceptedDeletions {\n if err := d.DeleteIssue(ctx, id); err != nil {\n deletionErrors = append(deletionErrors, fmt.Errorf(\"issue %s: %w\", id, err))\n }\n}\nif len(deletionErrors) \u003e 0 {\n return false, fmt.Errorf(\"deletion failures: %v\", deletionErrors)\n}\n\nFiles: cmd/bd/deletion_tracking.go:73-82","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-06T18:16:19.465137-08:00","updated_at":"2025-11-06T18:46:55.901973-08:00","closed_at":"2025-11-06T18:46:55.901973-08:00","source_repo":".","dependencies":[{"issue_id":"bd-2ifg","depends_on_id":"bd-rbxi","type":"parent-child","created_at":"2025-11-06T18:19:14.833477-08:00","created_by":"daemon"}]} {"id":"bd-2ku7","content_hash":"65cee891959383f7c8862b54b72c4bafae950ee47eecb47f0f842e6c10c8ba04","title":"Test integration issue","description":"This is a real integration test","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-07T19:07:11.528577-08:00","updated_at":"2025-11-07T22:07:17.343154-08:00","closed_at":"2025-11-07T21:55:09.426381-08:00","source_repo":"."} {"id":"bd-2o2","content_hash":"ec587855e11cbd34569de5f35e4c68404eb7f20926595615e852f73821aec950","title":"Add cancellation and timeout tests","description":"Add comprehensive tests for context cancellation and timeout behavior.\n\n## Context\nPart of context propagation work. Validates that bd-rtp and bd-yb8 work correctly.\n\n## Test Coverage Needed\n\n### 1. Cancellation Tests\n- [ ] Import operation cancelled mid-stream\n- [ ] Export operation cancelled mid-stream \n- [ ] Database query cancelled during long operation\n- [ ] No corruption after cancellation\n- [ ] Proper cleanup (defers execute, connections closed)\n\n### 2. Timeout Tests\n- [ ] Operations respect context deadlines\n- [ ] Appropriate error messages on timeout\n- [ ] State remains consistent after timeout\n\n### 3. Signal Handling Tests\n- [ ] SIGINT (Ctrl+C) triggers cancellation\n- [ ] SIGTERM triggers graceful shutdown\n- [ ] Multiple signals handled correctly\n\n## Implementation Approach\n```go\nfunc TestImportCancellation(t *testing.T) {\n ctx, cancel := context.WithCancel(context.Background())\n \n // Start import in goroutine\n go func() {\n err := runImport(ctx, largeFile)\n assert.Error(err, context.Canceled)\n }()\n \n // Cancel after short delay\n time.Sleep(100 * time.Millisecond)\n cancel()\n \n // Verify database integrity\n assertDatabaseConsistent(t, store)\n}\n```\n\n## Files to Create/Update\n- cmd/bd/import_test.go - cancellation tests\n- cmd/bd/export_test.go - cancellation tests\n- internal/storage/sqlite/*_test.go - context timeout tests\n\n## Acceptance Criteria\n- [ ] All critical operations have cancellation tests\n- [ ] Tests verify database integrity after cancellation\n- [ ] Signal handling tested (if feasible)\n- [ ] Test coverage \u003e80% for context paths","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-20T21:27:22.854636-05:00","updated_at":"2025-11-20T21:40:25.882758-05:00","closed_at":"2025-11-20T21:40:25.882758-05:00","source_repo":".","labels":["testing"],"dependencies":[{"issue_id":"bd-2o2","depends_on_id":"bd-yb8","type":"blocks","created_at":"2025-11-20T21:27:22.855574-05:00","created_by":"daemon"}]} -{"id":"bd-2q6d","content_hash":"d593b18be7696f1b6447d41a2b6988ee2e993169a183bec16e4df86607f288d1","title":"Beads commands operate on stale database without warning","description":"All beads read operations should validate database is in sync with JSONL before proceeding.\n\n**Current Behavior:**\n- Commands can query/read from stale database\n- Only mutation operations (like 'bd sync') check if JSONL is newer\n- User gets incorrect results without realizing database is out of sync\n\n**Expected Behavior:**\n- All beads commands should have pre-flight check for database freshness\n- If JSONL is newer than database, refuse to operate with error: \"Database out of sync. Run 'bd import' first.\"\n- Same safety check that exists for 'bd sync' should apply to ALL operations\n\n**Impact:**\n- Users make decisions based on incomplete/outdated data\n- Silent failures lead to confusion (e.g., thinking issues don't exist when they do)\n- Similar to running git commands on stale repo without being warned to pull\n\n**Example:**\n- Searched for bd-g9eu issue file: not found\n- Issue exists in .beads/issues.jsonl (in git)\n- Database was stale, but no warning was given\n- Led to incorrect conclusion that issue was already closed/deleted","notes":"## Implementation Complete\n\n**Phase 1: Created staleness check (cmd/bd/staleness.go)**\n- ensureDatabaseFresh() function checks JSONL mtime vs last_import_time\n- Returns error with helpful message when database is stale\n- Auto-skips in daemon mode (daemon has auto-import)\n\n**Phase 2: Added to all read commands**\n- list, show, ready, status, stale, info, duplicates, validate\n- Check runs before database queries in direct mode\n- Daemon mode already protected via checkAndAutoImportIfStale()\n\n**Phase 3: Code Review Findings**\nSee follow-up issues:\n- bd-XXXX: Add warning when staleness check errors\n- bd-YYYY: Improve CheckStaleness error handling\n- bd-ZZZZ: Refactor redundant daemon checks (low priority)\n\n**Testing:**\n- Build successful: go build ./cmd/bd\n- Binary works: ./bd --version\n- Ready for manual testing\n\n**Next Steps:**\n1. Test with stale database scenario\n2. Implement review improvements\n3. Close issue when tests pass","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-20T19:33:40.019297-05:00","updated_at":"2025-11-21T23:09:48.620035-08:00","source_repo":".","comments":[{"id":27,"issue_id":"bd-2q6d","author":"stevey","text":"# Updated Analysis\n\n## Root Cause\n\nThe bug has multiple contributing factors:\n\n1. **Daemon mode bypasses auto-import**: When running in daemon mode (most common), the `PersistentPreRun` returns early (main.go:332) before reaching auto-import logic (main.go:451-467)\n\n2. **No staleness validation on reads**: Read operations (list, show, search) don't verify database is fresh before returning results\n\n3. **Auto-import can be disabled**: Users with `--no-auto-import` can unknowingly operate on stale data\n\n## Current Auto-Import Behavior\n\nAuto-import DOES exist and uses SHA256 hash comparison:\n- Location: `autoflush.go:autoImportIfNewer()`\n- Stores last import hash in DB metadata: `last_import_hash`\n- Runs in `PersistentPreRun` for direct mode only\n- Skipped for: import, delete, sync --dry-run commands\n\n## Proposed Solution\n\nAdd lightweight hash-based staleness check to all read operations:\n\n### Implementation Points:\n1. **Before ANY database read** (list, show, search, ready, etc.):\n ```go\n func ensureDatabaseFresh(ctx context.Context) error {\n // Get stored import hash from DB\n storedHash, _ := store.GetMetadata(ctx, \"last_import_hash\")\n \n // Compute current JSONL hash\n currentHash := computeJSONLHash(findJSONLPath())\n \n if currentHash != storedHash {\n if autoImportEnabled {\n // Try auto-import\n autoImportIfNewer()\n // Re-check - fail if still stale\n } else {\n return fmt.Errorf(\"database out of sync with JSONL. Run 'bd import' or enable auto-import\")\n }\n }\n return nil\n }\n ```\n\n2. **Add to daemon RPC handlers** - daemon mode currently has NO staleness checking\n\n3. **Make check fast** - hash comparison is O(1) if JSONL hash is cached\n\n### Benefits:\n- Works in both daemon and direct mode\n- Minimal performance overhead (just hash comparison)\n- Catches all staleness cases\n- Clear error messages guide users to fix\n- Defense in depth - doesn't rely solely on auto-import\n\n### Alternatives Considered:\n- **mtime comparison**: Unreliable after git operations\n- **Block all reads when stale**: Too aggressive, breaks workflows \n- **Only check on mutations**: Current bug - reads return stale data\n- **Only rely on auto-import**: Fails in daemon mode and when disabled\n\n## Files to Modify:\n- `cmd/bd/list.go` - add check before SearchIssues\n- `cmd/bd/show.go` - add check before GetIssue\n- `cmd/bd/ready.go` - add check before GetReadyWork\n- `internal/rpc/server.go` - add check in daemon RPC handlers\n- Create `cmd/bd/staleness.go` - shared staleness check function","created_at":"2025-11-22T07:09:48Z"},{"id":28,"issue_id":"bd-2q6d","author":"stevey","text":"## Implementation Tasks\n\n### Phase 1: Core Infrastructure\n- [ ] Create `cmd/bd/staleness.go` with `ensureDatabaseFresh()` function\n- [ ] Add unit tests for staleness detection\n- [ ] Handle edge cases (missing JSONL, missing hash, etc.)\n\n### Phase 2: Direct Mode Read Commands\n- [ ] Add check to `cmd/bd/list.go`\n- [ ] Add check to `cmd/bd/show.go`\n- [ ] Add check to `cmd/bd/ready.go`\n- [ ] Add check to `cmd/bd/blocked.go`\n- [ ] Add check to `cmd/bd/stale.go`\n- [ ] Integration tests for direct mode\n\n### Phase 3: Daemon Mode\n- [ ] Add staleness check to daemon RPC handlers in `internal/rpc/server.go`\n- [ ] Ensure daemon can access JSONL path\n- [ ] Integration tests for daemon mode\n\n### Phase 4: Polish\n- [ ] Performance testing (check should be \u003c10ms)\n- [ ] Error message clarity\n- [ ] Documentation updates","created_at":"2025-11-22T07:09:48Z"}]} +{"id":"bd-2q6d","content_hash":"d593b18be7696f1b6447d41a2b6988ee2e993169a183bec16e4df86607f288d1","title":"Beads commands operate on stale database without warning","description":"All beads read operations should validate database is in sync with JSONL before proceeding.\n\n**Current Behavior:**\n- Commands can query/read from stale database\n- Only mutation operations (like 'bd sync') check if JSONL is newer\n- User gets incorrect results without realizing database is out of sync\n\n**Expected Behavior:**\n- All beads commands should have pre-flight check for database freshness\n- If JSONL is newer than database, refuse to operate with error: \"Database out of sync. Run 'bd import' first.\"\n- Same safety check that exists for 'bd sync' should apply to ALL operations\n\n**Impact:**\n- Users make decisions based on incomplete/outdated data\n- Silent failures lead to confusion (e.g., thinking issues don't exist when they do)\n- Similar to running git commands on stale repo without being warned to pull\n\n**Example:**\n- Searched for bd-g9eu issue file: not found\n- Issue exists in .beads/issues.jsonl (in git)\n- Database was stale, but no warning was given\n- Led to incorrect conclusion that issue was already closed/deleted","notes":"## Implementation Complete\n\n**Phase 1: Created staleness check (cmd/bd/staleness.go)**\n- ensureDatabaseFresh() function checks JSONL mtime vs last_import_time\n- Returns error with helpful message when database is stale\n- Auto-skips in daemon mode (daemon has auto-import)\n\n**Phase 2: Added to all read commands**\n- list, show, ready, status, stale, info, duplicates, validate\n- Check runs before database queries in direct mode\n- Daemon mode already protected via checkAndAutoImportIfStale()\n\n**Phase 3: Code Review Findings**\nSee follow-up issues:\n- bd-XXXX: Add warning when staleness check errors\n- bd-YYYY: Improve CheckStaleness error handling\n- bd-ZZZZ: Refactor redundant daemon checks (low priority)\n\n**Testing:**\n- Build successful: go build ./cmd/bd\n- Binary works: ./bd --version\n- Ready for manual testing\n\n**Next Steps:**\n1. Test with stale database scenario\n2. Implement review improvements\n3. Close issue when tests pass","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-20T19:33:40.019297-05:00","updated_at":"2025-11-22T15:18:47.433686601-07:00","source_repo":".","comments":[{"id":15,"issue_id":"bd-2q6d","author":"stevey","text":"# Updated Analysis\n\n## Root Cause\n\nThe bug has multiple contributing factors:\n\n1. **Daemon mode bypasses auto-import**: When running in daemon mode (most common), the `PersistentPreRun` returns early (main.go:332) before reaching auto-import logic (main.go:451-467)\n\n2. **No staleness validation on reads**: Read operations (list, show, search) don't verify database is fresh before returning results\n\n3. **Auto-import can be disabled**: Users with `--no-auto-import` can unknowingly operate on stale data\n\n## Current Auto-Import Behavior\n\nAuto-import DOES exist and uses SHA256 hash comparison:\n- Location: `autoflush.go:autoImportIfNewer()`\n- Stores last import hash in DB metadata: `last_import_hash`\n- Runs in `PersistentPreRun` for direct mode only\n- Skipped for: import, delete, sync --dry-run commands\n\n## Proposed Solution\n\nAdd lightweight hash-based staleness check to all read operations:\n\n### Implementation Points:\n1. **Before ANY database read** (list, show, search, ready, etc.):\n ```go\n func ensureDatabaseFresh(ctx context.Context) error {\n // Get stored import hash from DB\n storedHash, _ := store.GetMetadata(ctx, \"last_import_hash\")\n \n // Compute current JSONL hash\n currentHash := computeJSONLHash(findJSONLPath())\n \n if currentHash != storedHash {\n if autoImportEnabled {\n // Try auto-import\n autoImportIfNewer()\n // Re-check - fail if still stale\n } else {\n return fmt.Errorf(\"database out of sync with JSONL. Run 'bd import' or enable auto-import\")\n }\n }\n return nil\n }\n ```\n\n2. **Add to daemon RPC handlers** - daemon mode currently has NO staleness checking\n\n3. **Make check fast** - hash comparison is O(1) if JSONL hash is cached\n\n### Benefits:\n- Works in both daemon and direct mode\n- Minimal performance overhead (just hash comparison)\n- Catches all staleness cases\n- Clear error messages guide users to fix\n- Defense in depth - doesn't rely solely on auto-import\n\n### Alternatives Considered:\n- **mtime comparison**: Unreliable after git operations\n- **Block all reads when stale**: Too aggressive, breaks workflows \n- **Only check on mutations**: Current bug - reads return stale data\n- **Only rely on auto-import**: Fails in daemon mode and when disabled\n\n## Files to Modify:\n- `cmd/bd/list.go` - add check before SearchIssues\n- `cmd/bd/show.go` - add check before GetIssue\n- `cmd/bd/ready.go` - add check before GetReadyWork\n- `internal/rpc/server.go` - add check in daemon RPC handlers\n- Create `cmd/bd/staleness.go` - shared staleness check function","created_at":"2025-11-22T22:18:47Z"},{"id":16,"issue_id":"bd-2q6d","author":"stevey","text":"## Implementation Tasks\n\n### Phase 1: Core Infrastructure\n- [ ] Create `cmd/bd/staleness.go` with `ensureDatabaseFresh()` function\n- [ ] Add unit tests for staleness detection\n- [ ] Handle edge cases (missing JSONL, missing hash, etc.)\n\n### Phase 2: Direct Mode Read Commands\n- [ ] Add check to `cmd/bd/list.go`\n- [ ] Add check to `cmd/bd/show.go`\n- [ ] Add check to `cmd/bd/ready.go`\n- [ ] Add check to `cmd/bd/blocked.go`\n- [ ] Add check to `cmd/bd/stale.go`\n- [ ] Integration tests for direct mode\n\n### Phase 3: Daemon Mode\n- [ ] Add staleness check to daemon RPC handlers in `internal/rpc/server.go`\n- [ ] Ensure daemon can access JSONL path\n- [ ] Integration tests for daemon mode\n\n### Phase 4: Polish\n- [ ] Performance testing (check should be \u003c10ms)\n- [ ] Error message clarity\n- [ ] Documentation updates","created_at":"2025-11-22T22:18:47Z"}]} {"id":"bd-3","content_hash":"41ae09ef713b88fa3724ae81a255c55eb336b66c2a4173b6146bc298286021ba","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-47], 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":"closed","priority":2,"issue_type":"task","created_at":"2025-11-07T09:43:47.856354-08:00","updated_at":"2025-11-07T15:06:26.240131-08:00","closed_at":"2025-11-07T15:06:26.240131-08:00","source_repo":"."} {"id":"bd-307","content_hash":"6c1bda0d392414f4bb16f078a18f3958a869d3d1ed72bde6cc9012739eae88ef","title":"Multi-repo hydration layer","description":"Build core infrastructure to hydrate database from N repos (N≥1), with smart caching via file mtime tracking and routing writes to correct JSONL based on source_repo metadata.","design":"Components:\n- Config schema for repos.additional\n- source_repo metadata field (which repo owns each issue)\n- Hydration logic (read from N JSONLs)\n- Write routing (write to correct JSONL)\n- Smart caching (file mtime tracking to avoid re-parsing)\n- SQLite DB as cache layer","acceptance_criteria":"1. Can configure N repos via config.toml\n2. Database hydrates from all configured repos\n3. Writes route to correct JSONL via source_repo\n4. File mtime caching prevents re-parsing unchanged JSONLs\n5. Query performance \u003c100ms even with 5-10 polling interval\n6. N=1 (single repo) works unchanged","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-04T11:21:30.655765-08:00","updated_at":"2025-11-05T00:08:42.811877-08:00","closed_at":"2025-11-05T00:08:42.811879-08:00","source_repo":".","dependencies":[{"issue_id":"bd-307","depends_on_id":"bd-4ms","type":"parent-child","created_at":"2025-11-04T11:22:21.823652-08:00","created_by":"daemon"}]} {"id":"bd-317ddbbf","content_hash":"81a74ccf29037e5a780b12540a4059bab98b9a790a5a043a68118fc00a083cda","title":"Add BEADS_DAEMON_MODE flag handling","description":"Add environment variable BEADS_DAEMON_MODE (values: poll, events). Default to 'poll' for Phase 1. Wire into daemon startup to select runEventLoop vs runEventDrivenLoop.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T16:20:02.433638-07:00","updated_at":"2025-10-30T17:12:58.224373-07:00","closed_at":"2025-10-28T12:31:47.819136-07:00","source_repo":"."} @@ -112,7 +112,7 @@ {"id":"bd-3e9ddc31","content_hash":"4e03660281dbe2c069617fc8d723d546d6e5eb386142c0359b862747867a1b90","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-27T23:20:10.393759-07:00","updated_at":"2025-10-30T17:12:58.21613-07:00","closed_at":"2025-10-28T14:08:38.06721-07:00","source_repo":"."} {"id":"bd-3ee2c7e9","content_hash":"80a0101dd9082c194cd4f138dc116c0fc14d178d8afacb6b5b61ee863ee2eea7","title":"Add \"bd daemons\" command for multi-daemon management","description":"Add a new \"bd daemons\" command with subcommands to manage daemon processes across all beads repositories/worktrees. Should show all running daemons with metadata (version, workspace, uptime, last sync), allow stopping/restarting individual daemons, auto-clean stale processes, view logs, and show exclusive lock status.","design":"Subcommands:\n- list: Show all running daemons with metadata (workspace, PID, version, socket path, uptime, last activity, exclusive lock status)\n- stop \u003cpath|pid\u003e: Gracefully stop a specific daemon\n- restart \u003cpath|pid\u003e: Stop and restart daemon\n- killall: Emergency stop all daemons\n- health: Verify each daemon responds to ping\n- logs \u003cpath\u003e: View daemon logs\n\nFeatures:\n- Auto-clean stale sockets/dead processes\n- Discovery: Scan for .beads/bd.sock files + running processes\n- Communication: Use existing socket protocol, add GET /status endpoint for metadata","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-26T16:53:40.970042-07:00","updated_at":"2025-11-02T17:12:34.621017-08:00","closed_at":"2025-11-02T17:12:34.62102-08:00","source_repo":"."} {"id":"bd-3f6a","content_hash":"7fef5b08bbb32c4f4ab7d906539a765b01f1a74d0bb71102c954a5bdec4b442e","title":"Add concurrent import race condition tests","description":"Currently no tests verify behavior when multiple clones import simultaneously with external_ref matching.\n\nScenarios to test:\n1. Two clones import same external_ref update at same time\n2. Clone A imports while Clone B updates same issue\n3. Verify transaction isolation prevents corruption\n4. Document expected behavior (last-write-wins vs timestamp-based)\n\nRelated: bd-1022\nFiles: internal/importer/external_ref_test.go","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-02T15:32:11.286956-08:00","updated_at":"2025-11-02T16:11:16.127009-08:00","closed_at":"2025-11-02T16:11:16.127009-08:00","source_repo":"."} -{"id":"bd-3f80d9e0","content_hash":"6abdab20b716cb5f605f678d0f605bb07c5f9683d573ea724001d6f94177088e","title":"Improve internal/daemon test coverage (currently 22.5%)","description":"Daemon functionality needs better coverage:\n- Auto-start behavior\n- Lock file management\n- Discovery mechanisms\n- Connection handling\n- Error recovery\n\nCurrent coverage: 58.3% (improved from 22.5% as of Nov 2025)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T14:06:30.832728-07:00","updated_at":"2025-11-20T12:40:11.70644-05:00","closed_at":"2025-11-15T14:13:47.303529-08:00","source_repo":"."} +{"id":"bd-3f80d9e0","content_hash":"6abdab20b716cb5f605f678d0f605bb07c5f9683d573ea724001d6f94177088e","title":"Improve internal/daemon test coverage (currently 22.5%)","description":"Daemon functionality needs better coverage:\n- Auto-start behavior\n- Lock file management\n- Discovery mechanisms\n- Connection handling\n- Error recovery\n\nCurrent coverage: 58.3% (improved from 22.5% as of Nov 2025)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T14:06:30.832728-07:00","updated_at":"2025-11-16T15:50:05.874707004-07:00","closed_at":"2025-11-15T14:13:47.303529-08:00","source_repo":"."} {"id":"bd-3sz0","content_hash":"50d2315d5561c2b89acaa7c6ad84e7b2b0f5155f796bbbeeb862818c4b331423","title":"Auto-repair stale merge driver configs with invalid placeholders","description":"Old bd versions (\u003c0.24.0) installed merge driver with invalid placeholders %L %R instead of %A %B. Add detection to bd doctor --fix: check if git config merge.beads.driver contains %L or %R, auto-repair to 'bd merge %A %O %A %B'. One-time migration for users who initialized with old versions.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-21T23:16:10.762808-08:00","updated_at":"2025-11-21T23:16:28.892655-08:00","source_repo":".","dependencies":[{"issue_id":"bd-3sz0","depends_on_id":"bd-tbz3","type":"parent-child","created_at":"2025-11-21T23:16:10.763612-08:00","created_by":"daemon"}]} {"id":"bd-3tfh","content_hash":"d8a889d96a2a236db3d6c60d239878ffee607e6c91b2d6fc6dd85bfca938da03","title":"Benchmark Helper Functions","description":"Extend existing benchmark helpers in internal/storage/sqlite/bench_helpers_test.go (or create if organizing separately).\n\nExisting helper (in compact_bench_test.go):\n- setupBenchDB(tb) - Creates temp SQLite database with basic config\n * Used by compact and cycle benchmarks\n * Returns (*SQLiteStorage, cleanup func())\n\nNew helpers to add:\n- setupLargeBenchDB(b *testing.B) storage.Storage\n * Creates 10K issue database using LargeSQLite fixture\n * Returns configured storage instance\n \n- setupXLargeBenchDB(b *testing.B) storage.Storage\n * Creates 20K issue database using XLargeSQLite fixture\n * Returns configured storage instance\n\nImplementation options:\n1. Add to existing compact_bench_test.go (co-located with setupBenchDB)\n2. Create new bench_helpers_test.go for organization\n\nBoth approaches:\n- Build tag: //go:build bench\n- Uses fixture generator from internal/testutil/fixtures\n- Follows existing setupBenchDB() pattern\n- Handles database cleanup\n\nThese helpers reduce duplication across new benchmark functions and provide consistent large-scale database setup.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-13T22:22:55.694834-08:00","updated_at":"2025-11-13T23:13:41.244758-08:00","closed_at":"2025-11-13T23:13:41.244758-08:00","source_repo":".","dependencies":[{"issue_id":"bd-3tfh","depends_on_id":"bd-m62x","type":"blocks","created_at":"2025-11-13T22:24:02.632994-08:00","created_by":"daemon"}]} {"id":"bd-40a0","content_hash":"75611f4fb108e11cb4b98ded732fe94dd41ed700d8058b419e6fc796cf152391","title":"bd doctor should check for multiple DBs, multiple JSONLs, daemon health","description":"","design":"\nCurrently bd doctor only checks:\n- .beads/ directory exists\n- Database version vs CLI version \n- ID format (hash vs sequential)\n- CLI version vs latest GitHub release\n\nIt should ALSO check for operational issues that cause silent failures:\n\n1. **Multiple database files** (*.db excluding backups and vc.db)\n - Warn if multiple *.db files found (ambiguous which to use)\n - Suggest running 'bd migrate' or manually removing old DBs\n\n2. **Multiple JSONL files** \n - Check for both issues.jsonl and beads.jsonl\n - Warn about ambiguity, suggest standardizing on one\n\n3. **Daemon health** (integrate bd daemons health)\n - Check if daemon running for this workspace\n - Detect version mismatches between daemon and CLI\n - Detect zombie daemons (running but unresponsive)\n - Detect stale daemon.pid files\n\n4. **Database-JSONL sync issues**\n - Check if JSONL is newer than last import\n - Warn if they're out of sync\n\n5. **Permissions issues**\n - Check if .beads/ directory is writable\n - Check if database file is readable/writable\n\nImplementation approach:\n- Add new check functions to doctor.go\n- Reuse logic from bd daemons health\n- Keep checks fast (\u003c 1 second total)\n- Output actionable fixes for each issue\n","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-31T21:16:47.042913-07:00","updated_at":"2025-10-31T21:21:27.093525-07:00","closed_at":"2025-10-31T21:21:27.093525-07:00","source_repo":"."} @@ -121,12 +121,12 @@ {"id":"bd-46381404","content_hash":"580d0d38d9c888804627d6a9cb951fab92935f67d6247156a24759ccfc911f0d","title":"Test database naming","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T18:27:28.309676-07:00","updated_at":"2025-10-31T12:00:43.185201-07:00","closed_at":"2025-10-31T12:00:43.185201-07:00","source_repo":"."} {"id":"bd-49kw","content_hash":"32637477ea60088882c4637c9153af420f5843cab488a50af255b1c33b5db69e","title":"Workaround for FastMCP outputSchema bug in Claude Code","description":"The beads MCP server (v0.23.1) successfully connects to Claude Code, but all tools fail to load with a schema validation error due to a bug in FastMCP 2.13.1.\n\nError: \"Invalid literal value, expected \\\"object\\\"\" in outputSchema.\n\nRoot Cause: FastMCP generates outputSchema with $ref at root level without \"type\": \"object\" for self-referential models (Issue).\n\nWorkaround: Use slash commands (/beads:ready) or wait for FastMCP fix.\n","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-20T18:55:39.041831-05:00","updated_at":"2025-11-20T18:55:39.041831-05:00","source_repo":"."} {"id":"bd-4aao","content_hash":"67e1bab2ec59b16ea0daf6220b137588a6704793584663d1cf6d58765d41437e","title":"Fix failing integration tests in beads-mcp","description":"The `beads-mcp` test suite has failures in `tests/test_bd_client_integration.py` (assertion error in `test_init_creates_beads_directory`) and errors in `tests/test_worktree_separate_dbs.py` (setup failures finding database). These need to be investigated and fixed to ensure a reliable CI baseline.","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T18:53:28.4803-05:00","updated_at":"2025-11-20T18:53:28.4803-05:00","source_repo":"."} -{"id":"bd-4aeed709","content_hash":"3ab290915c117ec902bda1761e8c27850512f3fd4b494a93546c44b397d573a3","title":"bd resolve-conflicts - Git merge conflict resolver","description":"Automatically resolve JSONL merge conflicts.\n\nModes:\n- Mechanical: ID remapping (no AI)\n- AI-assisted: Smart merge/keep decisions\n- Interactive: Review each conflict\n\nHandles \u003c\u003c\u003c\u003c\u003c\u003c\u003c conflict markers in .beads/beads.jsonl\n\nFiles: cmd/bd/resolve_conflicts.go (new)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T12:40:11.707308-05:00","updated_at":"2025-11-20T12:40:11.707308-05:00","closed_at":"2025-10-28T15:47:33.037021-07:00","source_repo":"."} +{"id":"bd-4aeed709","content_hash":"3ab290915c117ec902bda1761e8c27850512f3fd4b494a93546c44b397d573a3","title":"bd resolve-conflicts - Git merge conflict resolver","description":"Automatically resolve JSONL merge conflicts.\n\nModes:\n- Mechanical: ID remapping (no AI)\n- AI-assisted: Smart merge/keep decisions\n- Interactive: Review each conflict\n\nHandles \u003c\u003c\u003c\u003c\u003c\u003c\u003c conflict markers in .beads/beads.jsonl\n\nFiles: cmd/bd/resolve_conflicts.go (new)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-22T15:18:47.437947579-07:00","updated_at":"2025-11-22T15:18:47.437947579-07:00","closed_at":"2025-10-28T15:47:33.037021-07:00","source_repo":"."} {"id":"bd-4b6u","content_hash":"352f8de1093c5d3bc53a4069c5a9c14a788f6214207d2353500d7bd056179800","title":"Update docs with multi-repo patterns","description":"Update AGENTS.md, README.md, QUICKSTART.md with multi-repo patterns. Document: config options, routing behavior, backward compatibility, troubleshooting, best practices.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-05T18:04:30.18358-08:00","updated_at":"2025-11-06T19:53:04.721589-08:00","closed_at":"2025-11-06T19:53:04.721589-08:00","source_repo":".","dependencies":[{"issue_id":"bd-4b6u","depends_on_id":"bd-8rd","type":"parent-child","created_at":"2025-11-05T18:04:39.297009-08:00","created_by":"daemon"}]} {"id":"bd-4ba5908b","content_hash":"70b8d577e5f65acb215f1c4caf18fdafcbd124db14fbc0e70132eea2b1848a93","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","notes":"Rename detection successfully implemented and tested!\n\n**What was implemented:**\n1. Content-hash based rename detection in DetectCollisions\n2. When importing JSONL, if an issue has different ID but same content as DB issue, treat as rename\n3. Delete old ID and accept new ID from JSONL\n4. Added post-import re-export in sync command to flush rename changes\n5. Added post-import commit to capture rename changes\n\n**Test results:**\nTestTwoCloneCollision now shows full convergence:\n- Clone A: test-2=\"Issue from clone A\", test-1=\"Issue from clone B\"\n- Clone B: test-1=\"Issue from clone B\", test-2=\"Issue from clone A\"\n\nBoth clones have **identical content** (titles match IDs correctly). Only timestamps differ (expected).\n\n**What remains:**\n- Test still expects exact JSON match including timestamps\n- Could normalize timestamp comparison, but content convergence is the critical success metric\n- The two-clone collision workflow now works without data corruption!","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-28T17:04:11.530026-07:00","updated_at":"2025-10-30T17:12:58.225987-07:00","closed_at":"2025-10-28T17:18:27.777019-07:00","source_repo":".","dependencies":[{"issue_id":"bd-4ba5908b","depends_on_id":"bd-71107098","type":"blocks","created_at":"2025-10-28T17:04:18.149604-07:00","created_by":"daemon"}]} {"id":"bd-4c18","content_hash":"d3d162cefdf9f3637ffb0ead341f48ffefe50fdf5e6ff9edc3ffcd05cdd703b4","title":"bd delete fails to find closed issues","description":"## Steps to Reproduce\n1. Close some issues with `bd close`\n2. Try to delete them with `bd delete \u003cids\u003e --force`\n3. Get error \"issues not found\"\n\n## Expected Behavior\nShould delete the closed issues\n\n## Actual Behavior\n```\nError: issues not found: bd-74ee, bd-9b13, bd-72w, bd-149, bd-5iv, bd-78w\n```\n\nBut `bd list --status closed --json` shows they exist.\n\n## Root Cause\nLikely the delete command is only looking for open issues, or there's a race condition with auto-import.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-03T20:57:31.763179-08:00","updated_at":"2025-11-03T21:31:18.677629-08:00","closed_at":"2025-11-03T21:31:18.677629-08:00","source_repo":"."} {"id":"bd-4cyb","content_hash":"1d02ccb8a552b2dec49bdfc3a7ed70b3307bcdebcaa8a563902a86a8bdcf7507","title":"Test graceful degradation when server unavailable","description":"Verify that agents continue working normally when Agent Mail server is stopped or unreachable.\n\nAcceptance Criteria:\n- Agent detects server unavailable on startup\n- Logs \"falling back to Beads-only mode\"\n- All bd commands work normally\n- Agent can claim issues (no reservations, like today)\n- Git sync operates as normal\n- No errors or crashes\n\nSuccess Metric: Zero functional difference when Agent Mail unavailable","status":"closed","priority":0,"issue_type":"task","created_at":"2025-11-07T22:42:00.094481-08:00","updated_at":"2025-11-08T00:20:29.841174-08:00","closed_at":"2025-11-08T00:20:29.841174-08:00","source_repo":".","dependencies":[{"issue_id":"bd-4cyb","depends_on_id":"bd-6hji","type":"blocks","created_at":"2025-11-07T23:03:53.054449-08:00","created_by":"daemon"}]} -{"id":"bd-4d7fca8a","content_hash":"5da2fc1fc0cbade7e4cfaf7fdb87b58487ce7661443e6ad4083f2f8de655e206","title":"Add tests for internal/utils package","description":"Currently 0.0% coverage. Need tests for utility functions including issue ID parsing and validation.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T14:06:24.066403-07:00","updated_at":"2025-11-08T22:42:08.860747-08:00","closed_at":"2025-11-08T17:57:28.956561-08:00","source_repo":".","dependencies":[{"issue_id":"bd-4d7fca8a","depends_on_id":"bd-cbed9619.5","type":"blocks","created_at":"2025-10-29T19:52:05.52888-07:00","created_by":"import-remap"},{"issue_id":"bd-4d7fca8a","depends_on_id":"bd-cbed9619.4","type":"blocks","created_at":"2025-10-29T19:52:05.529565-07:00","created_by":"import-remap"},{"issue_id":"bd-4d7fca8a","depends_on_id":"bd-0dcea000","type":"blocks","created_at":"2025-10-29T19:52:05.529982-07:00","created_by":"import-remap"}]} +{"id":"bd-4d7fca8a","content_hash":"5da2fc1fc0cbade7e4cfaf7fdb87b58487ce7661443e6ad4083f2f8de655e206","title":"Add tests for internal/utils package","description":"Currently 0.0% coverage. Need tests for utility functions including issue ID parsing and validation.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T14:06:24.066403-07:00","updated_at":"2025-11-11T08:42:35.00369134-07:00","closed_at":"2025-11-08T17:57:28.956561-08:00","source_repo":".","dependencies":[{"issue_id":"bd-4d7fca8a","depends_on_id":"bd-cbed9619.5","type":"blocks","created_at":"2025-10-29T19:52:05.52888-07:00","created_by":"import-remap"},{"issue_id":"bd-4d7fca8a","depends_on_id":"bd-cbed9619.4","type":"blocks","created_at":"2025-10-29T19:52:05.529565-07:00","created_by":"import-remap"},{"issue_id":"bd-4d7fca8a","depends_on_id":"bd-0dcea000","type":"blocks","created_at":"2025-10-29T19:52:05.529982-07:00","created_by":"import-remap"}]} {"id":"bd-4d80b7b1","content_hash":"7465ff154e916f0101dcd2aed683c2ffb72abdb3f1c8b60467a760441232d35b","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":"closed","priority":2,"issue_type":"task","created_at":"2025-10-24T11:49:12.836292-07:00","updated_at":"2025-11-07T14:55:51.908404-08:00","closed_at":"2025-11-07T14:55:51.908404-08:00","source_repo":"."} {"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","source_repo":"."} {"id":"bd-4ec8","content_hash":"64d140d382b4efd1a0d67cda9a0af9a0240c013cafc4aa61f3644b74b7b1cd94","title":"Widespread double JSON encoding bug in daemon mode RPC calls","description":"Multiple CLI commands had the same double JSON encoding bug found in bd-1048. All commands that called ResolveID via RPC used string(resp.Data) instead of properly unmarshaling the JSON response. This caused IDs to retain JSON quotes (\"bd-1048\" instead of bd-1048), which then got double-encoded when passed to subsequent RPC calls.\n\nAffected commands:\n- bd show (3 instances)\n- bd dep add/remove/tree (5 instances)\n- bd label add/remove/list (3 instances)\n- bd reopen (1 instance)\n\nRoot cause: resp.Data is json.RawMessage (already JSON-encoded), so string() conversion preserves quotes.\n\nFix: Replace all string(resp.Data) with json.Unmarshal(resp.Data, \u0026id) for proper deserialization.\n\nAll commands now tested and working correctly with daemon mode.","status":"open","priority":0,"issue_type":"bug","created_at":"2025-11-02T22:33:01.632691-08:00","updated_at":"2025-11-02T22:33:01.632691-08:00","source_repo":"."} @@ -161,21 +161,21 @@ {"id":"bd-5e1f","content_hash":"5b0aa7a2f651393bc13c46c172828acc4306d22d749ff71fbae96f0d25741847","title":"Issue with desc","description":"This is a description","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-10-31T21:41:11.128718-07:00","updated_at":"2025-11-04T11:10:23.531094-08:00","closed_at":"2025-11-04T11:10:23.531097-08:00","source_repo":"."} {"id":"bd-5f26","content_hash":"5131931d43040061d669159635de863740ed90e7c946c4b646c36c53bc274d6f","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","source_repo":"."} {"id":"bd-5f483051","content_hash":"c14449fb07074c3ff76a653cc632f5795e2e0fb8f381c5f1a1f0dd831fe4f13f","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":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T19:37:55.722827-07:00","updated_at":"2025-11-06T19:36:13.970903-08:00","closed_at":"2025-11-06T19:26:45.397628-08:00","source_repo":"."} -{"id":"bd-5ibn","content_hash":"3e651d081ea1dec7e5e30aaa2f9f521f3b9eaff7832d0dd55e5e6f89525f6b94","title":"Latency test 1","description":"","notes":"Resetting stale in_progress status from old executor run (yesterday)","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-20T12:16:30.703754-05:00","updated_at":"2025-11-21T15:11:55.187258-05:00","source_repo":"."} +{"id":"bd-5ibn","content_hash":"3e651d081ea1dec7e5e30aaa2f9f521f3b9eaff7832d0dd55e5e6f89525f6b94","title":"Latency test 1","description":"","notes":"Resetting stale in_progress status from old executor run (yesterday)","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-08T00:04:08.220629-08:00","updated_at":"2025-11-22T15:18:47.439285042-07:00","source_repo":"."} {"id":"bd-5iv","content_hash":"229ad9764bd3eb8b09441adefce960aede63fd1b5466d52cc74f112f5bb610ac","title":"Test Epic","description":"## Overview\n\n[Describe the high-level goal and scope of this epic]\n\n## Success Criteria\n\n- [ ] Criteria 1\n- [ ] Criteria 2\n- [ ] Criteria 3\n\n## Background\n\n[Provide context and motivation]\n\n## Scope\n\n**In Scope:**\n- Item 1\n- Item 2\n\n**Out of Scope:**\n- Item 1\n- Item 2\n","design":"## Architecture\n\n[Describe the overall architecture and approach]\n\n## Components\n\n- Component 1: [description]\n- Component 2: [description]\n\n## Dependencies\n\n[List external dependencies or constraints]\n","acceptance_criteria":"- [ ] All child issues are completed\n- [ ] Integration tests pass\n- [ ] Documentation is updated\n- [ ] Code review completed\n","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-03T20:15:03.864229-08:00","updated_at":"2025-11-05T00:25:06.538749-08:00","closed_at":"2025-11-05T00:25:06.538749-08:00","source_repo":".","labels":["epic"]} {"id":"bd-5ki8","content_hash":"d89e5e528819934bcb7ee162fa7e32c27298db5816ecf51bcc8ede1809f1d5b9","title":"Add integration tests for adapter library","description":"Test suite for beads_mail_adapter.py covering all scenarios.\n\nAcceptance Criteria:\n- Test enabled mode (server available)\n- Test disabled mode (server unavailable)\n- Test graceful degradation (server dies mid-operation)\n- Test reservation conflicts\n- Test message sending/receiving\n- Mock HTTP server for testing\n- 90%+ code coverage\n\nFile: lib/test_beads_mail_adapter.py","notes":"Test suite completed with 29 comprehensive tests covering:\n- Enabled mode (server available): 10 tests\n- Disabled mode (server unavailable): 2 tests \n- Graceful degradation: 4 tests\n- Reservation conflicts: 2 tests\n- Configuration: 5 tests\n- Health check scenarios: 3 tests\n- HTTP error handling: 3 tests\n\n**Performance**: All tests run in 10ms (fast!)\n\n**Coverage highlights**:\n✅ Server health checks (ok, degraded, error, timeout)\n✅ All API operations (reserve, release, notify, check_inbox, get_reservations)\n✅ HTTP errors (404, 409 conflict, 500, 503)\n✅ Network errors (timeout, connection refused)\n✅ Malformed responses (bad JSON, empty body, plain text errors)\n✅ Environment variable configuration\n✅ Graceful degradation when server dies mid-operation\n✅ Conflict handling with both JSON and plain text errors\n✅ Dict wrapper responses ({\"messages\": [...]} and {\"reservations\": [...]})\n✅ Custom TTL for reservations\n✅ Default agent name fallback\n\nNo external dependencies, no slow integration tests, just fast unit tests with mocks.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-07T22:43:21.294596-08:00","updated_at":"2025-11-08T01:32:39.906342-08:00","closed_at":"2025-11-08T01:32:39.906342-08:00","source_repo":".","dependencies":[{"issue_id":"bd-5ki8","depends_on_id":"bd-m9th","type":"blocks","created_at":"2025-11-07T22:43:21.296024-08:00","created_by":"daemon"}]} {"id":"bd-5ots","content_hash":"ba3efab3e7a2b9bb2bd2dba3aace56cfbdd1b67efd1cfc4758d9c79919f632af","title":"SearchIssues N+1 query causes context timeout with GetLabels","description":"scanIssues() calls GetLabels in a loop for every issue, causing N+1 queries and context deadline exceeded errors when used with short timeouts or in-memory databases. This is especially problematic since SearchIssues already supports label filtering via SQL WHERE clauses.","acceptance_criteria":"- Optimize scanIssues to batch-load labels for all issues in one query\n- Or make label loading optional/lazy\n- Add test that calls SearchIssues repeatedly with label filters and short context timeouts","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-05T19:12:02.245879-08:00","updated_at":"2025-11-05T19:22:11.668682-08:00","closed_at":"2025-11-05T19:22:11.668682-08:00","source_repo":"."} {"id":"bd-5qim","content_hash":"5117e87c5a56b5b8254402d982e85bea1478c1961f05654a50cf2df11e7ad6bf","title":"Optimize GetReadyWork performance - 752ms on 10K database (target: \u003c50ms)","description":"","notes":"# Performance Analysis (10K Issue Database)\n\nAnalyzed using CPU profiles from benchmark suite on Apple M2 Pro.\n\n## Operation Performance\n\n| Operation | Time | Allocations | Memory |\n|----------------------------------|---------|-------------|--------|\n| bd ready (GetReadyWork) | ~752ms | 167,466 | 16MB |\n| bd list (SearchIssues no filter) | ~11.6ms | 89,214 | 5.8MB |\n| bd list (SearchIssues filtered) | ~9.2ms | 62,365 | 3.5MB |\n| bd create (CreateIssue) | ~2.6ms | 146 | 8.6KB |\n| bd update (UpdateIssue) | ~0.32ms | 364 | 15KB |\n| bd close (UpdateIssue) | ~0.32ms | 364 | 15KB |\n\n**Target: \u003c50ms for all operations on 10K database**\n\n**Current issue: GetReadyWork is 15x over target (752ms vs 50ms)**\n\n## Root Cause\n\nGetReadyWork (internal/storage/sqlite/ready.go:90-128) uses recursive CTE to propagate blocking:\n- 65x slower than SearchIssues\n- Recalculates entire blocked issue tree on every call\n- Algorithm:\n 1. Find directly blocked issues via 'blocks' dependencies\n 2. Recursively propagate blockage to descendants (max depth: 50)\n 3. Exclude all blocked issues from results\n\n## CPU Profile Analysis\n\n- Database syscalls (pthread_cond_signal, syscall6): ~75%\n- SQLite engine overhead: inherent to recursive CTE\n- Application code (query construction): \u003c1%\n\n**Bottleneck is the recursive CTE query execution, not application code.**\n\n## Optimization Recommendations\n\n### High Impact (Likely to achieve \u003c50ms target)\n\n1. **Cache blocked issue calculation**\n - Add `blocked_issues` table updated on dependency changes\n - Trade write complexity for read speed (ready called \u003e\u003e dependency changes)\n - Eliminates recursive CTE on every read\n\n2. **Add/verify database indexes**\n ```sql\n CREATE INDEX IF NOT EXISTS idx_dependencies_blocked \n ON dependencies(issue_id, type, depends_on_id);\n CREATE INDEX IF NOT EXISTS idx_issues_status \n ON issues(status);\n ```\n\n### Medium Impact\n\n3. **Reduce allocations** (167K allocations for GetReadyWork)\n - Profile `scanIssues()` for object pooling opportunities\n - Reuse slice capacity for repeated calls\n\n### Low Impact (Not recommended)\n- Query optimization for CRUD operations (already \u003c3ms)\n- Connection pooling tuning (not showing in profiles)\n\n## Verification\n\nRun benchmarks to validate optimization:\n```bash\nmake bench-quick\ngo tool pprof -http=:8080 internal/storage/sqlite/bench-cpu-*.prof\n```\n\nProfile files automatically generated in `internal/storage/sqlite/`.","status":"open","priority":0,"issue_type":"bug","created_at":"2025-11-14T09:02:46.507526-08:00","updated_at":"2025-11-14T09:03:44.073236-08:00","source_repo":"."} -{"id":"bd-5xt","content_hash":"1a44abd45874666cea2170bb3559934f72acf3b5171d0b587cc49eef386e110d","title":"Log errors from timer-triggered flushes instead of discarding","description":"","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-20T21:22:06.694953-05:00","updated_at":"2025-11-20T21:35:53.117434-05:00","closed_at":"2025-11-20T21:35:53.117434-05:00","source_repo":".","comments":[{"id":34,"issue_id":"bd-5xt","author":"stevey","text":"In FlushManager.run() at flush_manager.go:197-200, timer-triggered flushes silently discard errors:\n\n```go\ncase \u003c-fm.timerFiredCh:\n if isDirty {\n _ = fm.performFlush(needsFullExport) // ← Error discarded!\n```\n\nUsers won't know if auto-flush is failing. Should at minimum log errors.\n\nConsider:\n- Log error with debug.Logf() or fmt.Fprintf(os.Stderr)\n- Optionally expose flush status via a Status() method\n- Track last flush error for diagnostics\n\nRelated: Code review finding #4 from bd-52 race condition fix review.","created_at":"2025-11-22T07:53:00Z"}]} -{"id":"bd-6049","content_hash":"16c54bc547f4ab180aee39efbb197709a47a39047f5bc2dd59e6e6b57ca8bc87","title":"bd doctor --json flag not working","description":"The --json flag on bd doctor command doesn't produce JSON output. It continues to show human-readable output instead. The flag is registered locally on doctorCmd but the code uses the global jsonOutput variable set by PersistentPreRun. Need to investigate why the flag isn't being honored.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-02T17:08:18.170428-08:00","updated_at":"2025-11-02T18:41:01.376783-08:00","closed_at":"2025-11-02T18:41:01.376786-08:00","source_repo":".","comments":[{"id":29,"issue_id":"bd-6049","author":"stevey","text":"Fixed by removing the local --json flag definition in doctor.go that was shadowing the persistent --json flag from main.go. The doctor command now correctly uses the global jsonOutput variable.","created_at":"2025-11-22T07:09:48Z"}]} +{"id":"bd-5xt","content_hash":"1a44abd45874666cea2170bb3559934f72acf3b5171d0b587cc49eef386e110d","title":"Log errors from timer-triggered flushes instead of discarding","description":"","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-20T21:22:06.694953-05:00","updated_at":"2025-11-20T21:35:53.117434-05:00","closed_at":"2025-11-20T21:35:53.117434-05:00","source_repo":".","comments":[{"id":9,"issue_id":"bd-5xt","author":"stevey","text":"In FlushManager.run() at flush_manager.go:197-200, timer-triggered flushes silently discard errors:\n\n```go\ncase \u003c-fm.timerFiredCh:\n if isDirty {\n _ = fm.performFlush(needsFullExport) // ← Error discarded!\n```\n\nUsers won't know if auto-flush is failing. Should at minimum log errors.\n\nConsider:\n- Log error with debug.Logf() or fmt.Fprintf(os.Stderr)\n- Optionally expose flush status via a Status() method\n- Track last flush error for diagnostics\n\nRelated: Code review finding #4 from bd-52 race condition fix review.","created_at":"2025-11-21T13:58:10Z"}]} +{"id":"bd-6049","content_hash":"16c54bc547f4ab180aee39efbb197709a47a39047f5bc2dd59e6e6b57ca8bc87","title":"bd doctor --json flag not working","description":"The --json flag on bd doctor command doesn't produce JSON output. It continues to show human-readable output instead. The flag is registered locally on doctorCmd but the code uses the global jsonOutput variable set by PersistentPreRun. Need to investigate why the flag isn't being honored.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-02T17:08:18.170428-08:00","updated_at":"2025-11-02T18:41:01.376783-08:00","closed_at":"2025-11-02T18:41:01.376786-08:00","source_repo":".","comments":[{"id":4,"issue_id":"bd-6049","author":"stevey","text":"Fixed by removing the local --json flag definition in doctor.go that was shadowing the persistent --json flag from main.go. The doctor command now correctly uses the global jsonOutput variable.","created_at":"2025-11-08T20:26:48Z"}]} {"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","source_repo":"."} -{"id":"bd-6221bdcd","content_hash":"6749091ed73f5ec7b55af226b2ae8c9aa134759951435e08e65a363c674ea0c9","title":"Optimize cmd/bd test suite performance (currently 30+ minutes)","description":"CLI test suite is extremely slow (~30+ minutes for full run). Tests are poorly designed and need performance optimization before expanding coverage.\n\nCurrent coverage: 24.8% (improved from 20.2%)\n\n**Problem**: Tests take far too long to run, making development iteration painful.\n\n**Priority**: Fix test performance FIRST, then consider increasing coverage.\n\n**Investigation needed**:\n- Profile test execution to identify bottlenecks\n- Look for redundant git operations, database initialization, or daemon operations\n- Identify opportunities for test parallelization\n- Consider mocking or using in-memory databases where appropriate\n- Review test design patterns\n\n**Related**: bd-ktng mentions 13 CLI tests with redundant git init calls (31s total)\n\n**Goal**: Get full test suite under 1-2 minutes before adding more tests.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T14:06:27.951656-07:00","updated_at":"2025-11-08T22:42:08.862178-08:00","closed_at":"2025-11-08T22:41:05.766749-08:00","source_repo":".","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"}]} +{"id":"bd-6221bdcd","content_hash":"6749091ed73f5ec7b55af226b2ae8c9aa134759951435e08e65a363c674ea0c9","title":"Optimize cmd/bd test suite performance (currently 30+ minutes)","description":"CLI test suite is extremely slow (~30+ minutes for full run). Tests are poorly designed and need performance optimization before expanding coverage.\n\nCurrent coverage: 24.8% (improved from 20.2%)\n\n**Problem**: Tests take far too long to run, making development iteration painful.\n\n**Priority**: Fix test performance FIRST, then consider increasing coverage.\n\n**Investigation needed**:\n- Profile test execution to identify bottlenecks\n- Look for redundant git operations, database initialization, or daemon operations\n- Identify opportunities for test parallelization\n- Consider mocking or using in-memory databases where appropriate\n- Review test design patterns\n\n**Related**: bd-ktng mentions 13 CLI tests with redundant git init calls (31s total)\n\n**Goal**: Get full test suite under 1-2 minutes before adding more tests.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T14:06:27.951656-07:00","updated_at":"2025-11-11T08:42:35.004790971-07:00","closed_at":"2025-11-08T22:41:05.766749-08:00","source_repo":".","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"}]} {"id":"bd-627d","content_hash":"5b3d3d69ceac28dcbfbc2c7ea2f7a6ff2a3a02bc58ce02dcf6b05f8469e8bddc","title":"AI-supervised database migrations for safer schema evolution","description":"## Problem\n\nDatabase migrations can lose user data through edge cases that are hard to anticipate (e.g., GH #201 where bd migrate failed to set issue_prefix, or bd-d355a07d false positive data loss warnings). Since beads is designed to be run by AI agents, we should leverage AI to make migrations safer.\n\n## Current State\n\nMigrations run blindly with:\n- No pre-flight validation\n- No data integrity verification\n- No rollback on failure\n- Limited post-migration testing\n\nRecent issues:\n- GH #201: Migration didn't set issue_prefix config, breaking commands\n- bd-d355a07d: False positive \"data loss\" warnings on collision resolution\n- Users reported migration data loss (fixed but broader problem remains)\n\n## Proposal: AI-Supervised Migration Framework\n\nUse AI to supervise migrations through structured verification:\n\n### 1. Pre-Migration Analysis\n- AI reads migration code and current schema\n- Identifies potential data loss scenarios\n- Generates validation queries to verify assumptions\n- Creates snapshot queries for before/after comparison\n\n### 2. Migration Execution\n- Take database backup/snapshot\n- Run validation queries (pre-state)\n- Execute migration in transaction\n- Run validation queries (post-state)\n\n### 3. Post-Migration Verification\n- AI compares pre/post snapshots\n- Verifies data integrity invariants\n- Checks for unexpected data loss\n- Validates config completeness (like issue_prefix)\n\n### 4. Rollback on Anomalies\n- If AI detects data loss, rollback transaction\n- Present human-readable error report\n- Suggest fix before retrying\n\n## Example Flow\n\n```\n$ bd migrate\n\n→ Analyzing migration plan...\n→ AI identified 3 potential data loss scenarios\n→ Generating validation queries...\n→ Creating pre-migration snapshot...\n→ Running migration in transaction...\n→ Verifying post-migration state...\n✓ All 247 issues accounted for\n✓ Config table complete (issue_prefix: \"mcp\")\n✓ Dependencies intact (342 relationships verified)\n→ Migration successful!\n```\n\nIf something goes wrong:\n```\n$ bd migrate\n\n→ Analyzing migration plan...\n→ AI identified issue: Missing issue_prefix config after migration\n→ Recommendation: Add prefix detection step\n→ Aborting migration - database unchanged\n```\n\n## Implementation Ideas\n\n### A. Migration Validator Tool\nCreate `bd migrate --validate` that:\n- Simulates migration on copy of database\n- Uses AI to verify data integrity\n- Reports potential issues before real migration\n\n### B. Migration Test Generator\nAI generates test cases for migrations:\n- Edge cases (empty DB, large DB, missing config)\n- Data integrity checks\n- Regression tests\n\n### C. Migration Invariants\nDefine invariants that AI checks:\n- Issue count should not decrease (unless collision resolution)\n- All required config keys present\n- Foreign key relationships intact\n- No orphaned dependencies\n\n### D. Self-Healing Migrations\nAI detects incomplete migrations and suggests fixes:\n- Missing config values (like GH #201)\n- Orphaned data\n- Index inconsistencies\n\n## Benefits\n\n1. **Catch edge cases**: AI explores scenarios humans miss\n2. **Self-documenting**: AI explains what migration does\n3. **Agent-friendly**: Agents can run migrations confidently\n4. **Fewer rollbacks**: Detect issues before committing\n5. **Better testing**: AI generates comprehensive test suites\n\n## Open Questions\n\n1. Which AI model? (Fast: Haiku, Thorough: Sonnet/GPT-4)\n2. How to balance safety vs migration speed?\n3. Should AI validation be required or optional?\n4. How to handle offline scenarios (no API access)?\n5. What invariants should always be checked?\n\n## Related Work\n\n- bd-b245: Migration registry (makes migrations introspectable)\n- GH #201: issue_prefix migration bug (motivating example)\n- bd-d355a07d: False positive data loss warnings","design":"## Architecture: Agent-Supervised Migrations (Inversion of Control)\n\n**Key principle:** Beads provides observability and validation primitives. AI agents supervise using their own reasoning. Beads NEVER makes AI API calls.\n\n## Phase 1: Migration Invariants (Pure Validation)\n\nCreate `internal/storage/sqlite/migration_invariants.go`:\n\n```go\ntype MigrationInvariant struct {\n Name string\n Description string\n Check func(*sql.DB, *Snapshot) error\n}\n\ntype Snapshot struct {\n IssueCount int\n ConfigKeys []string\n DependencyCount int\n LabelCount int\n}\n\nvar invariants = []MigrationInvariant{\n {\n Name: \"required_config_present\",\n Description: \"Required config keys must exist\",\n Check: checkRequiredConfig, // Would have caught GH #201\n },\n {\n Name: \"foreign_keys_valid\",\n Description: \"No orphaned dependencies or labels\",\n Check: checkForeignKeys,\n },\n {\n Name: \"issue_count_stable\",\n Description: \"Issue count should not decrease unexpectedly\",\n Check: checkIssueCount,\n },\n}\n\nfunc checkRequiredConfig(db *sql.DB, snapshot *Snapshot) error {\n required := []string{\"issue_prefix\", \"schema_version\"}\n for _, key := range required {\n var value string\n err := db.QueryRow(\"SELECT value FROM config WHERE key = ?\", key).Scan(\u0026value)\n if err != nil || value == \"\" {\n return fmt.Errorf(\"required config key missing: %s\", key)\n }\n }\n return nil\n}\n```\n\n## Phase 2: Dry-Run \u0026 Inspection Tools\n\nAdd `bd migrate --dry-run --json`:\n\n```json\n{\n \"pending_migrations\": [\n {\"name\": \"dirty_issues_table\", \"description\": \"Adds dirty_issues table\"},\n {\"name\": \"content_hash_column\", \"description\": \"Adds content_hash for collision resolution\"}\n ],\n \"current_state\": {\n \"schema_version\": \"0.9.9\",\n \"issue_count\": 247,\n \"config\": {\"schema_version\": \"0.9.9\"},\n \"missing_config\": [\"issue_prefix\"]\n },\n \"warnings\": [\n \"issue_prefix config not set - may break commands after migration\"\n ],\n \"invariants_to_check\": [\n \"required_config_present\",\n \"foreign_keys_valid\",\n \"issue_count_stable\"\n ]\n}\n```\n\nAdd `bd info --schema --json`:\n\n```json\n{\n \"tables\": [\"issues\", \"dependencies\", \"labels\", \"config\"],\n \"schema_version\": \"0.9.9\",\n \"config\": {},\n \"sample_issue_ids\": [\"mcp-1\", \"mcp-2\"],\n \"detected_prefix\": \"mcp\"\n}\n```\n\n## Phase 3: Pre/Post Snapshots with Rollback\n\nUpdate `RunMigrations()`:\n\n```go\nfunc RunMigrations(db *sql.DB) error {\n // Capture pre-migration snapshot\n snapshot := captureSnapshot(db)\n \n // Run migrations in transaction\n tx, err := db.Begin()\n if err != nil {\n return err\n }\n defer tx.Rollback()\n \n for _, migration := range migrations {\n if err := migration.Func(tx); err != nil {\n return fmt.Errorf(\"migration %s failed: %w\", migration.Name, err)\n }\n }\n \n // Verify invariants before commit\n if err := verifyInvariants(tx, snapshot); err != nil {\n return fmt.Errorf(\"post-migration validation failed (rolled back): %w\", err)\n }\n \n return tx.Commit()\n}\n```\n\n## Phase 4: MCP Tools for Agent Supervision\n\nAdd to beads-mcp:\n\n```python\n@server.tool()\nasync def inspect_migration(workspace_root: str) -\u003e dict:\n \"\"\"Get migration plan and current state for agent analysis.\n \n Agent should:\n 1. Review pending migrations\n 2. Check for warnings (missing config, etc.)\n 3. Verify invariants will pass\n 4. Decide whether to run bd migrate\n \"\"\"\n result = run_bd([\"migrate\", \"--dry-run\", \"--json\"], workspace_root)\n return json.loads(result.stdout)\n\n@server.tool() \nasync def get_schema_info(workspace_root: str) -\u003e dict:\n \"\"\"Get current database schema for migration analysis.\"\"\"\n result = run_bd([\"info\", \"--schema\", \"--json\"], workspace_root)\n return json.loads(result.stdout)\n```\n\n## Agent Workflow Example\n\n```python\n# Agent detects user wants to migrate\nmigration_plan = inspect_migration(\"/path/to/workspace\")\n\n# Agent analyzes (using its own reasoning, no API calls from beads)\nif \"issue_prefix\" in migration_plan[\"missing_config\"]:\n schema = get_schema_info(\"/path/to/workspace\")\n detected_prefix = schema[\"detected_prefix\"]\n \n # Agent fixes issue before migration\n run_bd([\"config\", \"set\", \"issue_prefix\", detected_prefix])\n \n# Now safe to migrate\nrun_bd([\"migrate\"])\n```\n\n## What Beads Provides\n\n✅ Deterministic validation (invariants)\n✅ Structured inspection (--dry-run, --explain)\n✅ Rollback on invariant failure\n✅ JSON output for agent parsing\n\n## What Beads Does NOT Do\n\n❌ No AI API calls\n❌ No external model access\n❌ No agent invocation\n\nAgents supervise migrations using their own reasoning and the inspection tools beads provides.","acceptance_criteria":"Phase 1: Migration invariants implemented and tested, checked after every migration, clear error messages when invariants fail.\n\nPhase 2: Snapshot capture before migrations, comparison after, rollback on verification failure.\n\nPhase 3 (stretch): AI validation optional flag implemented, AI can analyze migration code and generate custom validation queries.\n\nPhase 4 (stretch): Migration test fixtures created, all fixtures pass migrations, CI runs migration tests.","notes":"## Progress\n\n### ✅ Phase 1: Migration Invariants (COMPLETED)\n\n**Implemented:**\n- Created internal/storage/sqlite/migration_invariants.go with 3 invariants\n- Updated RunMigrations() to verify invariants after migrations\n- All tests pass ✓\n\n### ✅ Phase 2: Inspection Tools (COMPLETED \u0026 PUSHED)\n\n**Commit:** 1abe4e7 - \"Add migration inspection tools for AI agents (bd-627d Phase 2)\"\n\n**Implemented:**\n1. ✅ bd migrate --inspect --json - Shows migration plan\n2. ✅ bd info --schema --json - Returns schema details\n3. ✅ Migration warnings system\n4. ✅ Documentation updated in AGENTS.md\n5. ✅ All tests pass\n\n### ✅ Phase 3: MCP Tools (COMPLETED \u0026 PUSHED)\n\n**Commit:** 2493693 - \"Add MCP tools for migration inspection (bd-627d Phase 3)\"\n\n**Implemented:**\n1. ✅ inspect_migration(workspace_root) tool in beads-mcp\n2. ✅ get_schema_info(workspace_root) tool in beads-mcp\n3. ✅ Abstract methods in BdClientBase\n4. ✅ CLI client implementations\n5. ✅ All tests pass\n\n**All phases complete!** Migration inspection fully integrated into MCP server.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-02T12:57:10.722048-08:00","updated_at":"2025-11-02T14:31:25.095296-08:00","closed_at":"2025-11-02T14:31:25.095308-08:00","source_repo":"."} {"id":"bd-62a0","content_hash":"b8b2a58a86211a19aed9d21ec5215b4f14ef341ee95d4ed845e1412840d00fd7","title":"Create WASM build infrastructure (Makefile, scripts)","description":"Set up build tooling for WASM compilation:\n- Add GOOS=js GOARCH=wasm build target\n- Copy wasm_exec.js from Go distribution\n- Create wrapper script for Node.js execution\n- Add build task to Makefile or build script","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-02T21:58:07.286826-08:00","updated_at":"2025-11-02T22:23:49.376789-08:00","closed_at":"2025-11-02T22:23:49.376789-08:00","source_repo":".","dependencies":[{"issue_id":"bd-62a0","depends_on_id":"bd-44d0","type":"parent-child","created_at":"2025-11-02T22:23:49.423064-08:00","created_by":"stevey"}]} {"id":"bd-63e9","content_hash":"7c709804b6d15ce63897344b0674dfae6a4fe97e3ae2768585e2a3407484bad0","title":"Fix Nix flake build test failures","description":"Nix build is failing during test phase with same test errors as Windows.\n\n**Error:**\n```\nerror: Cannot build '/nix/store/rgyi1j44dm6ylrzlg2h3z97axmfq9hzr-beads-0.9.9.drv'.\nReason: builder failed with exit code 1.\nFAIL github.com/steveyegge/beads/cmd/bd 16.141s\n```\n\nThis may be related to test environment setup or the same issues affecting Windows tests.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-02T09:29:37.2851-08:00","updated_at":"2025-11-04T11:10:23.531386-08:00","closed_at":"2025-11-04T11:10:23.531389-08:00","source_repo":".","dependencies":[{"issue_id":"bd-63e9","depends_on_id":"bd-1231","type":"blocks","created_at":"2025-11-02T09:29:37.28618-08:00","created_by":"stevey"}]} {"id":"bd-64c05d00","content_hash":"ab391b33353bfe693ef571e9fcb4a222eb5289a07e60258bd88c29565e85c4d0","title":"Multi-clone collision resolution testing and documentation","description":"Epic to track improvements to multi-clone collision resolution based on ultrathinking analysis of-3d844c58 and [deleted:bd-71107098].\n\nCurrent state:\n- 2-clone collision resolution is SOUND and working correctly\n- Hash-based deterministic collision resolution works\n- Test fails due to timestamp comparison, not actual logic issues\n\nWork needed:\n1. Fix TestTwoCloneCollision to compare content not timestamps\n2. Add TestThreeCloneCollision for regression protection\n3. Document 3-clone ID non-determinism as known behavior","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-28T17:58:38.316626-07:00","updated_at":"2025-11-05T00:32:09.153134-08:00","closed_at":"2025-11-04T11:10:23.531681-08:00","source_repo":"."} {"id":"bd-64c05d00.1","content_hash":"4ed407ab9518dbf45a4097460354d7857dd53881b913ad770def31d46dc6dc15","title":"Fix TestTwoCloneCollision to compare content not timestamps","description":"The test at beads_twoclone_test.go:204-207 currently compares full JSON output including timestamps, causing false negative failures.\n\nCurrent behavior:\n- Both clones converge to identical semantic content\n- Clone A: test-2=\"Issue from clone A\", test-1=\"Issue from clone B\"\n- Clone B: test-1=\"Issue from clone B\", test-2=\"Issue from clone A\"\n- Titles match IDs correctly, no data corruption\n- Only timestamps differ (expected and acceptable)\n\nFix needed:\n- Replace exact JSON comparison with content-aware comparison\n- Normalize or ignore timestamp fields when asserting convergence\n- Test should PASS after this fix\n\nThis blocks completion of bd-71107098.","acceptance_criteria":"- Test compares issue content (title, description, status, priority) not timestamps\n- TestTwoCloneCollision passes\n- Both clones shown to have identical semantic content\n- Timestamps explicitly documented as acceptable difference","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T17:58:52.057194-07:00","updated_at":"2025-10-30T17:12:58.226744-07:00","closed_at":"2025-10-28T18:01:38.751895-07:00","source_repo":".","dependencies":[{"issue_id":"bd-64c05d00.1","depends_on_id":"bd-64c05d00","type":"parent-child","created_at":"2025-10-28T17:58:52.058202-07:00","created_by":"stevey"},{"issue_id":"bd-64c05d00.1","depends_on_id":"bd-71107098","type":"blocks","created_at":"2025-10-28T17:58:52.05873-07:00","created_by":"stevey"}]} -{"id":"bd-64c05d00.2","content_hash":"bee12f24cd1fc490bef9065a1981f4d4f5289d375102290db320e24afa90a3ca","title":"Document 3-clone ID non-determinism in collision resolution","description":"Document the known behavior of 3+ way collision resolution where ID assignments may vary based on sync order, even though content always converges correctly.\n\nUpdates needed:\n- Update bd-71107098 notes to mark 2-clone case as solved\n- Document 3-clone ID non-determinism as known limitation\n- Add explanation to ADVANCED.md or collision resolution docs\n- Explain why this happens (pairwise hash comparison is deterministic, but multi-way ID allocation uses sync-order dependent counters)\n- Clarify trade-offs: content convergence ✅ vs ID stability ❌\n\nKey points to document:\n- Hash-based resolution is pairwise deterministic\n- Content always converges correctly (all issues present with correct data)\n- Numeric ID assignments in 3+ way collisions depend on sync order\n- This is acceptable for most use cases (content convergence is primary goal)\n- Full determinism would require complex multi-way comparison","acceptance_criteria":"- bd-71107098 updated with notes about 2-clone solution being complete\n- 3-clone ID non-determinism documented in ADVANCED.md or similar\n- Explanation includes why it happens and trade-offs\n- Links to TestThreeCloneCollision as demonstration\n- Users understand this is expected behavior, not a bug","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-28T17:59:21.93014-07:00","updated_at":"2025-11-20T12:40:11.70764-05:00","closed_at":"2025-11-15T14:13:47.304584-08:00","source_repo":".","dependencies":[{"issue_id":"bd-64c05d00.2","depends_on_id":"bd-64c05d00","type":"parent-child","created_at":"2025-10-28T17:59:21.938709-07:00","created_by":"stevey"}]} +{"id":"bd-64c05d00.2","content_hash":"bee12f24cd1fc490bef9065a1981f4d4f5289d375102290db320e24afa90a3ca","title":"Document 3-clone ID non-determinism in collision resolution","description":"Document the known behavior of 3+ way collision resolution where ID assignments may vary based on sync order, even though content always converges correctly.\n\nUpdates needed:\n- Update bd-71107098 notes to mark 2-clone case as solved\n- Document 3-clone ID non-determinism as known limitation\n- Add explanation to ADVANCED.md or collision resolution docs\n- Explain why this happens (pairwise hash comparison is deterministic, but multi-way ID allocation uses sync-order dependent counters)\n- Clarify trade-offs: content convergence ✅ vs ID stability ❌\n\nKey points to document:\n- Hash-based resolution is pairwise deterministic\n- Content always converges correctly (all issues present with correct data)\n- Numeric ID assignments in 3+ way collisions depend on sync order\n- This is acceptable for most use cases (content convergence is primary goal)\n- Full determinism would require complex multi-way comparison","acceptance_criteria":"- bd-71107098 updated with notes about 2-clone solution being complete\n- 3-clone ID non-determinism documented in ADVANCED.md or similar\n- Explanation includes why it happens and trade-offs\n- Links to TestThreeCloneCollision as demonstration\n- Users understand this is expected behavior, not a bug","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-28T17:59:21.93014-07:00","updated_at":"2025-11-16T15:50:05.87971707-07:00","closed_at":"2025-11-15T14:13:47.304584-08:00","source_repo":".","dependencies":[{"issue_id":"bd-64c05d00.2","depends_on_id":"bd-64c05d00","type":"parent-child","created_at":"2025-10-28T17:59:21.938709-07:00","created_by":"stevey"}]} {"id":"bd-64c05d00.3","content_hash":"e006b991353a26f949bc3ae4476849ef785f399f6aca866586eb6fa03d243b35","title":"Add TestThreeCloneCollision for regression protection","description":"Add a 3-clone collision test to document behavior and provide regression protection.\n\nPurpose:\n- Verify content convergence regardless of sync order\n- Document the ID non-determinism behavior (IDs may be assigned differently based on sync order)\n- Provide regression protection for multi-way collisions\n\nTest design:\n- 3 clones create same ID with different content\n- Test two different sync orders (A→B→C vs C→A→B)\n- Assert content sets match (ignore specific ID assignments)\n- Add comment explaining ID non-determinism is expected behavior\n\nKnown limitation:\n- Content always converges correctly (all issues present with correct titles)\n- Numeric ID assignments (test-2 vs test-3) depend on sync order\n- This is acceptable if content convergence is the primary goal","acceptance_criteria":"- TestThreeCloneCollision added to beads_twoclone_test.go (or new file)\n- Tests 3 clones with same ID collision\n- Tests two different sync orders\n- Asserts content convergence (all issues present, correct titles)\n- Documents ID non-determinism in test comments\n- Test passes consistently","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-28T17:59:05.941735-07:00","updated_at":"2025-10-30T17:12:58.227089-07:00","closed_at":"2025-10-28T18:09:12.717604-07:00","source_repo":".","dependencies":[{"issue_id":"bd-64c05d00.3","depends_on_id":"bd-64c05d00","type":"parent-child","created_at":"2025-10-28T17:59:05.942783-07:00","created_by":"stevey"}]} {"id":"bd-64z4","content_hash":"d707d871411b33bd6268d2a83ec6cc7696d9b38c86510dc7cb7a073fb2a8cfa3","title":"Assigned issue","description":"","status":"closed","priority":1,"issue_type":"task","assignee":"testuser","created_at":"2025-11-07T19:04:24.201309-08:00","updated_at":"2025-11-07T22:07:17.344151-08:00","closed_at":"2025-11-07T21:55:09.427387-08:00","source_repo":"."} {"id":"bd-6545","content_hash":"1d49e101cae39bc8115422fdef1e2cde999e88e176e5bc5614a5aefdbcd174da","title":"Update daemon commit logic for separate branch","description":"Modify daemon to use worktree for commits when sync.branch configured.\n\nTasks:\n- Update internal/daemon/server_export_import_auto.go\n- Detect sync.branch configuration\n- Ensure worktree exists before commit\n- Sync JSONL to worktree\n- Commit in worktree context\n- Push to configured branch\n- Fallback to current behavior if sync.branch not set\n- Handle git errors (network, permissions, conflicts)\n\nEstimated effort: 3-4 days","acceptance_criteria":"- When sync.branch configured, commits go to separate branch\n- When sync.branch not configured, commits to current branch (backward compatible)\n- No disruption to primary worktree\n- Git errors handled gracefully with retry\n- Daemon logs show which branch was used","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-02T15:22:35.598861-08:00","updated_at":"2025-11-04T11:10:23.531964-08:00","closed_at":"2025-11-04T11:10:23.531966-08:00","source_repo":".","dependencies":[{"issue_id":"bd-6545","depends_on_id":"bd-a101","type":"parent-child","created_at":"2025-11-02T15:22:48.375661-08:00","created_by":"stevey"}]} @@ -203,7 +203,7 @@ {"id":"bd-736d","content_hash":"4743b1f41ff07fee3daa63240f0d5f7ac3f876e928b22c4ce0bee2cdf544e53a","title":"Refactor path canonicalization into helper function","description":"The path canonicalization logic (filepath.Abs + EvalSymlinks) is duplicated in 3 places:\n- beads.go:131-137 (BEADS_DIR handling)\n- cmd/bd/main.go:446-451 (--no-db cleanup)\n- cmd/bd/nodb.go:26-31 (--no-db initialization)\n\nRefactoring suggestion:\nExtract to a helper function like:\n func canonicalizePath(path string) string\n\nThis would:\n- Reduce code duplication\n- Make the logic easier to maintain\n- Ensure consistent behavior across all path handling\n\nRelated to bd-e16b implementation.","status":"open","priority":3,"issue_type":"chore","created_at":"2025-11-02T18:33:47.727443-08:00","updated_at":"2025-11-02T18:33:47.727443-08:00","source_repo":"."} {"id":"bd-73iz","content_hash":"6003ff8e78d951d6a708f6aac6bcf841637977cab4f4a93a80b3dc2bab3287cb","title":"Test issue 1","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-07T19:04:17.430269-08:00","updated_at":"2025-11-07T22:07:17.344468-08:00","closed_at":"2025-11-07T21:55:09.427697-08:00","source_repo":"."} {"id":"bd-74ee","content_hash":"476deaacd64c91c96e5c9aca9ba0640dcf0f3854f9f11bbaa25a8ae80af3adf3","title":"Frontend task","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-03T19:11:59.358631-08:00","updated_at":"2025-11-05T00:25:06.457813-08:00","closed_at":"2025-11-05T00:25:06.457813-08:00","source_repo":".","labels":["frontend","week1"]} -{"id":"bd-74q9","content_hash":"426f1e44ca47486e2fa5b97832a635612ac9fcb98064f00559c8833480f11bd6","title":"Issue to reopen with reason","description":"","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-20T19:43:48.752747-05:00","updated_at":"2025-11-20T19:43:48.752747-05:00","closed_at":"2025-11-09T16:13:23.938513-08:00","source_repo":"."} +{"id":"bd-74q9","content_hash":"426f1e44ca47486e2fa5b97832a635612ac9fcb98064f00559c8833480f11bd6","title":"Issue to reopen with reason","description":"","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-22T15:18:47.441831879-07:00","updated_at":"2025-11-22T15:18:47.441831879-07:00","closed_at":"2025-11-09T16:13:23.938513-08:00","source_repo":"."} {"id":"bd-763c","content_hash":"31265106d3d8856bdda09f00708f6efdda862abc97a14f8e2bcacc8535870099","title":"~/src/beads daemon has 'sql: database is closed' errors - zombie daemon","description":"","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-31T21:08:03.388007-07:00","updated_at":"2025-10-31T21:52:04.214274-07:00","closed_at":"2025-10-31T21:52:04.214274-07:00","source_repo":".","dependencies":[{"issue_id":"bd-763c","depends_on_id":"bd-2752a7a2","type":"discovered-from","created_at":"2025-10-31T21:08:03.388716-07:00","created_by":"stevey"}]} {"id":"bd-77gm","content_hash":"b227320f0cf0c889a1e0d617922c572a48eee563c9afb1662b44a22e183c0c80","title":"Import reports misleading '0 created, 0 updated' when actually importing all issues","description":"When running 'bd import' on a fresh database (no existing issues), the command reports 'Import complete: 0 created, 0 updated' even though it successfully imported all issues from the JSONL file.\n\n**Steps to reproduce:**\n1. Delete .beads/beads.db\n2. Run: bd import .beads/issues.jsonl\n3. Observe output: 'Import complete: 0 created, 0 updated'\n4. Run: bd list\n5. Confirm: All issues are actually present in the database\n\n**Expected behavior:**\nReport the actual number of issues imported, e.g., 'Import complete: 523 created, 0 updated'\n\n**Actual behavior:**\n'Import complete: 0 created, 0 updated' (misleading - makes user think import failed)\n\n**Impact:**\n- Users think import failed when it succeeded\n- Confusing during database sync operations (e.g., after git pull)\n- Makes debugging harder (can't tell if import actually worked)\n\n**Context:**\nDiscovered during VC session when syncing database after git pull. The misleading message caused confusion about whether the database was properly synced with the canonical JSONL file.","acceptance_criteria":"- Import command reports accurate count of created/updated issues\n- Fresh database import shows 'N created' where N is the actual number\n- Update operations show 'N updated' where N is the actual number changed\n- Message clearly indicates success vs failure","status":"open","priority":2,"issue_type":"bug","created_at":"2025-11-09T16:20:13.191156-08:00","updated_at":"2025-11-09T16:20:13.191156-08:00","source_repo":"."} {"id":"bd-78w","content_hash":"dd79ef79bf68b3a87f3a5b8d50fdfba9d6c6f7e6d728713e37dd34cf9fff835e","title":"Test Epic 2","description":"## Overview\n\n[Describe the high-level goal and scope of this epic]\n\n## Success Criteria\n\n- [ ] Criteria 1\n- [ ] Criteria 2\n- [ ] Criteria 3\n\n## Background\n\n[Provide context and motivation]\n\n## Scope\n\n**In Scope:**\n- Item 1\n- Item 2\n\n**Out of Scope:**\n- Item 1\n- Item 2\n","design":"## Architecture\n\n[Describe the overall architecture and approach]\n\n## Components\n\n- Component 1: [description]\n- Component 2: [description]\n\n## Dependencies\n\n[List external dependencies or constraints]\n","acceptance_criteria":"- [ ] All child issues are completed\n- [ ] Integration tests pass\n- [ ] Documentation is updated\n- [ ] Code review completed\n","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-03T20:15:03.878216-08:00","updated_at":"2025-11-05T00:25:06.566242-08:00","closed_at":"2025-11-05T00:25:06.566242-08:00","source_repo":".","labels":["epic"]} @@ -231,10 +231,11 @@ {"id":"bd-833559b3","content_hash":"d4b0ded6c4696813257f7e3fa84913e3e159690b74f78c909e68debae8d1e727","title":"bd validate - Comprehensive health check","description":"Run all validation checks in one command.\n\nChecks:\n- Duplicates\n- Orphaned dependencies\n- Test pollution\n- Git conflicts\n\nSupports --fix-all for auto-repair.\n\nDepends on bd-cbed9619.1, bd-0dcea000, bd-2752a7a2, bd-9826b69a.\n\nFiles: cmd/bd/validate.go (new)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T20:02:47.957692-07:00","updated_at":"2025-11-05T00:16:42.294117-08:00","closed_at":"2025-11-05T00:16:42.294117-08:00","source_repo":"."} {"id":"bd-8507","content_hash":"96a07fcf39392143fa9c75cbc96f54136809609f6ced80dd9581ec9144d54b1f","title":"Publish bd-wasm to npm","description":"Package and publish WASM build to npm. Child of epic bd-44d0.\n\n## Tasks\n- [ ] Optimize WASM bundle (compression)\n- [ ] Create README for npm package\n- [ ] Set up npm publishing workflow\n- [ ] Publish v0.1.0-alpha\n- [ ] Test installation in clean environment\n- [ ] Update beads AGENTS.md with installation instructions\n\n## Package Name\nbd-wasm (or @beads/wasm-cli)","status":"closed","priority":0,"issue_type":"task","created_at":"2025-11-02T18:33:31.371535-08:00","updated_at":"2025-11-05T00:55:48.757492-08:00","closed_at":"2025-11-05T00:55:48.757494-08:00","source_repo":".","dependencies":[{"issue_id":"bd-8507","depends_on_id":"bd-197b","type":"blocks","created_at":"2025-11-02T18:33:31.372224-08:00","created_by":"daemon"},{"issue_id":"bd-8507","depends_on_id":"bd-374e","type":"blocks","created_at":"2025-11-02T22:27:56.025207-08:00","created_by":"daemon"}]} {"id":"bd-8534","content_hash":"05b543a341ac0210f6025318e2eaead1da295b8d270fd17356fa3337c856607d","title":"Switch from modernc.org/sqlite to ncruces/go-sqlite3 for WASM support","description":"modernc.org/sqlite depends on modernc.org/libc which has no js/wasm support (platform-specific syscalls). Need to switch to ncruces/go-sqlite3 which wraps a WASM build of SQLite using wazero runtime.\n\nKey differences:\n- ncruces/go-sqlite3: Uses WASM build of SQLite + wazero runtime\n- modernc.org/sqlite: Pure Go translation, requires libc for syscalls\n\nThis is a prerequisite for bd-62a0 (WASM build infrastructure).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-02T22:14:27.627154-08:00","updated_at":"2025-11-02T22:23:49.377223-08:00","closed_at":"2025-11-02T22:23:49.377223-08:00","source_repo":".","dependencies":[{"issue_id":"bd-8534","depends_on_id":"bd-44d0","type":"parent-child","created_at":"2025-11-02T22:23:49.555691-08:00","created_by":"stevey"}]} -{"id":"bd-85487065","content_hash":"f11f458db379288179b4c2434eacee8940eac910781a74c721c7e6e889f76bc1","title":"Add tests for internal/autoimport package","description":"Currently 0.0% coverage. Need tests for auto-import functionality that detects and imports updated JSONL files.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T14:06:18.154805-07:00","updated_at":"2025-11-08T22:42:08.862467-08:00","closed_at":"2025-11-08T18:06:25.811317-08:00","source_repo":"."} +{"id":"bd-85487065","content_hash":"f11f458db379288179b4c2434eacee8940eac910781a74c721c7e6e889f76bc1","title":"Add tests for internal/autoimport package","description":"Currently 0.0% coverage. Need tests for auto-import functionality that detects and imports updated JSONL files.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T14:06:18.154805-07:00","updated_at":"2025-11-11T08:42:35.006519722-07:00","closed_at":"2025-11-08T18:06:25.811317-08:00","source_repo":"."} {"id":"bd-85d1","content_hash":"a82c0064b840eacb4896f68e73650a3e99aaeaffbb2a7269a857b6c4245b5572","title":"Add integration tests for multi-repo sync","description":"Test: Clone A deletes issue, Clone B imports Clone A's JSONL. Verify Clone B handles deletion gracefully with resurrection. Test concurrent imports with same orphans (should be idempotent). Test round-trip fidelity (export→delete parent→import→verify structure).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-04T12:32:21.410318-08:00","updated_at":"2025-11-05T00:44:27.948465-08:00","closed_at":"2025-11-05T00:44:27.948467-08:00","source_repo":"."} +{"id":"bd-8788","content_hash":"6100310f9e353bdbca34f80da41fa4947b984b617b0a8dfbe47f7f104df4c847","title":"Fix monitor-webui status filter","description":"","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-21T11:54:18.982820303-07:00","updated_at":"2025-11-21T11:54:36.091639066-07:00","closed_at":"2025-11-21T11:54:36.091639066-07:00","source_repo":"."} {"id":"bd-879d","content_hash":"9716c230d9b2793bd1e51d9e3c380c06caf7b3e9a0dd20253764af19e3de7ac8","title":"Test issue 1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-02T09:44:12.538697729Z","updated_at":"2025-11-02T09:45:20.76214671Z","closed_at":"2025-11-02T09:45:20.76214671Z","source_repo":".","dependencies":[{"issue_id":"bd-879d","depends_on_id":"bd-d3e5","type":"discovered-from","created_at":"2025-11-02T09:44:22.103468321Z","created_by":"mrdavidlaing"}]} -{"id":"bd-87a0","content_hash":"b6c322852ff360ade9f0d46bb2af29a7cf3d3acc8b7469dcbb5d98bf48050240","title":"Publish @beads/bd package to npm registry","description":"Publish the npm package to the public npm registry:\n\n## Prerequisites\n- npm account created\n- Organization @beads created (or use different namespace)\n- npm login completed locally\n- Package tested locally (bd-f282 completed)\n\n## Publishing steps\n1. Verify package.json version matches current bd version\n2. Run npm pack and inspect tarball contents\n3. Test installation from tarball one more time\n4. Run npm publish --access public\n5. Verify package appears on https://www.npmjs.com/package/@beads/bd\n6. Test installation from registry: npm install -g @beads/bd\n\n## Post-publish\n- Add npm badge to README.md\n- Update CHANGELOG.md with npm package release\n- Announce in release notes\n\n## Note\n- May need to choose different name if @beads namespace unavailable\n- Alternative: beads-cli, bd-cli, or unscoped beads-issue-tracker","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-02T23:40:25.263569-08:00","updated_at":"2025-11-03T10:39:41.772338-08:00","closed_at":"2025-11-03T10:39:41.772338-08:00","source_repo":".","dependencies":[{"issue_id":"bd-87a0","depends_on_id":"bd-febc","type":"parent-child","created_at":"2025-11-02T23:40:33.014043-08:00","created_by":"daemon"}],"comments":[{"id":30,"issue_id":"bd-87a0","author":"stevey","text":"Package is ready to publish. All code complete and tested locally. Next steps: 1) npm login, 2) create @beads org if needed, 3) npm publish --access public. See npm-package/PUBLISHING.md for complete instructions.","created_at":"2025-11-22T07:09:48Z"}]} +{"id":"bd-87a0","content_hash":"b6c322852ff360ade9f0d46bb2af29a7cf3d3acc8b7469dcbb5d98bf48050240","title":"Publish @beads/bd package to npm registry","description":"Publish the npm package to the public npm registry:\n\n## Prerequisites\n- npm account created\n- Organization @beads created (or use different namespace)\n- npm login completed locally\n- Package tested locally (bd-f282 completed)\n\n## Publishing steps\n1. Verify package.json version matches current bd version\n2. Run npm pack and inspect tarball contents\n3. Test installation from tarball one more time\n4. Run npm publish --access public\n5. Verify package appears on https://www.npmjs.com/package/@beads/bd\n6. Test installation from registry: npm install -g @beads/bd\n\n## Post-publish\n- Add npm badge to README.md\n- Update CHANGELOG.md with npm package release\n- Announce in release notes\n\n## Note\n- May need to choose different name if @beads namespace unavailable\n- Alternative: beads-cli, bd-cli, or unscoped beads-issue-tracker","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-02T23:40:25.263569-08:00","updated_at":"2025-11-03T10:39:41.772338-08:00","closed_at":"2025-11-03T10:39:41.772338-08:00","source_repo":".","dependencies":[{"issue_id":"bd-87a0","depends_on_id":"bd-febc","type":"parent-child","created_at":"2025-11-02T23:40:33.014043-08:00","created_by":"daemon"}],"comments":[{"id":5,"issue_id":"bd-87a0","author":"stevey","text":"Package is ready to publish. All code complete and tested locally. Next steps: 1) npm login, 2) create @beads org if needed, 3) npm publish --access public. See npm-package/PUBLISHING.md for complete instructions.","created_at":"2025-11-08T20:26:48Z"}]} {"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","source_repo":"."} {"id":"bd-8931","content_hash":"409c16d9e6c83c2bf6cccfa6ee6cb18e1e1eee032b522fb99500bb40f2a05649","title":"Daemon gets stuck when auto-import blocked by git conflicts","description":"CRITICAL: The daemon enters a corrupt state that breaks RPC commands when auto-import is triggered but git pull fails due to uncommitted changes.\n\nImpact: This is a data integrity and usability issue that could cause users to lose trust in Beads. The daemon silently fails for certain commands while appearing healthy.\n\nReproduction:\n1. Make local changes to issues (creates uncommitted .beads/beads.jsonl)\n2. Remote has updates (JSONL newer, triggers auto-import)\n3. Daemon tries to pull but fails: 'cannot pull with rebase: You have unstaged changes'\n4. Daemon enters bad state - 'bd show' and other commands return EOF\n5. 'bd list' still works, daemon process is running, no errors logged\n\nTechnical details:\n- Auto-import check runs in handleRequest() before processing RPC commands\n- When import is blocked, it appears to corrupt daemon state\n- Likely: deadlock, unclosed transaction, or storage handle corruption\n- Panic recovery (server_lifecycle_conn.go:183) didn't catch anything - not a panic\n\nRequired fix:\n- Auto-import must not block RPC command execution\n- Handle git pull failures gracefully without corrupting state\n- Consider: skip auto-import if git is dirty, queue import for later, or use separate goroutine\n- Add timeout/circuit breaker for import operations\n- Log clear warnings when auto-import is skipped\n\nWithout this fix, users in collaborative environments will frequently encounter mysterious EOF errors that require daemon restarts.","design":"Options to fix:\n\n1. Skip auto-import when git is dirty (safest, simplest)\n - Check git status before pull\n - Log warning and continue without import\n - User must manually import after cleaning git state\n\n2. Async import with timeout (better UX)\n - Run auto-import in background goroutine\n - Don't block RPC command execution\n - Timeout after 5s, log error if stuck\n - Use sync.Once or similar to prevent concurrent imports\n\n3. Transactional import with rollback\n - Wrap import in database transaction\n - Rollback if git operations fail\n - Ensure storage is never left in bad state\n\nRecommended: Combine #1 and #2\n- Check git status first, skip if dirty\n- If clean, do async import with timeout\n- Add metrics to track import success/failure rates","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-02T17:15:25.181425-08:00","updated_at":"2025-11-03T12:08:12.949061-08:00","closed_at":"2025-11-03T12:08:12.949064-08:00","source_repo":".","dependencies":[{"issue_id":"bd-8931","depends_on_id":"bd-1048","type":"blocks","created_at":"2025-11-02T17:15:25.181857-08:00","created_by":"stevey"}]} {"id":"bd-897a","content_hash":"ae488407bf5e71242535f4c35b59b0981d2b8b338d1701f19acba2c8e93049f0","title":"Add UNIQUE constraint on external_ref column","description":"The external_ref column should have a UNIQUE constraint to prevent multiple issues from having the same external reference. This ensures data integrity when syncing from external systems (Jira, GitHub, Linear).\n\nCurrent behavior:\n- Multiple issues can have the same external_ref\n- GetIssueByExternalRef returns first match (non-deterministic with duplicates)\n\nProposed solution:\n- Add UNIQUE constraint to external_ref column\n- Add migration to check for and resolve existing duplicates\n- Update tests to verify constraint enforcement\n\nRelated: bd-1022","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-02T15:31:54.718005-08:00","updated_at":"2025-11-02T16:01:45.742666-08:00","closed_at":"2025-11-02T16:01:45.742666-08:00","source_repo":"."} @@ -248,10 +249,10 @@ {"id":"bd-8kde","content_hash":"2bc64e3d456f5490598f8d49e65a870d5b9b6c1579046a80f616a12d98908fc9","title":"bd delete bulk operations fight with auto-import/daemon causing data resurrection","description":"When bulk deleting issues (e.g., 244 closed issues older than 24h), the process fights with auto-import and daemon infrastructure:\n\n**Expected behavior:**\n- Delete 244 issues from 468-issue database\n- Export to JSONL (224 lines)\n- Commit and push\n- Result: 224 issues\n\n**Actual behavior:**\n- Delete 244 issues \n- Import runs (from stale git JSONL with 468 issues)\n- Resurrects deleted issues back into database\n- Export writes 356 lines (not 224)\n- Math: 468 - 244 = 224, but got 356 (132 issues resurrected)\n\n**Root cause:**\nAuto-import keeps re-importing from git during the delete operation, before the new JSONL is committed. The workflow is:\n1. Delete from DB\n2. Auto-import runs (reads old JSONL from git with deleted issues still present)\n3. Issues come back\n4. Export writes partially-deleted state\n\n**Solution options:**\n1. Add `--no-auto-import` flag to bulk delete operations\n2. Atomic delete-export-commit operation that suppresses imports\n3. Dedicated `bd prune` command that handles this correctly\n4. Lock file to prevent auto-import during bulk mutations\n\n**Impact:**\n- Bulk cleanup operations don't work reliably\n- Makes it nearly impossible to prune old closed issues\n- Confusing UX (delete 244, but only 112 actually removed)","notes":"**FIXED**: Auto-import now skips during delete operations to prevent resurrection.\n\n**Root cause confirmed**: Auto-import was running in PersistentPreRun before delete executed, causing it to re-import stale JSONL from git and resurrect deleted issues.\n\n**Solution implemented**:\n1. Added delete to skip list in main.go PersistentPreRun (alongside import and sync --dry-run)\n2. Delete operations now complete atomically without auto-import interference\n3. Added comprehensive test (TestBulkDeleteNoResurrection) to prevent regression\n\n**Test verification**:\n- Creates 20 issues, deletes 10\n- Verifies no resurrection after delete\n- Confirms JSONL has correct count (10 remaining)\n- All existing tests still pass","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-08T03:01:09.796852-08:00","updated_at":"2025-11-08T03:06:04.416994-08:00","closed_at":"2025-11-08T03:06:04.416994-08:00","source_repo":"."} {"id":"bd-8mfn","content_hash":"866a8afcdadb8e4e015aab6ab0b8882f48ae9856098181205013b992d2aa08f3","title":"bd message: Implement full message reading functionality","description":"The `bd message read` command is incomplete and doesn't actually fetch or display message content.\n\n**Location:** cmd/bd/message.go:413-441\n\n**Current Behavior:**\n- Only marks message as read\n- Prints placeholder text\n- Doesn't fetch message body\n\n**Expected:**\n- Fetch full message from Agent Mail resource API\n- Display sender, subject, timestamp, body\n- Consider markdown rendering\n\n**Blocker:** Core feature for message system MVP","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-08T12:54:24.018957-08:00","updated_at":"2025-11-08T12:57:32.91854-08:00","closed_at":"2025-11-08T12:57:32.91854-08:00","source_repo":".","dependencies":[{"issue_id":"bd-8mfn","depends_on_id":"bd-6uix","type":"parent-child","created_at":"2025-11-08T12:55:54.811368-08:00","created_by":"daemon"}]} {"id":"bd-8ph6","content_hash":"c64a644d8f2ea530109e7e6ef569ebd18b553a793cce5a4bd657581d75304167","title":"Support Ubuntu 20.04 LTS (glibc compatibility issue)","description":"Starting at v0.22, precompiled binaries require GLIBC 2.32+ which is not available on Ubuntu 20.04 LTS (Focal Fossa). Ubuntu 20.04 has GLIBC 2.31.\n\nError:\n```\nbd: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by bd)\nbd: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by bd)\n```\n\nCurrent workarounds:\n1. Upgrade to Ubuntu 22.04+\n2. Build from source: `go build -o bd ./cmd/bd/`\n\nRoot cause: Go 1.24+ runtime requires newer glibc. CGO is already disabled in .goreleaser.yml.\n\nPossible solutions:\n- Pin Go version to 1.21 or 1.22 for releases\n- Use Docker/cross-compile with older build environment\n- Provide separate build for older distros\n- Document minimum requirements clearly","notes":"Decision: Document minimum requirements in README instead of pinning Go version.\n\nRationale:\n- Ubuntu 20.04 LTS standard support ended April 2025 (already EOL)\n- Pinning Go prevents security fixes, performance improvements, and new features\n- Users on EOL distros can upgrade OS or build from source\n- Added Requirements section to README with clear glibc 2.32+ requirement","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-07T14:25:47.055357-08:00","updated_at":"2025-11-07T14:30:15.755733-08:00","closed_at":"2025-11-07T14:30:15.755733-08:00","source_repo":"."} -{"id":"bd-8ql","content_hash":"590a0323ca0cc2c0b262ef0c174dd8d67a33bcc7b216a1e64df1cf6e4835c867","title":"Remove misleading placeholder 'bd merge' command from duplicates output","description":"**Problem:**\nThe `bd duplicates` command suggests running a command that doesn't exist:\n```\nbd merge \u003csource-ids\u003e --into \u003ctarget-id\u003e\n```\n\nThis is confusing because:\n1. `bd merge` is actually a git 3-way JSONL merge driver (takes 4 file paths)\n2. The suggested syntax for merging duplicate issues is not implemented\n3. Line 75 in duplicates.go even has: `// TODO: performMerge implementation pending`\n\n**Current behavior:**\n- Users see suggested command that doesn't work\n- No indication that feature is unimplemented\n- Related to issue #349 item #2\n\n**Proposed fix:**\nReplace line 77 in cmd/bd/duplicates.go with either:\n\nOption A (conservative):\n```go\ncmd := fmt.Sprintf(\"# TODO: Merge %s into %s (merge command not yet implemented)\", \n strings.Join(sources, \" \"), target.ID)\n```\n\nOption B (actionable):\n```go\ncmd := fmt.Sprintf(\"# Duplicate found: %s\\n# Manual merge: Close duplicates with 'bd close %s' and link to %s as 'related'\", \n strings.Join(sources, \" \"), strings.Join(sources, \" \"), target.ID)\n```\n\n**Files to modify:**\n- cmd/bd/duplicates.go (line ~77)","design":"Remove the non-existent command suggestion and replace with actionable guidance.\n\nSince there are two unrelated `bd merge` concepts:\n1. Git JSONL merge driver (exists, works)\n2. Duplicate issue merger (doesn't exist, TODO)\n\nWe should not conflate them in user-facing output.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-20T20:48:01.707967-05:00","updated_at":"2025-11-20T20:59:13.416865-05:00","closed_at":"2025-11-20T20:59:13.416865-05:00","source_repo":".","labels":["bug","documentation","ux"],"comments":[{"id":35,"issue_id":"bd-8ql","author":"stevey","text":"Addresses GitHub issue #349 item 2: https://github.com/steveyegge/beads/issues/349\n\nUser confused by 'bd merge' help text. The help text is actually correct (it's a git merge driver), but the duplicates command suggests a non-existent 'bd merge \u003cids\u003e --into \u003ctarget\u003e' syntax for merging duplicate issues.","created_at":"2025-11-22T07:53:00Z"}]} +{"id":"bd-8ql","content_hash":"590a0323ca0cc2c0b262ef0c174dd8d67a33bcc7b216a1e64df1cf6e4835c867","title":"Remove misleading placeholder 'bd merge' command from duplicates output","description":"**Problem:**\nThe `bd duplicates` command suggests running a command that doesn't exist:\n```\nbd merge \u003csource-ids\u003e --into \u003ctarget-id\u003e\n```\n\nThis is confusing because:\n1. `bd merge` is actually a git 3-way JSONL merge driver (takes 4 file paths)\n2. The suggested syntax for merging duplicate issues is not implemented\n3. Line 75 in duplicates.go even has: `// TODO: performMerge implementation pending`\n\n**Current behavior:**\n- Users see suggested command that doesn't work\n- No indication that feature is unimplemented\n- Related to issue #349 item #2\n\n**Proposed fix:**\nReplace line 77 in cmd/bd/duplicates.go with either:\n\nOption A (conservative):\n```go\ncmd := fmt.Sprintf(\"# TODO: Merge %s into %s (merge command not yet implemented)\", \n strings.Join(sources, \" \"), target.ID)\n```\n\nOption B (actionable):\n```go\ncmd := fmt.Sprintf(\"# Duplicate found: %s\\n# Manual merge: Close duplicates with 'bd close %s' and link to %s as 'related'\", \n strings.Join(sources, \" \"), strings.Join(sources, \" \"), target.ID)\n```\n\n**Files to modify:**\n- cmd/bd/duplicates.go (line ~77)","design":"Remove the non-existent command suggestion and replace with actionable guidance.\n\nSince there are two unrelated `bd merge` concepts:\n1. Git JSONL merge driver (exists, works)\n2. Duplicate issue merger (doesn't exist, TODO)\n\nWe should not conflate them in user-facing output.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-20T20:48:01.707967-05:00","updated_at":"2025-11-20T21:51:31.800383-05:00","closed_at":"2025-11-20T20:59:13.416865-05:00","source_repo":".","labels":["bug","documentation","ux"],"comments":[{"id":10,"issue_id":"bd-8ql","author":"stevey","text":"Addresses GitHub issue #349 item 2: https://github.com/steveyegge/beads/issues/349\n\nUser confused by 'bd merge' help text. The help text is actually correct (it's a git merge driver), but the duplicates command suggests a non-existent 'bd merge \u003cids\u003e --into \u003ctarget\u003e' syntax for merging duplicate issues.","created_at":"2025-11-21T13:58:10Z"}]} {"id":"bd-8rd","content_hash":"e5845f6bda21414b3715f9589c76f8a02594f4cb8691939ced6765329346e411","title":"Migration and onboarding for multi-repo","description":"Create migration tools, wizards, and documentation to help users adopt multi-repo workflow, with special focus on OSS contributor onboarding and team adoption scenarios.","design":"Components:\n- Migration guide documentation\n- bd migrate command to move issues between repos\n- bd init --contributor wizard for OSS setup\n- bd init --team wizard for team setup\n- Auto-detect scenarios and prompt users\n- Examples for common workflows (OSS, multi-phase, personas)\n\nScenarios:\n1. OSS contributor (fork workflow)\n2. Team member (branch workflow)\n3. Multi-phase development\n4. Multiple personas (architect/implementer)","acceptance_criteria":"1. Migration guide covers all scenarios\n2. bd migrate moves issues with filtering\n3. Init wizards guide common setups\n4. Examples demonstrate key workflows\n5. Auto-detection prompts users when appropriate\n6. Docs updated with multi-repo patterns\n7. Backward compatibility clearly documented","status":"closed","priority":2,"issue_type":"epic","created_at":"2025-11-04T11:22:13.491033-08:00","updated_at":"2025-11-07T16:08:24.951261-08:00","closed_at":"2025-11-07T16:03:09.75064-08:00","source_repo":".","dependencies":[{"issue_id":"bd-8rd","depends_on_id":"bd-4ms","type":"parent-child","created_at":"2025-11-04T11:22:21.858002-08:00","created_by":"daemon"}]} {"id":"bd-8wa","content_hash":"0cf757ff7ef5393901a61cfdfaa2d6f7ac627eaa1c62b63165050f21d9b5b390","title":"Code Review Sweep: thorough","description":"Perform thorough code review sweep based on accumulated activity.\n\n**AI Reasoning:**\nSignificant code volume added (150,273 lines) across multiple critical areas, including cmd/bd, internal/storage/sqlite, and internal/rpc. High file change count (616) indicates substantial refactoring or new functionality. The metrics suggest potential for subtle architectural or implementation issues that warrant review.\n\n**Scope:** thorough\n**Target Areas:** cmd/bd, internal/storage/sqlite, internal/rpc\n**Estimated Files:** 12\n**Estimated Cost:** $5\n\n**Task:**\nReview files for non-obvious issues that agents miss during focused work:\n- Inefficiencies (algorithmic, resource usage)\n- Subtle bugs (race conditions, off-by-one, copy-paste)\n- Poor patterns (coupling, complexity, duplication)\n- Missing best practices (error handling, docs, tests)\n- Unnamed anti-patterns\n\nFile discovered issues with detailed reasoning and suggestions.","acceptance_criteria":"- Reviewed target files for code quality issues\n- Filed discovered issues with detailed reasoning\n- Completed sweep according to scope criteria","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-21T10:25:37.081296-05:00","updated_at":"2025-11-21T10:25:37.081296-05:00","source_repo":".","labels":["code-review-sweep","review-area:cmd/bd","review-area:internal/rpc","review-area:internal/storage/sqlite"]} -{"id":"bd-8y1a","content_hash":"df8bc8f8f805255b0df54d3f053f3919c430237eb49724f231a6b79e4c83fdbb","title":"Update Nix flake Go modules hash","description":"","status":"closed","priority":0,"issue_type":"bug","assignee":"claude","created_at":"2025-11-22T10:56:09.819863-08:00","updated_at":"2025-11-22T10:59:18.858399-08:00","closed_at":"2025-11-22T10:59:18.858399-08:00","source_repo":"."} +{"id":"bd-8y1a","content_hash":"7290f181cb874705a9981d12c510f9506f7c74de40aafa1baa5a9b652e52495a","title":"Update Nix flake Go modules hash","description":"","status":"closed","priority":0,"issue_type":"bug","assignee":"claude","created_at":"2025-11-22T10:56:09.819863-08:00","updated_at":"2025-11-22T10:59:18.858399-08:00","closed_at":"2025-11-22T10:59:18.858399-08:00","source_repo":"."} {"id":"bd-8zf2","content_hash":"6aaca1fd593b88220f2d8e41f7af9b0cbce6d9152ac4d0b9d2ffe3b8f464adc5","title":"MCP server loses workspace context after Amp restart - causes silent failures","description":"**CRITICAL BUG**: The beads MCP server loses workspace context when Amp restarts, leading to silent failures and potential data corruption.\n\n## Reproduction\n1. Start Amp with beads MCP server configured\n2. Call `mcp__beads__set_context(workspace_root=\"/path/to/project\")`\n3. Use MCP tools successfully (e.g., `mcp__beads__show`, `mcp__beads__list`)\n4. Restart Amp (new thread/session)\n5. Try to use MCP tools without calling `set_context` again\n6. **Result**: \"Not connected\" or \"No workspace set\" errors\n\n## Impact\n- Amp agents silently fail when trying to read/update beads issues\n- May attempt to create duplicate issues because they can't see existing ones\n- Potential for data corruption if operating on wrong database\n- Breaks multi-session workflows\n- Creates confusion: CLI works (`./bd`) but MCP tools don't\n\n## Current Workaround\nManually call `mcp__beads__set_context()` at start of every Amp session.\n\n## Root Cause\nMCP server is stateful and doesn't persist workspace context across restarts.\n\n## Proposed Fix\n**Option 1 (Best)**: Auto-detect workspace from current working directory\n- Match behavior of CLI `./bd` commands\n- Check for `.beads/` directory in current dir or parents\n- No manual context setting needed\n\n**Option 2**: Persist context in MCP server state file\n- Save last workspace_root to `~/.config/beads/mcp_context.json`\n- Restore on server startup\n\n**Option 3**: Require explicit context in every MCP call\n- Add optional `workspace_root` parameter to all MCP tools\n- Fall back to saved context if not provided\n\nAcceptance:\n- MCP tools work across Amp restarts without manual set_context()\n- Auto-detection matches CLI behavior (walks up from CWD)\n- Clear error message when no workspace found\n- set_context() still works for explicit override\n- BEADS_WORKING_DIR env var support\n- Integration test validates restart behavior","design":"**Recommended Implementation: Option 1 (Auto-detect)**\n\n1. Workspace Discovery Algorithm (same as CLI):\n - Start from CWD or provided directory\n - Walk up directory tree looking for .beads/beads.db\n - Cache result for performance\n\n2. MCP Tool Wrapper Changes:\n - Before each MCP tool execution, check if workspace is set\n - If not set, try auto-detection from CWD\n - If found, auto-connect and cache\n - If not found, return clear error with instructions\n\n3. Fallback Behavior:\n - Auto-detect from CWD first\n - Check BEADS_WORKING_DIR env var\n - Check ~/.config/beads/last_workspace (persisted)\n - Return actionable error if all fail\n\n4. Backwards Compatibility:\n - Keep set_context() working for explicit control\n - Auto-detect is always tried first if no explicit context\n - set_context() takes precedence over auto-detect","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-07T23:50:52.083111-08:00","updated_at":"2025-11-07T23:58:44.397502-08:00","closed_at":"2025-11-07T23:58:44.397502-08:00","source_repo":"."} {"id":"bd-8zpg","content_hash":"31c8e1312c7d75e9c17f9557f86bc642ca47e5c9a39d4f7e76429cc61bc9793d","title":"Add tests for bd init --contributor wizard","description":"Write integration tests for the contributor wizard:\n- Test fork detection logic\n- Test planning repo creation\n- Test config setup\n- Test with/without upstream remote\n- Test with SSH vs HTTPS origins","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-05T18:58:18.171851-08:00","updated_at":"2025-11-06T18:19:16.232739-08:00","closed_at":"2025-11-06T16:14:06.341689-08:00","source_repo":"."} {"id":"bd-9063acda","content_hash":"0ea4606188e376705c46a14e5d64da1b706aad47a39054a732c21330db601960","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":"closed","priority":2,"issue_type":"epic","created_at":"2025-10-24T01:01:12.997982-07:00","updated_at":"2025-11-04T11:10:23.532431-08:00","closed_at":"2025-11-04T11:10:23.532433-08:00","source_repo":"."} @@ -282,10 +283,10 @@ {"id":"bd-a03d5e36","content_hash":"f63ec5a25a14c9b01ca8b97ea14d0b00c42e8d6fe3b39f6e261411134a024de8","title":"Improve integration test coverage for stateful features","description":"","design":"## Context\n\nbd-70419816 revealed a critical gap: the export deduplication feature had unit tests but no integration tests simulating real-world git operations. This led to silent data loss in production.\n\n## Root Cause\n- Unit tests only tested functions in isolation\n- No integration tests for git operations (pull, reset, checkout) modifying JSONL\n- No tests validating export_hashes and JSONL stay in sync\n- Missing tests for stateful distributed system interactions (DB + JSONL + git)\n\n## Completed (bd-70419816)\n✓ TestJSONLIntegrityValidation - unit tests for validation logic\n✓ TestImportClearsExportHashes - tests import clears hashes\n✓ TestExportIntegrityAfterJSONLTruncation - simulates git reset (would have caught bd-70419816)\n✓ TestExportIntegrityAfterJSONLDeletion - tests recovery from file deletion\n✓ TestMultipleExportsStayConsistent - tests repeated exports\n\n## Still Needed (High Priority)\n1. Multi-repo sync test - two clones staying in sync after push/pull\n2. Auto-flush integration test - JSONL integrity preserved during auto-flush\n3. Daemon auto-sync integration test - complex state management\n4. Import after corruption test - recovery from partial data loss\n\n## Medium Priority\n- Partial export failure handling (disk full, network interruption)\n- Concurrent export/import race conditions\n- Large dataset performance tests (1000+ issues)\n- Export hash migration tests (version upgrades)\n\n## Testing Principles\n1. Test real-world scenarios: git ops, user errors, system failures, concurrent ops\n2. Integration tests for stateful systems (DB + files + git)\n3. Regression test for every bug fix\n4. Test invariants: JSONL count == DB count, hash consistency, etc.\n\n## Key Lesson\nStateful distributed systems need integration tests, not just unit tests.","acceptance_criteria":"- [ ] Multi-repo sync test implemented\n- [ ] Auto-flush integration test implemented \n- [ ] Daemon auto-sync integration test implemented\n- [ ] Testing guidelines added to CONTRIBUTING.md\n- [ ] CI runs integration tests\n- [ ] All critical workflows have integration test coverage","status":"closed","priority":2,"issue_type":"epic","created_at":"2025-10-29T21:53:15.397137-07:00","updated_at":"2025-11-08T01:58:15.281757-08:00","closed_at":"2025-11-08T00:36:59.02371-08:00","source_repo":"."} {"id":"bd-a101","content_hash":"9c8ac3184d936a5483d307ea72e34fa6308e99416b27c930c1b7b05660173f47","title":"Support separate branch for beads commits","description":"Allow beads to commit to a separate branch (e.g., beads-metadata) using git worktrees to support protected main branch workflows.\n\nSolves GitHub Issue #205 - Users need to protect main branch while maintaining beads workflow.\n\nKey advantages:\n- Works on any git platform\n- Main branch stays protected \n- No disruption to user's working directory\n- Backward compatible (opt-in via config)\n- Minimal disk overhead (sparse checkout)\n\nTotal estimate: 17-24 days (4-6 weeks with parallel work)","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-02T15:21:20.098247-08:00","updated_at":"2025-11-04T12:36:53.772727-08:00","closed_at":"2025-11-04T12:36:53.772727-08:00","external_ref":"GH-205","source_repo":"."} {"id":"bd-a1691807","content_hash":"52a3da17d0db9e7998b77b4962c00eeb866ca1eb3581d362863b68788b162582","title":"Integration test: mutation to export latency","description":"Measure time from bd create to JSONL update. Verify \u003c500ms latency. Test with multiple rapid mutations to verify batching.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T20:49:49.105247-07:00","updated_at":"2025-10-31T12:00:43.198883-07:00","closed_at":"2025-10-31T12:00:43.198883-07:00","source_repo":"."} -{"id":"bd-a40f374f","content_hash":"a9385e9f00bc41e5e2258fdfccd9f2cbd5a702764b5f1d036274e6026f8c3e38","title":"bd validate - Comprehensive health check","description":"Run all validation checks in one command.\n\nChecks:\n- Duplicates\n- Orphaned dependencies\n- Test pollution\n- Git conflicts\n\nSupports --fix-all for auto-repair.\n\nDepends on bd-cbed9619.1, bd-0dcea000, bd-31aab707, bd-9826b69a.\n\nFiles: cmd/bd/validate.go (new)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T12:40:11.708313-05:00","updated_at":"2025-11-20T12:40:11.708313-05:00","closed_at":"2025-10-29T20:02:15.318966-07:00","source_repo":"."} +{"id":"bd-a40f374f","content_hash":"a9385e9f00bc41e5e2258fdfccd9f2cbd5a702764b5f1d036274e6026f8c3e38","title":"bd validate - Comprehensive health check","description":"Run all validation checks in one command.\n\nChecks:\n- Duplicates\n- Orphaned dependencies\n- Test pollution\n- Git conflicts\n\nSupports --fix-all for auto-repair.\n\nDepends on bd-cbed9619.1, bd-0dcea000, bd-31aab707, bd-9826b69a.\n\nFiles: cmd/bd/validate.go (new)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-22T15:18:47.444481609-07:00","updated_at":"2025-11-22T15:18:47.444481609-07:00","closed_at":"2025-10-29T20:02:15.318966-07:00","source_repo":"."} {"id":"bd-a4b5","content_hash":"3966f6f9ab3202fe740f2936c7743f679ea42b75803c99465176ccf69ffd9dd7","title":"Implement git worktree management","description":"Create git worktree lifecycle management for separate beads branch.\n\nTasks:\n- Create internal/git/worktree.go\n- Implement CreateBeadsWorktree(branch, path)\n- Implement RemoveBeadsWorktree(path)\n- Implement CheckWorktreeHealth(path)\n- Configure sparse checkout (only .beads/)\n- Implement SyncJSONLToWorktree()\n- Handle worktree errors gracefully\n- Auto-cleanup on config change\n\nEstimated effort: 3-4 days","acceptance_criteria":"- Worktree created successfully on first use\n- Sparse checkout limits to .beads/ only\n- Health check detects and fixes broken worktrees\n- JSONL synced correctly before commits\n- Cleanup removes worktree completely","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-02T15:22:35.56423-08:00","updated_at":"2025-11-04T11:10:23.533053-08:00","closed_at":"2025-11-04T11:10:23.533055-08:00","source_repo":".","dependencies":[{"issue_id":"bd-a4b5","depends_on_id":"bd-a101","type":"parent-child","created_at":"2025-11-02T15:22:48.359843-08:00","created_by":"stevey"}]} {"id":"bd-a5251b1a","content_hash":"71a54f24d3d1c9eba8bf185c273ab6624815eb1299a8718aa0199c97f518008c","title":"Test RPC mutation event","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T19:08:03.315443-07:00","updated_at":"2025-10-31T12:00:43.177494-07:00","closed_at":"2025-10-31T12:00:43.177494-07:00","source_repo":"."} -{"id":"bd-a557","content_hash":"35b394c75f08f60e3a8bf4cb5f837fd7644ae1bbc7a050d0f4b78d01c9e7a33e","title":"Issue 1 to reopen","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T19:43:48.753517-05:00","updated_at":"2025-11-20T19:43:48.753517-05:00","closed_at":"2025-11-07T21:57:59.910467-08:00","source_repo":"."} +{"id":"bd-a557","content_hash":"35b394c75f08f60e3a8bf4cb5f837fd7644ae1bbc7a050d0f4b78d01c9e7a33e","title":"Issue 1 to reopen","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-22T15:18:47.446338127-07:00","updated_at":"2025-11-22T15:18:47.446338127-07:00","closed_at":"2025-11-07T21:57:59.910467-08:00","source_repo":"."} {"id":"bd-a9699011","content_hash":"5c0f39c01f3aa92d6407ef3128f4c8acb44b177f55f5d3906b5e83af5c0a3472","title":"GH#146: No color showing in terminal for some users","description":"User reports color not working in macOS (Taho 26.0.1) with iTerm 3.6.4 and Terminal.app, despite color working elsewhere in terminal. Python rich and printf escape codes work.\n\nNeed to investigate:\n- Is NO_COLOR env var set?\n- Terminal type detection?\n- fatih/color library configuration\n- Does bd list show colors? bd ready? bd init?\n- What's the output of: echo $TERM, echo $NO_COLOR","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-10-24T22:26:36.22163-07:00","updated_at":"2025-11-08T01:58:15.282138-08:00","closed_at":"2025-11-08T00:54:40.47956-08:00","external_ref":"github:146","source_repo":"."} {"id":"bd-ad5e","content_hash":"67fdba1ba5b838384b16b82ff45e200cb5fd4960795bb5ae29d6fdec549170ca","title":"Add AI planning docs management guidance to bd onboard (GH-196)","description":"Enhanced bd onboard command to provide guidance for managing AI-generated planning documents (Claude slop).\n\nAddresses GitHub issue #196: https://github.com/steveyegge/beads/issues/196\n\nChanges:\n- Added Managing AI-Generated Planning Documents section to bd onboard\n- Recommends using history/ directory for ephemeral planning files\n- Updated AGENTS.md to demonstrate the pattern\n- Added comprehensive tests\n\nCommit: d46177d","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-02T17:11:33.183636-08:00","updated_at":"2025-11-02T17:12:05.599633-08:00","closed_at":"2025-11-02T17:12:05.599633-08:00","source_repo":"."} {"id":"bd-aewm","content_hash":"b9f0ebb0c99a35c39c918250a1220f74bfcd77905b85c66715b36d1df9c5ec4b","title":"bd-hv01: Missing cleanup of .merged temp file on failure","description":"Problem: deletion_tracking.go:49 creates tmpMerged file but does not clean up on failure, causing disk space leak and potential interference with subsequent syncs.\n\nFix: Add defer os.Remove(tmpMerged) after creating temp file path.\n\nFiles: cmd/bd/deletion_tracking.go:38-89","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-06T18:16:24.326719-08:00","updated_at":"2025-11-06T18:46:55.924379-08:00","closed_at":"2025-11-06T18:46:55.924379-08:00","source_repo":".","dependencies":[{"issue_id":"bd-aewm","depends_on_id":"bd-rbxi","type":"parent-child","created_at":"2025-11-06T18:19:15.061462-08:00","created_by":"daemon"}]} @@ -297,10 +298,10 @@ {"id":"bd-ar2.2","content_hash":"c4dee35a25421d4058d5debd5bd83914b134ebdea5faa4b6a63852d0d82b7ae4","title":"Add multi-repo support to export metadata updates","description":"## Problem\nThe bd-ymj fix only updates metadata for the main jsonlPath, but the codebase supports multi-repo mode where exports write to multiple JSONL files.\n\nOther daemon_sync operations handle multi-repo correctly:\n- Lines 509-518: Snapshots captured for all multi-repo paths\n- Lines 578-587: Deletions applied for all multi-repo paths\n\nBut metadata updates are missing!\n\n## Investigation Needed\nMetadata is stored globally in database (`last_import_hash`, `last_import_mtime`), but multi-repo has per-repo JSONL files. Current schema may not support tracking multiple JSONL files.\n\nOptions:\n1. Store metadata per-repo (new schema)\n2. Store combined hash of all repos\n3. Document that multi-repo doesn't need this metadata (why?)\n\n## Solution (if needed)\n```go\n// After export\nif multiRepoPaths := getMultiRepoJSONLPaths(); multiRepoPaths != nil {\n // Multi-repo mode: update metadata for each JSONL\n for _, path := range multiRepoPaths {\n updateExportMetadata(exportCtx, store, path, log)\n }\n} else {\n // Single-repo mode: update metadata for main JSONL\n updateExportMetadata(exportCtx, store, jsonlPath, log)\n}\n```\n\n## Files\n- cmd/bd/daemon_sync.go (createExportFunc, createSyncFunc)\n- Possibly: internal/storage/sqlite/metadata.go (schema changes)\n\n## Related\nDepends on bd-ar2.1 (extract helper function first)","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-21T10:24:32.482102-05:00","updated_at":"2025-11-21T23:53:00.477532-08:00","closed_at":"2025-11-21T11:07:17.124957-05:00","source_repo":".","dependencies":[{"issue_id":"bd-ar2.2","depends_on_id":"bd-ar2","type":"parent-child","created_at":"2025-11-21T10:24:32.482559-05:00","created_by":"daemon"}]} {"id":"bd-ar2.3","content_hash":"143dac2e836dcf93264d5654d2d9aa0960777d186c0fea1b146c21158a002234","title":"Fix TestExportUpdatesMetadata to test actual daemon functions","description":"## Problem\nTestExportUpdatesMetadata (daemon_sync_test.go:296) manually replicates the metadata update logic rather than calling the fixed functions (createExportFunc/createSyncFunc).\n\nThis means:\n- Test verifies the CONCEPT works\n- But doesn't verify the IMPLEMENTATION in the actual daemon functions\n- If daemon code is wrong, test still passes\n\n## Current Test Flow\n```go\n// Test does:\nexportToJSONLWithStore() // ← Direct call\n// ... manual metadata update ...\nexportToJSONLWithStore() // ← Direct call again\n```\n\n## Should Be\n```go\n// Test should:\ncreateExportFunc(...)() // ← Call actual daemon function\n// ... verify metadata was updated by the function ...\ncreateExportFunc(...)() // ← Call again, should not fail\n```\n\n## Challenge\ncreateExportFunc returns a closure that's run by the daemon. Testing this requires:\n- Mock logger\n- Proper context setup\n- Git operations might need mocking\n\n## Files\n- cmd/bd/daemon_sync_test.go\n\n## Acceptance Criteria\n- Test calls actual createExportFunc and createSyncFunc\n- Test verifies metadata updated by daemon code, not test code\n- Both functions tested (export and sync)","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-21T10:24:46.756315-05:00","updated_at":"2025-11-21T23:53:00.478047-08:00","closed_at":"2025-11-21T11:07:25.321289-05:00","source_repo":".","dependencies":[{"issue_id":"bd-ar2.3","depends_on_id":"bd-ar2","type":"parent-child","created_at":"2025-11-21T10:24:46.757622-05:00","created_by":"daemon"}]} {"id":"bd-ar2.4","content_hash":"2fe8e7ac1334017eabaeb7a906f632d112b3040bb2f618c9cabc00311e7d2886","title":"Use TryResurrectParentChain instead of TryResurrectParent in GetNextChildID","description":"## Context\nCurrent bd-dvd fix uses TryResurrectParent, which only resurrects the immediate parent. For deeply nested hierarchies, this might not be sufficient.\n\n## Example Scenario\nCreating child with parent \"bd-abc.1.2\" where:\n- bd-abc exists in DB\n- bd-abc.1 was deleted (missing from DB, exists in JSONL)\n- bd-abc.1.2 was deleted (missing from DB, exists in JSONL)\n\nCurrent fix: Only tries to resurrect \"bd-abc.1.2\", fails because its parent \"bd-abc.1\" is missing.\n\n## Solution\nReplace TryResurrectParent with TryResurrectParentChain:\n\n```go\nif count == 0 {\n // Try to resurrect entire parent chain from JSONL history (bd-dvd fix)\n // This handles deeply nested hierarchies where intermediate parents are also missing\n resurrected, err := s.TryResurrectParentChain(ctx, parentID)\n if err != nil {\n return \"\", fmt.Errorf(\"failed to resurrect parent chain for %s: %w\", parentID, err)\n }\n if !resurrected {\n return \"\", fmt.Errorf(\"parent issue %s does not exist and could not be resurrected from JSONL history\", parentID)\n }\n}\n```\n\n## Investigation\n- Check if this scenario actually happens in practice\n- TryResurrectParentChain already exists (resurrection.go:174-209)\n- May be overkill if users always create parents before children\n\n## Files\n- internal/storage/sqlite/hash_ids.go\n\n## Testing\nAdd test case for deeply nested resurrection","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-21T10:25:01.376071-05:00","updated_at":"2025-11-21T23:53:00.478538-08:00","closed_at":"2025-11-21T11:40:47.682699-05:00","source_repo":".","dependencies":[{"issue_id":"bd-ar2.4","depends_on_id":"bd-ar2","type":"parent-child","created_at":"2025-11-21T10:25:01.376561-05:00","created_by":"daemon"}]} -{"id":"bd-ar2.5","content_hash":"16ae300a7e23d596aef9cb39d131e252556905c04ebc2fdaca2a295256ea1191","title":"Add error handling guidance for export metadata update failures","description":"## Problem\nThe bd-ymj fix treats all metadata update failures as warnings:\n\n```go\nif err := store.SetMetadata(ctx, \"last_import_hash\", currentHash); err != nil {\n log.log(\"Warning: failed to update last_import_hash: %v\", err)\n}\n```\n\nBut if metadata updates fail, the NEXT export will fail with \"JSONL content has changed since last import\".\n\n## Questions\n1. Should metadata failures be critical (return error)?\n2. Should we implement retry logic?\n3. Is warning acceptable (safe, just requires import before next export)?\n\n## Current Behavior\n- Metadata failure is silent (only logged)\n- User won't know until next export fails\n- Next export requires import first (safe but annoying)\n\n## Recommendation\nAdd clear comment explaining the trade-off:\n\n```go\n// Note: Metadata update failures are treated as warnings, not errors.\n// This is acceptable because the worst case is the next export will\n// require an import first, which is safe and prevents data loss.\n// Alternative: Make this critical and fail the export if metadata\n// updates fail (but this makes exports more fragile).\nif err := store.SetMetadata(ctx, \"last_import_hash\", currentHash); err != nil {\n log.log(\"Warning: failed to update last_import_hash: %v\", err)\n log.log(\"Next export may require running 'bd import' first\")\n}\n```\n\n## Files\n- cmd/bd/daemon_sync.go\n\n## Decision Needed\nChoose approach based on failure mode preferences","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-21T10:25:16.52788-05:00","updated_at":"2025-11-21T23:53:00.479019-08:00","closed_at":"2025-11-21T11:40:47.684741-05:00","source_repo":".","dependencies":[{"issue_id":"bd-ar2.5","depends_on_id":"bd-ar2","type":"parent-child","created_at":"2025-11-21T10:25:16.528351-05:00","created_by":"daemon"}],"comments":[{"id":36,"issue_id":"bd-ar2.5","author":"stevey","text":"## Code Review Finding (bd-ar2.1 implementation)\n\nThe extracted `updateExportMetadata` function doesn't return errors, making it impossible for callers to detect failures:\n\n```go\nfunc updateExportMetadata(ctx context.Context, store storage.Storage, jsonlPath string, log daemonLogger, keySuffix string) {\n currentHash, err := computeJSONLHash(jsonlPath)\n if err != nil {\n log.log(\"Warning: failed to compute JSONL hash for metadata update: %v\", err)\n return // ❌ Silent failure\n }\n // ...\n}\n```\n\nConsider returning errors so callers can decide how to handle them:\n```go\nfunc updateExportMetadata(...) error {\n // ... return errors\n}\n\n// Caller decides:\nif err := updateExportMetadata(...); err != nil {\n log.log(\"Warning: metadata update failed: %v\", err)\n log.log(\"Next export may require import first\")\n // Don't fail the export, just log\n}\n```","created_at":"2025-11-22T07:53:00Z"}]} +{"id":"bd-ar2.5","content_hash":"16ae300a7e23d596aef9cb39d131e252556905c04ebc2fdaca2a295256ea1191","title":"Add error handling guidance for export metadata update failures","description":"## Problem\nThe bd-ymj fix treats all metadata update failures as warnings:\n\n```go\nif err := store.SetMetadata(ctx, \"last_import_hash\", currentHash); err != nil {\n log.log(\"Warning: failed to update last_import_hash: %v\", err)\n}\n```\n\nBut if metadata updates fail, the NEXT export will fail with \"JSONL content has changed since last import\".\n\n## Questions\n1. Should metadata failures be critical (return error)?\n2. Should we implement retry logic?\n3. Is warning acceptable (safe, just requires import before next export)?\n\n## Current Behavior\n- Metadata failure is silent (only logged)\n- User won't know until next export fails\n- Next export requires import first (safe but annoying)\n\n## Recommendation\nAdd clear comment explaining the trade-off:\n\n```go\n// Note: Metadata update failures are treated as warnings, not errors.\n// This is acceptable because the worst case is the next export will\n// require an import first, which is safe and prevents data loss.\n// Alternative: Make this critical and fail the export if metadata\n// updates fail (but this makes exports more fragile).\nif err := store.SetMetadata(ctx, \"last_import_hash\", currentHash); err != nil {\n log.log(\"Warning: failed to update last_import_hash: %v\", err)\n log.log(\"Next export may require running 'bd import' first\")\n}\n```\n\n## Files\n- cmd/bd/daemon_sync.go\n\n## Decision Needed\nChoose approach based on failure mode preferences","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-21T10:25:16.52788-05:00","updated_at":"2025-11-21T23:53:00.479019-08:00","closed_at":"2025-11-21T11:40:47.684741-05:00","source_repo":".","dependencies":[{"issue_id":"bd-ar2.5","depends_on_id":"bd-ar2","type":"parent-child","created_at":"2025-11-21T10:25:16.528351-05:00","created_by":"daemon"}],"comments":[{"id":17,"issue_id":"bd-ar2.5","author":"stevey","text":"## Code Review Finding (bd-ar2.1 implementation)\n\nThe extracted `updateExportMetadata` function doesn't return errors, making it impossible for callers to detect failures:\n\n```go\nfunc updateExportMetadata(ctx context.Context, store storage.Storage, jsonlPath string, log daemonLogger, keySuffix string) {\n currentHash, err := computeJSONLHash(jsonlPath)\n if err != nil {\n log.log(\"Warning: failed to compute JSONL hash for metadata update: %v\", err)\n return // ❌ Silent failure\n }\n // ...\n}\n```\n\nConsider returning errors so callers can decide how to handle them:\n```go\nfunc updateExportMetadata(...) error {\n // ... return errors\n}\n\n// Caller decides:\nif err := updateExportMetadata(...); err != nil {\n log.log(\"Warning: metadata update failed: %v\", err)\n log.log(\"Next export may require import first\")\n // Don't fail the export, just log\n}\n```","created_at":"2025-11-22T22:18:47Z"}]} {"id":"bd-ar2.6","content_hash":"f39ade8d1ce69a8a0bc4dd993c85e767053af140e86e761d648cefc0a0732e8e","title":"Add transaction boundaries for export metadata updates","description":"## Problem\nMetadata updates happen after export, but there's no transaction ensuring atomicity between:\n1. JSONL file write (exportToJSONLWithStore)\n2. Metadata update (updateExportMetadata)\n3. Database mtime update (TouchDatabaseFile)\n\nIf process crashes between these steps, metadata will be inconsistent.\n\n## Example Failure Scenario\n```\n1. Export to JSONL succeeds\n2. [CRASH] Process killed before metadata update\n3. Next export: \"JSONL content has changed\" error\n4. User must run import to fix metadata\n```\n\n## Options\n\n### Option 1: Tolerate Inconsistency (Current)\n- Simple, no code changes\n- Safe (worst case: need import before next export)\n- Annoying for users if crashes are frequent\n\n### Option 2: Add Write-Ahead Log\n- Write metadata intent to temp file\n- Complete operations\n- Clean up temp file\n- More complex, better guarantees\n\n### Option 3: Store Metadata in JSONL Comments\n- Add metadata as JSON comment in JSONL file\n- Single atomic write\n- Requires JSONL format change\n\n### Option 4: Defensive Checks\n- On startup, verify metadata matches JSONL\n- Auto-fix if mismatch detected\n- Simplest improvement\n\n## Recommendation\nStart with Option 4 (defensive checks), consider others if needed.\n\n## Files\n- cmd/bd/daemon_sync.go\n- Possibly: cmd/bd/main.go (startup checks)\n\n## Related\nThis is lower priority - current behavior is safe, just not ideal","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-21T10:25:32.469469-05:00","updated_at":"2025-11-21T23:53:00.479484-08:00","closed_at":"2025-11-21T11:40:47.685571-05:00","source_repo":".","dependencies":[{"issue_id":"bd-ar2.6","depends_on_id":"bd-ar2","type":"parent-child","created_at":"2025-11-21T10:25:32.470004-05:00","created_by":"daemon"}]} {"id":"bd-ar2.7","content_hash":"26c901628d9d4119e87337b434d5127686a0acda9442348c1feacfd864e5f792","title":"Add edge case tests for GetNextChildID parent resurrection","description":"## Current Coverage\nTestGetNextChildID_ResurrectParent tests happy path only:\n- Parent exists in JSONL\n- Resurrection succeeds\n\n## Missing Test Cases\n\n### 1. Parent Not in JSONL\n- Parent doesn't exist in DB\n- Parent doesn't exist in JSONL either\n- Should return: \"could not be resurrected from JSONL history\"\n\n### 2. JSONL File Missing\n- Parent doesn't exist in DB\n- No issues.jsonl file exists\n- Should handle gracefully\n\n### 3. Malformed JSONL\n- Parent doesn't exist in DB\n- JSONL file exists but has invalid JSON\n- Should skip bad lines, continue searching\n\n### 4. Concurrent Resurrections\n- Multiple goroutines call GetNextChildID with same parent\n- Only one should resurrect, others should succeed\n- Test for race conditions\n\n### 5. Deeply Nested Missing Parents\n- Creating bd-abc.1.2.1 where:\n - bd-abc exists\n - bd-abc.1 missing (should fail with current fix)\n- Related to bd-ar2.4\n\n### 6. Content Hash Mismatch\n- Parent in JSONL has different content_hash than expected\n- Should still resurrect (content_hash is for integrity, not identity)\n\n## Files\n- internal/storage/sqlite/child_id_test.go\n\n## Implementation\n```go\nfunc TestGetNextChildID_ResurrectParent_NotInJSONL(t *testing.T) { ... }\nfunc TestGetNextChildID_ResurrectParent_NoJSONL(t *testing.T) { ... }\nfunc TestGetNextChildID_ResurrectParent_MalformedJSONL(t *testing.T) { ... }\nfunc TestGetNextChildID_ResurrectParent_Concurrent(t *testing.T) { ... }\n```","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-21T10:25:46.661849-05:00","updated_at":"2025-11-21T23:53:00.479957-08:00","closed_at":"2025-11-21T11:40:47.686231-05:00","source_repo":".","dependencies":[{"issue_id":"bd-ar2.7","depends_on_id":"bd-ar2","type":"parent-child","created_at":"2025-11-21T10:25:46.66235-05:00","created_by":"daemon"}]} -{"id":"bd-ar2.8","content_hash":"b240e0021797bf78b279a92177b2562e5f85514ae35bdb843bffdfc687cad145","title":"Add edge case tests for export metadata updates","description":"## Current Coverage\nTestExportUpdatesMetadata tests basic happy path only.\n\n## Missing Test Cases\n\n### 1. Multi-Repo Mode\n- Export with multi-repo configuration\n- Verify metadata updated for ALL JSONL files\n- Critical gap (related to bd-ar2.2)\n\n### 2. computeJSONLHash Failure\n- JSONL file deleted/inaccessible after export\n- Should log warning, not crash\n- Verify behavior on next export\n\n### 3. SetMetadata Failures\n- Database write-protected\n- Disk full\n- Should log warnings, continue\n\n### 4. os.Stat Failure\n- JSONL file deleted after export, before stat\n- Should handle gracefully (mtime just not updated)\n\n### 5. Concurrent Exports\n- Two daemon instances export simultaneously\n- Verify metadata doesn't get corrupted\n- Race condition test\n\n### 6. Clock Skew\n- System time goes backward between exports\n- Verify mtime handling still works\n\n### 7. Partial Export Failure\n- Multi-repo mode: some exports succeed, some fail\n- What metadata should be updated?\n\n### 8. Large JSONL Files\n- Performance test with large files (10k+ issues)\n- Verify hash computation doesn't timeout\n\n## Files\n- cmd/bd/daemon_sync_test.go\n\n## Implementation Priority\n1. Multi-repo test (P1 - related to critical issue)\n2. Failure handling tests (P2)\n3. Performance/edge cases (P3)","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-21T10:25:59.526543-05:00","updated_at":"2025-11-21T23:53:00.480438-08:00","closed_at":"2025-11-21T14:39:53.143561-05:00","source_repo":".","dependencies":[{"issue_id":"bd-ar2.8","depends_on_id":"bd-ar2","type":"parent-child","created_at":"2025-11-21T10:25:59.527032-05:00","created_by":"daemon"}],"comments":[{"id":37,"issue_id":"bd-ar2.8","author":"stevey","text":"## Code Review Finding (bd-ar2.3 implementation)\n\nTestUpdateExportMetadataMultiRepo tests the helper function in isolation, but doesn't verify that createExportFunc/createSyncFunc actually call it correctly in multi-repo mode.\n\nNeed integration test that:\n1. Sets up multi-repo config\n2. Creates issues in different repos\n3. Calls createExportFunc (or full daemon flow)\n4. Verifies metadata updated for ALL repos\n5. Verifies validatePreExport passes on subsequent export\n\nChallenge: These functions have complex dependencies (git, locks, etc.) so testing requires mocking or test harness.","created_at":"2025-11-22T07:53:00Z"}]} +{"id":"bd-ar2.8","content_hash":"b240e0021797bf78b279a92177b2562e5f85514ae35bdb843bffdfc687cad145","title":"Add edge case tests for export metadata updates","description":"## Current Coverage\nTestExportUpdatesMetadata tests basic happy path only.\n\n## Missing Test Cases\n\n### 1. Multi-Repo Mode\n- Export with multi-repo configuration\n- Verify metadata updated for ALL JSONL files\n- Critical gap (related to bd-ar2.2)\n\n### 2. computeJSONLHash Failure\n- JSONL file deleted/inaccessible after export\n- Should log warning, not crash\n- Verify behavior on next export\n\n### 3. SetMetadata Failures\n- Database write-protected\n- Disk full\n- Should log warnings, continue\n\n### 4. os.Stat Failure\n- JSONL file deleted after export, before stat\n- Should handle gracefully (mtime just not updated)\n\n### 5. Concurrent Exports\n- Two daemon instances export simultaneously\n- Verify metadata doesn't get corrupted\n- Race condition test\n\n### 6. Clock Skew\n- System time goes backward between exports\n- Verify mtime handling still works\n\n### 7. Partial Export Failure\n- Multi-repo mode: some exports succeed, some fail\n- What metadata should be updated?\n\n### 8. Large JSONL Files\n- Performance test with large files (10k+ issues)\n- Verify hash computation doesn't timeout\n\n## Files\n- cmd/bd/daemon_sync_test.go\n\n## Implementation Priority\n1. Multi-repo test (P1 - related to critical issue)\n2. Failure handling tests (P2)\n3. Performance/edge cases (P3)","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-21T10:25:59.526543-05:00","updated_at":"2025-11-21T23:53:00.480438-08:00","closed_at":"2025-11-21T14:39:53.143561-05:00","source_repo":".","dependencies":[{"issue_id":"bd-ar2.8","depends_on_id":"bd-ar2","type":"parent-child","created_at":"2025-11-21T10:25:59.527032-05:00","created_by":"daemon"}],"comments":[{"id":18,"issue_id":"bd-ar2.8","author":"stevey","text":"## Code Review Finding (bd-ar2.3 implementation)\n\nTestUpdateExportMetadataMultiRepo tests the helper function in isolation, but doesn't verify that createExportFunc/createSyncFunc actually call it correctly in multi-repo mode.\n\nNeed integration test that:\n1. Sets up multi-repo config\n2. Creates issues in different repos\n3. Calls createExportFunc (or full daemon flow)\n4. Verifies metadata updated for ALL repos\n5. Verifies validatePreExport passes on subsequent export\n\nChallenge: These functions have complex dependencies (git, locks, etc.) so testing requires mocking or test harness.","created_at":"2025-11-22T22:18:47Z"}]} {"id":"bd-ar2.9","content_hash":"d7b949abf252bdf02a64e5a9fc579e650b6fcfb7fff91f2bbfd9588783818187","title":"Fix variable shadowing in GetNextChildID resurrection code","description":"## Problem\nMinor variable shadowing in hash_ids.go:\n\n```go\n// Line 33: err declared here\nerr := s.db.QueryRowContext(ctx, `SELECT COUNT(*) FROM issues WHERE id = ?`, parentID).Scan(\u0026count)\n\n// Line 38: err reused/shadowed here\nresurrected, err := s.TryResurrectParent(ctx, parentID)\n```\n\nWhile Go allows this, it can be confusing and some linters flag it.\n\n## Solution\nUse different variable name:\n\n```go\nresurrected, resurrectErr := s.TryResurrectParent(ctx, parentID)\nif resurrectErr != nil {\n return \"\", fmt.Errorf(\"failed to resurrect parent %s: %w\", parentID, resurrectErr)\n}\n```\n\n## Files\n- internal/storage/sqlite/hash_ids.go:38\n\n## Priority\nLow - code works correctly, just a style improvement","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-21T10:26:09.734162-05:00","updated_at":"2025-11-21T23:53:00.480926-08:00","closed_at":"2025-11-21T11:25:23.408878-05:00","source_repo":".","dependencies":[{"issue_id":"bd-ar2.9","depends_on_id":"bd-ar2","type":"parent-child","created_at":"2025-11-21T10:26:09.734618-05:00","created_by":"daemon"}]} {"id":"bd-au0","content_hash":"755c63ab5b27bc77ee20034d16cc63614a0b3f10a81728f1bde5503cf6615813","title":"Command Set Standardization \u0026 Flag Consistency","description":"Comprehensive improvements to bd command set based on 2025 audit findings.\n\n## Background\nSee docs/command-audit-2025.md for detailed analysis.\n\n## Goals\n1. Standardize flag naming and behavior across all commands\n2. Add missing flags for feature parity\n3. Fix naming confusion\n4. Improve consistency in JSON output\n\n## Success Criteria\n- All mutating commands support --dry-run (no --preview variants)\n- bd update supports label operations\n- bd search has filter parity with bd list\n- Priority flags accept both int and P0-P4 format everywhere\n- JSON output is consistent across all commands","status":"open","priority":2,"issue_type":"epic","created_at":"2025-11-21T21:05:55.672749-05:00","updated_at":"2025-11-21T21:05:55.672749-05:00","source_repo":"."} {"id":"bd-au0.10","content_hash":"50d18ebce621f3e83c512a74dcb66d98a6d7f67d6632d872a4278f0e46e4bb7a","title":"Add global verbosity flags (--verbose, --quiet)","description":"Add consistent verbosity controls across all commands.\n\n**Current state:**\n- bd init has --quiet flag\n- No other commands have verbosity controls\n- Debug output controlled by BD_VERBOSE env var\n\n**Proposal:**\nAdd persistent flags:\n- --verbose / -v: Enable debug output\n- --quiet / -q: Suppress non-essential output\n\n**Implementation:**\n- Add to rootCmd.PersistentFlags()\n- Replace BD_VERBOSE checks with flag checks\n- Standardize output levels:\n * Quiet: Errors only\n * Normal: Errors + success messages\n * Verbose: Errors + success + debug info\n\n**Files to modify:**\n- cmd/bd/main.go (add flags)\n- internal/debug/debug.go (respect flags)\n- Update all commands to respect quiet mode\n\n**Testing:**\n- Verify --verbose shows debug output\n- Verify --quiet suppresses normal output\n- Ensure errors always show regardless of mode","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-21T21:08:21.600209-05:00","updated_at":"2025-11-21T21:08:21.600209-05:00","source_repo":".","dependencies":[{"issue_id":"bd-au0.10","depends_on_id":"bd-au0","type":"parent-child","created_at":"2025-11-21T21:08:21.602557-05:00","created_by":"daemon"}]} @@ -309,10 +310,10 @@ {"id":"bd-au0.7","content_hash":"38cf025be27a35266601cc65faa97464ec05db76591388d55372c1ec6d26c68a","title":"Audit and standardize JSON output across all commands","description":"Ensure consistent JSON format and error handling when --json flag is used.\n\n**Scope:**\n1. Verify all commands respect --json flag\n2. Standardize success response format\n3. Standardize error response format\n4. Document JSON schemas\n\n**Commands to audit:**\n- Core CRUD: create, update, delete, show, list, search ✓\n- Queries: ready, blocked, stale, count, stats, status\n- Deps: dep add/remove/tree/cycles\n- Labels: label commands\n- Comments: comments add/list/delete\n- Epics: epic status/close-eligible\n- Export/import: already support --json ✓\n\n**Testing:**\n- Success cases return valid JSON\n- Error cases return valid JSON (not plain text)\n- Consistent field naming (snake_case vs camelCase)\n- Array vs object wrapping consistency","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-21T21:07:35.304424-05:00","updated_at":"2025-11-21T21:07:35.304424-05:00","source_repo":".","dependencies":[{"issue_id":"bd-au0.7","depends_on_id":"bd-au0","type":"parent-child","created_at":"2025-11-21T21:07:35.305663-05:00","created_by":"daemon"}]} {"id":"bd-au0.8","content_hash":"3a2fa758b811136e939b5cbb12041106901daab5251effed7ed6f4a6078babd2","title":"Improve clean vs cleanup command naming/documentation","description":"Clarify the difference between bd clean and bd cleanup to reduce user confusion.\n\n**Current state:**\n- bd clean: Remove temporary artifacts (.beads/bd.sock, logs, etc.)\n- bd cleanup: Delete old closed issues from database\n\n**Options:**\n1. Rename for clarity:\n - bd clean → bd clean-temp\n - bd cleanup → bd cleanup-issues\n \n2. Keep names but improve help text and documentation\n\n3. Add prominent warnings in help output\n\n**Preferred approach:** Option 2 (improve documentation)\n- Update short/long descriptions in commands\n- Add examples to help text\n- Update README.md\n- Add cross-references in help output\n\n**Files to modify:**\n- cmd/bd/clean.go\n- cmd/bd/cleanup.go\n- README.md or ADVANCED.md","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-21T21:07:49.960534-05:00","updated_at":"2025-11-21T21:07:49.960534-05:00","source_repo":".","dependencies":[{"issue_id":"bd-au0.8","depends_on_id":"bd-au0","type":"parent-child","created_at":"2025-11-21T21:07:49.962743-05:00","created_by":"daemon"}]} {"id":"bd-au0.9","content_hash":"825794959c7b81e7d19cc6028b7d098c707627319b9c53a2477e062ced1d03f4","title":"Review and document rarely-used commands","description":"Document use cases or consider deprecation for infrequently-used commands.\n\n**Commands to review:**\n1. bd rename-prefix - How often is this used? Document use cases\n2. bd detect-pollution - Consider integrating into bd validate\n3. bd migrate-hash-ids - One-time migration, keep but document as legacy\n\n**For each command:**\n- Document typical use cases\n- Add examples to help text\n- Consider if it should be a subcommand instead\n- Add deprecation warning if appropriate\n\n**Not changing:**\n- duplicates ✓ (useful for data quality)\n- repair-deps ✓ (useful for fixing broken refs)\n- restore ✓ (critical for compacted issues)\n- compact ✓ (performance feature)\n\n**Deliverable:**\n- Updated help text\n- Documentation in ADVANCED.md\n- Deprecation plan if needed","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-21T21:08:05.588275-05:00","updated_at":"2025-11-21T21:08:05.588275-05:00","source_repo":".","dependencies":[{"issue_id":"bd-au0.9","depends_on_id":"bd-au0","type":"parent-child","created_at":"2025-11-21T21:08:05.59003-05:00","created_by":"daemon"}]} -{"id":"bd-auf1","content_hash":"0e60a1a40065ce53b0adcbd9863b45694a94ccc455ce7020154ce10b2c5d4b03","title":"Clean up snapshot files after successful merge","description":"After a successful 3-way merge and import during 'bd sync', the snapshot files (beads.base.jsonl, beads.left.jsonl, and their .meta.json files) are left in the .beads/ directory indefinitely.\n\nThese files are only needed temporarily during the merge process:\n- beads.base.jsonl: snapshot from last successful import\n- beads.left.jsonl: snapshot before git pull\n\nOnce the merge succeeds and the new JSONL is imported, these files serve no purpose and should be cleaned up.\n\nCurrent behavior:\n- sync.go:269 calls updateBaseSnapshot() after successful import\n- UpdateBase() updates beads.base.jsonl to the new state\n- beads.left.jsonl is never removed\n- Both files accumulate in .beads/ directory\n\nExpected behavior:\n- After successful merge and import, clean up both snapshot files\n- Only retain snapshots between sync operations (create on export, use during merge, clean up after import)\n\nThe cleanup logic exists (SnapshotManager.Cleanup()) but is only called on validation failures (deletion_tracking.go:48), not on success.\n\nDiscovered in vc project where stale snapshot files from Nov 8 merge were still present.","acceptance_criteria":"- Snapshot files are removed after successful merge and import\n- Files are created fresh on next 'bd sync' export step\n- Validation failure path still cleans up (existing behavior)\n- Tests verify cleanup happens in success path","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-08T22:39:56.460778-08:00","updated_at":"2025-11-08T22:45:40.5809-08:00","closed_at":"2025-11-08T22:45:40.5809-08:00","source_repo":"."} +{"id":"bd-auf1","content_hash":"0e60a1a40065ce53b0adcbd9863b45694a94ccc455ce7020154ce10b2c5d4b03","title":"Clean up snapshot files after successful merge","description":"After a successful 3-way merge and import during 'bd sync', the snapshot files (beads.base.jsonl, beads.left.jsonl, and their .meta.json files) are left in the .beads/ directory indefinitely.\n\nThese files are only needed temporarily during the merge process:\n- beads.base.jsonl: snapshot from last successful import\n- beads.left.jsonl: snapshot before git pull\n\nOnce the merge succeeds and the new JSONL is imported, these files serve no purpose and should be cleaned up.\n\nCurrent behavior:\n- sync.go:269 calls updateBaseSnapshot() after successful import\n- UpdateBase() updates beads.base.jsonl to the new state\n- beads.left.jsonl is never removed\n- Both files accumulate in .beads/ directory\n\nExpected behavior:\n- After successful merge and import, clean up both snapshot files\n- Only retain snapshots between sync operations (create on export, use during merge, clean up after import)\n\nThe cleanup logic exists (SnapshotManager.Cleanup()) but is only called on validation failures (deletion_tracking.go:48), not on success.\n\nDiscovered in vc project where stale snapshot files from Nov 8 merge were still present.","acceptance_criteria":"- Snapshot files are removed after successful merge and import\n- Files are created fresh on next 'bd sync' export step\n- Validation failure path still cleans up (existing behavior)\n- Tests verify cleanup happens in success path","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-08T22:39:56.460778-08:00","updated_at":"2025-11-08T22:47:51.96296-08:00","closed_at":"2025-11-08T22:47:51.96296-08:00","source_repo":"."} {"id":"bd-aysr","content_hash":"f8ff127568f471cc42391b1287cce69b376fb1b49bbef20a24d3394f57fba066","title":"Test numeric 1","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-05T12:58:41.498034-08:00","updated_at":"2025-11-05T12:58:44.73082-08:00","closed_at":"2025-11-05T12:58:44.73082-08:00","source_repo":"."} -{"id":"bd-ayw","content_hash":"dff7eeef440bbd9de64177bc9b88f77b61bcc7e4c0dba241405e80639734cb6f","title":"Add 'When to use daemon mode' decision tree to daemon.md","description":"**Problem:**\nUsers (especially local-only developers) see daemon-related messages but don't understand:\n- What daemon mode does (git sync automation)\n- Whether they need it\n- Why they see \"daemon_unsupported\" messages\n\nRelated to issue #349 item #3.\n\n**Current state:**\ncommands/daemon.md explains WHAT daemon does but not WHEN to use it.\n\n**Proposed addition:**\nAdd a \"When to Use Daemon Mode\" section after line 20 in commands/daemon.md with clear decision criteria:\n\n**✅ You SHOULD use daemon mode if:**\n- Working in a team with git remote sync\n- Want automatic commit/push of issue changes\n- Need background auto-sync (5-second debounce)\n- Making frequent bd commands (performance benefit)\n\n**❌ You DON'T need daemon mode if:**\n- Solo developer with local-only tracking\n- Working in git worktrees (use --no-daemon)\n- Running one-off commands/scripts\n- Debugging database issues\n\n**Local-only users:** Direct mode is perfectly fine. Daemon mainly helps with git sync automation. You can use `bd sync` manually when needed.\n\n**Files to modify:**\n- commands/daemon.md (add section after line 20)","design":"Clear decision tree that helps users understand:\n1. Daemon = git sync automation + performance\n2. Local-only users don't need it\n3. Direct mode is simpler for debugging\n4. Both modes are valid depending on workflow","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-20T20:48:23.111621-05:00","updated_at":"2025-11-20T20:59:13.429263-05:00","closed_at":"2025-11-20T20:59:13.429263-05:00","source_repo":".","labels":["documentation","onboarding"],"comments":[{"id":38,"issue_id":"bd-ayw","author":"stevey","text":"Addresses GitHub issue #349 item 3: https://github.com/steveyegge/beads/issues/349\n\nLocal-only users see daemon-related messages without understanding when they need daemon mode vs when direct mode is sufficient. Need clear decision tree in daemon.md.","created_at":"2025-11-22T07:53:00Z"}]} -{"id":"bd-az0m","content_hash":"91dd58e84b57c84ae065004ef4c15d0b5330935a5fde35eed489a93452feb2e9","title":"Issue 1","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T19:43:48.754145-05:00","updated_at":"2025-11-20T19:43:48.754145-05:00","closed_at":"2025-11-07T21:55:09.42865-08:00","source_repo":".","dependencies":[{"issue_id":"bd-az0m","depends_on_id":"bd-bvo2","type":"related","created_at":"2025-11-07T19:07:21.069031-08:00","created_by":"daemon"}]} +{"id":"bd-ayw","content_hash":"dff7eeef440bbd9de64177bc9b88f77b61bcc7e4c0dba241405e80639734cb6f","title":"Add 'When to use daemon mode' decision tree to daemon.md","description":"**Problem:**\nUsers (especially local-only developers) see daemon-related messages but don't understand:\n- What daemon mode does (git sync automation)\n- Whether they need it\n- Why they see \"daemon_unsupported\" messages\n\nRelated to issue #349 item #3.\n\n**Current state:**\ncommands/daemon.md explains WHAT daemon does but not WHEN to use it.\n\n**Proposed addition:**\nAdd a \"When to Use Daemon Mode\" section after line 20 in commands/daemon.md with clear decision criteria:\n\n**✅ You SHOULD use daemon mode if:**\n- Working in a team with git remote sync\n- Want automatic commit/push of issue changes\n- Need background auto-sync (5-second debounce)\n- Making frequent bd commands (performance benefit)\n\n**❌ You DON'T need daemon mode if:**\n- Solo developer with local-only tracking\n- Working in git worktrees (use --no-daemon)\n- Running one-off commands/scripts\n- Debugging database issues\n\n**Local-only users:** Direct mode is perfectly fine. Daemon mainly helps with git sync automation. You can use `bd sync` manually when needed.\n\n**Files to modify:**\n- commands/daemon.md (add section after line 20)","design":"Clear decision tree that helps users understand:\n1. Daemon = git sync automation + performance\n2. Local-only users don't need it\n3. Direct mode is simpler for debugging\n4. Both modes are valid depending on workflow","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-20T20:48:23.111621-05:00","updated_at":"2025-11-20T21:51:31.800878-05:00","closed_at":"2025-11-20T20:59:13.429263-05:00","source_repo":".","labels":["documentation","onboarding"],"comments":[{"id":11,"issue_id":"bd-ayw","author":"stevey","text":"Addresses GitHub issue #349 item 3: https://github.com/steveyegge/beads/issues/349\n\nLocal-only users see daemon-related messages without understanding when they need daemon mode vs when direct mode is sufficient. Need clear decision tree in daemon.md.","created_at":"2025-11-21T13:58:10Z"}]} +{"id":"bd-az0m","content_hash":"91dd58e84b57c84ae065004ef4c15d0b5330935a5fde35eed489a93452feb2e9","title":"Issue 1","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-22T15:18:47.448055946-07:00","updated_at":"2025-11-22T15:18:47.448055946-07:00","closed_at":"2025-11-07T21:55:09.42865-08:00","source_repo":".","dependencies":[{"issue_id":"bd-az0m","depends_on_id":"bd-bvo2","type":"related","created_at":"2025-11-07T19:07:21.069031-08:00","created_by":"daemon"}]} {"id":"bd-azqv","content_hash":"b4e68adcec7b19f567ebee47f505ca6b529c17b4c4b885282cfc564e8a874f9f","title":"Ready issue","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-07T19:04:22.247039-08:00","updated_at":"2025-11-07T22:07:17.344986-08:00","closed_at":"2025-11-07T21:55:09.429024-08:00","source_repo":"."} {"id":"bd-b121","content_hash":"5d71e793a6de110be977bf87cfd25c3b461f452a1e8e44633452de1f8343a098","title":"Fix :memory: database connection pool issue causing \"no such table\" errors","description":"Critical bug in v0.21.6 where :memory: databases with cache=shared create multiple connections in the pool, causing intermittent \"no such table\" errors. SQLite's shared cache for in-memory databases only works reliably with a single connection.\n\nRoot cause: Missing db.SetMaxOpenConns(1) after sql.Open() for :memory: databases.\n\nImpact: 37 test failures in VC project, affects all consumers using :memory: for testing.","acceptance_criteria":"- Add db.SetMaxOpenConns(1) for :memory: databases only\n- Verify VC test suite passes (37 previously failing tests)\n- Add a test in Beads that reproduces the issue\n- Document the pool limitation in code comments\n- Release as Beads v0.21.7","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-04T00:52:56.318619-08:00","updated_at":"2025-11-05T11:31:27.50439-08:00","closed_at":"2025-11-05T00:50:00.558124-08:00","source_repo":"."} {"id":"bd-b134","content_hash":"455202a74224066aca5a1e300d045ae99e5c4ba5c306c043fd4c4c70c4aea058","title":"Add tests for Integration Layer Implementation","description":"While implementing bd-wfmw, noticed missing tests","notes":"Reviewed existing coverage:\n- Basic test coverage exists in lib/test_beads_mail_adapter.py\n- Integration tests cover failure scenarios in tests/integration/test_mail_failures.py\n- Good coverage of: enabled/disabled modes, graceful degradation, 409 conflicts, HTTP errors, config\n- Missing: authorization headers detail, request body structure validation, concurrent reservation timing, TTL edge cases","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-08T00:20:30.804172-08:00","updated_at":"2025-11-08T02:17:04.046571-08:00","closed_at":"2025-11-08T02:17:04.046571-08:00","source_repo":".","dependencies":[{"issue_id":"bd-b134","depends_on_id":"bd-wfmw","type":"discovered-from","created_at":"2025-11-08T00:20:30.850776-08:00","created_by":"daemon"}]} @@ -328,7 +329,7 @@ {"id":"bd-b92a","content_hash":"01d8b852f1d9936835a253f6b9576c401cbd143772302b25ac859db79b6be76a","title":"Wire config to import pipeline","description":"Connect import.orphan_handling config to importer.go and sqlite validation functions. Pass mode flag through call chain. Implement all four modes (strict/resurrect/skip/allow) with proper error messages and logging.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-04T12:32:08.612142-08:00","updated_at":"2025-11-05T00:44:27.949021-08:00","closed_at":"2025-11-05T00:44:27.949024-08:00","source_repo":"."} {"id":"bd-bb08","content_hash":"df5b8f359f459b9fc8a24e089878e65222f4b7ba541e829ebb1d34e5beb3a9fc","title":"Add ON DELETE CASCADE to child_counters schema","description":"Update schema.go child_counters table foreign key with ON DELETE CASCADE. When parent deleted, child counter should also be deleted. If parent is resurrected, counter gets recreated from scratch. Add migration for existing databases.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-04T12:32:30.681452-08:00","updated_at":"2025-11-05T11:31:27.505024-08:00","closed_at":"2025-11-05T00:55:12.427194-08:00","source_repo":"."} {"id":"bd-bc2c6191","content_hash":"46ab7e965823421a1cc06fdbb3a1faa8ef31f0c46487cd05a4cec8127af8e480","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","notes":"Audit complete. See CACHE_AUDIT.md for full findings.\n\nSummary:\n- Cache was already removed in commit 322ab63 (2025-10-28)\n- server_cache_storage.go deleted (~286 lines)\n- All getStorageForRequest calls replaced with s.storage\n- All environment variables removed\n- MCP multi-repo works via per-project daemon architecture\n- All tests updated and passing\n- Only stale comment in server.go needed fixing","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T23:02:43.506373-07:00","updated_at":"2025-11-06T20:06:49.218998-08:00","closed_at":"2025-11-06T19:48:30.520616-08:00","source_repo":"."} -{"id":"bd-bc7l","content_hash":"bc091a6fed46130e6cb791c4d58c777b904e22f92cc6921d231053abf48c3c4b","title":"Issue 2 to reopen","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T19:43:48.754817-05:00","updated_at":"2025-11-20T19:43:48.754817-05:00","closed_at":"2025-11-07T21:57:59.91095-08:00","source_repo":"."} +{"id":"bd-bc7l","content_hash":"bc091a6fed46130e6cb791c4d58c777b904e22f92cc6921d231053abf48c3c4b","title":"Issue 2 to reopen","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-22T15:18:47.449721296-07:00","updated_at":"2025-11-22T15:18:47.449721296-07:00","closed_at":"2025-11-07T21:57:59.91095-08:00","source_repo":"."} {"id":"bd-bdaf24d5","content_hash":"64067e38421a77f1b54fca73e6b98923d15aca0933463a1fa6862270c3102566","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","source_repo":"."} {"id":"bd-bdhn","content_hash":"ddbc003327e0492285b53fd765e90a816b9cea1e4cf9fc8797e8a465a1e834bd","title":"bd message: Add input validation for --importance flag","description":"The --importance flag accepts any string without validation, leading to confusing server errors.\n\n**Location:** cmd/bd/message.go:256-258\n\n**Fix:**\n- Add flag validation for: low, normal, high, urgent\n- Add shell completion support\n- Validate in runMessageSend before sending\n\n**Impact:** Better UX, prevents confusing errors","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-08T12:54:26.43027-08:00","updated_at":"2025-11-08T12:57:59.65367-08:00","closed_at":"2025-11-08T12:57:59.65367-08:00","source_repo":".","dependencies":[{"issue_id":"bd-bdhn","depends_on_id":"bd-6uix","type":"parent-child","created_at":"2025-11-08T12:55:54.910841-08:00","created_by":"daemon"}]} {"id":"bd-be7a","content_hash":"d9043a7a49f8e42dc88c3c01aaa178c1560b67c1637c3373b39c387272e8b725","title":"Create npm package structure with package.json","description":"Set up initial npm package structure for @beads/bd:\n\n## Files to create\n- npm/package.json - Package metadata, dependencies, scripts\n- npm/bin/bd - CLI wrapper script that invokes native binary\n- npm/.gitignore - Ignore downloaded binaries\n- npm/README.md - Installation and usage instructions\n\n## package.json structure\n- Name: @beads/bd (scoped package)\n- Main: index.js (exports binary path)\n- Bin: bin/bd (CLI entry point)\n- Scripts: postinstall (download binary)\n- Keywords: issue-tracker, cli, beads, bd\n- License: MIT\n\n## Bin wrapper\nSimple Node.js script that:\n- Spawns native binary with child_process.spawn\n- Passes through all arguments and stdio\n- Exits with binary's exit code","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-02T23:39:47.416779-08:00","updated_at":"2025-11-03T10:31:45.381258-08:00","closed_at":"2025-11-03T10:31:45.381258-08:00","source_repo":".","dependencies":[{"issue_id":"bd-be7a","depends_on_id":"bd-febc","type":"parent-child","created_at":"2025-11-02T23:40:32.923859-08:00","created_by":"daemon"}]} @@ -337,14 +338,14 @@ {"id":"bd-br8","content_hash":"3f7413965cebb0a08803c601413ce62ea82af565c63b1747da623ca42a791316","title":"Implement `bd setup claude` command for Claude Code integration","description":"Create a `bd setup claude` command that installs Claude Code integration files (slash commands and hooks). This is idempotent and safe to run multiple times.","design":"## Implementation\n\nCreate `cmd/bd/setup.go` with subcommand `claude` that installs hooks via **JSON configuration** (Claude Code's native hook system).\n\n### Command Interface\n```bash\nbd setup claude # Install globally (default)\nbd setup claude --project # Install for this project only\nbd setup claude --check # Verify installation\nbd setup claude --remove # Remove bd hooks\n```\n\n### Claude Code Hook Architecture\n\n**Claude Code uses JSON configuration, NOT file discovery:**\n- Hooks defined in `settings.json` as arrays\n- Multiple tools coexist natively (parallel execution)\n- Configuration-based, not directory-based\n\n**Configuration files:**\n- Global: `~/.claude/settings.json`\n- Project: `./.claude/settings.json` or `./.claude/settings.local.json`\n\n### What Gets Installed\n\n**settings.json configuration only** (no script files needed):\n```json\n{\n \"hooks\": {\n \"SessionStart\": [\n {\n \"matcher\": \"\",\n \"hooks\": [\n {\n \"type\": \"command\",\n \"command\": \"bd prime\"\n }\n ]\n }\n ],\n \"PreCompact\": [\n {\n \"matcher\": \"\",\n \"hooks\": [\n {\n \"type\": \"command\",\n \"command\": \"bd prime\"\n }\n ]\n }\n ]\n }\n}\n```\n\n**Why no script files:**\n- `bd prime` is cross-platform (no shell syntax needed)\n- `bd prime` always exits 0 (no `|| true` needed)\n- `bd prime` never writes to stderr (no `2\u003e/dev/null` needed)\n- Simpler: one file to manage (settings.json), not two\n- More portable: no file permissions, no path dependencies\n\n### Installation Logic\n\n```go\nfunc setupClaude(global bool) error {\n var settingsPath string\n \n if global {\n home, _ := os.UserHomeDir()\n settingsPath = filepath.Join(home, \".claude/settings.json\")\n } else {\n settingsPath = \".claude/settings.local.json\"\n }\n \n // Update settings.json (merge with existing)\n return updateSettingsJSON(settingsPath, addBeadsHooks)\n}\n\nfunc updateSettingsJSON(path string, updateFn func(map[string]interface{})) error {\n // Create parent directory if needed\n os.MkdirAll(filepath.Dir(path), 0755)\n \n // Read existing settings (or create empty)\n var settings map[string]interface{}\n if data, err := os.ReadFile(path); err == nil {\n json.Unmarshal(data, \u0026settings)\n } else {\n settings = make(map[string]interface{})\n }\n \n // Apply updates\n updateFn(settings)\n \n // Write back atomically\n data, _ := json.MarshalIndent(settings, \"\", \" \")\n return atomicWriteFile(path, data, 0644)\n}\n\nfunc addBeadsHooks(settings map[string]interface{}) {\n hooks, _ := settings[\"hooks\"].(map[string]interface{})\n if hooks == nil {\n hooks = make(map[string]interface{})\n settings[\"hooks\"] = hooks\n }\n \n // Add SessionStart hook if not present\n addHookCommand(hooks, \"SessionStart\", \"bd prime\")\n \n // Add PreCompact hook if not present\n addHookCommand(hooks, \"PreCompact\", \"bd prime\")\n}\n\nfunc addHookCommand(hooks map[string]interface{}, event, command string) {\n // Get or create event array\n eventHooks, _ := hooks[event].([]interface{})\n if eventHooks == nil {\n eventHooks = []interface{}{}\n }\n \n // Check if bd hook already registered\n for _, hook := range eventHooks {\n hookMap, _ := hook.(map[string]interface{})\n commands, _ := hookMap[\"hooks\"].([]interface{})\n for _, cmd := range commands {\n cmdMap, _ := cmd.(map[string]interface{})\n if cmdMap[\"command\"] == command {\n fmt.Println(\"✓ Hook already registered:\", event)\n return // Already present\n }\n }\n }\n \n // Add bd hook to array\n newHook := map[string]interface{}{\n \"matcher\": \"\",\n \"hooks\": []interface{}{\n map[string]interface{}{\n \"type\": \"command\",\n \"command\": command,\n },\n },\n }\n \n eventHooks = append(eventHooks, newHook)\n hooks[event] = eventHooks\n fmt.Println(\"✓ Registered hook:\", event)\n}\n```\n\n### Slash Command (Optional)\n\n**`.claude/commands/prime_beads.md`:**\n```markdown\n---\ndescription: Load Beads workflow context\n---\n\nRun `bd prime` to refresh bd workflow understanding.\n```\n\n### Integration with `bd init`\n\nAfter git hooks:\n```go\nif isClaudeDetected() \u0026\u0026 !quietMode {\n fmt.Println(\"\\nClaude Code Integration:\")\n fmt.Println(\" Install hooks to prevent agent from forgetting bd workflow?\")\n fmt.Println(\" (Works with MCP server or CLI approach)\")\n \n choice := promptYesNo(\"Install Claude hooks globally?\")\n if choice {\n setupClaude(true) // global=true\n }\n}\n```\n\n### Safe Multi-Tool Coexistence\n\n**Why this approach is safe:**\n- JSON arrays support multiple tools natively\n- Each tool gets its own array entry\n- Parallel execution (no conflicts)\n- Removal only touches bd entries\n- No file overwriting needed\n\n### Removal\n\n```go\nfunc removeBeadsHooks(settings map[string]interface{}) {\n hooks, _ := settings[\"hooks\"].(map[string]interface{})\n if hooks == nil {\n return\n }\n \n // Remove bd prime hooks from each event\n for _, event := range []string{\"SessionStart\", \"PreCompact\"} {\n removeHookCommand(hooks, event, \"bd prime\")\n }\n}\n\nfunc removeHookCommand(hooks map[string]interface{}, event, command string) {\n eventHooks, _ := hooks[event].([]interface{})\n if eventHooks == nil {\n return\n }\n \n // Filter out bd prime hooks\n var filtered []interface{}\n for _, hook := range eventHooks {\n hookMap, _ := hook.(map[string]interface{})\n commands, _ := hookMap[\"hooks\"].([]interface{})\n \n keepHook := true\n for _, cmd := range commands {\n cmdMap, _ := cmd.(map[string]interface{})\n if cmdMap[\"command\"] == command {\n keepHook = false\n break\n }\n }\n \n if keepHook {\n filtered = append(filtered, hook)\n }\n }\n \n hooks[event] = filtered\n}\n```\n\n### Files to Create\n- `cmd/bd/setup.go` - Setup command with JSON merging logic\n- `cmd/bd/setup_test.go` - Tests for JSON manipulation\n- No hook script files needed (bd prime is self-contained)","acceptance_criteria":"- `bd setup claude` installs .claude/ files\n- Idempotent (can run multiple times safely)\n- Backs up existing files\n- `bd setup claude --check` verifies installation\n- Works when .claude/ doesn't exist (skip with message)\n- Unit tests cover installation logic","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-11T23:28:59.374019-08:00","updated_at":"2025-11-12T08:51:23.281292-08:00","closed_at":"2025-11-12T08:51:23.281292-08:00","source_repo":".","dependencies":[{"issue_id":"bd-br8","depends_on_id":"bd-rpn","type":"blocks","created_at":"2025-11-11T23:28:59.375616-08:00","created_by":"daemon"},{"issue_id":"bd-br8","depends_on_id":"bd-90v","type":"parent-child","created_at":"2025-11-11T23:31:23.762685-08:00","created_by":"daemon"}]} {"id":"bd-bt6y","content_hash":"462f08aa379cf2f196b4c0ca096271fa47ab5e1a18c5663c28d2d86fd02115cf","title":"Improve compact/daemon/merge documentation and UX","description":"Multiple documentation and UX issues encountered:\n1. \"bd compact --analyze\" fails with misleading \"requires SQLite storage\" error when daemon is running. Needs --no-daemon or better error.\n2. \"bd merge\" help text is outdated (refers to 3-way merge instead of issue merging).\n3. Daemon mode purpose isn't clear to local-only users.\n4. Compact/cleanup commands are hard to discover.\n\nProposed fixes:\n- Fix compact+daemon interaction or error message.\n- Update \"bd merge\" help text.\n- Add \"when to use daemon\" section to docs.\n- Add maintenance section to quickstart.\n","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T18:55:43.637047-05:00","updated_at":"2025-11-20T18:55:43.637047-05:00","source_repo":"."} {"id":"bd-buol","content_hash":"020dc9dbbd7f3e2b40c35f01bf8a65cf32ab419c188081493ea4e541bad1442e","title":"Invert control for compact: provide tools for agent-driven compaction","description":"Currently compact requires Anthropic API key because bd calls the AI directly. This is backwards - we should provide tools (like all other bd commands) that let an AI agent perform the compaction. The agent decides what to keep/merge, not bd. Related to GH #243 complaint about API key requirement.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-07T00:27:28.498069-08:00","updated_at":"2025-11-07T23:18:08.38606-08:00","closed_at":"2025-11-07T23:08:51.67473-08:00","source_repo":"."} -{"id":"bd-bvo2","content_hash":"66fd2d53d97eb8dcb3231e82702ca7eb0f1887dc9b3ee2b2865e0d5158ca7311","title":"Issue 2","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T19:43:48.755403-05:00","updated_at":"2025-11-20T19:43:48.755403-05:00","closed_at":"2025-11-07T21:55:09.429328-08:00","source_repo":"."} +{"id":"bd-bvo2","content_hash":"66fd2d53d97eb8dcb3231e82702ca7eb0f1887dc9b3ee2b2865e0d5158ca7311","title":"Issue 2","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-22T15:18:47.451604034-07:00","updated_at":"2025-11-22T15:18:47.451604034-07:00","closed_at":"2025-11-07T21:55:09.429328-08:00","source_repo":"."} {"id":"bd-bwk2","content_hash":"b69758a5dd9ce7605a61dc6e1fe3e753b87dfc6824c248d6ad56e038d47e77e7","title":"Centralize error handling patterns in storage layer","description":"80+ instances of inconsistent error handling across sqlite.go with mix of %w, %v, and no wrapping.\n\nLocation: internal/storage/sqlite/sqlite.go (throughout)\n\nProblem:\n- Some use fmt.Errorf(\"op failed: %w\", err) - correct wrapping\n- Some use fmt.Errorf(\"op failed: %v\", err) - loses error chain\n- Some return err directly - no context\n- Hard to debug production issues\n- Can't distinguish error types\n\nSolution: Create internal/storage/sqlite/errors.go:\n- Define sentinel errors (ErrNotFound, ErrInvalidID, etc.)\n- Create wrapDBError(op string, err error) helper\n- Convert sql.ErrNoRows to ErrNotFound\n- Always wrap with operation context\n\nImpact: Lost error context; inconsistent messages; hard to debug\n\nEffort: 5-7 hours","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-16T14:51:54.974909-08:00","updated_at":"2025-11-16T14:51:54.974909-08:00","source_repo":"."} {"id":"bd-bxha","content_hash":"c2ecc8ebb17f47bbb4b23bfc6d283f91fa45bdbe48076082b0397616de197b81","title":"Default to YES for git hooks and merge driver installation","description":"Currently bd init prompts user to install git hooks and merge driver, but setup is incomplete if user declines. Change to install by default unless --skip-hooks or --skip-merge-driver flags are passed. Better safe defaults. If installation fails, warn user and suggest bd doctor --fix.","status":"open","priority":1,"issue_type":"feature","created_at":"2025-11-21T23:16:10.172238-08:00","updated_at":"2025-11-21T23:16:28.369137-08:00","source_repo":".","dependencies":[{"issue_id":"bd-bxha","depends_on_id":"bd-tbz3","type":"parent-child","created_at":"2025-11-21T23:16:10.173034-08:00","created_by":"daemon"}]} {"id":"bd-by3x","content_hash":"80149be1ddf4ef26d5d56c444895be01ec8b59492c258c2365fa1c2619061bbd","title":"Windows binaries lack SQLite support (GH #253)","description":"Windows users installing via install.ps1 get \"sql: unknown driver sqlite\" error. Root cause: GoReleaser was building with CGO_ENABLED=0, which excludes SQLite driver.\n\nFixed by:\n1. Enabling CGO in .goreleaser.yml\n2. Installing MinGW cross-compiler in release workflow\n3. Splitting builds per platform to set correct CC for Windows\n\nNeeds new release to fix for users.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-07T15:54:13.134815-08:00","updated_at":"2025-11-07T15:55:07.024156-08:00","closed_at":"2025-11-07T15:55:07.024156-08:00","source_repo":"."} {"id":"bd-bzfy","content_hash":"90bbde4d90d68728a9377d5d966682dc836740f1be43a0cf80d3cc69002a560b","title":"Integrate beads-merge tool by @neongreen","description":"**Context**: @neongreen built a production-ready 3-way merge tool for JSONL files that works with both Git and Jujutsu. This is superior to our planned bd resolve-conflicts because it prevents conflicts proactively instead of resolving them after the fact.\n\n**Tool**: https://github.com/neongreen/mono/tree/main/beads-merge\n\n**What it does**:\n- 3-way merge of JSONL files (base, left, right)\n- Field-level merging (titles, status, priority, etc.)\n- Smart dependency merging (union + dedup)\n- Conflict markers for unresolvable conflicts\n- Exit code 1 for conflicts (standard)\n\n**Integration options**:\n\n1. **Recommend (minimal effort)** - Document in AGENTS.md + TROUBLESHOOTING.md\n2. **Bundle binary** - Include in releases (cross-platform builds)\n3. **Port to Go** - Reimplement in bd codebase\n4. **Auto-install hook** - During bd init, offer to install merge driver\n\n**Recommendation**: Start with option 1 (document), then option 2 (bundle) once proven.\n\n**Related**: bd-5f483051 (bd resolve-conflicts - can close as superseded)","notes":"Created GitHub issue to discuss integration approach with @neongreen: https://github.com/neongreen/mono/issues/240\n\nAwaiting their preference on:\n1. Vendor with attribution (fastest)\n2. Extract as importable module (best long-term)\n3. Keep as separate tool (current state)\n\nNext: Wait for response before proceeding with integration.\n\nUPDATE 2025-11-06: @neongreen gave permission to vendor! Quote: \"I switched from beads to my own thing (tk) so I'm very happy to give beads-merge away — feel free to move it into the beads repo and I will point mono's readme to beads\"\n\nNext: Vendor beads-merge with full attribution","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-05T11:31:44.906652-08:00","updated_at":"2025-11-06T18:19:16.233387-08:00","closed_at":"2025-11-06T15:38:37.052274-08:00","source_repo":"."} {"id":"bd-c01f","content_hash":"14269c39f13784e0ee793fae005b1869fea5c08af1bbdc4a2f841720278180d5","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","source_repo":"."} {"id":"bd-c13f","content_hash":"0e428b0589a6f763a32195b32241ec71141793101ee102df5df69d3c7fadfaaf","title":"Add unit tests for parent resurrection","description":"Test resurrection with deleted parent (should succeed), resurrection with never-existed parent (should fail gracefully), multi-level resurrection (bd-abc.1.2 with both parents missing). Verify tombstone creation and is_tombstone flag.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-04T12:32:21.325335-08:00","updated_at":"2025-11-05T00:08:42.813728-08:00","closed_at":"2025-11-05T00:08:42.813731-08:00","source_repo":"."} -{"id":"bd-c362","content_hash":"9bbfaede59e2433760f69b45649405ee0885f18849cb30ff0357e56c90c8d4cd","title":"Extract database search logic into helper function","description":"The logic for finding a database in a beads directory is duplicated:\n- FindDatabasePath() BEADS_DIR section (beads.go:141-169)\n- findDatabaseInTree() (beads.go:248-280)\n\nBoth implement the same search order:\n1. Check config.json first (single source of truth)\n2. Fall back to canonical beads.db\n3. Search for *.db files, filtering backups and vc.db\n\nRefactoring suggestion:\nExtract to a helper function like:\n func findDatabaseInBeadsDir(beadsDir string) string\n\nBenefits:\n- Single source of truth for database search logic\n- Easier to maintain and update search order\n- Reduces code duplication\n\nRelated to [deleted:[deleted:[deleted:bd-e16b]]] implementation.","status":"open","priority":3,"issue_type":"chore","created_at":"2025-11-02T18:34:02.831543-08:00","updated_at":"2025-11-20T22:02:51.640916-05:00","source_repo":".","dependencies":[{"issue_id":"bd-c362","depends_on_id":"bd-e16b","type":"blocks","created_at":"2025-11-02T18:34:02.832607-08:00","created_by":"daemon"}]} +{"id":"bd-c362","content_hash":"9bbfaede59e2433760f69b45649405ee0885f18849cb30ff0357e56c90c8d4cd","title":"Extract database search logic into helper function","description":"The logic for finding a database in a beads directory is duplicated:\n- FindDatabasePath() BEADS_DIR section (beads.go:141-169)\n- findDatabaseInTree() (beads.go:248-280)\n\nBoth implement the same search order:\n1. Check config.json first (single source of truth)\n2. Fall back to canonical beads.db\n3. Search for *.db files, filtering backups and vc.db\n\nRefactoring suggestion:\nExtract to a helper function like:\n func findDatabaseInBeadsDir(beadsDir string) string\n\nBenefits:\n- Single source of truth for database search logic\n- Easier to maintain and update search order\n- Reduces code duplication\n\nRelated to [deleted:[deleted:[deleted:bd-e16b]]] implementation.","status":"open","priority":3,"issue_type":"chore","created_at":"2025-11-02T18:34:02.831543-08:00","updated_at":"2025-11-21T06:58:10.019497477-07:00","source_repo":".","dependencies":[{"issue_id":"bd-c362","depends_on_id":"bd-e16b","type":"blocks","created_at":"2025-11-02T18:34:02.832607-08:00","created_by":"daemon"}]} {"id":"bd-c3ei","content_hash":"33a1bd2deaee412d0523c512061f2e31e3f15340858b550869e43b4ccec5211f","title":"Migration guide documentation","description":"Write comprehensive migration guide covering: OSS contributor workflow, team workflow, multi-phase development, multiple personas. Include step-by-step instructions, troubleshooting, and backward compatibility notes.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-05T18:04:29.84662-08:00","updated_at":"2025-11-05T18:12:30.907835-08:00","closed_at":"2025-11-05T18:12:30.907835-08:00","source_repo":".","dependencies":[{"issue_id":"bd-c3ei","depends_on_id":"bd-8rd","type":"parent-child","created_at":"2025-11-05T18:04:39.028291-08:00","created_by":"daemon"}]} {"id":"bd-c49","content_hash":"c1594c0e8df8fafa5c3a7295817f8660f653569d33f7f51d00b3d3c8ed51dc78","title":"Audit all cmd/bd tests and group into suites","description":"Analyze all 279 tests in cmd/bd and identify:\n1. Which tests can share DB setup (most of them\\!)\n2. Which tests actually need isolation (export/import, git ops)\n3. Optimal grouping into test suites\n\nCreate a mapping document showing:\n- Current: 279 individual test functions\n- Proposed: ~10-15 test suites with subtests\n- Expected speedup per suite\n\nBlocks all refactoring work.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-21T11:49:19.438242-05:00","updated_at":"2025-11-21T19:42:23.181699-05:00","closed_at":"2025-11-21T15:15:29.50544-05:00","source_repo":"."} {"id":"bd-c4rq","content_hash":"4c096e1d84c3ba5b5b4e107692b990a99166b4c99a4262fd26ec08297fb81046","title":"Refactor: Move staleness check inside daemon branch","description":"## Problem\n\nCurrently ensureDatabaseFresh() is called before the daemon mode check, but it checks daemonClient != nil internally and returns early. This is redundant.\n\n**Location:** All read commands (list.go:196, show.go:27, ready.go:102, status.go:80, etc.)\n\n## Current Pattern\n\nCall happens before daemon check, function checks daemonClient internally.\n\n## Better Pattern\n\nMove staleness check to direct mode branch only, after daemon check.\n\n## Impact\nLow - minor performance improvement (avoids one function call per command in daemon mode)\n\n## Effort\nMedium - requires refactoring 8 command files\n\n## Priority\nLow - can defer to future cleanup PR","status":"open","priority":3,"issue_type":"chore","created_at":"2025-11-20T20:17:45.119583-05:00","updated_at":"2025-11-20T20:17:45.119583-05:00","source_repo":"."} @@ -373,7 +374,7 @@ {"id":"bd-cdf7","content_hash":"50ba3c5bc3a0f06ebd20dd9b373086e0ecd218eea56a9edbef321f4e042115a4","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","source_repo":"."} {"id":"bd-ce37850f","content_hash":"c31f96602e91797883758c5a5b778a148257959256605fca6378bbbc22c54ccc","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":"closed","priority":2,"issue_type":"task","created_at":"2025-10-28T14:48:29.072913-07:00","updated_at":"2025-11-06T19:36:13.972562-08:00","closed_at":"2025-11-06T19:27:25.234801-08:00","source_repo":"."} {"id":"bd-ce75","content_hash":"025d43c12e9cc08c6d1db0b4a97f7a086a1a9f24f07769d48a7e2666d04ea217","title":"Test parent issue","description":"","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-07T16:08:24.952167-08:00","updated_at":"2025-11-07T22:07:17.343848-08:00","closed_at":"2025-11-07T22:07:17.34385-08:00","source_repo":"."} -{"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-11-20T19:43:48.755997-05:00","updated_at":"2025-11-20T19:43:48.755997-05:00","closed_at":"2025-11-07T10:55:55.985273-08:00","source_repo":"."} +{"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-11-22T15:18:47.454199953-07:00","updated_at":"2025-11-22T15:18:47.454199953-07:00","closed_at":"2025-11-07T10:55:55.985273-08:00","source_repo":"."} {"id":"bd-chsc","content_hash":"ea167029efad3c506e42dfc20748a6ada0914aa93cb04caa14a48ca223386365","title":"Test lowercase p0","description":"","status":"closed","priority":0,"issue_type":"task","created_at":"2025-11-05T12:58:41.457875-08:00","updated_at":"2025-11-05T12:58:44.721486-08:00","closed_at":"2025-11-05T12:58:44.721486-08:00","source_repo":"."} {"id":"bd-cjxp","content_hash":"2a2c0aa49be01be64c5e0a6bd24ebd7b762846d31a06fd8e9360672fb476b879","title":"Bug P0","description":"","status":"closed","priority":0,"issue_type":"bug","assignee":"alice","created_at":"2025-11-07T19:00:22.536449-08:00","updated_at":"2025-11-07T22:07:17.345535-08:00","closed_at":"2025-11-07T21:55:09.429643-08:00","source_repo":"."} {"id":"bd-ckvw","content_hash":"a4b27c0e21e3ae0a1e8fb9f64913c286164ff6746c657d70bb7cbbdbf2e365c9","title":"Add schema compatibility probe to prevent silent migration failures","description":"Issue #262 revealed a serious bug: migrations may fail silently, causing UNIQUE constraint errors later.\n\nRoot cause:\n- sqlite.New() runs migrations once on open\n- checkVersionMismatch() prints 'database will be upgraded automatically' but only updates metadata\n- If migrations fail or daemon runs older version, queries expecting new columns fail with 'no such column'\n- Import logic misinterprets this as 'not found' and tries INSERT on existing ID\n- Result: UNIQUE constraint failed: issues.id\n\nFix strategy (minimal):\n1. Add schema probe in sqlite.New() after RunMigrations\n - SELECT all expected columns from all tables with LIMIT 0\n - If fails, retry RunMigrations and probe again\n - If still fails, return fatal error with clear message\n2. Fix checkVersionMismatch to not claim 'will upgrade' unless probe passes\n3. Only update bd_version after successful migration probe\n4. Add schema verification before import operations\n5. Map 'no such column' errors to clear actionable message\n\nRelated: #262","design":"Minimal path (now includes daemon gating):\n\n1. Schema probe in sqlite.New()\n - After RunMigrations, verify all expected columns exist\n - SELECT id, title, description, created_at, updated_at, closed_at, content_hash, external_ref, source_repo, compacted_at, compacted_at_commit FROM issues LIMIT 0\n - Also probe: dependencies, labels, events, dirty_issues, export_hashes, snapshots, child_counters\n - If probe fails: retry RunMigrations once, probe again\n - If still fails: return fatal error with missing columns/tables\n\n2. Fix checkVersionMismatch()\n - Don't claim 'will be upgraded automatically' unless probe verified\n - Only update bd_version after successful probe\n\n3. Better error surfacing\n - Wrap storage errors: if 'no such column/table', return ErrSchemaIncompatible\n - Actionable message: 'Database schema is incompatible. Run bd doctor to diagnose.'\n\n4. Add 'bd doctor' command\n - Runs migrations + probe\n - Reports missing columns/tables\n - Suggests fixes (upgrade daemon, run migrations manually, etc.)\n - Exit 1 if incompatible\n\n5. Daemon version gating (REQUIRED - prevents future schema bugs)\n - On RPC connect, client/daemon exchange semver\n - If client.minor \u003e daemon.minor: refuse RPC, print 'Client vX.Y requires daemon upgrade. Run: bd daemons killall'\n - Forces users to restart daemon when bd binary is upgraded\n - Prevents stale daemon serving requests with old schema assumptions\n - Already documented best practice, now enforced\n\nEstimated effort: M-L (3-5h with daemon gating + bd doctor)","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-08T13:23:26.934246-08:00","updated_at":"2025-11-08T13:53:29.219542-08:00","closed_at":"2025-11-08T13:53:29.219542-08:00","source_repo":"."} @@ -393,13 +394,13 @@ {"id":"bd-d9e0","content_hash":"de4e01414f8863b63cb693a709048b85c3f4417f03e7d7b2528560076be0e1f7","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-02T12:32:00.159298-08:00","closed_at":"2025-11-02T12:32:00.1593-08:00","source_repo":"."} {"id":"bd-da96-baseline-lint","content_hash":"e4d4a2d3ef8082c42c6b39a3b73f26ff29ff1639f5f5f78f48e6ef71bb587068","title":"Baseline quality gate failure: lint","description":"The lint quality gate is failing on the baseline (main branch).\n\nThis blocks the executor from claiming work until fixed.\n\nError: golangci-lint failed: exit status 1\n\nOutput:\n```\ncmd/bd/search.go:39:12: Error return value of `cmd.Help` is not checked (errcheck)\n\t\t\tcmd.Help()\n\t\t\t ^\ncmd/bd/clean.go:118:15: G304: Potential file inclusion via variable (gosec)\n\tfile, err := os.Open(gitignorePath)\n\t ^\ncmd/bd/doctor/gitignore.go:98:12: G306: Expect WriteFile permissions to be 0600 or less (gosec)\n\tif err := os.WriteFile(gitignorePath, []byte(GitignoreTemplate), 0644); err != nil {\n\t ^\ncmd/bd/merge.go:121:16: G204: Subprocess launched with variable (gosec)\n\t\t\tgitRmCmd := exec.Command(\"git\", \"rm\", \"-f\", \"--quiet\", fullPath)\n\t\t\t ^\ncmd/bd/doctor.go:167:20: `cancelled` is a misspelling of `canceled` (misspell)\n\t\tfmt.Println(\"Fix cancelled.\")\n\t\t ^\ncmd/bd/flush_manager.go:139:42: `cancelling` is a misspelling of `canceling` (misspell)\n\t\t// Send shutdown request FIRST (before cancelling context)\n\t\t ^\ncmd/bd/flush_manager.go:261:15: `cancelled` is a misspelling of `canceled` (misspell)\n\t\t\t// Context cancelled (shouldn't normally happen)\n\t\t\t ^\ncmd/bd/flush_manager.go:269:55: (*FlushManager).performFlush - result 0 (error) is always nil (unparam)\nfunc (fm *FlushManager) performFlush(fullExport bool) error {\n ^\n8 issues:\n* errcheck: 1\n* gosec: 3\n* misspell: 3\n* unparam: 1\n\n```","design":"Fix the lint gate failures reported above.","acceptance_criteria":"- lint gate passes on main branch\n- Preflight check succeeds\n- Executor can resume claiming work","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-21T10:17:25.963791-05:00","updated_at":"2025-11-21T10:25:33.537845-05:00","closed_at":"2025-11-21T10:25:33.53596-05:00","source_repo":".","labels":["baseline-failure","gate:lint","system"]} {"id":"bd-dcd6f14b","content_hash":"c07a4b8a39e6e81513278ee335fe14aa767cbcba72e3b511cfd95705053483b1","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","source_repo":"."} -{"id":"bd-dd6f6d26","content_hash":"1ac634b2515cb7f7738f06bc3ad083d02025bc915aca7eae690c9dcc1a552878","title":"Fix autoimport tests for content-hash collision scoring","description":"## Overview\nThree autoimport tests are failing after [deleted: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-11-08T03:09:48.253086-08:00","updated_at":"2025-11-20T19:43:48.756262-05:00","closed_at":"2025-11-08T02:28:35.317704-08:00","source_repo":".","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"}]} +{"id":"bd-dd6f6d26","content_hash":"1ac634b2515cb7f7738f06bc3ad083d02025bc915aca7eae690c9dcc1a552878","title":"Fix autoimport tests for content-hash collision scoring","description":"## Overview\nThree autoimport tests are failing after [deleted: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-11-08T03:09:48.253086-08:00","updated_at":"2025-11-22T15:18:47.455095155-07:00","closed_at":"2025-11-08T02:28:35.317704-08:00","source_repo":".","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"}]} {"id":"bd-de0h","content_hash":"8b8b43683607e73012cf8bd7cf8631c6ae34498d0c93ca5b77d3f68944c8088d","title":"bd message: Add HTTP client timeout to prevent hangs","description":"HTTP client in `sendAgentMailRequest` uses default http.Post with no timeout.\n\n**Location:** cmd/bd/message.go:181\n\n**Problem:**\n- Can hang indefinitely if server is unresponsive\n- No way to cancel stuck requests\n- Poor UX in flaky networks\n\n**Fix:**\n```go\nclient := \u0026http.Client{Timeout: 30 * time.Second}\nresp, err := client.Post(url, \"application/json\", bytes.NewReader(reqBody))\n```\n\n**Impact:** Production reliability and security issue","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-08T12:54:24.942645-08:00","updated_at":"2025-11-08T12:56:59.948929-08:00","closed_at":"2025-11-08T12:56:59.948929-08:00","source_repo":".","dependencies":[{"issue_id":"bd-de0h","depends_on_id":"bd-6uix","type":"parent-child","created_at":"2025-11-08T12:55:54.860847-08:00","created_by":"daemon"}]} {"id":"bd-df11","content_hash":"9d688c3fe5f4994ab29ed22c8c4ae467f2069c4cbb676a2168303b2ffcba48c4","title":"Add import metrics for external_ref matching statistics","description":"Add observability for external_ref matching behavior during imports to help debug and optimize import operations.\n\nMetrics to track:\n- Number of issues matched by external_ref\n- Number of issues matched by ID\n- Number of issues matched by content hash\n- Number of external_ref updates vs creates\n- Average import time with vs without external_ref\n\nOutput format:\n- Add to ImportResult struct\n- Include in import command output\n- Consider structured logging\n\nUse cases:\n- Debugging slow imports\n- Understanding match distribution\n- Optimizing import performance\n\nRelated: bd-1022","status":"closed","priority":4,"issue_type":"chore","created_at":"2025-11-02T15:32:46.157899-08:00","updated_at":"2025-11-08T02:24:24.686136-08:00","closed_at":"2025-11-08T02:20:01.01371-08:00","source_repo":"."} {"id":"bd-df190564","content_hash":"4966d22faf43b7de1b27315f85365d7ed896741e4e589ed01ee16f4c2f600a24","title":"bd repair-deps - Orphaned dependency cleaner","description":"Find and fix orphaned dependency references.\n\nImplementation:\n- Scan all issues for dependencies pointing to non-existent issues\n- Report orphaned refs\n- Auto-fix with --fix flag\n- Interactive mode with --interactive\n\nFiles: cmd/bd/repair_deps.go (new)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T19:42:29.852745-07:00","updated_at":"2025-10-31T18:24:19.418221-07:00","closed_at":"2025-10-31T18:24:19.418221-07:00","source_repo":"."} {"id":"bd-dow9","content_hash":"5fa420f7eb64396bcd8a58626ae82209d9d75da474a03847d4fbaba76a953846","title":"Improve CheckStaleness error handling","description":"## Problem\n\nCheckStaleness returns 'false' (not stale) for multiple error conditions instead of returning errors. This masks problems.\n\n**Location:** internal/autoimport/autoimport.go:253-285\n\n## Edge Cases That Return False\n\n1. **Invalid last_import_time format** (line 259-262)\n - Corrupted metadata returns 'not stale'\n - Could show stale data\n\n2. **No JSONL file found** (line 267-277)\n - If glob fails, falls back to 'issues.jsonl'\n - If that's empty, returns 'not stale'\n\n3. **JSONL stat fails** (line 279-282)\n - Permission denied, file missing\n - Returns 'not stale' even though can't verify\n\n## Current Code\n\n```go\nlastImportTime, err := time.Parse(time.RFC3339, lastImportStr)\nif err \\!= nil {\n return false, nil // ← Should return error\n}\n\n// ...\n\nif jsonlPath == \"\" {\n return false, nil // ← Should return error\n}\n\nstat, err := os.Stat(jsonlPath)\nif err \\!= nil {\n return false, nil // ← Should return error\n}\n```\n\n## Fix\n\n```go\nlastImportTime, err := time.Parse(time.RFC3339, lastImportStr)\nif err \\!= nil {\n return false, fmt.Errorf(\"corrupted last_import_time: %w\", err)\n}\n\n// ...\n\nif jsonlPath == \"\" {\n return false, fmt.Errorf(\"no JSONL file found\")\n}\n\nstat, err := os.Stat(jsonlPath)\nif err \\!= nil {\n return false, fmt.Errorf(\"cannot stat JSONL: %w\", err)\n}\n```\n\n## Impact\nMedium - edge cases are rare but should be handled\n\n## Effort \n30 minutes - requires updating callers in RPC server\n\n## Dependencies\nRequires: bd-n4td (warning on errors)","status":"open","priority":2,"issue_type":"bug","created_at":"2025-11-20T20:16:45.658965-05:00","updated_at":"2025-11-20T20:16:45.658965-05:00","source_repo":"."} {"id":"bd-dvd","content_hash":"23ac9c6da0e1dafb9948d204d9312f09ce9cca7561cd90ced49ede0adaa7c648","title":"GetNextChildID doesn't attempt parent resurrection from JSONL history","description":"When creating a child issue with --parent flag, GetNextChildID fails immediately if parent doesn't exist in DB, without attempting to resurrect it from JSONL history. This breaks the intended resurrection workflow and causes 'parent issue X does not exist' errors even when the parent exists in JSONL.\n\nRelated to GH #334 and #278.\n\nCurrent behavior:\n- GetNextChildID checks if parent exists in DB\n- If not found, returns error immediately\n- No resurrection attempt\n\nExpected behavior:\n- GetNextChildID should call TryResurrectParent before failing\n- Parent should be restored as tombstone if found in JSONL history\n- Child creation should succeed if resurrection succeeds\n\nImpact: Users cannot create child issues for parents that were deleted but exist in JSONL history.","design":"Modify internal/storage/sqlite/hash_ids.go:29-38 to call s.TryResurrectParent(ctx, parentID) when parent is not found in database, before returning the 'does not exist' error.\n\nThe resurrection logic already exists in internal/storage/sqlite/resurrection.go and is used by CreateIssue for hierarchical IDs - we just need to call it from GetNextChildID as well.","acceptance_criteria":"1. bd create with --parent flag succeeds when parent exists in JSONL but not DB\n2. Parent is resurrected as tombstone (closed status)\n3. Child issue is created with correct hierarchical ID\n4. All existing tests continue to pass\n5. Add test case for this scenario in child_id_test.go","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-21T10:02:51.496365-05:00","updated_at":"2025-11-21T23:53:00.481392-08:00","closed_at":"2025-11-21T15:09:02.731171-05:00","external_ref":"https://github.com/steveyegge/beads/issues/334","source_repo":".","labels":["bug","parent-child","resurrection"]} -{"id":"bd-dxdn","content_hash":"1ad5838334d77403d884787d2b5c99b88c6fa28fb08a16014246c8db0f9f4020","title":"bd ready taking 5 seconds with 132 issues (89 closed)","description":"User reports bd ready is annoyingly slow on M2 Mac - 5 seconds for 132 issues (89 closed). Started noticing after hash-based IDs update. Need to investigate performance regression. Reported in GH #243.","notes":"Root cause identified: Not a query performance issue, but stale daemon locks causing 5s timeout delays.\n\nFixed in bd-ndyz (closed) via 5 sub-issues:\n- bd-expt: Fast-fail socket checks (200ms timeout)\n- bd-wgu4: Lock probe before RPC attempts\n- bd-1mzt: Self-heal stale artifacts\n- bd-vcg5: Panic recovery + socket cleanup\n- bd-j7e2: RPC diagnostics (BD_RPC_DEBUG)\n\nAll fixes merged. Ready for v0.22.2 release.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-07T00:26:30.359512-08:00","updated_at":"2025-11-08T13:17:08.766029-08:00","closed_at":"2025-11-08T02:35:47.956638-08:00","source_repo":"."} +{"id":"bd-dxdn","content_hash":"1ad5838334d77403d884787d2b5c99b88c6fa28fb08a16014246c8db0f9f4020","title":"bd ready taking 5 seconds with 132 issues (89 closed)","description":"User reports bd ready is annoyingly slow on M2 Mac - 5 seconds for 132 issues (89 closed). Started noticing after hash-based IDs update. Need to investigate performance regression. Reported in GH #243.","notes":"Root cause identified: Not a query performance issue, but stale daemon locks causing 5s timeout delays.\n\nFixed in bd-ndyz (closed) via 5 sub-issues:\n- bd-expt: Fast-fail socket checks (200ms timeout)\n- bd-wgu4: Lock probe before RPC attempts\n- bd-1mzt: Self-heal stale artifacts\n- bd-vcg5: Panic recovery + socket cleanup\n- bd-j7e2: RPC diagnostics (BD_RPC_DEBUG)\n\nAll fixes merged. Ready for v0.22.2 release.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-07T00:26:30.359512-08:00","updated_at":"2025-11-11T08:42:35.009428675-07:00","closed_at":"2025-11-08T02:35:47.956638-08:00","source_repo":"."} {"id":"bd-e044","content_hash":"8393c18d7f6edfed3d3e360a32a3075a9e0d9caa6f02d704774482aa1d9b0a7f","title":"Add mermaid output format for bd dep tree","description":"Add visual dependency graph output using Mermaid format for better visualization of issue relationships.\n\nExample usage:\n bd dep tree --format mermaid \u003cissue-id\u003e\n bd dep tree --format mermaid bd-42 \u003e graph.md\n\nThis would output Mermaid syntax that can be rendered in GitHub, documentation sites, or Mermaid live editor.\n\nImplementation notes:\n- Add --format flag to dep tree command\n- Support 'text' (default) and 'mermaid' formats\n- Mermaid graph should show issue IDs, titles, and dependency types\n- Consider using flowchart LR or graph TD syntax","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-03T18:10:18.978383-08:00","updated_at":"2025-11-03T20:55:06.696363-08:00","closed_at":"2025-11-03T20:55:06.69637-08:00","source_repo":"."} {"id":"bd-e05d","content_hash":"c2f4d60f5bd679d9bf609c35efc9c15e8dd52130fb9b68eacfe47bdda910ecd7","title":"Investigate and optimize test suite performance","description":"Test suite is taking very long to run (\u003e45s for cmd/bd tests, full suite timing unknown but was cancelled).\n\nThis impacts development velocity and CI/CD performance.\n\nInvestigation needed:\n- Profile which tests are slowest\n- Identify bottlenecks (disk I/O, network, excessive setup/teardown?)\n- Consider parallelization opportunities\n- Look for redundant test cases\n- Check if integration tests can be optimized","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-02T15:37:44.529955-08:00","updated_at":"2025-11-02T16:35:38.093133-08:00","closed_at":"2025-11-02T16:35:38.093137-08:00","source_repo":"."} {"id":"bd-e0o","content_hash":"4f1210b547378520d45c54b1236415ca9c71e742893a5d340e2f237daf64ab9a","title":"Phase 3: Enhance daemon robustness for GH #353","description":"Improve daemon health checks and metadata refresh to prevent staleness issues.\n\n**Tasks:**\n1. Enhance daemon health checks to detect unreachable daemons\n2. Add daemon metadata refresh (check disk every 5s)\n3. Comprehensive testing in sandbox environments\n\n**Implementation:**\n- cmd/bd/main.go: Better health check error handling (lines 300-367)\n- cmd/bd/daemon_event_loop.go: Periodic metadata refresh\n- cmd/bd/daemon_unix.go: Permission-aware process checks\n\n**References:**\n- docs/GH353_INVESTIGATION.md (Solutions 4 \u0026 5, lines 161-209)\n- Depends on: Phase 2 (bd-u3t)\n\n**Acceptance Criteria:**\n- Daemon detects when it's unreachable and auto-switches to direct mode\n- Daemon picks up external import operations without restart\n- All edge cases handled gracefully","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-21T18:52:13.376092-05:00","updated_at":"2025-11-21T23:53:00.481866-08:00","closed_at":"2025-11-21T19:31:42.718395-05:00","source_repo":"."} @@ -421,9 +422,9 @@ {"id":"bd-ef85","content_hash":"56b7e0c048938940053b127e4f9ed578e797b99dc93d010138ec823efbe7842c","title":"Add --json flags to all bd commands for agent-friendly output","description":"","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-31T22:39:45.312496-07:00","updated_at":"2025-10-31T22:39:50.157022-07:00","closed_at":"2025-10-31T22:39:50.157022-07:00","source_repo":"."} {"id":"bd-eimz","content_hash":"03d818a0c6277838251b1bd67f3e88c1aedad81fa458291f27469a807a69fc13","title":"Add Agent Mail to QUICKSTART.md","description":"Mention Agent Mail as optional advanced feature in quickstart guide.\n\nFile: docs/QUICKSTART.md","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-07T22:42:51.357009-08:00","updated_at":"2025-11-08T01:07:11.598558-08:00","closed_at":"2025-11-08T01:07:11.598558-08:00","source_repo":".","dependencies":[{"issue_id":"bd-eimz","depends_on_id":"bd-xzrv","type":"blocks","created_at":"2025-11-07T23:04:09.841956-08:00","created_by":"daemon"}]} {"id":"bd-eiz9","content_hash":"0f1722abb1f24d08d2c643d9cd4109935325eb3ea994166ff88202d0a457b003","title":"Help agents understand version changes with bd info --whats-new","description":"**Problem** (from GH Discussion #239 by @maphew):\nWeekly major versions mean agents need to adapt workflows, but currently there's no efficient way to communicate \"what changed that affects you.\"\n\n**Proposed solutions:**\n\n1. **bd info --whats-new** - Show agent-actionable changes since last version\n ```\n Since v0.20.1:\n • Hash IDs eliminate collisions - remove ID coordination workarounds\n • Event-driven daemon (opt-in) - add BEADS_DAEMON_MODE=events\n • Merge driver auto-configured - conflicts rarer\n ```\n\n2. **Version-aware bd onboard** - Detect version changes and show diff of agent-relevant changes\n\n3. **AGENTS.md top section** - \"🆕 Recent Changes (Last 3 Versions)\" with workflow impacts\n\n**Why agents need this:**\n- Raw CHANGELOG is token-heavy and buried in release details\n- Full bd onboard re-run wasteful if only 2-3 things changed\n- Currently requires user to manually explain updates\n\n**Related:** https://github.com/steveyegge/beads/discussions/239","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-06T21:03:30.057576-08:00","updated_at":"2025-11-08T02:42:56.733731-08:00","closed_at":"2025-11-08T02:25:55.509249-08:00","source_repo":"."} -{"id":"bd-epvx","content_hash":"f0acf2bcec5857c61c542764f62c5f5a66cfa74cdafa941c1754db40dd173efc","title":"Create Go adapter library (optional)","description":"For agents written in Go, provide native adapter library instead of shelling out to curl.\n\nAcceptance Criteria:\n- agentmail.Client struct\n- HTTP client with timeout/retry logic\n- Same API as Python adapter\n- Example usage in examples/go-agent/\n- Unit tests\n\nFile: pkg/agentmail/client.go\n\nNote: Lower priority - can shell out to curl initially","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-11-07T22:42:28.781577-08:00","updated_at":"2025-11-08T15:58:37.146674-08:00","closed_at":"2025-11-08T15:48:57.83973-08:00","source_repo":".","dependencies":[{"issue_id":"bd-epvx","depends_on_id":"bd-m9th","type":"blocks","created_at":"2025-11-07T23:04:01.47471-08:00","created_by":"daemon"}]} +{"id":"bd-epvx","content_hash":"f0acf2bcec5857c61c542764f62c5f5a66cfa74cdafa941c1754db40dd173efc","title":"Create Go adapter library (optional)","description":"For agents written in Go, provide native adapter library instead of shelling out to curl.\n\nAcceptance Criteria:\n- agentmail.Client struct\n- HTTP client with timeout/retry logic\n- Same API as Python adapter\n- Example usage in examples/go-agent/\n- Unit tests\n\nFile: pkg/agentmail/client.go\n\nNote: Lower priority - can shell out to curl initially","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-11-07T22:42:28.781577-08:00","updated_at":"2025-11-11T08:42:35.010474696-07:00","closed_at":"2025-11-08T15:48:57.83973-08:00","source_repo":".","dependencies":[{"issue_id":"bd-epvx","depends_on_id":"bd-m9th","type":"blocks","created_at":"2025-11-07T23:04:01.47471-08:00","created_by":"daemon"}]} {"id":"bd-eqjc","content_hash":"8acc3d91ca9f9bef36d19358cb7f24eac247583a0e6701036aaff92607474c21","title":"bd init creates nested .beads directories","description":"bd init sometimes creates .beads/.beads/ nested directories, which should never happen. This occurs fairly often and can cause confusion about which .beads directory is active. Need to add validation to detect if already inside a .beads directory and either error or use the parent .beads location.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-06T22:21:22.948727-08:00","updated_at":"2025-11-06T22:22:41.04958-08:00","closed_at":"2025-11-06T22:22:41.04958-08:00","source_repo":"."} -{"id":"bd-es19","content_hash":"5c5951971ed466f30fa12e1d7f73457ecc430464726516f069e6659f762687e6","title":"BG's issue to reopen","description":"","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-20T19:43:48.756893-05:00","updated_at":"2025-11-20T19:43:48.756893-05:00","closed_at":"2025-11-07T21:57:59.90981-08:00","source_repo":"."} +{"id":"bd-es19","content_hash":"5c5951971ed466f30fa12e1d7f73457ecc430464726516f069e6659f762687e6","title":"BG's issue to reopen","description":"","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-22T15:18:47.457809055-07:00","updated_at":"2025-11-22T15:18:47.457809055-07:00","closed_at":"2025-11-07T21:57:59.90981-08:00","source_repo":"."} {"id":"bd-expt","content_hash":"6e14db64fb24882e4cf544ec24eaa994aba970fd0ae31c72dda2d8ea88560753","title":"RPC fast-fail: stat socket before dial, cap timeouts to 200ms","description":"Eliminate 5s delay when daemon socket is missing by:\n1. Add os.Stat(socketPath) check before dialing in TryConnect\n2. Return (nil, nil) immediately if socket doesn't exist\n3. Set default dial timeout to 200ms in TryConnect\n4. Keep TryConnectWithTimeout for explicit health/status checks (1-2s)\n\nThis prevents clients from waiting through full timeout when no daemon is running.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-11-07T16:42:12.688526-08:00","updated_at":"2025-11-07T22:07:17.345918-08:00","closed_at":"2025-11-07T21:04:21.671436-08:00","source_repo":".","dependencies":[{"issue_id":"bd-expt","depends_on_id":"bd-ndyz","type":"discovered-from","created_at":"2025-11-07T16:42:12.689284-08:00","created_by":"daemon"}]} {"id":"bd-f0d9bcf2","content_hash":"00e0c7b440024e6257d1bac9c1d5af10f8a12ee1726478e4b5bab06e34bfb586","title":"Batch test 1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T15:29:01.795728-07:00","updated_at":"2025-10-31T12:00:43.184078-07:00","closed_at":"2025-10-31T12:00:43.184078-07:00","source_repo":"."} {"id":"bd-f282","content_hash":"90043e5e39cbb062ce0ff6a323ce2d0a16465783742d06ac9da1df66d837e025","title":"Test npm package installation locally","description":"Verify npm package works before publishing:\n\n## Local testing\n- Run npm pack in npm/ directory\n- Install tarball globally: npm install -g beads-bd-0.21.5.tgz\n- Test basic commands:\n - bd --version\n - bd init --quiet --prefix test\n - bd create \"Test issue\" -p 1 --json\n - bd list --json\n - bd sync\n\n## Test environments\n- macOS (darwin-arm64 and darwin-amd64)\n- Linux (ubuntu docker container for linux-amd64)\n- Windows (optional, if available)\n\n## Validation\n- Binary downloads during postinstall\n- All bd commands work identically to native\n- No permission issues\n- Proper error messages on failure","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-02T23:40:05.71835-08:00","updated_at":"2025-11-03T10:31:45.382577-08:00","closed_at":"2025-11-03T10:31:45.382577-08:00","source_repo":".","dependencies":[{"issue_id":"bd-f282","depends_on_id":"bd-febc","type":"parent-child","created_at":"2025-11-02T23:40:32.968748-08:00","created_by":"daemon"}]} @@ -444,17 +445,17 @@ {"id":"bd-f9a1","content_hash":"97f9387b20f741a9f71ee43b0671b5d970bd594098db299dc871d0b3074c5384","title":"Add index usage verification test for external_ref lookups","description":"Currently we test that idx_issues_external_ref index exists, but we don't verify that it's actually being used by the query planner.\n\nProposed solution:\n- Add test using EXPLAIN QUERY PLAN\n- Verify that 'SEARCH TABLE issues USING INDEX idx_issues_external_ref' appears in plan\n- Ensures O(1) lookup performance is maintained\n\nRelated: bd-1022\nFiles: internal/storage/sqlite/external_ref_test.go:260","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-02T15:32:09.85419-08:00","updated_at":"2025-11-02T16:04:47.221064-08:00","closed_at":"2025-11-02T16:04:47.221064-08:00","source_repo":"."} {"id":"bd-fasa","content_hash":"bc2c647cac7355a66fa4aefd116c82e01f536da4b4404e922b3307505413210f","title":"Prefix detection treats embedded hyphens as prefix delimiters","description":"The prefix detection logic in bd import incorrectly identifies issues like 'vc-baseline-test' and 'vc-92cl-gate-test' as having different prefixes ('vc-baseline-' and 'vc-92cl-gate-') instead of recognizing them as having the standard 'vc-' prefix with hyphenated suffixes.\n\nThis breaks import with error: 'prefix mismatch detected: database uses vc- but found issues with prefixes: [vc-92cl-gate- (1 issues) vc-baseline- (1 issues)]'\n\nThe prefix should be determined by the pattern: prefix is everything up to and including the first hyphen. The suffix can contain hyphens without being treated as part of the prefix.\n\nExample problematic IDs:\n- vc-baseline-test (detected as prefix: vc-baseline-)\n- vc-92cl-gate-test (detected as prefix: vc-92cl-gate-)\n- vc-test (correctly detected as prefix: vc-)\n\nImpact: Users cannot use descriptive multi-part IDs without triggering false prefix mismatch errors.","acceptance_criteria":"- Prefix detection only considers the first hyphen as prefix delimiter\n- IDs like 'vc-baseline-test' correctly identified as having prefix 'vc-'\n- Import succeeds without --rename-on-import for hyphenated suffixes\n- Tests added for multi-part ID suffix handling","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-09T14:27:19.046489-08:00","updated_at":"2025-11-09T14:53:53.22312-08:00","closed_at":"2025-11-09T14:53:53.22312-08:00","source_repo":"."} {"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:30:09.833675-07:00","closed_at":"2025-11-01T22:30:09.833675-07:00","source_repo":"."} -{"id":"bd-fb95094c","content_hash":"d30f2a45055cdb28efd6b15f97880f3fd50bee024876308440acea3f279f8920","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":"closed","priority":2,"issue_type":"epic","created_at":"2025-10-27T20:39:22.22227-07:00","updated_at":"2025-11-08T22:42:08.863126-08:00","closed_at":"2025-11-08T18:15:59.971899-08:00","source_repo":".","labels":["cleanup","epic"]} +{"id":"bd-fb95094c","content_hash":"d30f2a45055cdb28efd6b15f97880f3fd50bee024876308440acea3f279f8920","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":"closed","priority":2,"issue_type":"epic","created_at":"2025-10-27T20:39:22.22227-07:00","updated_at":"2025-11-11T08:42:35.011523762-07:00","closed_at":"2025-11-08T18:15:59.971899-08:00","source_repo":".","labels":["cleanup","epic"]} {"id":"bd-fb95094c.1","content_hash":"8f7533da448dea49a01aa747892eab9f855127343ced4fbd6e17cb80d56419af","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","source_repo":".","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":"072a2e76c3a9690c49c805351891235d488936d7a0e7b1d1334bd933f79de338","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":"closed","priority":3,"issue_type":"task","created_at":"2025-10-27T20:31:19.090608-07:00","updated_at":"2025-11-08T22:42:08.863677-08:00","closed_at":"2025-11-08T18:15:54.319047-08:00","source_repo":".","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"}]} +{"id":"bd-fb95094c.10","content_hash":"072a2e76c3a9690c49c805351891235d488936d7a0e7b1d1334bd933f79de338","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":"closed","priority":3,"issue_type":"task","created_at":"2025-10-27T20:31:19.090608-07:00","updated_at":"2025-11-11T08:42:35.013135303-07:00","closed_at":"2025-11-08T18:15:54.319047-08:00","source_repo":".","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"}]} {"id":"bd-fb95094c.2","content_hash":"685c91a6de8e1610feb5dbda18412f3eee178a37064d9ddf55511fb693dec9ba","title":"Delete skipped tests for \"old buggy behavior\"","description":"Three test functions are permanently skipped with comments indicating they test behavior that was fixed in GH#120. These tests will never run again and should be deleted.\n\nTest functions to remove:\n\n1. `cmd/bd/import_collision_test.go:228`\n ```go\n t.Skip(\"Test expects old buggy behavior - needs rewrite for GH#120 fix\")\n ```\n\n2. `cmd/bd/import_collision_test.go:505`\n ```go\n t.Skip(\"Test expects old buggy behavior - needs rewrite for GH#120 fix\")\n ```\n\n3. `internal/storage/sqlite/collision_test.go:919`\n ```go\n t.Skip(\"Test expects old buggy behavior - needs rewrite for GH#120 fix\")\n ```\n\nImpact: Removes ~150 LOC of permanently skipped tests","acceptance_criteria":"- Delete the 3 test functions entirely (~150 LOC total)\n- Update test file comments to reference GH#120 fix if needed\n- All remaining tests pass: `go test ./...`\n- No reduction in meaningful test coverage (these test fixed bugs)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T20:30:19.961185-07:00","updated_at":"2025-10-30T17:12:58.196387-07:00","closed_at":"2025-10-28T14:09:21.642632-07:00","source_repo":".","labels":["cleanup","dead-code","phase-1","test-cleanup"],"dependencies":[{"issue_id":"bd-fb95094c.2","depends_on_id":"bd-fb95094c","type":"parent-child","created_at":"2025-10-27T20:30:19.962815-07:00","created_by":"daemon"}]} -{"id":"bd-fb95094c.3","content_hash":"84783b0ba6c7fc6b75167935be981a0ae52069936137ec65d79b52b54cb43f2c","title":"Update documentation after code health cleanup","description":"Update all documentation to reflect code structure changes after cleanup phases complete.\n\nDocumentation to update:\n1. **AGENTS.md** - Update file structure references\n2. **CONTRIBUTING.md** (if exists) - Update build/test instructions\n3. **Code comments** - Update any outdated references\n4. **Package documentation** - Update godoc for reorganized packages\n\nNew documentation to add:\n1. **internal/util/README.md** - Document shared utilities\n2. **internal/debug/README.md** - Document debug logging\n3. **internal/rpc/README.md** - Document new file organization\n4. **internal/storage/sqlite/migrations/README.md** - Migration system docs\n\nImpact: Keeps documentation in sync with code","acceptance_criteria":"- All documentation references to deleted files removed\n- New package READMEs written\n- Code comments updated for reorganized code\n- Migration guide for developers (if needed)\n- Architecture diagrams updated (if they exist)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T20:32:00.141028-07:00","updated_at":"2025-11-08T22:42:08.86399-08:00","closed_at":"2025-11-08T18:15:48.644285-08:00","source_repo":".","labels":["documentation","phase-4"],"dependencies":[{"issue_id":"bd-fb95094c.3","depends_on_id":"bd-fb95094c","type":"parent-child","created_at":"2025-10-27T20:32:00.1423-07:00","created_by":"daemon"}]} +{"id":"bd-fb95094c.3","content_hash":"84783b0ba6c7fc6b75167935be981a0ae52069936137ec65d79b52b54cb43f2c","title":"Update documentation after code health cleanup","description":"Update all documentation to reflect code structure changes after cleanup phases complete.\n\nDocumentation to update:\n1. **AGENTS.md** - Update file structure references\n2. **CONTRIBUTING.md** (if exists) - Update build/test instructions\n3. **Code comments** - Update any outdated references\n4. **Package documentation** - Update godoc for reorganized packages\n\nNew documentation to add:\n1. **internal/util/README.md** - Document shared utilities\n2. **internal/debug/README.md** - Document debug logging\n3. **internal/rpc/README.md** - Document new file organization\n4. **internal/storage/sqlite/migrations/README.md** - Migration system docs\n\nImpact: Keeps documentation in sync with code","acceptance_criteria":"- All documentation references to deleted files removed\n- New package READMEs written\n- Code comments updated for reorganized code\n- Migration guide for developers (if needed)\n- Architecture diagrams updated (if they exist)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T20:32:00.141028-07:00","updated_at":"2025-11-11T08:42:35.014560154-07:00","closed_at":"2025-11-08T18:15:48.644285-08:00","source_repo":".","labels":["documentation","phase-4"],"dependencies":[{"issue_id":"bd-fb95094c.3","depends_on_id":"bd-fb95094c","type":"parent-child","created_at":"2025-10-27T20:32:00.1423-07:00","created_by":"daemon"}]} {"id":"bd-fb95094c.4","content_hash":"c2831a4b1f3847a8aff257d72eda7aa280b7f572a3e4e72d2283a9af367b52ea","title":"Audit and consolidate collision test coverage","description":"The codebase has 2,019 LOC of collision detection tests across 3 files. Run coverage analysis to identify redundant test cases and consolidate.\n\nTest files:\n- `cmd/bd/import_collision_test.go` - 974 LOC\n- `cmd/bd/autoimport_collision_test.go` - 750 LOC\n- `cmd/bd/import_collision_regression_test.go` - 295 LOC\n\nTotal: 2,019 LOC of collision tests\n\nAnalysis steps:\n1. Run coverage analysis\n2. Identify redundant tests\n3. Document findings\n\nConsolidation strategy:\n- Keep regression tests for critical bugs\n- Merge overlapping table-driven tests\n- Remove redundant edge case tests covered elsewhere\n- Ensure all collision scenarios still tested\n\nExpected outcome: Reduce to ~1,200 LOC (save ~800 lines) while maintaining coverage\n\nImpact: Faster test runs, easier maintenance, clearer test intent","acceptance_criteria":"- Coverage analysis completed and documented\n- Redundant tests identified (~800 LOC estimated)\n- Consolidated test suite maintains or improves coverage\n- All remaining tests pass: `go test ./cmd/bd/...`\n- Test run time unchanged or faster\n- Document which tests were removed and why\n- Coverage percentage maintained: `go test -cover ./cmd/bd/` shows same %","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T20:32:00.130855-07:00","updated_at":"2025-11-08T01:58:15.283373-08:00","closed_at":"2025-11-07T23:27:41.970013-08:00","source_repo":".","labels":["phase-4","test-cleanup"],"dependencies":[{"issue_id":"bd-fb95094c.4","depends_on_id":"bd-fb95094c","type":"parent-child","created_at":"2025-10-27T20:32:00.132251-07:00","created_by":"daemon"}]} {"id":"bd-fb95094c.5","content_hash":"11521fe159f640e2cefd3d138fbbbc3b8d2b4fda48c6542f39761d5a124d6154","title":"Centralize BD_DEBUG logging into debug package","description":"The codebase has 43 scattered instances of `if os.Getenv(\"BD_DEBUG\") != \"\"` debug checks across 6 files. Centralize into a debug logging package.\n\nCurrent locations:\n- `cmd/bd/main.go` - 15 checks\n- `cmd/bd/autoflush.go` - 6 checks\n- `cmd/bd/nodb.go` - 4 checks\n- `internal/rpc/server.go` - 2 checks\n- `internal/rpc/client.go` - 5 checks\n- `cmd/bd/daemon_autostart.go` - 11 checks\n\nTarget structure:\n```\ninternal/debug/\n└── debug.go\n```\n\nBenefits:\n- Centralized debug logging\n- Easier to add structured logging later\n- Testable (can mock debug output)\n- Consistent debug message format\n\nImpact: Removes 43 scattered checks, improves code clarity","acceptance_criteria":"- Create `internal/debug/debug.go` with `Enabled`, `Logf`, `Printf`\n- Add unit tests in `internal/debug/debug_test.go` (test with/without BD_DEBUG)\n- Replace all 43 instances of `os.Getenv(\"BD_DEBUG\")` checks with `debug.Logf()`\n- Verify debug output works: run with `BD_DEBUG=1 bd status`\n- All tests pass: `go test ./...`\n- No behavior change (output identical to before)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T20:31:19.089078-07:00","updated_at":"2025-11-07T00:28:01.781121-08:00","closed_at":"2025-11-06T20:13:09.412212-08:00","source_repo":".","labels":["deduplication","logging","phase-3","refactor"],"dependencies":[{"issue_id":"bd-fb95094c.5","depends_on_id":"bd-fb95094c","type":"parent-child","created_at":"2025-10-27T21:48:41.542395-07:00","created_by":"stevey"}]} {"id":"bd-fb95094c.6","content_hash":"a8fe5793d281df23eb2a4856cbc4fa3fecc0a12762e75f7b80601af7d76d06da","title":"Extract normalizeLabels to shared utility package","description":"The `normalizeLabels` function appears in multiple locations with identical implementation. Extract to a shared utility package.\n\nCurrent locations:\n- `internal/rpc/server.go:37` (53 lines) - full implementation\n- `cmd/bd/list.go:50-52` - uses the server version (needs to use new shared version)\n\nFunction purpose:\n- Trims whitespace from labels\n- Removes empty strings\n- Deduplicates labels\n- Preserves order\n\nTarget structure:\n```\ninternal/util/\n├── strings.go # String utilities\n └── NormalizeLabels([]string) []string\n```\n\nImpact: DRY principle, single source of truth, easier to test","acceptance_criteria":"- Create `internal/util/strings.go` with `NormalizeLabels`\n- Add comprehensive unit tests in `internal/util/strings_test.go`\n- Update `internal/rpc/server.go` to import and use `util.NormalizeLabels`\n- Update `cmd/bd/list.go` to import and use `util.NormalizeLabels`\n- Remove duplicate implementations\n- All tests pass: `go test ./...`\n- Verify label normalization works: test `bd list --label` commands","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T20:31:19.078622-07:00","updated_at":"2025-11-06T20:06:49.219555-08:00","closed_at":"2025-11-06T19:58:59.467567-08:00","source_repo":".","labels":["deduplication","phase-3","refactor"],"dependencies":[{"issue_id":"bd-fb95094c.6","depends_on_id":"bd-fb95094c","type":"parent-child","created_at":"2025-10-27T20:31:19.08015-07:00","created_by":"daemon"}]} {"id":"bd-fb95094c.7","content_hash":"6b0e7ce36c1680778cf79aaa9881688001818f2e2081f8c8a240fa0257f08e10","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":"closed","priority":2,"issue_type":"task","assignee":"amp","created_at":"2025-10-27T20:30:47.870671-07:00","updated_at":"2025-11-06T20:05:05.01308-08:00","closed_at":"2025-11-06T20:05:05.01308-08:00","source_repo":".","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-11-20T19:43:48.757493-05:00","updated_at":"2025-11-20T19:43:48.757493-05:00","closed_at":"2025-11-07T10:55:55.982696-08:00","source_repo":".","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-11-20T19:43:48.758109-05:00","updated_at":"2025-11-20T19:43:48.758109-05:00","closed_at":"2025-11-07T10:55:55.984293-08:00","source_repo":".","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-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-11-22T15:18:47.45982834-07:00","updated_at":"2025-11-22T15:18:47.45982834-07:00","closed_at":"2025-11-07T10:55:55.982696-08:00","source_repo":".","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-11-22T15:18:47.461183337-07:00","updated_at":"2025-11-22T15:18:47.461183337-07:00","closed_at":"2025-11-07T10:55:55.984293-08:00","source_repo":".","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":"02e7f133acdef2eb52454fe9f5275575e3c237cdf665e57601c1cd09790106d7","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","source_repo":"."} {"id":"bd-fd56","content_hash":"50437cea170f5b8a962661711d2ba639f9c7d1494a55115408afe3cbc9bebc86","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-02T12:32:00.159595-08:00","closed_at":"2025-11-02T12:32:00.159597-08:00","source_repo":"."} {"id":"bd-fd8753d9","content_hash":"faea57d583689933e7a173d18595095125b5fd79689cbb3c41039608ba4b335b","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":"closed","priority":2,"issue_type":"task","created_at":"2025-10-26T13:23:47.982295-07:00","updated_at":"2025-11-06T20:06:49.219828-08:00","closed_at":"2025-11-06T19:41:08.675575-08:00","source_repo":"."} @@ -462,11 +463,11 @@ {"id":"bd-fkdw","content_hash":"aae326186151d20e26b9b5c34efa43d9261ffd0fe0d6f4de843f951e4c813886","title":"Update bash-agent example with Agent Mail integration","description":"Add Agent Mail integration to examples/bash-agent/agent.sh using curl for HTTP calls.\n\nAcceptance Criteria:\n- Health check function using curl\n- Reserve issue before claiming\n- Send notifications on status change\n- Release on completion\n- Graceful degradation if curl fails\n- No bash errors when Agent Mail unavailable\n\nFile: examples/bash-agent/agent.sh","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-07T22:42:28.722048-08:00","updated_at":"2025-11-08T01:09:25.900138-08:00","closed_at":"2025-11-08T01:09:25.900138-08:00","source_repo":".","dependencies":[{"issue_id":"bd-fkdw","depends_on_id":"bd-m9th","type":"blocks","created_at":"2025-11-07T23:04:01.398259-08:00","created_by":"daemon"}]} {"id":"bd-fsb1","content_hash":"a519fdd6d0ca6f70a177c2cb9441994b28d4bc2fe51a663532d4067caf126049","title":"Test issue","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-05T11:21:51.383077-08:00","updated_at":"2025-11-05T11:21:56.888913-08:00","closed_at":"2025-11-05T11:21:56.888913-08:00","source_repo":".","labels":["test","urgent"]} {"id":"bd-fzbg","content_hash":"4bf5f57a0a66a94d76882e337c25d49e807ec79257a0aeb636fb81d963493860","title":"Update python-agent example with Agent Mail integration","description":"Modify examples/python-agent/agent.py to use Agent Mail adapter at 4 integration points.\n\nAcceptance Criteria:\n- Import and initialize adapter\n- Check inbox before find_ready_work()\n- Reserve issue before claim_task()\n- Notify on status changes\n- Release reservation on complete_task()\n- Works identically when Agent Mail disabled\n- No changes required to core Beads CLI\n\nFile: examples/python-agent/agent.py","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-07T22:42:28.661337-08:00","updated_at":"2025-11-08T00:20:35.213902-08:00","closed_at":"2025-11-08T00:20:35.213902-08:00","source_repo":".","dependencies":[{"issue_id":"bd-fzbg","depends_on_id":"bd-m9th","type":"blocks","created_at":"2025-11-07T23:04:01.315332-08:00","created_by":"daemon"}]} -{"id":"bd-g3ey","content_hash":"e59ecb28d0ceade96c076688de71f5d0022a9b0c0676f3abb1e4e06d90f8f559","title":"bd sync --import-only doesn't update DB mtime causing bd doctor false warning","description":"","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-08T15:18:16.761052+01:00","updated_at":"2025-11-08T15:58:37.147425-08:00","closed_at":"2025-11-08T13:12:01.718252-08:00","source_repo":"."} -{"id":"bd-g5p7","content_hash":"6ef3578afcab8a96c6018ec27f64d36df05b32fe867ad50b5309cdefe6b7f486","title":"Extract duplicated validation logic from CLI commands","description":"~150 lines of identical validation logic duplicated between cmd_create.go and cmd_update.go\n\nDuplication found:\n- validateBeadFields(): 2 identical copies (50+ lines each) \n- parseTimeWithDefault(): 2 identical copies (30 lines each)\n- Flag definitions: 15+ duplicate registrations\n\nSolution: Extract to shared packages:\n- internal/validation/bead.go - Centralized validation\n- internal/utils/time.go - Consolidate time parsing (already exists)\n- cmd/bd/flags.go - Shared flag registration\n\nImpact: Changes require touching 2+ files; high risk of inconsistency; steep learning curve\n\nEffort: 4-6 hours","status":"closed","priority":0,"issue_type":"task","created_at":"2025-11-16T14:51:10.159953-08:00","updated_at":"2025-11-21T23:53:00.48232-08:00","closed_at":"2025-11-20T20:39:34.426726-05:00","source_repo":"."} +{"id":"bd-g3ey","content_hash":"e59ecb28d0ceade96c076688de71f5d0022a9b0c0676f3abb1e4e06d90f8f559","title":"bd sync --import-only doesn't update DB mtime causing bd doctor false warning","description":"","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-08T15:18:16.761052+01:00","updated_at":"2025-11-11T08:42:35.015616264-07:00","closed_at":"2025-11-08T13:12:01.718252-08:00","source_repo":"."} +{"id":"bd-g5p7","content_hash":"6ef3578afcab8a96c6018ec27f64d36df05b32fe867ad50b5309cdefe6b7f486","title":"Extract duplicated validation logic from CLI commands","description":"~150 lines of identical validation logic duplicated between cmd_create.go and cmd_update.go\n\nDuplication found:\n- validateBeadFields(): 2 identical copies (50+ lines each) \n- parseTimeWithDefault(): 2 identical copies (30 lines each)\n- Flag definitions: 15+ duplicate registrations\n\nSolution: Extract to shared packages:\n- internal/validation/bead.go - Centralized validation\n- internal/utils/time.go - Consolidate time parsing (already exists)\n- cmd/bd/flags.go - Shared flag registration\n\nImpact: Changes require touching 2+ files; high risk of inconsistency; steep learning curve\n\nEffort: 4-6 hours","status":"closed","priority":0,"issue_type":"task","created_at":"2025-11-16T14:51:10.159953-08:00","updated_at":"2025-11-20T20:39:34.426726-05:00","closed_at":"2025-11-20T20:39:34.426726-05:00","source_repo":"."} {"id":"bd-g9eu","content_hash":"79fe2f96d06e3f0750b55f323bc104b02de6ab8a745e0bd36cf3425e125af89c","title":"Investigate TestRoutingIntegration failure","description":"TestRoutingIntegration/maintainer_with_SSH_remote failed during pre-commit check with \"expected role maintainer, got contributor\".\nThis occurred while running `go test -short ./...` on darwin/arm64.\nThe failure appears unrelated to storage/sqlite changes.\nNeed to investigate if this is a flaky test or environmental issue.","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T15:55:19.337094-08:00","updated_at":"2025-11-20T15:55:19.337094-08:00","source_repo":"."} {"id":"bd-gart","content_hash":"c4b3d68ec7d85a26e9c23ef529e4479b4741eade511d17f8f3602d412b0b3f0a","title":"Debug test 2","description":"","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-08T00:04:35.317835-08:00","updated_at":"2025-11-08T00:06:46.18875-08:00","closed_at":"2025-11-08T00:06:46.18875-08:00","source_repo":"."} -{"id":"bd-gdn","content_hash":"3411b7c03ec961d665181fbffa8f8b98a7809e296013786e743e371e92e9dc58","title":"Add functional tests for FlushManager correctness verification","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-20T21:21:53.967757-05:00","updated_at":"2025-11-20T21:35:53.1183-05:00","closed_at":"2025-11-20T21:35:53.1183-05:00","source_repo":".","comments":[{"id":39,"issue_id":"bd-gdn","author":"stevey","text":"Current race detector tests only verify \"no race detected\" but don't verify data correctness.\n\nNeed functional tests that:\n- Create real SQLite store with test data\n- Mark issues dirty and trigger flush\n- Verify JSONL file was updated correctly\n- Test debouncing actually reduces flush count\n- Verify shutdown performs final flush\n- Test recovery after flush failures\n\nExample test structure:\n```go\nfunc TestFlushManagerActuallyFlushes(t *testing.T) {\n // Setup real SQLite store in temp dir\n // Create test issue\n // Mark dirty via FlushManager\n // Wait for debounce + flush\n // Read JSONL file\n // Verify issue appears in JSONL with correct data\n}\n```\n\nRelated: Code review finding #3 from bd-52 race condition fix review.","created_at":"2025-11-22T07:53:00Z"}]} +{"id":"bd-gdn","content_hash":"3411b7c03ec961d665181fbffa8f8b98a7809e296013786e743e371e92e9dc58","title":"Add functional tests for FlushManager correctness verification","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-20T21:21:53.967757-05:00","updated_at":"2025-11-20T21:35:53.1183-05:00","closed_at":"2025-11-20T21:35:53.1183-05:00","source_repo":".","comments":[{"id":12,"issue_id":"bd-gdn","author":"stevey","text":"Current race detector tests only verify \"no race detected\" but don't verify data correctness.\n\nNeed functional tests that:\n- Create real SQLite store with test data\n- Mark issues dirty and trigger flush\n- Verify JSONL file was updated correctly\n- Test debouncing actually reduces flush count\n- Verify shutdown performs final flush\n- Test recovery after flush failures\n\nExample test structure:\n```go\nfunc TestFlushManagerActuallyFlushes(t *testing.T) {\n // Setup real SQLite store in temp dir\n // Create test issue\n // Mark dirty via FlushManager\n // Wait for debounce + flush\n // Read JSONL file\n // Verify issue appears in JSONL with correct data\n}\n```\n\nRelated: Code review finding #3 from bd-52 race condition fix review.","created_at":"2025-11-21T13:58:10Z"}]} {"id":"bd-gdzd","content_hash":"54a68b8b4c63fd88b33dbf8239de070a3c95f97d4a0aa5f64e694ff1384199b3","title":"Import fails on same-content-different-ID instead of treating as update","description":"## Problem\n\nThe importer still has rename detection (importer.go:482-500) that triggers when same content hash has different IDs. With hash IDs, this shouldn't happen, but when it does (test data, bugs, legacy data), the import fails:\n\n```\nfailed to handle rename bd-ce75 -\u003e bd-5a90: rename collision handling removed - should not occur with hash IDs\n```\n\n## Current Behavior\n\n1. Importer finds same content hash with different IDs\n2. Calls handleRename() (line 490)\n3. handleRename() errors out (line 294): \"rename collision handling removed\"\n4. Import fails\n\n## Expected Behavior\n\nSame content hash + different IDs should be treated as an **update**, not a rename:\n- Keep existing ID (already in database)\n- Update fields if incoming has newer timestamp\n- Discard incoming ID (it's wrong - hash should have generated same ID)\n\n## Impact\n\n- Import fails on legitimate edge cases (test data, data corruption)\n- Cryptic error message\n- Blocks sync operations\n\n## Fix\n\nIn handleRename() or import loop, instead of erroring:\n```go\n// Same content, different ID - treat as update\nif incoming.UpdatedAt.After(existing.UpdatedAt) {\n existing.Status = incoming.Status\n // ... copy other fields\n s.UpdateIssue(ctx, existing)\n}\nresult.Updated++\n```\n\n## Files\n- internal/importer/importer.go:271-294 (handleRename)\n- internal/importer/importer.go:482-500 (rename detection)\n\n## Repro\nImport JSONL with bd-ce75 and bd-5a90 (both \"Test parent issue\" but different content hashes).","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-05T00:27:51.150233-08:00","updated_at":"2025-11-05T01:02:54.469971-08:00","closed_at":"2025-11-05T01:02:54.469979-08:00","source_repo":"."} {"id":"bd-ge7","content_hash":"84248781654b9924e1f4284058f141b73d761dead05ef9a3d1cc9b9f8cd4b60d","title":"Improve Beads test coverage from 46% to 80%","description":"","design":"Currently at 46% test coverage. Need to systematically improve coverage across all subsystems, focusing first on packages with minimal or no tests.\n\nTarget: 80% overall coverage\n\nApproach:\n- Break down by subsystem (internal/* packages)\n- Prioritize packages with 0-1 test files\n- Each child issue targets specific coverage goals\n- Focus on unit tests for core logic, error paths, and edge cases\n\nThis epic will be executed by the VC executor to test its ability to handle sustained multi-issue work.","acceptance_criteria":"- Overall test coverage reaches 80% or higher\n- All internal/* packages have at least 60% coverage\n- All packages with only 1 test file now have at least 3 test files\n- Quality gates (go test, golangci-lint) pass\n- Tests are maintainable and test actual behavior, not implementation details","status":"open","priority":1,"issue_type":"epic","created_at":"2025-11-20T21:21:03.700271-05:00","updated_at":"2025-11-20T21:21:03.700271-05:00","source_repo":"."} {"id":"bd-ggbc","content_hash":"bfb238f72474f25fcf132603ae45e6c97c7c1e60ad865062bff75f32f54a9135","title":"Update documentation for merge driver auto-config","description":"Update documentation to reflect the new merge driver auto-configuration during `bd init`.\n\n**Files to update:**\n- README.md - Mention merge driver setup in initialization section\n- AGENTS.md - Update onboarding section about merge driver\n- Possibly QUICKSTART.md\n\n**Content:**\n- Explain what the merge driver does\n- Show --skip-merge-driver flag usage\n- Manual installation steps for post-init setup","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-05T19:27:04.155662-08:00","updated_at":"2025-11-05T19:29:55.188122-08:00","closed_at":"2025-11-05T19:29:55.188122-08:00","source_repo":".","dependencies":[{"issue_id":"bd-ggbc","depends_on_id":"bd-32nm","type":"discovered-from","created_at":"2025-11-05T19:27:04.156491-08:00","created_by":"daemon"}]} @@ -483,7 +484,7 @@ {"id":"bd-hv01","content_hash":"293d9078e613afae960df6681f8c8d7a5f6ba28ddd2708e9c7af2010ef76b407","title":"Deletions not propagated across multi-workspace sync","description":"## Problem\n\nWhen working with multiple beads workspaces (clones) sharing the same git remote, deleted issues keep coming back.\n\n## Reproduction\n\n1. Clone A deletes issue `bd-xyz` via `bd delete bd-xyz --force`\n2. Clone A daemon syncs and pushes to GitHub\n3. Clone B still has `bd-xyz` in its database\n4. Clone B daemon exports and pushes its JSONL\n5. Clone A pulls and imports → `bd-xyz` comes back!\n\n## Root Cause\n\n**No deletion tracking mechanism.** The system has no way to distinguish between:\n- \"Issue doesn't exist in JSONL because it was deleted\" \n- \"Issue doesn't exist in JSONL because the export is stale\"\n\nImport treats missing issues as \"not in this export\" rather than \"explicitly deleted.\"\n\n## Solution Options\n\n1. **Tombstone records** - Keep deleted issues in JSONL with `\"status\":\"deleted\"` or `\"deleted_at\"` field\n2. **Deletion log** - Separate `.beads/deletions.jsonl` file tracking all deleted IDs\n3. **Three-way merge** - Import compares: DB state, old JSONL, new JSONL\n4. **Manual conflict resolution** - Detect resurrection and prompt user\n\n## Related\n\n- Similar to resurrection logic for orphaned children (bd-cc4f)\n- beads-merge tool handles this better with 3-way merge","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-05T18:34:24.094474-08:00","updated_at":"2025-11-06T18:19:16.233949-08:00","closed_at":"2025-11-06T17:52:24.860716-08:00","source_repo":".","dependencies":[{"issue_id":"bd-hv01","depends_on_id":"bd-qqvw","type":"blocks","created_at":"2025-11-05T18:42:35.485002-08:00","created_by":"daemon"}]} {"id":"bd-hw3c","content_hash":"83359ec96e2b8fc9ce2ece25d56bfbc1c1f948b27dfa56cc7b3715dc86c6d024","title":"Fix GH #227: bd edit broken pipe errors","description":"bd edit command gets \"broken pipe\" errors when using daemon mode because editing can take minutes and the daemon connection times out.\n\nSolution: Force bd edit to always use direct mode (--no-daemon) since it's human-only and interactive.\n\nFixed by checking cmd.Name() == \"edit\" in main.go PersistentPreRun and setting noDaemon = true.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-05T14:36:04.289431-08:00","updated_at":"2025-11-05T14:36:08.103964-08:00","closed_at":"2025-11-05T14:36:08.103964-08:00","source_repo":"."} {"id":"bd-hy9p","content_hash":"338c8d09c267dbca4b25d2ee0c5e6f130d94360a59597c3ecb4f1b64308d208b","title":"Add --body-file flag to bd create for reading descriptions from files","description":"## Problem\n\nCreating issues with long/complex descriptions via CLI requires shell escaping gymnastics:\n\n```bash\n# Current workaround - awkward heredoc quoting\nbd create --title=\"...\" --description=\"$(cat \u003c\u003c'EOF'\n...markdown...\nEOF\n)\"\n\n# Often fails with quote escaping errors in eval context\n# Agents resort to writing temp files then reading them\n```\n\n## Proposed Solution\n\nAdd `--body-file` and `--description-file` flags to read description from a file, matching `gh` CLI pattern.\n\n```bash\n# Natural pattern that aligns with training data\ncat \u003e /tmp/desc.md \u003c\u003c 'EOF'\n...markdown content...\nEOF\n\nbd create --title=\"...\" --body-file=/tmp/desc.md\n```\n\n## Implementation\n\n### 1. Add new flags to `bd create`\n\n```go\ncreateCmd.Flags().String(\"body-file\", \"\", \"Read description from file (use - for stdin)\")\ncreateCmd.Flags().String(\"description-file\", \"\", \"Alias for --body-file\")\n```\n\n### 2. Flag precedence\n\n- If `--body-file` or `--description-file` is provided, read from file\n- If value is `-`, read from stdin\n- Otherwise fall back to `--body` or `--description` flag\n- If neither provided, description is empty (current behavior)\n\n### 3. Error handling\n\n- File doesn't exist → clear error message\n- File not readable → clear error message\n- stdin specified but not available → clear error message\n\n## Benefits\n\n✅ **Matches training data**: `gh issue create --body-file file.txt` is a common pattern\n✅ **No shell escaping issues**: File content is read directly\n✅ **Works with any content**: Markdown, special characters, quotes, etc.\n✅ **Agent-friendly**: Agents already write complex content to temp files\n✅ **User-friendly**: Easier for humans too when pasting long descriptions\n\n## Related Commands\n\nConsider adding similar support to:\n- `bd update --body-file` (for updating descriptions)\n- `bd comment --body-file` (if/when we add comments)\n\n## Examples\n\n```bash\n# From file\nbd create --title=\"Add new feature\" --body-file=feature.md\n\n# From stdin\necho \"Quick description\" | bd create --title=\"Bug fix\" --body-file=-\n\n# With other flags\nbd create \\\n --title=\"Security issue\" \\\n --type=bug \\\n --priority=0 \\\n --body-file=security-report.md \\\n --label=security\n```\n\n## Testing\n\n- Test with normal files\n- Test with stdin (`-`)\n- Test with non-existent files (error handling)\n- Test with binary files (should handle gracefully)\n- Test with empty files (valid - empty description)\n- Test that `--description-file` and `--body-file` are equivalent aliases","status":"open","priority":1,"issue_type":"feature","created_at":"2025-11-22T00:02:08.762684-08:00","updated_at":"2025-11-22T00:02:08.762684-08:00","source_repo":"."} -{"id":"bd-i00","content_hash":"eb91d1bd82defffa773c7706f4094ca1a322f1e7be017aebc91fd7eb8e6b7aad","title":"Convert magic numbers to named constants in FlushManager","description":"","status":"closed","priority":4,"issue_type":"task","created_at":"2025-11-20T21:22:17.845269-05:00","updated_at":"2025-11-20T21:35:53.11654-05:00","closed_at":"2025-11-20T21:35:53.11654-05:00","source_repo":".","comments":[{"id":40,"issue_id":"bd-i00","author":"stevey","text":"Several magic numbers should be named constants for clarity and maintainability:\n\nflush_manager.go:\n- Line 64: `10` (markDirtyCh buffer size)\n- Line 65: `1` (timerFiredCh buffer size)\n- Line 139: `30 * time.Second` (shutdown timeout)\n\nautoflush.go:\n- Line 562: `3` (flush failure threshold before warning)\n\nSuggested constants:\n```go\nconst (\n markDirtyBufferSize = 10 // Buffer rapid mark requests\n timerFiredBufferSize = 1 // Timer notifications coalesce\n shutdownTimeout = 30 * time.Second // Generous for large DBs\n flushFailureThreshold = 3 // Show warning after N failures\n)\n```\n\nRelated: Code review finding #6 from bd-52 race condition fix review.","created_at":"2025-11-22T07:53:00Z"}]} +{"id":"bd-i00","content_hash":"eb91d1bd82defffa773c7706f4094ca1a322f1e7be017aebc91fd7eb8e6b7aad","title":"Convert magic numbers to named constants in FlushManager","description":"","status":"closed","priority":4,"issue_type":"task","created_at":"2025-11-20T21:22:17.845269-05:00","updated_at":"2025-11-20T21:35:53.11654-05:00","closed_at":"2025-11-20T21:35:53.11654-05:00","source_repo":".","comments":[{"id":13,"issue_id":"bd-i00","author":"stevey","text":"Several magic numbers should be named constants for clarity and maintainability:\n\nflush_manager.go:\n- Line 64: `10` (markDirtyCh buffer size)\n- Line 65: `1` (timerFiredCh buffer size)\n- Line 139: `30 * time.Second` (shutdown timeout)\n\nautoflush.go:\n- Line 562: `3` (flush failure threshold before warning)\n\nSuggested constants:\n```go\nconst (\n markDirtyBufferSize = 10 // Buffer rapid mark requests\n timerFiredBufferSize = 1 // Timer notifications coalesce\n shutdownTimeout = 30 * time.Second // Generous for large DBs\n flushFailureThreshold = 3 // Show warning after N failures\n)\n```\n\nRelated: Code review finding #6 from bd-52 race condition fix review.","created_at":"2025-11-21T13:58:10Z"}]} {"id":"bd-ic1m","content_hash":"b837a8183ba2b636a3116deb35aa96d99fee84eabdfc8f8d93a91415c3ff4490","title":"Benchmark git traffic reduction","description":"Automated benchmark comparing git operations with/without Agent Mail.\n\nAcceptance Criteria:\n- Script that processes 50 issues\n- Counts git operations (pull, commit, push)\n- Generates comparison report\n- Verifies ≥70% reduction\n- Fails if regression detected\n\nFile: tests/benchmarks/git_traffic.py\n\nOutput: Without Agent Mail: 450 git operations, With Agent Mail: 135 git operations, Reduction: 70%","notes":"Implemented automated benchmark script with following features:\n- Processes configurable number of issues (default 50)\n- Compares git operations in two modes: git-only vs Agent Mail\n- Generates detailed comparison report with statistics\n- Exit code reflects pass/fail based on 70% reduction target\n- Results: 98.5% reduction (200 ops → 3 ops) for 50 issues\n\nFiles created:\n- tests/benchmarks/git_traffic.py (main benchmark script)\n- tests/benchmarks/README.md (documentation)\n- tests/benchmarks/git_traffic_50_issues.md (sample results)\n\nThe benchmark vastly exceeds the 70% target, showing 98.5% reduction.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-07T22:43:21.486095-08:00","updated_at":"2025-11-08T02:08:19.648473-08:00","closed_at":"2025-11-08T02:08:19.648473-08:00","source_repo":".","dependencies":[{"issue_id":"bd-ic1m","depends_on_id":"bd-fzbg","type":"blocks","created_at":"2025-11-07T22:43:21.486966-08:00","created_by":"daemon"},{"issue_id":"bd-ic1m","depends_on_id":"bd-nemp","type":"blocks","created_at":"2025-11-07T22:43:21.487388-08:00","created_by":"daemon"}]} {"id":"bd-ihp9","content_hash":"e66bdd32aeb5a67440da6cb06bec0da001d28f123c34c2559352f7c98a6b2381","title":"Fix FOREIGN KEY constraint failures in AddComment and ApplyCompaction","description":"The 'CloseIssue', 'UpdateIssueID', and 'RemoveLabel' methods were fixed in PR #348 to prevent foreign key constraint failures when operating on non-existent issues.\n\nHowever, the Oracle identified two other methods that follow the same problematic pattern:\n1. `AddComment` (in `internal/storage/sqlite/events.go`)\n2. `ApplyCompaction` (in `internal/storage/sqlite/compact.go`)\n\nThese methods attempt to insert an event record after updating the issue, without verifying that the issue update actually affected any rows. This leads to a foreign key constraint failure if the issue does not exist.\n\nWe need to:\n1. Create reproduction tests for these failure cases\n2. Apply the same fix pattern: check `RowsAffected()` after the update, and return a proper \"issue not found\" error if it is 0, before attempting to insert the event.\n3. Standardize the error message format to \"issue %s not found\" or \"issue not found: %s\" for consistency.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T09:49:55.090644-08:00","updated_at":"2025-11-20T09:53:54.466769-08:00","closed_at":"2025-11-20T09:53:54.466769-08:00","source_repo":"."} {"id":"bd-iou5","content_hash":"4aaf92c783a9ff8acc47ec4a03409cfb9df9259ff73b184013422445bbd10932","title":"Detect and warn about outdated git hooks","description":"Users may have outdated git hooks installed that reference removed flags (e.g., --resolve-collisions). bd should detect this and warn users to reinstall.","design":"\n- Add version comments to hook templates (e.g., # bd-hooks-v0.21.0)\n- Check during 'bd info' or 'bd daemon start' (not every command to avoid overhead)\n- Compare installed hook version against current bd version\n- Warn with clear message: 'Git hooks are outdated (v0.X.Y), run: examples/git-hooks/install.sh'\n- Could also check if hooks exist but aren't installed at all","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-06T13:59:45.778781-08:00","updated_at":"2025-11-06T15:02:16.928192-08:00","closed_at":"2025-11-06T15:02:16.928192-08:00","source_repo":"."} @@ -496,15 +497,15 @@ {"id":"bd-j7e2","content_hash":"aeb3aec5ebb3b7554949f7161f58408c445983c993aaa5b31e4df93b083cf19c","title":"RPC diagnostics: BD_RPC_DEBUG timing logs","description":"Add lightweight diagnostic logging for RPC connection attempts:\n- BD_RPC_DEBUG=1 prints to stderr:\n - Socket path being dialed\n - Socket exists check result \n - Dial start/stop time\n - Connection outcome\n- Improve bd daemon --status messaging when lock not held\n\nThis helps field triage of connection issues without verbose daemon logs.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-07T16:42:12.772364-08:00","updated_at":"2025-11-07T22:07:17.346817-08:00","closed_at":"2025-11-07T21:29:32.243458-08:00","source_repo":".","dependencies":[{"issue_id":"bd-j7e2","depends_on_id":"bd-ndyz","type":"discovered-from","created_at":"2025-11-07T16:42:12.773714-08:00","created_by":"daemon"}]} {"id":"bd-jgxi","content_hash":"9af80db7f04944bbc55f2d77e3576028c553c936e9d40266ccbf169eec47eb9f","title":"Auto-migrate database on CLI version bump","description":"When CLI is upgraded (e.g., 0.24.0 → 0.24.1), database version becomes stale. Add auto-migration in PersistentPreRun or daemon startup. Check dbVersion != CLIVersion and run bd migrate automatically. Fixes recurring UX issue where bd doctor shows version mismatch after every CLI upgrade.","status":"open","priority":0,"issue_type":"feature","created_at":"2025-11-21T23:16:09.004619-08:00","updated_at":"2025-11-21T23:16:27.229388-08:00","source_repo":".","dependencies":[{"issue_id":"bd-jgxi","depends_on_id":"bd-tbz3","type":"parent-child","created_at":"2025-11-21T23:16:09.005513-08:00","created_by":"daemon"}]} {"id":"bd-jijf","content_hash":"9ecadb3d67b00337d8822ace5378edfe9b3baaa4e64a9e7edc5a2b43d82d9caf","title":"Fix: --parent flag doesn't create parent-child dependency","description":"When using `bd create --parent \u003cid\u003e`, the code generates a hierarchical child ID (e.g., bd-123.1) but never creates a parent-child dependency. This causes `bd epic status` to show zero children even though child issues exist.\n\nRoot cause: create.go generates child ID using store.GetNextChildID() but never calls store.AddDependency() with type parent-child.\n\nFix: After creating the issue when parentID is set, automatically add a parent-child dependency linking child -\u003e parent.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-15T13:15:22.138854-08:00","updated_at":"2025-11-15T13:18:29.301788-08:00","closed_at":"2025-11-15T13:18:29.301788-08:00","source_repo":"."} -{"id":"bd-jjua","content_hash":"40e73380589198a2e43bc484c7d55dd1d3bef620dbc1529ddaf54ca9282284e4","title":"Auto-invoke 3-way merge for JSONL conflicts","description":"Currently when git pull encounters merge conflicts in .beads/issues.jsonl, the post-merge hook fails with an error message pointing users to manual resolution or the beads-merge tool.\n\nThis is a poor user experience - the conflict detection is working, but we should automatically invoke the advanced 3-way merging instead of just telling users about it.\n\n**Current behavior:**\n- Detect conflict markers in JSONL\n- Display error with manual resolution options\n- Exit with failure\n\n**Desired behavior:**\n- Detect conflict markers in JSONL\n- Automatically invoke beads-merge 3-way merge\n- Only fail if automatic merge cannot resolve the conflicts\n\n**Reference:**\n- beads-merge tool: https://github.com/neongreen/mono/tree/main/beads-merge\n- Error occurs in post-merge hook during bd sync after git pull","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-08T03:09:18.258708-08:00","updated_at":"2025-11-08T03:15:55.529652-08:00","closed_at":"2025-11-08T03:15:55.529652-08:00","source_repo":".","comments":[{"id":31,"issue_id":"bd-jjua","author":"stevey","text":"Implemented automatic 3-way merge resolution for JSONL conflicts.\n\n**Changes Made:**\n\n1. **Modified conflict detection in cmd/bd/import.go (lines 105-152)**\n - When git conflict markers are detected, instead of immediately failing, the system now attempts automatic resolution\n - Calls new `attemptAutoMerge()` function to invoke bd merge tool\n - If auto-merge succeeds, restarts import with the merged JSONL\n - If auto-merge fails, falls back to displaying manual resolution instructions\n\n2. **Added attemptAutoMerge() function (lines 469-585)**\n - Extracts the three git conflict stages: base (:1), ours/left (:2), theirs/right (:3)\n - Creates temporary files for each version\n - Invokes `bd merge` command to perform intelligent 3-way merge\n - Writes merged result back to original file\n - Auto-stages the resolved file with git add\n\n**How it works:**\n- When git pull creates conflicts in .beads/issues.jsonl\n- The post-merge hook runs `bd sync --import-only`\n- Import detects conflict markers on line scan\n- Automatically extracts conflict versions from git\n- Runs bd merge tool with field-level merge intelligence\n- If successful, continues import seamlessly\n- Only fails if conflicts cannot be auto-resolved\n\n**Benefits:**\n- Zero user intervention for most JSONL conflicts\n- Leverages existing bd merge 3-way merge logic\n- Maintains data integrity with field-level merging\n- Graceful fallback to manual resolution when needed\n\n**Testing:**\n- Code builds successfully\n- Ready for real-world testing on next git pull conflict\n\nThe solution transforms the error into an automatic resolution step, significantly improving user experience.","created_at":"2025-11-22T07:09:48Z"},{"id":32,"issue_id":"bd-jjua","author":"stevey","text":"**Discovery: Git merge driver was already configured but not being triggered**\n\nThe 3-way merge tool was properly vendored and `bd init` does configure the git merge driver:\n- `git config merge.beads.driver \"bd merge %A %O %L %R\"`\n- `.gitattributes` entry for `.beads/beads.jsonl merge=beads`\n\nThis should have prevented conflicts entirely by auto-invoking `bd merge` during git merge operations.\n\n**Root Cause:**\nHowever, the automatic merge driver doesn't help when conflicts reach the import stage, which happens in the post-merge hook flow:\n1. Git pull encounters conflicts\n2. Post-merge hook runs `bd sync --import-only`\n3. Import reads the JSONL file and detects conflict markers\n4. Previous behavior: fail with error message\n\nThe merge driver prevents conflicts during git operations, but if conflicts somehow make it through (or if the merge driver itself produces conflicts that it can't resolve), the import process needed fallback handling.\n\n**Our Solution:**\nAdded automatic 3-way merge invocation at the import stage as a safety net. This provides defense-in-depth:\n- Primary: git merge driver prevents most conflicts\n- Fallback: import auto-merge handles any that slip through\n\n**Bonus Discovery:**\nFound that `.beads/issues.jsonl` is a zombie file that keeps reappearing despite multiple removal attempts in git history. Renamed it to `.beads/issues.jsonl.zombie-do-not-use` with a warning message. The canonical file is `.beads/beads.jsonl`.","created_at":"2025-11-22T07:09:48Z"}]} +{"id":"bd-jjua","content_hash":"40e73380589198a2e43bc484c7d55dd1d3bef620dbc1529ddaf54ca9282284e4","title":"Auto-invoke 3-way merge for JSONL conflicts","description":"Currently when git pull encounters merge conflicts in .beads/issues.jsonl, the post-merge hook fails with an error message pointing users to manual resolution or the beads-merge tool.\n\nThis is a poor user experience - the conflict detection is working, but we should automatically invoke the advanced 3-way merging instead of just telling users about it.\n\n**Current behavior:**\n- Detect conflict markers in JSONL\n- Display error with manual resolution options\n- Exit with failure\n\n**Desired behavior:**\n- Detect conflict markers in JSONL\n- Automatically invoke beads-merge 3-way merge\n- Only fail if automatic merge cannot resolve the conflicts\n\n**Reference:**\n- beads-merge tool: https://github.com/neongreen/mono/tree/main/beads-merge\n- Error occurs in post-merge hook during bd sync after git pull","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-08T03:09:18.258708-08:00","updated_at":"2025-11-08T03:15:55.529652-08:00","closed_at":"2025-11-08T03:15:55.529652-08:00","source_repo":".","comments":[{"id":6,"issue_id":"bd-jjua","author":"stevey","text":"Implemented automatic 3-way merge resolution for JSONL conflicts.\n\n**Changes Made:**\n\n1. **Modified conflict detection in cmd/bd/import.go (lines 105-152)**\n - When git conflict markers are detected, instead of immediately failing, the system now attempts automatic resolution\n - Calls new `attemptAutoMerge()` function to invoke bd merge tool\n - If auto-merge succeeds, restarts import with the merged JSONL\n - If auto-merge fails, falls back to displaying manual resolution instructions\n\n2. **Added attemptAutoMerge() function (lines 469-585)**\n - Extracts the three git conflict stages: base (:1), ours/left (:2), theirs/right (:3)\n - Creates temporary files for each version\n - Invokes `bd merge` command to perform intelligent 3-way merge\n - Writes merged result back to original file\n - Auto-stages the resolved file with git add\n\n**How it works:**\n- When git pull creates conflicts in .beads/issues.jsonl\n- The post-merge hook runs `bd sync --import-only`\n- Import detects conflict markers on line scan\n- Automatically extracts conflict versions from git\n- Runs bd merge tool with field-level merge intelligence\n- If successful, continues import seamlessly\n- Only fails if conflicts cannot be auto-resolved\n\n**Benefits:**\n- Zero user intervention for most JSONL conflicts\n- Leverages existing bd merge 3-way merge logic\n- Maintains data integrity with field-level merging\n- Graceful fallback to manual resolution when needed\n\n**Testing:**\n- Code builds successfully\n- Ready for real-world testing on next git pull conflict\n\nThe solution transforms the error into an automatic resolution step, significantly improving user experience.","created_at":"2025-11-11T15:42:35Z"},{"id":7,"issue_id":"bd-jjua","author":"stevey","text":"**Discovery: Git merge driver was already configured but not being triggered**\n\nThe 3-way merge tool was properly vendored and `bd init` does configure the git merge driver:\n- `git config merge.beads.driver \"bd merge %A %O %L %R\"`\n- `.gitattributes` entry for `.beads/beads.jsonl merge=beads`\n\nThis should have prevented conflicts entirely by auto-invoking `bd merge` during git merge operations.\n\n**Root Cause:**\nHowever, the automatic merge driver doesn't help when conflicts reach the import stage, which happens in the post-merge hook flow:\n1. Git pull encounters conflicts\n2. Post-merge hook runs `bd sync --import-only`\n3. Import reads the JSONL file and detects conflict markers\n4. Previous behavior: fail with error message\n\nThe merge driver prevents conflicts during git operations, but if conflicts somehow make it through (or if the merge driver itself produces conflicts that it can't resolve), the import process needed fallback handling.\n\n**Our Solution:**\nAdded automatic 3-way merge invocation at the import stage as a safety net. This provides defense-in-depth:\n- Primary: git merge driver prevents most conflicts\n- Fallback: import auto-merge handles any that slip through\n\n**Bonus Discovery:**\nFound that `.beads/issues.jsonl` is a zombie file that keeps reappearing despite multiple removal attempts in git history. Renamed it to `.beads/issues.jsonl.zombie-do-not-use` with a warning message. The canonical file is `.beads/beads.jsonl`.","created_at":"2025-11-11T15:42:35Z"}]} {"id":"bd-jo38","content_hash":"05e0df789df0a8056258cc1594c3f695d77bb735f2b2ae694d8fbb7c14c51bc9","title":"Add WaitGroup tracking to FileWatcher goroutines","description":"FileWatcher spawns goroutines without WaitGroup tracking, causing race condition on shutdown.\n\nLocation: cmd/bd/daemon_watcher.go:123-182, 215-291\n\nProblem:\n- Goroutines spawned without sync.WaitGroup\n- Close() cancels context but doesn't wait for goroutines to exit\n- Race condition: goroutine may access fw.debouncer during Close() cleanup\n- No guarantee goroutine stopped before fw.watcher.Close() is called\n\nSolution:\n- Add sync.WaitGroup field to FileWatcher\n- Track goroutines with wg.Add(1) and defer wg.Done()\n- Call wg.Wait() in Close() before cleanup\n\nImpact: Race condition on daemon shutdown; potential panic\n\nEffort: 2 hours","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-16T14:51:38.591371-08:00","updated_at":"2025-11-16T15:04:00.466334-08:00","closed_at":"2025-11-16T15:04:00.466334-08:00","source_repo":"."} {"id":"bd-jx90","content_hash":"3dfa306c43d7febfbd072d4bb5c1b6018f8a7301380bb128f53abb0eca5deb65","title":"Add simple cleanup command to delete closed issues","description":"Users want a simple command to delete all closed issues without requiring Anthropic API key (unlike compact). Requested in GH #243.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-07T00:26:30.372137-08:00","updated_at":"2025-11-07T22:07:17.347122-08:00","closed_at":"2025-11-07T22:05:16.325863-08:00","source_repo":"."} {"id":"bd-k0j9","content_hash":"52d1e6f87bd7655018bd89dbbbaf8da66bdcba45de6138fd237810365a04606a","title":"Test dependency parent","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-05T11:23:02.505901-08:00","updated_at":"2025-11-05T11:23:20.91305-08:00","closed_at":"2025-11-05T11:23:20.91305-08:00","source_repo":"."} {"id":"bd-k58","content_hash":"cc90fb20e7bd178b52133d4d0f8781dce2debb46519674ae6356291d597fc13d","title":"Proposal workflow (propose/withdraw/accept)","description":"Implement commands and state machine for moving issues between personal planning repos and canonical upstream repos, enabling contributors to propose work without polluting PRs.","design":"Commands:\n- bd propose \u003cid\u003e [--target \u003crepo\u003e] - Move issue to target repo\n- bd withdraw \u003cid\u003e - Un-propose (move back)\n- bd accept \u003cid\u003e - Maintainer accepts proposal\n\nVisibility states:\n- local: Personal planning only\n- proposed: Staged for upstream PR\n- canonical: Accepted by upstream (default for existing)\n\nOptional visibility field (backward compatible, defaults to canonical)","acceptance_criteria":"1. bd propose moves issue from planning to primary repo\n2. bd withdraw reverses proposal\n3. bd accept (maintainer) finalizes acceptance\n4. Visibility field tracks state (local/proposed/canonical)\n5. Backward compatible - existing issues default to canonical\n6. State transitions are atomic and git-tracked","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-04T11:21:41.113647-08:00","updated_at":"2025-11-05T00:08:42.814698-08:00","closed_at":"2025-11-05T00:08:42.814699-08:00","source_repo":".","dependencies":[{"issue_id":"bd-k58","depends_on_id":"bd-4ms","type":"parent-child","created_at":"2025-11-04T11:22:21.811261-08:00","created_by":"daemon"}]} {"id":"bd-kazt","content_hash":"83b14f6b183318f85ae852db1caa593d5f6592a00b168ae057bb31238701d4fa","title":"Add tests for 3-way merge scenarios","description":"Comprehensive test coverage for merge logic.\n\n**Test cases**:\n- Simple field updates (left vs right)\n- Dependency merging (union + dedup)\n- Timestamp handling (max wins)\n- Deletion detection (deleted in one, modified in other)\n- Conflict generation (incompatible changes)\n- Issue resurrection prevention (bd-hv01 regression test)\n\n**Files**:\n- `internal/merge/merge_test.go`\n- `cmd/bd/merge_test.go`","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-05T18:42:20.472275-08:00","updated_at":"2025-11-06T15:52:41.863426-08:00","closed_at":"2025-11-06T15:52:41.863426-08:00","source_repo":".","dependencies":[{"issue_id":"bd-kazt","depends_on_id":"bd-qqvw","type":"parent-child","created_at":"2025-11-05T18:42:28.740517-08:00","created_by":"daemon"},{"issue_id":"bd-kazt","depends_on_id":"bd-oif6","type":"blocks","created_at":"2025-11-05T18:42:35.469582-08:00","created_by":"daemon"}]} -{"id":"bd-kb4g","content_hash":"e68405211ed698918001dc1354242971a604bc140a026580f24e2a472747ff8c","title":"TestHooksCheckGitHooks failing - version mismatch (0.23.0 vs 0.23.1)","description":"The test is checking embedded hook versions and expecting 0.23.1, but got 0.23.0. This appears to be a version consistency issue that needs investigation.\n\nTest output:\n```\nHook pre-commit version mismatch: got 0.23.0, want 0.23.1\nHook post-merge version mismatch: got 0.23.0, want 0.23.1\nHook pre-push version mismatch: got 0.23.0, want 0.23.1\n```\n\nThis is blocking the landing of GH #274 fix.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-09T14:13:14.138537-08:00","updated_at":"2025-11-20T18:54:56.496852-05:00","closed_at":"2025-11-10T10:46:09.94181-08:00","source_repo":"."} +{"id":"bd-kb4g","content_hash":"e68405211ed698918001dc1354242971a604bc140a026580f24e2a472747ff8c","title":"TestHooksCheckGitHooks failing - version mismatch (0.23.0 vs 0.23.1)","description":"The test is checking embedded hook versions and expecting 0.23.1, but got 0.23.0. This appears to be a version consistency issue that needs investigation.\n\nTest output:\n```\nHook pre-commit version mismatch: got 0.23.0, want 0.23.1\nHook post-merge version mismatch: got 0.23.0, want 0.23.1\nHook pre-push version mismatch: got 0.23.0, want 0.23.1\n```\n\nThis is blocking the landing of GH #274 fix.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-09T14:13:14.138537-08:00","updated_at":"2025-11-22T15:18:47.461872301-07:00","closed_at":"2025-11-10T10:46:09.94181-08:00","source_repo":"."} {"id":"bd-kdoh","content_hash":"e017424d5478bc870b37142dba22ab2a4a863819d5d399b9224cc8992a0411b4","title":"Add tests for getMultiRepoJSONLPaths() edge cases","description":"From bd-xo6b code review: Missing test coverage for getMultiRepoJSONLPaths() edge cases.\n\nCurrent test gaps:\n- No tests for empty paths in config\n- No tests for duplicate paths\n- No tests for tilde expansion\n- No tests for relative paths\n- No tests for symlinks\n- No tests for paths with spaces\n- No tests for invalid/non-existent paths\n\nTest cases needed:\n\n1. Empty path handling:\n Primary = empty, Additional = [empty]\n Expected: Should either use . as default or error gracefully\n\n2. Duplicate detection:\n Primary = ., Additional = [., ./]\n Expected: Should return unique paths only\n\n3. Path normalization:\n Primary = ~/repos/main, Additional = [../other, ./foo/../bar]\n Expected: Should expand to absolute canonical paths\n\n4. Partial failure scenarios:\n What if snapshot capture succeeds for repos 1-2 but fails on repo 3?\n Test that system does not end up in inconsistent state\n\nFiles:\n- cmd/bd/deletion_tracking_test.go (add new tests)\n\nDependencies:\nDepends on fixing getMultiRepoJSONLPaths() path normalization first.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-06T19:31:52.921241-08:00","updated_at":"2025-11-06T20:06:49.220334-08:00","closed_at":"2025-11-06T19:53:34.515411-08:00","source_repo":".","dependencies":[{"issue_id":"bd-kdoh","depends_on_id":"bd-xo6b","type":"discovered-from","created_at":"2025-11-06T19:32:12.353459-08:00","created_by":"daemon"},{"issue_id":"bd-kdoh","depends_on_id":"bd-iye7","type":"blocks","created_at":"2025-11-06T19:32:13.688686-08:00","created_by":"daemon"}]} -{"id":"bd-keb","content_hash":"74cb243817cd6b77b5cdb6280bba866cc133b8c01eb4bbbb4e23c5b47a973546","title":"Add database maintenance commands section to QUICKSTART.md","description":"**Problem:**\nUsers don't discover `bd compact` or `bd cleanup` commands until their database grows large. These maintenance commands aren't mentioned in quickstart documentation.\n\nRelated to issue #349 item #4.\n\n**Current state:**\ndocs/QUICKSTART.md ends at line 217 with \"See README.md for full documentation\" but has no mention of maintenance operations.\n\n**Proposed addition:**\nAdd a \"Database Maintenance\" section after line 140 (before \"Advanced: Agent Mail\" section) covering:\n- When database grows (many closed issues)\n- How to view compaction statistics\n- How to compact old issues\n- How to delete closed issues\n- Warning about permanence\n\n**Example content:**\n```markdown\n## Database Maintenance\n\nAs your project accumulates closed issues, the database grows. Use these commands to manage size:\n\n```bash\n# View compaction statistics\nbd compact --stats\n\n# Preview compaction candidates (30+ days closed)\nbd compact --analyze --json\n\n# Apply agent-generated summary\nbd compact --apply --id bd-42 --summary summary.txt\n\n# Immediately delete closed issues (use with caution!)\nbd cleanup --force\n```\n\n**When to compact:**\n- Database file \u003e 10MB with many old closed issues\n- After major project milestones\n- Before archiving a project phase\n```\n\n**Files to modify:**\n- docs/QUICKSTART.md (add section after line 140)","design":"Brief, actionable guidance on database maintenance.\n\nFocus on:\n1. When to do maintenance (size/age triggers)\n2. Non-destructive options first (stats, analyze)\n3. Clear warnings about permanence\n4. Reference to bd restore for git history recovery","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-20T20:48:40.488512-05:00","updated_at":"2025-11-20T20:59:13.439462-05:00","closed_at":"2025-11-20T20:59:13.439462-05:00","source_repo":".","labels":["documentation","onboarding"],"comments":[{"id":41,"issue_id":"bd-keb","author":"stevey","text":"Addresses GitHub issue #349 item 4: https://github.com/steveyegge/beads/issues/349\n\nUsers don't discover compact/cleanup commands until database grows large. Quickstart should mention maintenance operations.","created_at":"2025-11-22T07:53:00Z"}]} +{"id":"bd-keb","content_hash":"74cb243817cd6b77b5cdb6280bba866cc133b8c01eb4bbbb4e23c5b47a973546","title":"Add database maintenance commands section to QUICKSTART.md","description":"**Problem:**\nUsers don't discover `bd compact` or `bd cleanup` commands until their database grows large. These maintenance commands aren't mentioned in quickstart documentation.\n\nRelated to issue #349 item #4.\n\n**Current state:**\ndocs/QUICKSTART.md ends at line 217 with \"See README.md for full documentation\" but has no mention of maintenance operations.\n\n**Proposed addition:**\nAdd a \"Database Maintenance\" section after line 140 (before \"Advanced: Agent Mail\" section) covering:\n- When database grows (many closed issues)\n- How to view compaction statistics\n- How to compact old issues\n- How to delete closed issues\n- Warning about permanence\n\n**Example content:**\n```markdown\n## Database Maintenance\n\nAs your project accumulates closed issues, the database grows. Use these commands to manage size:\n\n```bash\n# View compaction statistics\nbd compact --stats\n\n# Preview compaction candidates (30+ days closed)\nbd compact --analyze --json\n\n# Apply agent-generated summary\nbd compact --apply --id bd-42 --summary summary.txt\n\n# Immediately delete closed issues (use with caution!)\nbd cleanup --force\n```\n\n**When to compact:**\n- Database file \u003e 10MB with many old closed issues\n- After major project milestones\n- Before archiving a project phase\n```\n\n**Files to modify:**\n- docs/QUICKSTART.md (add section after line 140)","design":"Brief, actionable guidance on database maintenance.\n\nFocus on:\n1. When to do maintenance (size/age triggers)\n2. Non-destructive options first (stats, analyze)\n3. Clear warnings about permanence\n4. Reference to bd restore for git history recovery","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-20T20:48:40.488512-05:00","updated_at":"2025-11-20T21:51:31.801834-05:00","closed_at":"2025-11-20T20:59:13.439462-05:00","source_repo":".","labels":["documentation","onboarding"],"comments":[{"id":14,"issue_id":"bd-keb","author":"stevey","text":"Addresses GitHub issue #349 item 4: https://github.com/steveyegge/beads/issues/349\n\nUsers don't discover compact/cleanup commands until database grows large. Quickstart should mention maintenance operations.","created_at":"2025-11-21T13:58:10Z"}]} {"id":"bd-khnb","content_hash":"4f55475e1150be5a2710768a06f3162510814d96ffb2145b0a1693f5972ca5ae","title":"bd migrate --update-repo-id triggers auto-import that resurrects deleted issues","description":"**Bug:** Running `bd migrate --update-repo-id` can resurrect previously deleted issues from git history.\n\n## What Happened\n\nUser deleted 490 closed issues:\n- Deletion committed successfully (06d655a) with JSONL at 48 lines\n- Database had 48 issues after deletion\n- User ran `bd migrate --update-repo-id` to fix legacy database\n- Migration triggered daemon auto-import\n- JSONL had been restored to 538 issues (from commit 6cd3a32 - before deletion)\n- Auto-import loaded the old JSONL over the cleaned database\n- Result: 490 deleted issues resurrected\n\n## Root Cause\n\nThe auto-import logic in `cmd/bd/sync.go:130-136`:\n```go\nif isJSONLNewer(jsonlPath) {\n fmt.Println(\"→ JSONL is newer than database, importing first...\")\n if err := importFromJSONL(ctx, jsonlPath, renameOnImport); err != nil {\n```\n\nThis checks if JSONL mtime is newer than database and auto-imports. The problem:\n1. Git operations (pull, merge, checkout) can restore old JSONL files\n2. Restored file has recent mtime (time of git operation)\n3. Auto-import sees \"newer\" JSONL and imports it\n4. Old data overwrites current database state\n\n## Timeline\n\n- 19:59: Commit 6cd3a32 restored JSONL to 538 issues from d99222d\n- 20:22: Commit 3520321 (bd sync)\n- 20:23: Commit 06d655a deleted 490 issues → JSONL now 48 lines\n- 20:23: User ran `bd migrate --update-repo-id`\n- Migration completed, daemon started\n- Daemon saw JSONL (restored earlier to 538) was \"newer\" than database\n- Auto-import resurrected 490 deleted issues\n\n## Impact\n\n- **Critical data loss bug** - user deletions can be undone silently\n- Affects any workflow that uses git branches, merges, or checkouts\n- Auto-import has no safety checks against importing older data\n- Users have no warning that old data will overwrite current state\n\n## Fix Options\n\n1. **Content-based staleness** (not mtime-based)\n - Compare JSONL content hash vs database content hash\n - Only import if content actually changed\n - Prevents re-importing old data with new mtime\n\n2. **Database timestamp check**\n - Store \"last export timestamp\" in database metadata\n - Only import JSONL if it's newer than last export\n - Prevents importing old JSONL after git operations\n\n3. **User confirmation**\n - Before auto-import, show diff of what will change\n - Require confirmation for large changes (\u003e10% issues affected)\n - Safety valve for destructive imports\n\n4. **Explicit sync mode**\n - Disable auto-import entirely\n - Require explicit `bd sync` or `bd import` commands\n - Trade convenience for safety\n\n## Recommended Solution\n\nCombination of #1 and #2:\n- Add `last_export_timestamp` to database metadata\n- Check JSONL mtime \u003e last_export_timestamp before importing\n- Add content hash check as additional safety\n- Show warning if importing would delete \u003e10 issues\n\nThis preserves auto-import convenience while preventing data loss.\n\n## Files Involved\n\n- `cmd/bd/sync.go:130-136` - Auto-import logic\n- `cmd/bd/daemon_sync.go` - Daemon export/import cycle\n- `internal/autoimport/autoimport.go` - Staleness detection\n\n## Reproduction Steps\n\n1. Create and delete some issues, commit to git\n2. Checkout an earlier commit (before deletion)\n3. Checkout back to current commit\n4. JSONL file now has recent mtime but old content\n5. Run any bd command that triggers auto-import\n6. Deleted issues are resurrected","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-20T20:44:35.235807-05:00","updated_at":"2025-11-20T21:51:31.806158-05:00","closed_at":"2025-11-20T21:51:31.806158-05:00","source_repo":"."} {"id":"bd-kla1","content_hash":"825b411d37b412a1ee19e3ebc246b6725aca0f32b83e65c8b4680fa4ef2193ff","title":"Add bd init --contributor wizard","description":"Interactive wizard for OSS contributor setup. Guides user through: fork workflow setup, separate planning repo configuration, auto-detection of fork relationships, examples of common OSS workflows.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-05T18:04:29.958409-08:00","updated_at":"2025-11-05T19:27:33.07529-08:00","closed_at":"2025-11-05T18:53:51.267625-08:00","source_repo":".","dependencies":[{"issue_id":"bd-kla1","depends_on_id":"bd-8rd","type":"parent-child","created_at":"2025-11-05T18:04:39.120064-08:00","created_by":"daemon"}]} {"id":"bd-ktng","content_hash":"0a09f3e1549a70817f23aa57444811aaf18683ff9336944ff6e8c277ac5684b4","title":"Optimize CLI test suite - eliminate redundant git init calls","description":"Current: Each of 13 CLI tests calls git init (31s total). Solution: Use single test binary built once in init(), skip git operations where possible, or use mock filesystem.","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-04T11:23:13.660276-08:00","updated_at":"2025-11-04T11:23:13.660276-08:00","source_repo":".","dependencies":[{"issue_id":"bd-ktng","depends_on_id":"bd-l5gq","type":"discovered-from","created_at":"2025-11-04T11:23:13.662102-08:00","created_by":"daemon"}]} @@ -512,7 +513,7 @@ {"id":"bd-l4b6","content_hash":"62f76d6f751783139b97ee4b08e1134f6154d0eb5696e0f78ce258f841c9738e","title":"Add tests for bd init --team wizard","description":"Write integration tests for the team wizard:\n- Test branch detection\n- Test sync branch creation\n- Test protected branch workflow\n- Test auto-sync configuration","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-05T18:58:18.192425-08:00","updated_at":"2025-11-06T20:06:49.22056-08:00","closed_at":"2025-11-06T19:55:39.687439-08:00","source_repo":"."} {"id":"bd-l5gq","content_hash":"9c6f895c8e0066874073474fded02d3b1b10a008c3448f1e650e2ff39b5e8e02","title":"Optimize test suite performance - cut runtime by 50%+","description":"## Problem\nTest suite takes ~20.8 seconds, with 95% of time spent in just 2 tests:\n- TestHashIDs_MultiCloneConverge: 11.08s (53%)\n- TestHashIDs_IdenticalContentDedup: 8.78s (42%)\n\nBoth tests in beads_hash_multiclone_test.go perform extensive Git operations (bare repos, multiple clones, sync rounds).\n\n## Goal\nCut total test time by at least 50% (to ~10 seconds or less).\n\n## Analysis\nTests already have some optimizations:\n- --shared --depth=1 --no-tags for fast cloning\n- Disabled hooks, gc, fsync\n- Support -short flag\n\n## Impact\n- Faster development feedback loop\n- Reduced CI costs and time\n- Better developer experience","status":"closed","priority":2,"issue_type":"epic","created_at":"2025-11-04T01:23:14.410648-08:00","updated_at":"2025-11-04T11:23:13.683213-08:00","closed_at":"2025-11-04T11:23:13.683213-08:00","source_repo":"."} {"id":"bd-l954","content_hash":"263dd2111cf0353b307f2e47489aa42ecf607e49b1316b54a6497cad9d3722b0","title":"Performance Testing Framework","description":"Add comprehensive performance testing for beads focusing on optimization guidance and validating 10K+ database scale. Uses standard Go tooling, follows existing patterns, minimal complexity.\n\nComponents:\n- Benchmark suite for critical operations at 10K-20K scale\n- Fixture generator for realistic test data (epic hierarchies, cross-links)\n- User diagnostics via bd doctor --perf\n- Always-on profiling integration\n\nGoals:\n- Identify bottlenecks for optimization work\n- Validate performance at 10K+ issue scale\n- Enable users to collect diagnostics for bug reports\n- Support both SQLite and JSONL import paths","status":"open","priority":2,"issue_type":"epic","created_at":"2025-11-13T22:22:11.203467-08:00","updated_at":"2025-11-13T22:22:11.203467-08:00","source_repo":"."} -{"id":"bd-la9d","content_hash":"298e5922cb0e6460d1cf14d2b7230c63403e72fcb511fb31d3fe2e2f241fd18a","title":"Blocking issue","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T19:43:48.758706-05:00","updated_at":"2025-11-20T19:43:48.758706-05:00","closed_at":"2025-11-07T21:55:09.43148-08:00","source_repo":"."} +{"id":"bd-la9d","content_hash":"298e5922cb0e6460d1cf14d2b7230c63403e72fcb511fb31d3fe2e2f241fd18a","title":"Blocking issue","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-22T15:18:47.463543482-07:00","updated_at":"2025-11-22T15:18:47.463543482-07:00","closed_at":"2025-11-07T21:55:09.43148-08:00","source_repo":"."} {"id":"bd-lln","content_hash":"1442bc38612a1818859f36da7c92fefd75f24126ca8dd179dd245545283b7c58","title":"Add tests for performFlush error handling in FlushManager","description":"Test coverage gap identified by automated analysis (vc-217).\n\n**Original Issue:** [deleted:bd-da96-baseline-lint]\n\nIn cmd/bd/flush_manager.go:269, the performFlush method is flagged by unparam as always returning nil, indicating the error return value is never used.\n\nAdd tests to determine:\n- Whether performFlush can actually return errors in failure scenarios\n- If error return is needed, add tests for error cases (disk full, permission denied, etc.)\n- If error return is not needed, refactor to remove unused return value\n- Test full export vs incremental export error handling\n\nThis ensures proper error handling in the flush mechanism and removes dead code if the return value is unnecessary.\n\n_This issue was automatically created by AI test coverage analysis._","acceptance_criteria":"- Tests written for uncovered functionality\n- Test coverage verified\n- All tests passing","status":"closed","priority":2,"issue_type":"task","assignee":"ai-supervisor","created_at":"2025-11-21T10:25:33.533653-05:00","updated_at":"2025-11-21T20:30:01.940186-05:00","closed_at":"2025-11-21T19:31:21.876949-05:00","source_repo":".","labels":["discovered:supervisor"],"dependencies":[{"issue_id":"bd-lln","depends_on_id":"bd-da96-baseline-lint","type":"discovered-from","created_at":"2025-11-21T10:25:33.534913-05:00","created_by":"ai-supervisor"}]} {"id":"bd-lm2q","content_hash":"e26fa6c461610f000935fb4ccd62239dd3ac22b5b1d2f0b440418f6e06551a4a","title":"Fix `bd sync` failure due to daemon auto-export timestamp skew","description":"`bd sync` fails with false-positive \"JSONL is newer than database\" after daemon auto-export.\nRoot Cause: Daemon exports local changes to JSONL, updating its timestamp. `bd sync` sees JSONL.mtime \u003e DB.mtime and assumes external changes, blocking export.\nProposed Fixes:\n1. `bd sync` auto-imports if timestamp matches but content differs (or just auto-imports).\n2. Content-based comparison instead of timestamp only.\n","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-20T18:56:16.876685-05:00","updated_at":"2025-11-20T22:02:51.641709-05:00","closed_at":"2025-11-20T20:54:39.512574-05:00","source_repo":"."} {"id":"bd-lwnt","content_hash":"ddfa247870eb3734ffa7a4d0da6fcd4a359d2b48e02d70aad8560ec4bc13afdc","title":"Test P1 priority","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-05T12:58:38.074112-08:00","updated_at":"2025-11-05T12:58:44.711763-08:00","closed_at":"2025-11-05T12:58:44.711763-08:00","source_repo":"."} @@ -545,7 +546,7 @@ {"id":"bd-ola6","content_hash":"79461888e8a7875bf3623b8db44ea004f73a2374daa52ae9cb3fc9d3ce5e6a8b","title":"Implement transaction retry logic for SQLITE_BUSY","description":"BEGIN IMMEDIATE fails immediately on SQLITE_BUSY instead of retrying with exponential backoff.\n\nLocation: internal/storage/sqlite/sqlite.go:223-225\n\nProblem:\n- Under concurrent write load, BEGIN IMMEDIATE can fail with SQLITE_BUSY\n- Current implementation fails immediately instead of retrying\n- Results in spurious failures under normal concurrent usage\n\nSolution: Implement exponential backoff retry:\n- Retry up to N times (e.g., 5)\n- Backoff: 10ms, 20ms, 40ms, 80ms, 160ms\n- Check for context cancellation between retries\n- Only retry on SQLITE_BUSY/database locked errors\n\nImpact: Spurious failures under concurrent write load\n\nEffort: 3 hours","status":"open","priority":1,"issue_type":"feature","created_at":"2025-11-16T14:51:31.247147-08:00","updated_at":"2025-11-16T14:51:31.247147-08:00","source_repo":"."} {"id":"bd-omx1","content_hash":"e61d74adb03fc8275c97242df8ce0e4146db7e49271e4e86c3379b4a3fbab0d8","title":"Add `bd merge` command wrapping 3-way merge logic","description":"Implement CLI command to invoke beads-merge functionality.\n\n**Interface**:\n```bash\nbd merge \u003coutput\u003e \u003cbase\u003e \u003cleft\u003e \u003cright\u003e\nbd merge --debug \u003coutput\u003e \u003cbase\u003e \u003cleft\u003e \u003cright\u003e\n```\n\n**Behavior**:\n- Exit code 0 on clean merge\n- Exit code 1 if conflicts (write conflict markers)\n- Support --debug flag for verbose output\n- Match beads-merge's existing behavior\n\n**File**: `cmd/bd/merge.go`","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-05T18:42:20.427429-08:00","updated_at":"2025-11-05T19:01:29.071365-08:00","closed_at":"2025-11-05T19:01:29.071365-08:00","source_repo":".","dependencies":[{"issue_id":"bd-omx1","depends_on_id":"bd-qqvw","type":"parent-child","created_at":"2025-11-05T18:42:28.709123-08:00","created_by":"daemon"},{"issue_id":"bd-omx1","depends_on_id":"bd-oif6","type":"blocks","created_at":"2025-11-05T18:42:35.436444-08:00","created_by":"daemon"}]} {"id":"bd-p0zr","content_hash":"5e518ce89ce35cb4b5b534b8c1287679b7984bc73f7c6747773962277d2ad1bc","title":"bd message: Improve type safety with typed parameter structs","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-08T12:54:29.675678-08:00","updated_at":"2025-11-08T12:58:59.559643-08:00","closed_at":"2025-11-08T12:58:59.559643-08:00","source_repo":".","dependencies":[{"issue_id":"bd-p0zr","depends_on_id":"bd-6uix","type":"parent-child","created_at":"2025-11-08T12:55:55.058354-08:00","created_by":"daemon"}]} -{"id":"bd-p65x","content_hash":"9fb7f74dbd1c92d47ff34bae3a58b9a4b97643a065cc07e3f76d20537f93be91","title":"Latency test 1","description":"","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-20T12:09:09.267424-05:00","updated_at":"2025-11-20T12:09:09.267424-05:00","closed_at":"2025-11-08T00:06:46.198388-08:00","source_repo":"."} +{"id":"bd-p65x","content_hash":"9fb7f74dbd1c92d47ff34bae3a58b9a4b97643a065cc07e3f76d20537f93be91","title":"Latency test 1","description":"","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-08T00:04:38.815725-08:00","updated_at":"2025-11-08T00:06:46.198388-08:00","closed_at":"2025-11-08T00:06:46.198388-08:00","source_repo":"."} {"id":"bd-p68x","content_hash":"2adc58598da8443025691815c351057400ddaa6fa6f0121f1dbb85af58d8d6e8","title":"Create examples for common workflows","description":"Add examples/ subdirectories: OSS contributor workflow, team branch workflow, multi-phase development, multiple personas (architect/implementer). Each with README and sample configs.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-05T18:04:30.128257-08:00","updated_at":"2025-11-05T19:27:33.07555-08:00","closed_at":"2025-11-05T19:08:39.035904-08:00","source_repo":".","dependencies":[{"issue_id":"bd-p68x","depends_on_id":"bd-8rd","type":"parent-child","created_at":"2025-11-05T18:04:39.247515-08:00","created_by":"daemon"}]} {"id":"bd-p6vp","content_hash":"1df6d3b9b438cdcdbc618c24fea48769c1f22e8a8701af4e742531d4433ca7ea","title":"Clarify .beads/.gitattributes handling in Protected Branches docs","description":"Protected Branches docs quick start leaves untracked `.beads` directory and `.gitattributes`.\nQuestion: Are these changes meant to be checked into the protected branch?\nNeed to clarify if these should be ignored or committed, or if the instructions are missing a step.\n","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T18:56:25.79407-05:00","updated_at":"2025-11-20T18:56:25.79407-05:00","source_repo":"."} {"id":"bd-pdjb","content_hash":"ac30f03839ef20d09a5a6c4915b8046b270ebdb564c1ee7511edc72128cd8fa0","title":"Testing \u0026 Validation","description":"Ensure reliability through comprehensive testing.","notes":"Completed comprehensive Agent Mail test coverage analysis and implementation.\n\n**Test Coverage Summary:**\n- 66 total tests across 5 files\n- 51 unit tests for HTTP adapter (0.02s)\n- 15 integration tests for multi-agent scenarios (~55s total)\n\n**New Tests Added:**\nCreated `test_multi_agent_coordination.py` (4 tests, 11s) covering:\n1. Fairness: 10 agents competing for 5 issues → exactly 1 claim per issue\n2. Notifications: End-to-end message delivery between agents\n3. Handoff: Clean reservation transfer from agent1 to agent2\n4. Idempotency: Double reserve/release by same agent\n\n**Coverage Quality:**\n✅ Collision prevention (race conditions)\n✅ Graceful degradation (7 failure modes)\n✅ TTL/expiration behavior\n✅ Multi-agent coordination\n✅ JSONL consistency\n✅ HTTP error handling\n✅ Authorization and configuration\n\n**Intentionally Skipped:**\n- Path traversal (validated elsewhere)\n- Retry policies (nice-to-have)\n- HTTPS/TLS (out of scope)\n- Slow tests (50+ agents, soak tests)\n\nSee `tests/integration/AGENT_MAIL_TEST_COVERAGE.md` for details.\n\nAll tests pass. Agent Mail integration is well-tested and reliable for multi-agent scenarios.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-07T22:43:00.457985-08:00","updated_at":"2025-11-08T03:09:48.253758-08:00","closed_at":"2025-11-08T02:47:34.153586-08:00","source_repo":".","dependencies":[{"issue_id":"bd-pdjb","depends_on_id":"bd-wfmw","type":"blocks","created_at":"2025-11-07T22:43:00.459403-08:00","created_by":"daemon"}]} @@ -597,7 +598,7 @@ {"id":"bd-vxdr","content_hash":"d188358987c7a7d444f9144a4a6cc5164eccd35b16325edba51dad104ab2a7f2","title":"Investigate database pollution - issue count anomalies","description":"Multiple repos showing inflated issue counts suggesting cross-repo pollution:\n- ~/src/dave/beads: 895 issues (675 open) - clearly polluted\n- ~/src/stevey/src/beads: 280 issues (expected ~209-220) - possibly polluted\n\nNeed to investigate:\n1. Source of pollution (multi-repo sync issues?)\n2. How many duplicate/foreign issues exist\n3. Whether recent sync operations caused cross-contamination\n4. How to clean up and prevent future pollution","notes":"Investigation findings:\n\n**Root cause identified:**\n- NOT cross-repo contamination\n- NOT automated test leakage (tests properly use t.TempDir())\n- Manual testing during template feature development (Nov 2-4)\n- Commit ba325a2: \"test issues were accidentally committed during template feature development\"\n\n**Database growth timeline:**\n- Nov 3: 19 issues (baseline)\n- Nov 2-5: +244 issues (massive development spike)\n- Nov 6-7: +40 issues (continued growth)\n- Current: 291 issues → 270 after cleanup\n\n**Test pollution breakdown:**\n- 21 issues matching \"Test \" prefix pattern\n- Most created Nov 2-5 during feature development\n- Pollution from manual `./bd create \"Test issue\"` commands in production workspace\n- All automated tests properly isolated with t.TempDir()\n\n**Cleanup completed:**\n- Ran scripts/cleanup-test-pollution.sh successfully\n- Removed 21 test issues\n- Database reduced from 291 → 270 issues (7.2% cleanup)\n- JSONL synced to git\n\n**Prevention strategy:**\n- Filed follow-up issue for prevention mechanisms\n- Script can be deleted once prevention is in place\n- Tests are already properly isolated - no code changes needed there","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-06T22:34:40.137483-08:00","updated_at":"2025-11-07T16:07:28.274136-08:00","closed_at":"2025-11-07T16:04:02.199807-08:00","source_repo":"."} {"id":"bd-wcl","content_hash":"c08d62ce3627a49126c63f6a630a08c1666e5b1b8d9148ae0c72d7d06611b2a9","title":"Document CLI + hooks as recommended approach over MCP","description":"Update documentation to position CLI + bd prime hooks as the primary recommended approach over MCP server, explaining why minimizing context matters even with large context windows (compute cost, energy, environment, latency).","design":"## Goals\n\nPosition CLI + `bd prime` hooks as the **primary recommended approach** for AI agent integration, with MCP server as a legacy/fallback option.\n\nExplore **hybrid mode** - if certain commands benefit from MCP (UX/DX advantages like no approval prompts), minimize MCP surface area to only those commands.\n\nThis requires production validation first - only update docs after CLI mode is proven reliable.\n\n## Why Minimize Context (Even With Large Windows)\n\n**Context window size ≠ free resource**\n\nLarge context windows (100k+, 200k+) don't mean we should fill them wastefully. Every token in context has real costs:\n\n### Compute Cost\n- **Processing overhead**: Larger context = more GPU/CPU cycles per request\n- **Memory usage**: 10.5k tokens consume significant RAM/VRAM\n- **Scaling impact**: Multiplied across all users, all sessions, all requests\n\n### Energy \u0026 Environment\n- **Electricity**: More compute = more power consumption\n- **Carbon footprint**: Data centers running on grid power (not all renewable)\n- **Sustainability**: Unnecessary token usage contributes to AI's environmental impact\n- **Responsibility**: Efficient tools are better for the planet\n\n### User Experience\n- **Latency**: Larger context = slower processing (noticeable at 10k+ tokens)\n- **Cost**: Many AI services charge per token (input + output)\n- **Rate limits**: Context counts against API quotas\n\n### Engineering Excellence\n- **Efficiency**: Good engineering minimizes resource usage\n- **Scalability**: Efficient tools scale better\n- **Best practices**: Optimize for the common case\n\n**The comparison:**\n\n| Approach | Standing Context | Efficiency | User Cost | Environmental Impact |\n|----------|-----------------|------------|-----------|---------------------|\n| **CLI + hooks** | ~1-2k tokens | 80-90% reduction | Lower | Sustainable ✓ |\n| **MCP minimal** | ~2-4k tokens | 60-80% reduction | Medium | Better ✓ |\n| **MCP full** | ~10.5k tokens | Baseline | Higher | Wasteful ✗ |\n\n**Functional equivalence:**\n- CLI via Bash tool works just as well as MCP native calls\n- Same features, same reliability\n- No downside except initial learning curve\n\n## Hybrid Mode: Minimal MCP Surface Area\n\n**Philosophy:** MCP server doesn't have to expose everything.\n\nIf certain commands have legitimate UX/DX benefits from MCP (e.g., no approval prompts, cleaner syntax), we can expose ONLY those commands via MCP while using CLI for everything else.\n\n### Potential MCP-Only Candidates (TBD)\n\nCommands that might benefit from MCP native calls:\n- `ready` - frequently checked, no side effects, approval prompt annoying\n- `show` - read-only, frequently used, approval slows workflow\n- `list` - read-only, no risk, approval adds friction\n\nCommands that work fine via CLI:\n- `create` - complex parameters, benefits from explicit confirmation\n- `update` - state changes, good to see command explicitly\n- `close` - state changes, explicit is better\n- `dep` - relationships, good to see what's being linked\n- `sync` - git operations, definitely want visibility\n\n### Token Budget\n\n**Full MCP** (current): ~10.5k tokens\n- All ~20+ bd commands exposed\n- All parameter schemas\n- All descriptions and examples\n\n**Minimal MCP** (proposed): ~2-4k tokens\n- 3-5 high-frequency read commands only\n- Simplified schemas\n- Minimal descriptions\n- Everything else via CLI\n\n**Pure CLI**: ~1-2k tokens (only on SessionStart/PreCompact)\n- No MCP tools loaded\n- All commands via Bash\n\n### Investigation Required\n\nBefore implementing hybrid mode, validate:\n\n1. **Do MCP calls actually skip approval prompts?**\n - Test with Claude Code approval settings\n - Compare MCP tool calls vs Bash tool calls\n - Measure UX difference in real usage\n\n2. **What's the actual token breakdown per command?**\n - Measure individual command schemas\n - Calculate token savings for minimal vs full\n\n3. **Is approval prompt the only benefit?**\n - Are there other UX advantages to MCP?\n - Does native syntax actually improve experience?\n - User testing with both approaches\n\n4. **Can we dynamically load MCP tools?**\n - Only load MCP when certain commands needed?\n - Hot-swap between CLI and MCP?\n - Probably not - MCP loads at startup\n\n### Hybrid Mode Documentation (If Validated)\n\n```markdown\n## Choosing Your Integration Approach\n\nBeads supports three AI agent integration approaches:\n\n### CLI + Hooks (Recommended - Most Efficient)\n\n**Setup:** `bd setup claude`\n\nUses Claude Code hooks to inject workflow context via `bd prime` command. Agent uses bd via Bash tool.\n\n**Tokens:** ~1-2k (on SessionStart/PreCompact only)\n\n**Pros:**\n- Maximum efficiency (80-90% reduction vs full MCP)\n- Lowest compute/energy usage\n- Same functionality as MCP\n\n**Cons:**\n- Bash tool calls may require approval prompts\n- Slightly more verbose in conversation\n\n### Minimal MCP + Hooks (Balanced)\n\n**Setup:** Install minimal MCP server (read-only commands) + `bd setup claude`\n\nExposes only high-frequency read commands via MCP (ready, show, list). Everything else via CLI.\n\n**Tokens:** ~2-4k MCP + ~1-2k hooks\n\n**Pros:**\n- 60-80% reduction vs full MCP\n- No approval prompts for common queries\n- Cleaner syntax for frequent operations\n- Still efficient\n\n**Cons:**\n- Requires MCP server (additional setup)\n- Mixed interface (some MCP, some CLI)\n\n### Full MCP + Hooks (Legacy)\n\n**Setup:** Install full MCP server + `bd setup claude`\n\n**Tokens:** ~10.5k MCP + hooks\n\n**Pros:**\n- All commands as native function calls\n- Consistent interface\n\n**Cons:**\n- Highest token usage (worst for compute/energy/cost)\n- Slowest processing\n- Less sustainable\n\n### Recommendation\n\n1. **Start with CLI + hooks** - most efficient, works great\n2. **Try minimal MCP** if approval prompts become annoying\n3. **Avoid full MCP** - wasteful with no significant benefit\n```\n\n## Production Validation Checklist\n\nBefore making these documentation changes, validate CLI approach works reliably:\n\n### Phase 1: Pure CLI Validation\n- [ ] `bd prime` implemented and tested\n- [ ] Hooks installed and working in Claude Code\n- [ ] Real-world usage by at least 2-3 developers for 1+ weeks\n- [ ] No significant usability issues reported\n- [ ] Agent successfully uses bd via Bash tool\n- [ ] Document which commands (if any) have approval prompt issues\n\n### Phase 2: Hybrid Mode Investigation (Optional)\n- [ ] Test if MCP calls skip approval prompts vs Bash calls\n- [ ] Measure token cost per MCP command\n- [ ] Identify minimal set of commands worth exposing via MCP\n- [ ] Build minimal MCP server variant\n- [ ] Validate token savings (should be 60-80% vs full MCP)\n- [ ] User testing shows actual UX improvement\n\n### Phase 3: Documentation Update\n- [ ] Update based on validation results\n- [ ] Include measured token counts (not estimates)\n- [ ] Provide clear migration paths\n- [ ] Update `bd doctor` recommendations\n\n## Migration Guide (Optional)\n\nFor users currently using MCP:\n\n```markdown\n### Migrating from Full MCP to CLI + Hooks\n\nAlready using full MCP server? You can switch to the more efficient CLI approach:\n\n1. Install hooks: `bd setup claude`\n2. Test it works (hooks inject context, agent uses Bash tool)\n3. Remove MCP server from `~/.claude/settings.json`\n4. Restart Claude Code\n\nYou'll get the same functionality with 80-90% less token usage.\n\n### Migrating to Minimal MCP (If Available)\n\nIf you find approval prompts annoying for certain commands:\n\n1. Replace full MCP with minimal MCP in `~/.claude/settings.json`\n2. Restart Claude Code\n3. Verify high-frequency commands (ready, show, list) work via MCP\n4. Everything else automatically uses CLI\n\nYou'll get 60-80% token reduction vs full MCP while keeping the UX benefits.\n```\n\n## Files to Update\n\n- `README.md` - Add recommendation in AI Integration section\n- `AGENTS.md` - Add \"Choosing Your Integration Approach\" section early\n- `QUICKSTART.md` - Update AI integration section\n- `docs/` - Any other AI integration docs if they exist\n- `mcp-server/` - Create minimal variant if hybrid validated\n\n## Future: Update `bd init`\n\nOnce validated, update `bd init` to:\n- Default to recommending `bd setup claude` (hooks only)\n- Mention minimal MCP as option for UX improvement\n- Detect existing full MCP and suggest migration\n- Provide token usage estimates for each approach\n\n## MCP Server Architecture Note\n\n**Key insight:** MCP server doesn't have to expose all bd functionality.\n\nCurrent design exposes ~20+ commands (all bd subcommands). This is over-engineered.\n\n**Better design:**\n- **Minimal MCP**: 3-5 read-only commands (~2-4k tokens)\n- **CLI**: Everything else via Bash tool\n- **Hooks**: Context injection via `bd prime`\n\nThis achieves best of both worlds:\n- Low token usage (efficient)\n- No approval prompts for common queries (UX)\n- Explicit visibility for state changes (safety)\n\nIf validation shows NO meaningful benefit to MCP (even minimal), skip hybrid mode entirely and recommend pure CLI.","acceptance_criteria":"- Documentation explains CLI + hooks as recommended approach\n- Explains why context size matters (compute/energy/cost/latency)\n- Token comparison table shows 80-90% reduction\n- Migration guide for existing MCP users\n- Only deployed AFTER production validation\n- Clear that both approaches are supported","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-12T00:15:25.923025-08:00","updated_at":"2025-11-12T00:18:16.786857-08:00","source_repo":"."} {"id":"bd-we4p","content_hash":"0e3248d31a6524c7a665960682cf2b159449fa31f5427771796dce8639059faf","title":"Cache getMultiRepoJSONLPaths() result during sync to avoid redundant calls","description":"From bd-xo6b code review: getMultiRepoJSONLPaths() is called 3x per sync cycle.\n\n**Current behavior:**\ndaemon_sync.go calls getMultiRepoJSONLPaths() three times per sync:\n- Line 505: Snapshot capture before pull\n- Line 575: Merge/prune after pull\n- Line 613: Base snapshot update after import\n\n**Cost per call:**\n- Config lookup (likely cached, but still overhead)\n- Path construction: O(N) where N = number of repos\n- String allocations: (N + 1) × filepath.Join() calls\n\n**Total per sync:** 3N path constructions + 3 config lookups + 3 slice allocations\n\n**Impact:**\n- For N=3 repos: Negligible (\u003c 1ms)\n- For N=10 repos: Still minimal\n- For N=100+ repos: Wasteful\n\n**Solution:**\nCall once at sync start, reuse result:\n\n```go\nfunc createSyncFunc(...) func() {\n return func() {\n // ... existing setup ...\n \n // Call once at start\n multiRepoPaths := getMultiRepoJSONLPaths()\n \n // Snapshot capture\n if multiRepoPaths != nil {\n for _, path := range multiRepoPaths {\n if err := captureLeftSnapshot(path); err != nil { ... }\n }\n }\n \n // ... later ...\n \n // Merge/prune - reuse same paths\n if multiRepoPaths != nil {\n for _, path := range multiRepoPaths { ... }\n }\n \n // ... later ...\n \n // Base snapshot update - reuse same paths\n if multiRepoPaths != nil {\n for _, path := range multiRepoPaths { ... }\n }\n }\n}\n```\n\n**Files:**\n- cmd/bd/daemon_sync.go:449-636 (createSyncFunc)\n\n**Note:** This is a performance optimization, not a correctness fix. Low priority unless multi-repo usage scales significantly.","status":"closed","priority":2,"issue_type":"chore","created_at":"2025-11-06T19:31:32.128674-08:00","updated_at":"2025-11-06T19:40:50.871176-08:00","closed_at":"2025-11-06T19:40:50.871176-08:00","source_repo":".","dependencies":[{"issue_id":"bd-we4p","depends_on_id":"bd-xo6b","type":"discovered-from","created_at":"2025-11-06T19:32:12.39754-08:00","created_by":"daemon"}]} -{"id":"bd-web8","content_hash":"8d8657093add8c3447d0488810569116ea1fd9db632cdbef29b209c5f8830a48","title":"Fix Windows test failures - metadata keys contain colons from absolute paths","description":"","status":"closed","priority":0,"issue_type":"bug","assignee":"claude","created_at":"2025-11-22T10:56:05.537802-08:00","updated_at":"2025-11-22T10:59:13.74478-08:00","closed_at":"2025-11-22T10:59:13.74478-08:00","source_repo":"."} +{"id":"bd-web8","content_hash":"096ecdfa8a6013dcf48d5d1672f0897bee74da6161c105e1a1806ab8d1c51d3f","title":"Fix Windows test failures - metadata keys contain colons from absolute paths","description":"","status":"closed","priority":0,"issue_type":"bug","assignee":"claude","created_at":"2025-11-22T10:56:05.537802-08:00","updated_at":"2025-11-22T10:59:13.74478-08:00","closed_at":"2025-11-22T10:59:13.74478-08:00","source_repo":"."} {"id":"bd-wfmw","content_hash":"21706f1701be9fb51fa9e17d1dded6343bc2585e4bdb608239a20c5853d00220","title":"Integration Layer Implementation","description":"Build the adapter layer that makes Agent Mail optional and non-intrusive.","notes":"Progress: bd-m9th (Python adapter library) completed with full test coverage. Next: bd-fzbg (update python-agent example with Agent Mail integration).","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-07T22:42:09.356429-08:00","updated_at":"2025-11-08T00:20:30.888756-08:00","closed_at":"2025-11-08T00:20:30.888756-08:00","source_repo":".","dependencies":[{"issue_id":"bd-wfmw","depends_on_id":"bd-spmx","type":"blocks","created_at":"2025-11-07T22:42:09.357488-08:00","created_by":"daemon"}]} {"id":"bd-wgu4","content_hash":"31cf5cc105fee5de26f4c2756b8368c90b18eb5f65c656eb0d90f96b23daf21d","title":"Standardize daemon detection: use tryDaemonLock probe before RPC","description":"Before attempting RPC connection, call tryDaemonLock() to check if lock is held:\n- If lock NOT held: skip RPC attempt (no daemon running)\n- If lock IS held: proceed with RPC + short timeout\n\nThis is extremely cheap and eliminates unnecessary connection attempts.\n\nApply across all client entry points that probe for daemon.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-07T16:42:12.709802-08:00","updated_at":"2025-11-07T20:15:23.282181-08:00","closed_at":"2025-11-07T20:15:23.282181-08:00","source_repo":".","dependencies":[{"issue_id":"bd-wgu4","depends_on_id":"bd-ndyz","type":"discovered-from","created_at":"2025-11-07T16:42:12.710564-08:00","created_by":"daemon"}]} {"id":"bd-wta","content_hash":"eee40bbe4e00af632ad46e1461a25e4b0e5508bea115422aea0772381eec0d84","title":"Add performance benchmarks for multi-repo hydration","description":"The contributor-workflow-analysis.md asserts sub-second queries (line 702) and describes smart caching via file mtime tracking (Decision #4, lines 584-618), but doesn't provide concrete performance benchmarks.\n\nVC's requirement (from VC feedback section):\n- Executor polls GetReadyWork() every 5-10 seconds\n- Queries must be sub-second (ideally \u003c100ms)\n- Smart caching must avoid re-parsing JSONLs on every query\n\nSuggested performance targets to validate:\n- File stat overhead: \u003c1ms per repo\n- Hydration (when needed): \u003c500ms for typical JSONL (\u003c25k)\n- Query (from cache): \u003c10ms\n- Total GetReadyWork(): \u003c100ms (VC's requirement)\n\nAlso test at scale:\n- N=1 repo (baseline)\n- N=3 repos (typical)\n- N=10 repos (edge case)\n\nThese benchmarks are critical for library consumers like VC that run automated polling loops.","acceptance_criteria":"- Performance benchmark suite created for multi-repo hydration\n- Benchmarks cover file stat, hydration, and query times\n- Tests at N=1, N=3, N=10 repo scales\n- Results documented in contributor-workflow-analysis.md\n- Performance targets met or issues filed for optimization","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-03T20:24:39.331528-08:00","updated_at":"2025-11-05T14:17:15.079226-08:00","closed_at":"2025-11-05T14:17:15.079226-08:00","source_repo":"."} @@ -610,13 +611,14 @@ {"id":"bd-y6d","content_hash":"9d63262aa6b79d03e9fd1639833d0827b74743aad0a430d0478e46034776bc13","title":"Refactor create_test.go to use shared DB setup","description":"Convert TestCreate_* functions to use test suites with shared database setup.\n\nExample transformation:\n- Before: 10 separate tests, each with newTestStore() \n- After: 1 TestCreate() with 10 t.Run() subtests sharing one DB\n\nEstimated speedup: 10x faster (1 DB setup instead of 10)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-21T11:48:56.858213-05:00","updated_at":"2025-11-21T19:42:23.186565-05:00","closed_at":"2025-11-21T15:15:31.315407-05:00","source_repo":".","dependencies":[{"issue_id":"bd-y6d","depends_on_id":"bd-1rh","type":"blocks","created_at":"2025-11-21T11:49:09.660182-05:00","created_by":"daemon"},{"issue_id":"bd-y6d","depends_on_id":"bd-c49","type":"blocks","created_at":"2025-11-21T11:49:26.410452-05:00","created_by":"daemon"}]} {"id":"bd-yb8","content_hash":"9579eb6536ba3a6fe6c62e7275f467c6926b08e78861a77869878849fb2f3b17","title":"Propagate context through command handlers","description":"Thread context from signal-aware parent through all command handlers.\n\n## Context\nPart of context propagation work. Builds on bd-rtp (signal-aware contexts).\n\n## Current State\nMany command handlers create their own context.Background() locally instead of receiving context from parent.\n\n## Implementation\n1. Add context parameter to command handler functions\n2. Pass context from cobra command Run/RunE closures\n3. Update all storage operations to use propagated context\n\n## Example Pattern\n```go\n// Before\nRun: func(cmd *cobra.Command, args []string) {\n ctx := context.Background()\n store.GetIssues(ctx, ...)\n}\n\n// After \nRun: func(cmd *cobra.Command, args []string) {\n // ctx comes from parent signal-aware context\n store.GetIssues(ctx, ...)\n}\n```\n\n## Files to Update\n- All cmd/bd/*.go command handlers\n- Ensure context flows from main -\u003e cobra -\u003e handlers -\u003e storage\n\n## Benefits\n- Commands respect cancellation signals\n- Consistent context handling\n- Enables timeouts and deadlines\n\n## Acceptance Criteria\n- [ ] All command handlers use propagated context\n- [ ] No new context.Background() calls in command handlers\n- [ ] Context flows from signal handler to storage layer","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-20T21:27:02.854242-05:00","updated_at":"2025-11-20T21:37:32.44525-05:00","closed_at":"2025-11-20T21:37:32.44525-05:00","source_repo":".","dependencies":[{"issue_id":"bd-yb8","depends_on_id":"bd-rtp","type":"blocks","created_at":"2025-11-20T21:27:02.854904-05:00","created_by":"daemon"}]} {"id":"bd-ybv5","content_hash":"52f6d2143a3e9d63937e7dee2cfb4055740132d3c0831c3e948210179336820f","title":"Refactor AGENTS.md to use external references","description":"Suggestion to use external references (e.g., \"ALWAYS REFER TO ./beads/prompt.md\") instead of including all instructions directly within AGENTS.md.\nReasons:\n1. Agents can follow external references.\n2. Prevents context pollution/stuffing in AGENTS.md as more tools append instructions.\n","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-20T18:55:53.259144-05:00","updated_at":"2025-11-20T18:55:53.259144-05:00","source_repo":"."} +{"id":"bd-ye0d","content_hash":"40962ef4e144b58167a07ae13458b40cedff3f3549fccab3a172ca908cd754bc","title":"troubleshoot GH#278 daemon exits every few secs","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-13T06:27:23.39509215-07:00","updated_at":"2025-11-13T06:27:23.39509215-07:00","source_repo":"."} {"id":"bd-yek6","content_hash":"f155913af8c58c0a7ea3da6a7d9e232e8cb29c3825f2d6f272a5417a449692a9","title":"CLI tests (cli_fast_test.go) are slow and should be integration tests","description":"The TestCLI_* tests in cmd/bd/cli_fast_test.go are taking 4-5 seconds each (40+ seconds total), making them the slowest part of the fast test suite.\n\nCurrent timings:\n- TestCLI_Import: 4.73s\n- TestCLI_Blocked: 4.33s \n- TestCLI_DepTree: 4.15s\n- TestCLI_Close: 3.59s\n- TestCLI_DepAdd: 3.50s\n- etc.\n\nThese tests compile the bd binary once in init(), but then execute it multiple times per test with filesystem operations. Despite being named \"fast\", they're actually end-to-end CLI integration tests.\n\nOptions:\n1. Tag with //go:build integration (move to integration suite)\n2. Optimize: Use in-memory databases, reduce exec calls, better parallelization\n3. Keep as-is but understand they're the baseline for \"fast\" tests\n\nTotal test suite currently: 13.8s (cmd/bd alone is 12.8s, and most of that is these CLI tests)","notes":"Fixed by reusing existing bd binary from repo root instead of rebuilding.\n\nBefore: 15+ minutes (rebuilding binary for every test package)\nAfter: ~12 seconds (reuses pre-built binary)\n\nThe init() function now checks for ../../bd first before falling back to building. This means `go build \u0026\u0026 go test` is now fast.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-05T20:19:12.822543-08:00","updated_at":"2025-11-05T20:31:19.321787-08:00","closed_at":"2025-11-05T20:31:19.321787-08:00","source_repo":"."} {"id":"bd-ykd9","content_hash":"f1446ecf58b117dae936c32d30370b5a42a2c081ffae6ce749d87300a893fa72","title":"Add bd doctor --fix flag to automatically repair issues","description":"Implement a --fix flag for bd doctor that can automatically repair detected issues.\n\nRequirements:\n- Add --fix flag to bd doctor command\n- Show all fixable issues and prompt for confirmation before applying fixes\n- Organize fix implementations under doctor/fix/\u003ctype_of_fix\u003e.go\n- Each fix type should have its own file (e.g., doctor/fix/hooks.go, doctor/fix/sync.go)\n- Display what will be fixed and ask user to confirm (Y/n) before proceeding\n- Support fixing issues like:\n - Missing or broken git hooks\n - Sync problems with remote\n - File permission issues\n - Any other auto-repairable issues doctor detects\n\nImplementation notes:\n- Maintain separation between detection (existing doctor code) and repair (new fix code)\n- Each fix should be idempotent and safe to run multiple times\n- Provide clear output about what was fixed\n- Log any fixes that fail with actionable error messages","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-14T18:17:48.411264-08:00","updated_at":"2025-11-14T18:17:58.88609-08:00","source_repo":"."} {"id":"bd-ymj","content_hash":"63a435805f6d91b26243b234bc572eb41c6af7aaa37b6f985a7cfaa8fa311b7e","title":"Export doesn't update last_import_hash metadata causing perpetual 'JSONL content has changed' errors","description":"After a successful export, the daemon doesn't update last_import_hash or last_import_mtime metadata. This causes hasJSONLChanged to return true on the next export attempt, blocking with 'refusing to export: JSONL content has changed since last import'.\n\nRelated to GH #334.\n\nScenario:\n1. Daemon exports successfully → JSONL updated, hash changes\n2. Metadata NOT updated (last_import_hash still points to old hash)\n3. Next mutation triggers export\n4. validatePreExport calls hasJSONLChanged\n5. hasJSONLChanged sees current JSONL hash != last_import_hash\n6. Export blocked with 'JSONL content has changed since last import'\n7. Issue stuck: can't export, can't make progress\n\nThis creates a catch-22 where the system thinks JSONL changed externally when it was the daemon itself that changed it.\n\nCurrent behavior:\n- Import updates metadata (import.go:310-336)\n- Export does NOT update metadata (daemon_sync.go:307)\n- Result: metadata becomes stale after every export","design":"Add metadata updates after successful export in daemon_sync.go:\n\nAfter line 307 in createExportFunc (after 'Exported to JSONL' log):\n- Compute current JSONL hash\n- Update last_import_hash metadata\n- Update last_import_mtime metadata \n- Same for createSyncFunc at line 497\n\nThis mirrors what import.go does at lines 310-336.\n\nThe logic is: after export, DB and JSONL are in sync, so metadata should reflect the current JSONL state to prevent false positives in hasJSONLChanged.","acceptance_criteria":"1. After daemon export, last_import_hash matches current JSONL hash\n2. After daemon export, last_import_mtime matches current JSONL mtime\n3. Subsequent exports don't fail with 'JSONL content has changed'\n4. Import still correctly detects external JSONL changes\n5. All existing export/import tests pass","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-21T10:05:34.871333-05:00","updated_at":"2025-11-21T23:53:00.483255-08:00","closed_at":"2025-11-21T15:09:04.016651-05:00","source_repo":".","labels":["bug","daemon","export","metadata"],"dependencies":[{"issue_id":"bd-ymj","depends_on_id":"bd-dvd","type":"related","created_at":"2025-11-21T10:06:11.462508-05:00","created_by":"daemon"}]} {"id":"bd-yuf7","content_hash":"97e18d89914d698df5ec673d40ff980a87a29e1435a887ec2b5dd77d7d412a79","title":"bd config set succeeds but doesn't persist to config.toml","description":"Commands like `bd config set daemon.auto_push true` return \"Set daemon.auto_push = true\" but the config file is never created and `bd info --json | jq '.config'` returns null.\n\n**Steps to reproduce:**\n1. Run `bd config set daemon.auto_push true`\n2. See success message: \"Set daemon.auto_push = true\"\n3. Check `cat .beads/config.toml` → file doesn't exist\n4. Check `bd info --json | jq '.config'` → returns null\n\n**Expected:**\n- .beads/config.toml should be created with the setting\n- bd info should show the config value\n\n**Impact:**\nUsers can't enable auto-push/auto-commit via CLI as documented in AGENTS.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-08T01:14:58.726198-08:00","updated_at":"2025-11-08T01:17:41.377912-08:00","closed_at":"2025-11-08T01:17:41.377912-08:00","source_repo":"."} {"id":"bd-yvlc","content_hash":"7447f9c24de76b56a3e753619c20571c3ca4ec0fb69a12b917def9d9580b1854","title":"URGENT: main branch has failing tests (syncbranch migration error)","description":"The main branch has failing tests that are blocking CI for all PRs.\n\n## Problem\nAll syncbranch_test.go tests failing with:\n\"migration external_ref_column failed: failed to create index on external_ref: sqlite3: SQL logic error: no such table: main.issues\"\n\n## Evidence\n- Last 5 CI runs on main: ALL FAILED\n- Tests fail locally on current main (bd6dca5)\n- Affects: TestGet, TestSet, TestUnset in internal/syncbranch\n\n## Impact\n- Blocking all PR merges\n- CI shows red for all branches\n- Can't trust test results\n\n## Root Cause\nMigration order issue - trying to create index on external_ref column before the issues table exists, or before the external_ref column is added to the issues table.\n\n## Quick Fix Needed\nNeed to investigate migration order in internal/storage/sqlite/migrations.go and ensure:\n1. issues table is created first\n2. external_ref column is added to issues table\n3. THEN index on external_ref is created\n\nThis is CRITICAL - main should never have breaking tests.","design":"Investigation steps:\n1. Check internal/storage/sqlite/migrations.go\n2. Verify migration order and dependencies\n3. Look at external_ref_column migration specifically\n4. Ensure proper table/column creation before index\n5. Test fix locally with fresh database\n6. Push fix to main\n7. Verify CI passes","acceptance_criteria":"- All tests pass on main branch\n- CI is green\n- syncbranch_test.go tests all passing","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-15T12:25:31.51688-08:00","updated_at":"2025-11-15T12:43:11.489612-08:00","closed_at":"2025-11-15T12:43:11.489612-08:00","source_repo":"."} {"id":"bd-yxy","content_hash":"53a1e2edc222d1b0e67106563d1b8f4e6347b0e778f0a56e301b4bd74303cbc7","title":"Add command injection prevention tests for git rm in merge command","description":"Test coverage gap identified by automated analysis (vc-217).\n\n**Original Issue:** [deleted:bd-da96-baseline-lint]\n\nIn cmd/bd/merge.go:121, exec.Command is called with variable fullPath, flagged by gosec G204 for potential command injection.\n\nAdd tests covering:\n- File paths with shell metacharacters (;, |, \u0026, $, etc.)\n- Paths with spaces and special characters\n- Paths attempting command injection (e.g., 'file; rm -rf /')\n- Validation that fullPath is properly sanitized\n- Only valid git-tracked files can be removed\n\nThis is a critical security path preventing arbitrary command execution.\n\n_This issue was automatically created by AI test coverage analysis._","acceptance_criteria":"- Tests written for uncovered functionality\n- Test coverage verified\n- All tests passing","status":"closed","priority":0,"issue_type":"task","assignee":"ai-supervisor","created_at":"2025-11-21T10:25:33.531631-05:00","updated_at":"2025-11-21T20:30:01.941373-05:00","closed_at":"2025-11-21T19:31:21.853136-05:00","source_repo":".","labels":["discovered:supervisor"],"dependencies":[{"issue_id":"bd-yxy","depends_on_id":"bd-da96-baseline-lint","type":"discovered-from","created_at":"2025-11-21T10:25:33.533126-05:00","created_by":"ai-supervisor"}]} -{"id":"bd-z0yn","content_hash":"d642aa388f336290811fa0a5f8f7a546f676ca9727f0d21072300219bccf037b","title":"Channel isolation test - beads","description":"","notes":"Resetting stale in_progress status from old executor run (13 days old)","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-08T04:21:17.327983-08:00","updated_at":"2025-11-21T15:11:55.188481-05:00","source_repo":"."} +{"id":"bd-z0yn","content_hash":"d642aa388f336290811fa0a5f8f7a546f676ca9727f0d21072300219bccf037b","title":"Channel isolation test - beads","description":"","notes":"Resetting stale in_progress status from old executor run (13 days old)","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-08T04:21:17.327983-08:00","updated_at":"2025-11-22T15:18:47.464267052-07:00","source_repo":"."} {"id":"bd-z3s3","content_hash":"24d99dc1a9a5f35af962137f5709d4b0f1b6a9ec91511c30a2517d790640cce8","title":"Create deployment scripts for GCP","description":"Automated provisioning scripts for GCP Compute Engine deployment.\n\nAcceptance Criteria:\n- Terraform/gcloud scripts\n- Static IP allocation\n- Firewall rules\n- NGINX reverse proxy config\n- TLS setup (Let's Encrypt)\n- Systemd service file\n\nFile: deployment/agent-mail/gcp/","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-07T22:43:43.294839-08:00","updated_at":"2025-11-07T22:43:43.294839-08:00","source_repo":".","dependencies":[{"issue_id":"bd-z3s3","depends_on_id":"bd-9li4","type":"blocks","created_at":"2025-11-07T23:04:27.982336-08:00","created_by":"daemon"}]} {"id":"bd-z528","content_hash":"3f332e9997d2b7eb0af23885820df5f607fe08671a2615cadec941bbe7d36f68","title":"Prevent test pollution in production database","description":"The bd-vxdr cleanup revealed test issues were created during manual testing in the production workspace (Nov 2-4, template feature development).\n\n**Root cause:** Manual testing with `./bd create \"Test issue\"` pollutes the production .beads database.\n\n**Prevention strategies:**\n1. Use TEST_DB environment variable for manual testing\n2. Add warning when creating issues with \"Test\" prefix\n3. Improve developer docs about testing workflow\n4. Consider adding `bd test-mode` command for isolated testing","notes":"**Implementation completed:**\n\n1. ✅ Added warning when creating issues with \"Test\" prefix in production database\n - Shows yellow warning with ⚠ symbol\n - Suggests using BEADS_DB for isolated testing\n - Warning appears in create.go after title validation\n\n2. ✅ Documented BEADS_DB testing workflow in AGENTS.md\n - Added \"Testing Workflow\" section in Development Guidelines\n - Includes manual testing examples with BEADS_DB\n - Includes automated testing examples with t.TempDir()\n - Clear warning about not polluting production database\n\n3. ⚠️ Decided against bd test-mode command\n - BEADS_DB already provides simple, flexible isolation\n - Additional command would add complexity without much benefit\n - Current approach follows Unix philosophy (env vars for config)\n\n**Files modified:**\n- cmd/bd/create.go - Added Test prefix warning\n- AGENTS.md - Added Testing Workflow section\n\n**Testing:**\n- Verified warning appears when creating \"Test\" prefix issues\n- Verified BEADS_DB isolation works correctly\n- Built successfully with `go build`","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-07T16:07:28.255289-08:00","updated_at":"2025-11-07T23:18:08.386514-08:00","closed_at":"2025-11-07T22:43:28.669908-08:00","source_repo":"."} {"id":"bd-zbq2","content_hash":"56dfd7f2c09dafd232a1ae26063744c89a1ba317e50a3429ec19b73ee1402993","title":"bd export should verify JSONL line count matches database count","description":"After export completes, bd should verify that the JSONL file line count matches the number of issues exported. This would catch silent failures where the export appears to succeed but doesn't actually write all issues.\n\nReal-world scenario from VC project:\n- Ran direct SQL DELETE to remove 240 issues \n- Ran 'bd export -o .beads/issues.jsonl'\n- No error shown, appeared to succeed\n- But JSONL file was not updated (still had old line count)\n- Later session found all 240 issues still in JSONL\n- Had to repeat the cleanup\n\nIf export had verified line count, it would have immediately shown:\n Error: Export verification failed\n Expected: 276 issues\n JSONL file: 516 lines\n Mismatch indicates export failed to write all issues\n\nThis is especially important because:\n1. JSONL is source of truth in git\n2. Silent export failures cause data inconsistency\n3. Users assume export succeeded if no error shown\n4. The verification is cheap (just count lines)\n\nImplementation:\n- After writing JSONL, count lines in file\n- Compare to len(exportedIDs)\n- If mismatch, remove temp file and return error\n- Show clear error message with both counts","design":"In cmd/bd/export.go, after atomic rename (line ~301):\n\n1. Count lines in final JSONL file:\n - Read file and count newlines\n - Or reuse countIssuesInJSONL() helper (already exists)\n\n2. Compare to len(exportedIDs)\n\n3. If mismatch:\n - Log error with both counts\n - Optionally: remove the bad JSONL file (or leave for debugging?)\n - Return error (exit 1)\n\n4. Consider adding --skip-verify flag for edge cases\n\nEdge cases:\n- Partial line writes (corrupted file)\n- File system issues\n- Race conditions (another process modifying JSONL during export)\n\nThe countIssuesInJSONL() function already exists at line 20, can reuse it.","acceptance_criteria":"1. bd export verifies JSONL line count after write\n2. Clear error shown if mismatch detected\n3. Test case that simulates partial write failure\n4. Does not affect export performance significantly (line counting is fast)","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-05T14:24:56.278249-08:00","updated_at":"2025-11-05T15:09:41.636141-08:00","closed_at":"2025-11-05T14:31:24.494885-08:00","source_repo":"."}