115 lines
113 KiB
JSON
115 lines
113 KiB
JSON
{"id":"bd-5ibn","title":"Latency test 1","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"}
|
||
{"id":"bd-ykd9","title":"Add bd doctor --fix flag to automatically repair issues","description":"Implement a --fix flag for bd doctor that can automatically repair detected issues.\n\nRequirements:\n- Add --fix flag to bd doctor command\n- Show all fixable issues and prompt for confirmation before applying fixes\n- Organize fix implementations under doctor/fix/\u003ctype_of_fix\u003e.go\n- Each fix type should have its own file (e.g., doctor/fix/hooks.go, doctor/fix/sync.go)\n- Display what will be fixed and ask user to confirm (Y/n) before proceeding\n- Support fixing issues like:\n - Missing or broken git hooks\n - Sync problems with remote\n - File permission issues\n - Any other auto-repairable issues doctor detects\n\nImplementation notes:\n- Maintain separation between detection (existing doctor code) and repair (new fix code)\n- Each fix should be idempotent and safe to run multiple times\n- Provide clear output about what was fixed\n- Log any fixes that fail with actionable error messages","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-14T18:17:48.411264-08:00","updated_at":"2025-11-14T18:17:58.88609-08:00"}
|
||
{"id":"bd-5b6e","title":"Add tests for helper functions (GetDirtyIssueHash, GetAllDependencyRecords, export hashes)","description":"Several utility functions have 0% coverage:\n- GetDirtyIssueHash (dirty.go)\n- GetAllDependencyRecords (dependencies.go)\n- GetExportHash, SetExportHash, ClearAllExportHashes (hash.go)\n\nThese are lower priority but should have basic coverage.","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-01T22:40:58.989976-07:00","updated_at":"2025-11-01T22:40:58.989976-07:00"}
|
||
{"id":"bd-n25","title":"Speed up main_test.go - tests hang indefinitely due to nil rootCtx","description":"## Problem\n\nmain_test.go tests are hanging indefinitely, making them unusable and blocking development.\n\n## Root Cause\n\nTests that call flushToJSONL() or autoImportIfNewer() hang forever because:\n- rootCtx is nil in test environment (defined in cmd/bd/main.go:67)\n- flushToJSONL() uses rootCtx for DB operations (autoflush.go:503)\n- When rootCtx is nil, DB calls timeout/hang indefinitely\n\n## Affected Tests (10+)\n\n- TestAutoFlushOnExit\n- TestAutoFlushJSONLContent \n- TestAutoFlushErrorHandling\n- TestAutoImportIfNewer\n- TestAutoImportDisabled\n- TestAutoImportWithUpdate\n- TestAutoImportNoUpdate\n- TestAutoImportMergeConflict\n- TestAutoImportConflictMarkerFalsePositive\n- TestAutoImportClosedAtInvariant\n\n## Proof\n\n```bash\n# Before fix: TestAutoFlushJSONLContent HANGS (killed after 2+ min)\n# After adding rootCtx init: Completes in 0.04s\n# Speedup: ∞ → 0.04s\n```\n\n## Solution\n\nSee MAIN_TEST_OPTIMIZATION_PLAN.md for complete fix plan.\n\n**Quick Fix (5 min)**: Add to each hanging test:\n```go\nctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\ndefer cancel()\noldRootCtx := rootCtx\nrootCtx = ctx\ndefer func() { rootCtx = oldRootCtx }()\n```\n\n**Full Optimization (40 min total)**:\n1. Fix rootCtx (5 min) - unblocks tests\n2. Reduce sleep durations 10x (2 min) - saves ~280ms\n3. Use in-memory DBs (10 min) - saves ~1s\n4. Share test fixtures (15 min) - saves ~1.2s\n5. Fix skipped debounce test (5 min)\n\n## Expected Results\n\n- Tests go from hanging → \u003c5s total runtime\n- Keep critical integration test coverage\n- Tests caught real bugs: bd-270, bd-206, bd-160\n\n## Files\n\n- Analysis: MAIN_TEST_REFACTOR_NOTES.md\n- Solution: MAIN_TEST_OPTIMIZATION_PLAN.md\n- Tests: cmd/bd/main_test.go (18 tests, 1322 LOC)\n\n## Priority\n\nP1 - Blocking development, tests unusable in current state","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-21T18:27:48.942814-05:00","updated_at":"2025-11-21T18:44:21.944901-05:00","closed_at":"2025-11-21T18:44:21.944901-05:00"}
|
||
{"id":"bd-z3s3","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","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-rfj","title":"Add unit tests for hasJSONLChanged() function","description":"The hasJSONLChanged() function has no unit tests. Should test:\n- Normal case: hash matches\n- Normal case: hash differs\n- Edge case: empty file\n- Edge case: missing metadata (first run)\n- Edge case: corrupted metadata\n- Edge case: file read errors\n- Edge case: invalid hash format in metadata\n\nAlso add performance benchmarks for large JSONL files.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-20T21:31:10.389481-05:00","updated_at":"2025-11-20T21:40:02.664516-05:00","closed_at":"2025-11-20T21:40:02.664516-05:00","dependencies":[{"issue_id":"bd-rfj","depends_on_id":"bd-khnb","type":"blocks","created_at":"2025-11-20T21:31:10.39058-05:00","created_by":"daemon"}]}
|
||
{"id":"bd-379","title":"Implement `bd setup cursor` for Cursor IDE integration","description":"Create a `bd setup cursor` command that integrates Beads workflow into Cursor IDE via .cursorrules file. Unlike Claude Code (which has hooks), Cursor uses a static rules file to provide context to its AI.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-11-11T23:32:22.170083-08:00","updated_at":"2025-11-11T23:32:22.170083-08:00"}
|
||
{"id":"bd-5a90","title":"Test parent issue","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-02T11:50:35.85367-08:00","updated_at":"2025-11-02T11:50:35.85367-08:00"}
|
||
{"id":"bd-s02","title":"Manual task","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-03T20:15:10.022202-08:00","updated_at":"2025-11-03T20:15:10.022202-08:00"}
|
||
{"id":"bd-ar2.1","title":"Extract duplicated metadata update code in daemon_sync.go","description":"## Problem\nThe same 22-line metadata update block appears identically in both:\n- createExportFunc (lines 309-328)\n- createSyncFunc (lines 520-539)\n\nThis violates DRY principle and makes maintenance harder.\n\n## Solution\nExtract to helper function:\n\n```go\n// updateExportMetadata updates last_import_hash and related metadata after a successful export.\n// This prevents \"JSONL content has changed since last import\" errors on subsequent exports (bd-ymj fix).\nfunc updateExportMetadata(ctx context.Context, store storage.Storage, jsonlPath string, log daemonLogger) {\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\n }\n \n if 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 exportTime := time.Now().Format(time.RFC3339)\n if err := store.SetMetadata(ctx, \"last_import_time\", exportTime); err != nil {\n log.log(\"Warning: failed to update last_import_time: %v\", err)\n }\n \n // Store mtime for fast-path optimization\n if jsonlInfo, statErr := os.Stat(jsonlPath); statErr == nil {\n mtimeStr := fmt.Sprintf(\"%d\", jsonlInfo.ModTime().Unix())\n if err := store.SetMetadata(ctx, \"last_import_mtime\", mtimeStr); err != nil {\n log.log(\"Warning: failed to update last_import_mtime: %v\", err)\n }\n }\n}\n```\n\n## Files\n- cmd/bd/daemon_sync.go\n\n## Benefits\n- Easier maintenance\n- Single source of truth\n- Consistent behavior","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-21T10:24:18.888412-05:00","updated_at":"2025-11-21T19:15:00.119796-05:00","closed_at":"2025-11-21T10:47:24.430037-05:00","dependencies":[{"issue_id":"bd-ar2.1","depends_on_id":"bd-ar2","type":"parent-child","created_at":"2025-11-21T10:24:18.889171-05:00","created_by":"daemon"}]}
|
||
{"id":"bd-1a6j","title":"Test issue 2","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-07T19:07:12.24632-08:00","updated_at":"2025-11-07T19:07:12.24632-08:00"}
|
||
{"id":"bd-56p","title":"Add #nosec G304 comments to JSONL file reads in sync.go","description":"sync.go:610 uses os.ReadFile(jsonlPath) without #nosec comment, inconsistent with other JSONL reads that have '// #nosec G304 - controlled path'.\n\nAdd comment for consistency with integrity.go:43 and import.go:316.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-20T21:31:09.107493-05:00","updated_at":"2025-11-20T21:34:28.378089-05:00","closed_at":"2025-11-20T21:34:28.378089-05:00","dependencies":[{"issue_id":"bd-56p","depends_on_id":"bd-khnb","type":"blocks","created_at":"2025-11-20T21:31:09.108632-05:00","created_by":"daemon"}]}
|
||
{"id":"bd-9cdc","title":"Update docs for import bug fix","description":"Update AGENTS.md, README.md, TROUBLESHOOTING.md with import.orphan_handling config documentation. Document resurrection behavior, tombstones, config modes. Add troubleshooting section for import failures with deleted parents.","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-04T12:32:30.770415-08:00","updated_at":"2025-11-04T12:32:30.770415-08:00"}
|
||
{"id":"bd-1h8","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","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"}
|
||
{"id":"bd-tne","title":"Add Claude setup tip with dynamic priority","description":"Add a predefined tip that suggests running `bd setup claude` when Claude Code is detected but not configured. This tip should have higher priority (shown more frequently) until the setup is complete.","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-11T23:29:29.871324-08:00","updated_at":"2025-11-11T23:50:29.756454-08:00","dependencies":[{"issue_id":"bd-tne","depends_on_id":"bd-d4i","type":"blocks","created_at":"2025-11-11T23:29:29.872081-08:00","created_by":"daemon"}]}
|
||
{"id":"bd-8ql","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)","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"}
|
||
{"id":"bd-9li4","title":"Create Docker image for Agent Mail","description":"Containerize Agent Mail server for easy deployment.\n\nAcceptance Criteria:\n- Dockerfile with Python 3.14\n- Health check endpoint\n- Volume mount for storage\n- Environment variable configuration\n- Multi-arch builds (amd64, arm64)\n\nFile: deployment/agent-mail/Dockerfile","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-07T22:43:43.231964-08:00","updated_at":"2025-11-07T22:43:43.231964-08:00"}
|
||
{"id":"bd-5qim","title":"Optimize GetReadyWork performance - 752ms on 10K database (target: \u003c50ms)","notes":"# Performance Analysis (10K Issue Database)\n\nAnalyzed using CPU profiles from benchmark suite on Apple M2 Pro.\n\n## Operation Performance\n\n| Operation | Time | Allocations | Memory |\n|----------------------------------|---------|-------------|--------|\n| bd ready (GetReadyWork) | ~752ms | 167,466 | 16MB |\n| bd list (SearchIssues no filter) | ~11.6ms | 89,214 | 5.8MB |\n| bd list (SearchIssues filtered) | ~9.2ms | 62,365 | 3.5MB |\n| bd create (CreateIssue) | ~2.6ms | 146 | 8.6KB |\n| bd update (UpdateIssue) | ~0.32ms | 364 | 15KB |\n| bd close (UpdateIssue) | ~0.32ms | 364 | 15KB |\n\n**Target: \u003c50ms for all operations on 10K database**\n\n**Current issue: GetReadyWork is 15x over target (752ms vs 50ms)**\n\n## Root Cause\n\nGetReadyWork (internal/storage/sqlite/ready.go:90-128) uses recursive CTE to propagate blocking:\n- 65x slower than SearchIssues\n- Recalculates entire blocked issue tree on every call\n- Algorithm:\n 1. Find directly blocked issues via 'blocks' dependencies\n 2. Recursively propagate blockage to descendants (max depth: 50)\n 3. Exclude all blocked issues from results\n\n## CPU Profile Analysis\n\n- Database syscalls (pthread_cond_signal, syscall6): ~75%\n- SQLite engine overhead: inherent to recursive CTE\n- Application code (query construction): \u003c1%\n\n**Bottleneck is the recursive CTE query execution, not application code.**\n\n## Optimization Recommendations\n\n### High Impact (Likely to achieve \u003c50ms target)\n\n1. **Cache blocked issue calculation**\n - Add `blocked_issues` table updated on dependency changes\n - Trade write complexity for read speed (ready called \u003e\u003e dependency changes)\n - Eliminates recursive CTE on every read\n\n2. **Add/verify database indexes**\n ```sql\n CREATE INDEX IF NOT EXISTS idx_dependencies_blocked \n ON dependencies(issue_id, type, depends_on_id);\n CREATE INDEX IF NOT EXISTS idx_issues_status \n ON issues(status);\n ```\n\n### Medium Impact\n\n3. **Reduce allocations** (167K allocations for GetReadyWork)\n - Profile `scanIssues()` for object pooling opportunities\n - Reuse slice capacity for repeated calls\n\n### Low Impact (Not recommended)\n- Query optimization for CRUD operations (already \u003c3ms)\n- Connection pooling tuning (not showing in profiles)\n\n## Verification\n\nRun benchmarks to validate optimization:\n```bash\nmake bench-quick\ngo tool pprof -http=:8080 internal/storage/sqlite/bench-cpu-*.prof\n```\n\nProfile files automatically generated in `internal/storage/sqlite/`.","status":"open","issue_type":"bug","created_at":"2025-11-14T09:02:46.507526-08:00","updated_at":"2025-11-14T09:03:44.073236-08:00"}
|
||
{"id":"bd-ar2.5","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":"open","priority":2,"issue_type":"task","created_at":"2025-11-21T10:25:16.52788-05:00","updated_at":"2025-11-21T10:25:16.52788-05:00","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"}]}
|
||
{"id":"bd-e0o","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":"open","priority":3,"issue_type":"task","created_at":"2025-11-21T18:52:13.376092-05:00","updated_at":"2025-11-21T18:52:13.376092-05:00"}
|
||
{"id":"bd-z0yn","title":"Channel isolation test - beads","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"}
|
||
{"id":"bd-ar2","title":"Code review follow-up for bd-dvd and bd-ymj fixes","description":"Track improvements and issues identified during code review of parent resurrection (bd-dvd) and export metadata (bd-ymj) bug fixes.\n\n## Context\nCode review identified several areas for improvement:\n- Code duplication in metadata updates\n- Missing multi-repo support\n- Test coverage gaps\n- Potential race conditions\n\n## Related Issues\nOriginal bugs fixed: bd-dvd, bd-ymj\n\n## Goals\n- Eliminate code duplication\n- Add multi-repo support where needed\n- Improve test coverage\n- Address edge cases","status":"open","priority":2,"issue_type":"epic","created_at":"2025-11-21T10:24:05.78635-05:00","updated_at":"2025-11-21T10:24:05.78635-05:00"}
|
||
{"id":"bd-9e23","title":"Optimize Memory backend GetIssueByExternalRef with index","description":"Currently GetIssueByExternalRef in Memory storage uses O(n) linear search through all issues.\n\nCurrent code (memory.go:282-308):\nfor _, issue := range m.issues {\n if issue.ExternalRef != nil \u0026\u0026 *issue.ExternalRef == externalRef {\n return \u0026issueCopy, nil\n }\n}\n\nProposed optimization:\n- Add externalRefToID map[string]string to MemoryStorage\n- Maintain it in CreateIssue, UpdateIssue, DeleteIssue\n- Achieve O(1) lookup like SQLite's index\n\nImpact: Low (--no-db mode typically has smaller datasets)\nRelated: bd-1022","status":"open","priority":4,"issue_type":"chore","created_at":"2025-11-02T15:32:30.242357-08:00","updated_at":"2025-11-02T15:32:30.242357-08:00"}
|
||
{"id":"bd-ar2.7","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":"open","priority":3,"issue_type":"task","created_at":"2025-11-21T10:25:46.661849-05:00","updated_at":"2025-11-21T10:25:46.661849-05:00","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-4ec8","title":"Widespread double JSON encoding bug in daemon mode RPC calls","description":"Multiple CLI commands had the same double JSON encoding bug found in bd-1048. All commands that called ResolveID via RPC used string(resp.Data) instead of properly unmarshaling the JSON response. This caused IDs to retain JSON quotes (\"bd-1048\" instead of bd-1048), which then got double-encoded when passed to subsequent RPC calls.\n\nAffected commands:\n- bd show (3 instances)\n- bd dep add/remove/tree (5 instances)\n- bd label add/remove/list (3 instances)\n- bd reopen (1 instance)\n\nRoot cause: resp.Data is json.RawMessage (already JSON-encoded), so string() conversion preserves quotes.\n\nFix: Replace all string(resp.Data) with json.Unmarshal(resp.Data, \u0026id) for proper deserialization.\n\nAll commands now tested and working correctly with daemon mode.","status":"open","issue_type":"bug","created_at":"2025-11-02T22:33:01.632691-08:00","updated_at":"2025-11-02T22:33:01.632691-08:00"}
|
||
{"id":"bd-gdn","title":"Add functional tests for FlushManager correctness verification","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-20T21:21:53.967757-05:00","updated_at":"2025-11-21T10:59:00.4089-05:00","closed_at":"2025-11-20T21:35:53.1183-05:00"}
|
||
{"id":"bd-e166","title":"Improve timestamp comparison readability in import","description":"The timestamp comparison logic uses double-negative which can be confusing:\n\nCurrent code:\nif !incoming.UpdatedAt.After(existing.UpdatedAt) {\n // skip update\n}\n\nMore readable:\nif incoming.UpdatedAt.After(existing.UpdatedAt) {\n // perform update\n} else {\n // skip (local is newer)\n}\n\nThis is a minor refactor for code clarity.\n\nRelated: bd-1022\nFiles: internal/importer/importer.go:411, 488","status":"open","priority":4,"issue_type":"chore","created_at":"2025-11-02T15:32:12.27108-08:00","updated_at":"2025-11-02T15:32:12.27108-08:00"}
|
||
{"id":"bd-81a","title":"Add programmatic tip injection API","description":"Allow tips to be programmatically injected at runtime based on detected conditions. This enables dynamic tips (not just pre-defined ones) to be shown with custom priority and frequency.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-11T23:29:46.645583-08:00","updated_at":"2025-11-11T23:50:12.209135-08:00","dependencies":[{"issue_id":"bd-81a","depends_on_id":"bd-d4i","type":"blocks","created_at":"2025-11-11T23:29:46.646327-08:00","created_by":"daemon"}]}
|
||
{"id":"bd-mnap","title":"Investigate performance issues in VS Code Copilot (Windows)","description":"Beads unusable in Windows 11 VS Code Copilot chat with Sonnet 4.5.\nSummary event happens every 3-4 turns, taking 3 minutes.\nCopilot summarizes after ~125k tokens despite model supporting 1M.\nLarge context size of beads might be triggering aggressive summarization.\nNeed workaround or optimization for context size.\n","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T18:56:30.124918-05:00","updated_at":"2025-11-20T18:56:30.124918-05:00"}
|
||
{"id":"bd-90v","title":"bd prime: AI context loading and Claude Code integration","description":"Implement `bd prime` command and Claude Code hooks for context recovery. Hooks work with BOTH MCP server and CLI approaches - they solve the context memory problem (keeping bd workflow fresh after compaction) not the tool access problem (MCP vs CLI).","status":"open","priority":2,"issue_type":"epic","created_at":"2025-11-11T23:31:12.119012-08:00","updated_at":"2025-11-12T00:11:07.743189-08:00"}
|
||
{"id":"bd-m8t","title":"Extract computeJSONLHash helper to eliminate code duplication","description":"SHA256 hash computation is duplicated in 3 places:\n- cmd/bd/integrity.go:50-52\n- cmd/bd/sync.go:611-613\n- cmd/bd/import.go:318-319\n\nExtract to shared helper function computeJSONLHash(jsonlPath string) (string, error) that includes proper #nosec comment and error handling.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-20T21:31:05.836496-05:00","updated_at":"2025-11-20T21:35:36.04171-05:00","closed_at":"2025-11-20T21:35:36.04171-05:00","dependencies":[{"issue_id":"bd-m8t","depends_on_id":"bd-khnb","type":"blocks","created_at":"2025-11-20T21:31:05.837915-05:00","created_by":"daemon"}]}
|
||
{"id":"bd-c362","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"}
|
||
{"id":"bd-m7ge","title":"Add .beads/README.md during 'bd init' for project documentation and promotion","description":"When 'bd init' is run, automatically generate a .beads/README.md file that:\n\n1. Briefly explains what Beads is (AI-native issue tracking that lives in your repo)\n2. Links to the main repository: https://github.com/steveyegge/beads\n3. Provides a quick reference of essential commands:\n - bd create: Create new issues\n - bd list: View all issues\n - bd update: Modify issue status/details\n - bd show: View issue details\n - bd sync: Sync with git remote\n4. Highlights key benefits for AI coding agents and developers\n5. Encourages developers to try it out\n\nThe README should be enthusiastic and compelling to get open source contributors excited about using Beads for their AI-assisted development workflows.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-16T22:32:50.478681-08:00","updated_at":"2025-11-16T22:32:58.492868-08:00"}
|
||
{"id":"bd-ge7","title":"Improve Beads test coverage from 46% to 80%","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"}
|
||
{"id":"bd-0fvq","title":"bd doctor should recommend bd prime migration for existing repos","description":"bd doctor should detect old beads integration patterns and recommend migrating to bd prime approach.\n\n## Current behavior\n- bd doctor checks if Claude hooks are installed globally\n- Doesn't check project-level integration (AGENTS.md, CLAUDE.md)\n- Doesn't recommend migration for repos using old patterns\n\n## Desired behavior\nbd doctor should detect and suggest:\n\n1. **Old slash command pattern detected**\n - Check for /beads:* references in AGENTS.md, CLAUDE.md\n - Suggest: These slash commands are deprecated, use bd prime hooks instead\n \n2. **No agent documentation**\n - Check if AGENTS.md or CLAUDE.md exists\n - Suggest: Run 'bd onboard' or 'bd setup claude' to document workflow\n \n3. **Old MCP-only pattern**\n - Check for instructions to use MCP tools but no bd prime hooks\n - Suggest: Add bd prime hooks for better token efficiency\n\n4. **Migration path**\n - Show: 'Run bd setup claude to add SessionStart/PreCompact hooks'\n - Show: 'Update AGENTS.md to reference bd prime instead of slash commands'\n\n## Example output\n\n⚠ Warning: Old beads integration detected in CLAUDE.md\n Found: /beads:* slash command references (deprecated)\n Recommend: Migrate to bd prime hooks for better token efficiency\n Fix: Run 'bd setup claude' and update CLAUDE.md\n\n💡 Tip: bd prime + hooks reduces token usage by 80-99% vs slash commands\n MCP mode: ~50 tokens vs ~10.5k for full MCP scan\n CLI mode: ~1-2k tokens with automatic context recovery\n\n## Benefits\n- Helps existing repos adopt new best practices\n- Clear migration path for users\n- Better token efficiency messaging","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-12T03:20:25.567748-08:00","updated_at":"2025-11-12T03:20:25.567748-08:00"}
|
||
{"id":"bd-2o2","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","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-d4i","title":"Create tip system infrastructure for contextual hints","description":"Implement a tip/hint system that shows helpful contextual messages after successful commands. This is different from the existing error-path \"Hint:\" messages - tips appear on success paths to educate users about features they might not know about.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-11T23:29:15.693956-08:00","updated_at":"2025-11-11T23:49:50.812933-08:00"}
|
||
{"id":"bd-ar2.2","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":"open","priority":1,"issue_type":"bug","created_at":"2025-11-21T10:24:32.482102-05:00","updated_at":"2025-11-21T10:24:32.482102-05:00","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-3bg","title":"Add performance optimization to hasJSONLChanged with mtime fast-path","description":"hasJSONLChanged() reads entire JSONL file to compute SHA256 hash on every check. For large databases (50MB+), this is expensive and called frequently by daemon.\n\nOptimization: Check mtime first as fast-path. Only compute hash if mtime changed. This catches git operations (mtime changes but content doesn't) while avoiding expensive hash computation in common case (mtime unchanged = content unchanged).\n\nPerformance impact: 99% of checks will use fast path, only git operations need slow path.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T21:31:04.577264-05:00","updated_at":"2025-11-20T21:33:31.499918-05:00","closed_at":"2025-11-20T21:33:31.499918-05:00","dependencies":[{"issue_id":"bd-3bg","depends_on_id":"bd-khnb","type":"blocks","created_at":"2025-11-20T21:31:04.578768-05:00","created_by":"daemon"}]}
|
||
{"id":"bd-j3zt","title":"Fix mypy errors in beads-mcp","description":"Running `mypy .` in `integrations/beads-mcp` reports 287 errors. These should be addressed to improve type safety and code quality.","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-20T18:53:28.557708-05:00","updated_at":"2025-11-20T18:53:28.557708-05:00"}
|
||
{"id":"bd-790","title":"Document which files to commit after bd init --branch","description":"GH #312 reported confusion about which files should be committed after running 'bd init --branch beads-metadata'. Updated PROTECTED_BRANCHES.md to clearly document:\n\n1. Files that should be committed to protected branch (main):\n - .beads/.gitignore\n - .gitattributes\n\n2. Files that are automatically gitignored\n3. Files that live in the sync branch (beads-metadata)\n\nChanges:\n- Added step-by-step instructions in Quick Start section\n- Added 'What lives in each branch' section to How It Works\n- Clarified the directory structure diagram\n\nFixes: https://github.com/steveyegge/beads/issues/312","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-20T21:47:25.813954-05:00","updated_at":"2025-11-20T21:47:33.567649-05:00","closed_at":"2025-11-20T21:47:33.567651-05:00"}
|
||
{"id":"bd-bwk2","title":"Centralize error handling patterns in storage layer","description":"80+ instances of inconsistent error handling across sqlite.go with mix of %w, %v, and no wrapping.\n\nLocation: internal/storage/sqlite/sqlite.go (throughout)\n\nProblem:\n- Some use fmt.Errorf(\"op failed: %w\", err) - correct wrapping\n- Some use fmt.Errorf(\"op failed: %v\", err) - loses error chain\n- Some return err directly - no context\n- Hard to debug production issues\n- Can't distinguish error types\n\nSolution: Create internal/storage/sqlite/errors.go:\n- Define sentinel errors (ErrNotFound, ErrInvalidID, etc.)\n- Create wrapDBError(op string, err error) helper\n- Convert sql.ErrNoRows to ErrNotFound\n- Always wrap with operation context\n\nImpact: Lost error context; inconsistent messages; hard to debug\n\nEffort: 5-7 hours","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-16T14:51:54.974909-08:00","updated_at":"2025-11-16T14:51:54.974909-08:00"}
|
||
{"id":"bd-wcl","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).","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"}
|
||
{"id":"bd-gra","title":"Add error handling test for cmd.Help() in search command","description":"Test coverage gap identified by automated analysis (vc-217).\n\n**Original Issue:** [deleted:bd-da96-baseline-lint]\n\nIn cmd/bd/search.go:39, the return value of cmd.Help() is not checked, flagged by errcheck linter.\n\nAdd test to verify:\n- Error handling when cmd.Help() fails (e.g., output redirection fails)\n- Proper error propagation to caller\n- Command still exits gracefully on help error\n\nThis ensures the search command handles help errors properly and doesn't silently ignore failures.\n\n_This issue was automatically created by AI test coverage analysis._","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-21T10:25:33.52308-05:00","updated_at":"2025-11-21T19:50:54.017163-05:00","closed_at":"2025-11-21T19:31:21.889039-05:00","dependencies":[{"issue_id":"bd-gra","depends_on_id":"bd-da96-baseline-lint","type":"discovered-from","created_at":"2025-11-21T10:25:33.526016-05:00","created_by":"ai-supervisor"}]}
|
||
{"id":"bd-g9eu","title":"Investigate TestRoutingIntegration failure","description":"TestRoutingIntegration/maintainer_with_SSH_remote failed during pre-commit check with \"expected role maintainer, got contributor\".\nThis occurred while running `go test -short ./...` on darwin/arm64.\nThe failure appears unrelated to storage/sqlite changes.\nNeed to investigate if this is a flaky test or environmental issue.","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T15:55:19.337094-08:00","updated_at":"2025-11-20T15:55:19.337094-08:00"}
|
||
{"id":"bd-g5p7","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","issue_type":"task","created_at":"2025-11-16T14:51:10.159953-08:00","updated_at":"2025-11-21T10:59:00.408364-05:00","closed_at":"2025-11-20T20:39:34.426726-05:00"}
|
||
{"id":"bd-e92","title":"Add test coverage for internal/autoimport package","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T21:21:22.338577-05:00","updated_at":"2025-11-20T21:21:22.338577-05:00","dependencies":[{"issue_id":"bd-e92","depends_on_id":"bd-ge7","type":"blocks","created_at":"2025-11-20T21:21:31.128625-05:00","created_by":"daemon"}]}
|
||
{"id":"bd-3852","title":"Add orphan detection migration","description":"Create migration to detect orphaned children in existing databases. Query: SELECT id FROM issues WHERE id LIKE '%.%' AND substr(id, 1, instr(id || '.', '.') - 1) NOT IN (SELECT id FROM issues). Log results, let user decide action (delete orphans or convert to top-level).","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-04T12:32:30.727044-08:00","updated_at":"2025-11-04T12:32:30.727044-08:00"}
|
||
{"id":"bd-ayw","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)","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"}
|
||
{"id":"bd-y6d","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-21T16:07:50.846505-05:00","closed_at":"2025-11-21T15:15:31.315407-05:00","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-gqo","title":"Implement health checks in daemon event loop","description":"Add health checks to checkDaemonHealth() function in daemon_event_loop.go:170:\n- Database integrity check\n- Disk space check\n- Memory usage check\n\nCurrently it's just a no-op placeholder.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-11-21T18:55:07.534304-05:00","updated_at":"2025-11-21T18:55:07.534304-05:00"}
|
||
{"id":"bd-ar2.6","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":"open","priority":2,"issue_type":"task","created_at":"2025-11-21T10:25:32.469469-05:00","updated_at":"2025-11-21T10:25:32.469469-05:00","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-ktng","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"}
|
||
{"id":"bd-ybv5","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"}
|
||
{"id":"bd-c49","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-21T16:07:50.846006-05:00","closed_at":"2025-11-21T15:15:29.50544-05:00"}
|
||
{"id":"bd-1vv","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","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"}
|
||
{"id":"bd-p6vp","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"}
|
||
{"id":"bd-zj8e","title":"Performance Testing Documentation","description":"Create docs/performance-testing.md documenting the performance testing framework.\n\nSections:\n1. Overview - What the framework does, goals\n2. Running Benchmarks\n - make bench command\n - Running specific benchmarks\n - Interpreting output (ns/op, allocs/op)\n3. Profiling and Analysis\n - Viewing CPU profiles with pprof\n - Reading flamegraphs\n - Memory profiling\n - Finding hotspots\n4. User Diagnostics\n - bd doctor --perf usage\n - Sharing profiles with bug reports\n - Understanding the report output\n5. Comparing Performance\n - Using benchstat for before/after comparisons\n - Detecting regressions\n6. Tips for Optimization\n - Common patterns\n - When to profile vs benchmark\n\nStyle:\n- Concise, practical examples\n- Screenshots/examples of pprof output\n- Clear command-line examples\n- Focus on workflow, not theory","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-13T22:23:38.99897-08:00","updated_at":"2025-11-13T22:23:38.99897-08:00"}
|
||
{"id":"bd-9msn","title":"Add monitoring and alerting","description":"Observability for production Agent Mail server.\n\nAcceptance Criteria:\n- Health check endpoint (/health)\n- Prometheus metrics export\n- Grafana dashboard\n- Alerts for server downtime\n- Alerts for high error rate\n- Log aggregation config\n\nFile: deployment/agent-mail/monitoring/","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-07T22:43:43.354117-08:00","updated_at":"2025-11-07T22:43:43.354117-08:00","dependencies":[{"issue_id":"bd-9msn","depends_on_id":"bd-z3s3","type":"blocks","created_at":"2025-11-07T23:04:28.050074-08:00","created_by":"daemon"}]}
|
||
{"id":"bd-u3t","title":"Phase 2: Implement sandbox auto-detection for GH #353","description":"Implement automatic sandbox detection to improve UX for users in sandboxed environments (e.g., Codex).\n\n**Tasks:**\n1. Implement sandbox detection heuristic using syscall.Kill permission checks\n2. Auto-enable --sandbox mode when sandbox is detected\n3. Display informative message when sandbox is detected\n\n**Implementation:**\n- Add isSandboxed() function in cmd/bd/main.go\n- Auto-set sandboxMode = true in PersistentPreRun when detected\n- Show: 'ℹ️ Sandbox detected, using direct mode'\n\n**References:**\n- docs/GH353_INVESTIGATION.md (Solution 3, lines 120-160)\n- Depends on: Phase 1 (bd-???)\n\n**Acceptance Criteria:**\n- Codex users don't need to manually specify --sandbox\n- No false positives in normal environments\n- Clear messaging when auto-detection triggers","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-21T18:51:57.254358-05:00","updated_at":"2025-11-21T18:51:57.254358-05:00"}
|
||
{"id":"bd-rtp","title":"Implement signal-aware context in CLI commands","description":"Replace context.Background() with signal.NotifyContext() to enable graceful cancellation.\n\n## Context\nPart of context propagation work (bd-350). Phase 1 infrastructure is complete - sqlite.New() now accepts context parameter.\n\n## Implementation\nSet up signal-aware context at the CLI entry points:\n\n```go\nctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)\ndefer cancel()\n```\n\n## Key Locations\n- cmd/bd/main.go:438 (marked with TODO(bd-350))\n- cmd/bd/daemon.go:317 (marked with TODO(bd-350))\n- Other command entry points\n\n## Benefits\n- Ctrl+C cancels ongoing database operations\n- Graceful shutdown on SIGTERM\n- Better user experience during long operations\n\n## Acceptance Criteria\n- [ ] Ctrl+C during import cancels operation cleanly\n- [ ] Ctrl+C during export cancels operation cleanly\n- [ ] No database corruption on cancellation\n- [ ] Proper cleanup on signal (defers execute)","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-20T21:26:34.621983-05:00","updated_at":"2025-11-20T21:32:26.288303-05:00","closed_at":"2025-11-20T21:32:26.288303-05:00"}
|
||
{"id":"bd-8wa","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.","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"}
|
||
{"id":"bd-9f86-baseline-test","title":"Baseline quality gate failure: test","description":"The test quality gate is failing on the baseline (main branch).\n\nThis blocks the executor from claiming work until fixed.\n\nError: go test failed: exit status 1\n\nOutput:\n```\n? \tgithub.com/steveyegge/beads\t[no test files]\n# github.com/steveyegge/beads/internal/beads_test [github.com/steveyegge/beads/internal/beads.test]\ninternal/beads/routing_integration_test.go:142:27: not enough arguments in call to sqlite.New\n\thave (string)\n\twant (context.Context, string)\n# github.com/steveyegge/beads/internal/compact [github.com/steveyegge/beads/internal/compact.test]\ninternal/compact/compactor_test.go:17:27: not enough arguments in call to sqlite.New\n\thave (string)\n\twant (context.Context, string)\n# github.com/steveyegge/beads/cmd/bd [github.com/steveyegge/beads/cmd/bd.test]\ncmd/bd/integrity_content_test.go:31:32: undefined: ctx\ncmd/bd/integrity_content_test.go:183:32: undefined: ctx\nFAIL\tgithub.com/steveyegge/beads/cmd/bd [build failed]\n# github.com/steveyegge/beads/internal/daemon [github.com/steveyegge/beads/internal/daemon.test]\ninternal/daemon/discovery_test.go:21:27: not enough arguments in call to sqlite.New\n\thave (string)\n\twant (context.Context, string)\ninternal/daemon/discovery_test.go:59:27: not enough arguments in call to sqlite.New\n\thave (string)\n\twant (context.Context, string)\ninternal/daemon/discovery_test.go:232:27: not enough arguments in call to sqlite.New\n\thave (string)\n\twant (context.Context, string)\n# github.com/steveyegge/beads/internal/importer [github.com/steveyegge/beads/internal/importer.test]\ninternal/importer/external_ref_test.go:22:27: not enough arguments in call to sqlite.New\n\thave (string)\n\twant (context.Context, string)\ninternal/importer/external_ref_test.go:106:27: not enough arguments in call to sqlite.New\n\thave (string)\n\twant (context.Context, string)\ninternal/importer/external_ref_test.go:197:27: not enough arguments in call to sqlite.New\n\thave (string)\n\twant (context.Context, string)\ninternal/importer/external_ref_test.go:295:27: not enough arguments in call to sqlite.New\n\thave (string)\n\twant (context.Context, string)\ninternal/importer/importer_test.go:566:27: not enough arguments in call to sqlite.New\n\thave (st\n... (truncated, see full output in logs)\n```","notes":"Released by executor after budget limit hit. Tests were already fixed manually. Issue can be closed when tests are verified to pass.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-21T10:17:25.962406-05:00","updated_at":"2025-11-21T11:04:33.570067-05:00","closed_at":"2025-11-21T11:04:33.570067-05:00"}
|
||
{"id":"bd-tru","title":"Update documentation for bd prime and Claude integration","description":"Update AGENTS.md, README.md, and QUICKSTART.md to document the new `bd prime` command, `bd setup claude` command, and tip system.","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-11T23:30:22.77349-08:00","updated_at":"2025-11-11T23:45:23.242658-08:00","dependencies":[{"issue_id":"bd-tru","depends_on_id":"bd-90v","type":"parent-child","created_at":"2025-11-11T23:31:35.277819-08:00","created_by":"daemon"}]}
|
||
{"id":"bd-nbc","title":"Add security tests for file path validation in clean command","description":"Test coverage gap identified by automated analysis (vc-217).\n\n**Original Issue:** [deleted:bd-da96-baseline-lint]\n\nIn cmd/bd/clean.go:118, os.Open(gitignorePath) is flagged by gosec G304 for potential file inclusion via variable without validation.\n\nAdd tests covering:\n- Path traversal attempts (../../etc/passwd)\n- Absolute paths outside project directory\n- Symlink following behavior\n- Non-existent file handling\n- Validation that only .gitignore files in valid locations are opened\n\nThis is a security-sensitive code path that needs validation to prevent unauthorized file access.\n\n_This issue was automatically created by AI test coverage analysis._","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-21T10:25:33.526884-05:00","updated_at":"2025-11-21T19:50:54.019038-05:00","closed_at":"2025-11-21T19:31:21.864673-05:00","dependencies":[{"issue_id":"bd-nbc","depends_on_id":"bd-da96-baseline-lint","type":"discovered-from","created_at":"2025-11-21T10:25:33.528582-05:00","created_by":"ai-supervisor"}]}
|
||
{"id":"bd-m0w","title":"Add test coverage for internal/validation package","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T21:21:24.129559-05:00","updated_at":"2025-11-20T21:21:24.129559-05:00","dependencies":[{"issue_id":"bd-m0w","depends_on_id":"bd-ge7","type":"blocks","created_at":"2025-11-20T21:21:31.350477-05:00","created_by":"daemon"}]}
|
||
{"id":"bd-cb2f","title":"Week 1 task","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-03T19:11:59.358093-08:00","updated_at":"2025-11-03T19:11:59.358093-08:00"}
|
||
{"id":"bd-2q6d","title":"Beads commands operate on stale database without warning","description":"All beads read operations should validate database is in sync with JSONL before proceeding.\n\n**Current Behavior:**\n- Commands can query/read from stale database\n- Only mutation operations (like 'bd sync') check if JSONL is newer\n- User gets incorrect results without realizing database is out of sync\n\n**Expected Behavior:**\n- All beads commands should have pre-flight check for database freshness\n- If JSONL is newer than database, refuse to operate with error: \"Database out of sync. Run 'bd import' first.\"\n- Same safety check that exists for 'bd sync' should apply to ALL operations\n\n**Impact:**\n- Users make decisions based on incomplete/outdated data\n- Silent failures lead to confusion (e.g., thinking issues don't exist when they do)\n- Similar to running git commands on stale repo without being warned to pull\n\n**Example:**\n- Searched for bd-g9eu issue file: not found\n- Issue exists in .beads/issues.jsonl (in git)\n- Database was stale, but no warning was given\n- Led to incorrect conclusion that issue was already closed/deleted","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-20T19:33:40.019297-05:00","updated_at":"2025-11-20T19:33:40.019297-05:00"}
|
||
{"id":"bd-yb8","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","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-ar2.3","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":"open","priority":1,"issue_type":"bug","created_at":"2025-11-21T10:24:46.756315-05:00","updated_at":"2025-11-21T10:24:46.756315-05:00","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-9nw","title":"Document sandbox workarounds for GH #353","description":"Add documentation for sandbox troubleshooting and new flags.\n\n**Tasks:**\n1. Create or update TROUBLESHOOTING.md with sandbox section\n2. Document new flags in CLI reference\n3. Add comment to GH #353 with immediate workarounds\n\n**Content needed:**\n- Symptoms of daemon lock issues in sandboxed environments\n- Usage guide for --sandbox, --force, and --allow-stale flags\n- Step-by-step troubleshooting for Codex users\n- Examples of each escape hatch\n\n**Files to update:**\n- docs/TROUBLESHOOTING.md (create if needed)\n- docs/CLI_REFERENCE.md or README.md\n- GitHub issue #353\n\n**References:**\n- docs/GH353_INVESTIGATION.md (lines 240-276)","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-21T18:52:30.794526-05:00","updated_at":"2025-11-21T18:52:30.794526-05:00"}
|
||
{"id":"bd-ar2.4","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":"open","priority":2,"issue_type":"task","created_at":"2025-11-21T10:25:01.376071-05:00","updated_at":"2025-11-21T10:25:01.376071-05:00","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-39o","title":"Rename last_import_hash metadata key to jsonl_content_hash","description":"The metadata key 'last_import_hash' is misleading because it's updated on both import AND export (sync.go:614, import.go:320).\n\nBetter names:\n- jsonl_content_hash (more accurate)\n- last_sync_hash (clearer intent)\n\nThis is a breaking change requiring migration of existing metadata values.","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T21:31:07.568739-05:00","updated_at":"2025-11-20T21:31:07.568739-05:00","dependencies":[{"issue_id":"bd-39o","depends_on_id":"bd-khnb","type":"blocks","created_at":"2025-11-20T21:31:07.5698-05:00","created_by":"daemon"}]}
|
||
{"id":"bd-19er","title":"Create backup and restore procedures","description":"Disaster recovery procedures for Agent Mail data.\n\nAcceptance Criteria:\n- Automated daily snapshots (GCP persistent disk)\n- SQLite backup script\n- Git repository backup\n- Restore procedure documentation\n- Test restore from backup\n\nFile: deployment/agent-mail/backup.sh","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-07T22:43:43.417403-08:00","updated_at":"2025-11-07T22:43:43.417403-08:00","dependencies":[{"issue_id":"bd-19er","depends_on_id":"bd-z3s3","type":"blocks","created_at":"2025-11-07T23:04:28.122501-08:00","created_by":"daemon"}]}
|
||
{"id":"bd-7e7ddffa.1","title":"bd resolve-conflicts - Git merge conflict resolver","description":"Automatically resolve JSONL merge conflicts.\n\nModes:\n- Mechanical: ID remapping (no AI)\n- AI-assisted: Smart merge/keep decisions\n- Interactive: Review each conflict\n\nHandles \u003c\u003c\u003c\u003c\u003c\u003c\u003c conflict markers in .beads/beads.jsonl\n\nFiles: cmd/bd/resolve_conflicts.go (new)","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-28T14:48:30.083642-07:00","updated_at":"2025-10-30T17:12:58.220145-07:00"}
|
||
{"id":"bd-28db","title":"Add 'bd status' command for issue database overview","description":"Implement a bd status command that provides a quick snapshot of the issue database state, similar to how git status shows working tree state.\n\nExpected output: Show summary including counts by state (open, in-progress, blocked, closed), recent activity (last 7 days), and quick overview without needing multiple queries.\n\nExample output showing issue counts, recent activity stats, and pointer to bd list for details.\n\nProposed options: --all (show all issues), --assigned (show issues assigned to current user), --json (JSON format output)\n\nUse cases: Quick project health check, onboarding for new contributors, integration with shell prompts or CI/CD, daily standup reference","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-02T17:25:59.203549-08:00","updated_at":"2025-11-02T17:25:59.203549-08:00"}
|
||
{"id":"bd-4h3","title":"Add test coverage for internal/git package","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T21:21:23.497486-05:00","updated_at":"2025-11-20T21:21:23.497486-05:00","dependencies":[{"issue_id":"bd-4h3","depends_on_id":"bd-ge7","type":"blocks","created_at":"2025-11-20T21:21:31.277639-05:00","created_by":"daemon"}]}
|
||
{"id":"bd-yxy","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._","status":"closed","issue_type":"task","created_at":"2025-11-21T10:25:33.531631-05:00","updated_at":"2025-11-21T19:50:54.019588-05:00","closed_at":"2025-11-21T19:31:21.853136-05:00","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-ar2.8","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":"open","priority":3,"issue_type":"task","created_at":"2025-11-21T10:25:59.526543-05:00","updated_at":"2025-11-21T10:25:59.526543-05:00","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"}]}
|
||
{"id":"bd-dvd","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.","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-21T10:02:51.496365-05:00","updated_at":"2025-11-21T10:03:05.615526-05:00"}
|
||
{"id":"bd-bt6y","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"}
|
||
{"id":"bd-i00","title":"Convert magic numbers to named constants in FlushManager","status":"closed","priority":4,"issue_type":"task","created_at":"2025-11-20T21:22:17.845269-05:00","updated_at":"2025-11-21T10:59:00.409385-05:00","closed_at":"2025-11-20T21:35:53.11654-05:00"}
|
||
{"id":"bd-0a43","title":"Split monolithic sqlite.go into focused files","description":"internal/storage/sqlite/sqlite.go is 1050 lines containing initialization, 20+ CRUD methods, query building, and schema management.\n\nSplit into:\n- store.go: Store struct \u0026 initialization (150 lines)\n- bead_queries.go: Bead CRUD (300 lines)\n- work_queries.go: Work queries (200 lines) \n- stats_queries.go: Statistics (150 lines)\n- schema.go: Schema \u0026 migrations (150 lines)\n- helpers.go: Common utilities (100 lines)\n\nImpact: Impossible to understand at a glance; hard to find specific functionality; high cognitive load\n\nEffort: 6-8 hours","status":"open","issue_type":"task","created_at":"2025-11-16T14:51:16.520465-08:00","updated_at":"2025-11-16T14:51:16.520465-08:00"}
|
||
{"id":"bd-ymj","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","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-21T10:05:34.871333-05:00","updated_at":"2025-11-21T10:05:34.871333-05:00","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-t5o","title":"Document error handling strategy for metadata update failures","description":"Multiple places silently ignore metadata update failures (sync.go:614-617, import.go:320-322) with non-fatal warnings. This is intentional (degrades gracefully to mtime-based approach) but not well documented.\n\nAdd comments explaining:\n- Why these failures are non-fatal\n- How system degrades gracefully\n- What the fallback behavior is (mtime-based detection)","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-20T21:31:12.366861-05:00","updated_at":"2025-11-20T21:36:16.972395-05:00","closed_at":"2025-11-20T21:36:16.972395-05:00","dependencies":[{"issue_id":"bd-t5o","depends_on_id":"bd-khnb","type":"blocks","created_at":"2025-11-20T21:31:12.367744-05:00","created_by":"daemon"}]}
|
||
{"id":"bd-l954","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"}
|
||
{"id":"bd-e1085716","title":"bd validate - Comprehensive health check","description":"Run all validation checks in one command.\n\nChecks:\n- Duplicates\n- Orphaned dependencies\n- Test pollution\n- Git conflicts\n\nSupports --fix-all for auto-repair.\n\nDepends on bd-cbed9619.1, bd-0dcea000, bd-31aab707, bd-9826b69a.\n\nFiles: cmd/bd/validate.go (new)","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-29T23:05:13.980679-07:00","updated_at":"2025-10-30T17:12:58.19736-07:00"}
|
||
{"id":"bd-khnb","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","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"}
|
||
{"id":"bd-keb","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)","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"}
|
||
{"id":"bd-1rh","title":"cmd/bd test suite is absurdly slow - 279 tests taking 8+ minutes","description":"# Problem\n\nThe cmd/bd test suite is painfully slow:\n- **279 tests** in cmd/bd alone\n- Full suite takes **8+ minutes** to run\n- Even with the 16 slowest integration tests now tagged with `integration` build tag, the remaining tests still take forever\n\nThis makes the development loop unusable. We can't wait 8+ minutes every time we want to run tests.\n\n# Root Cause Analysis\n\n## 1. Sheer Volume\n279 tests is too many for a single package. Even at 0.1s per test, that's 28 seconds minimum just for cmd/bd.\n\n## 2. Each Test Creates Full Database + Temp Directories\nEvery test does heavy setup:\n- Creates temp directory (`t.TempDir()` or `os.MkdirTemp`)\n- Initializes SQLite database\n- Sets up git repo in many cases\n- Creates full storage layer\n\nExample from the tests:\n```go\nfunc setupCLITestDB(t *testing.T) string {\n tmpDir := createTempDirWithCleanup(t)\n runBDInProcess(t, tmpDir, \"init\", \"--prefix\", \"test\", \"--quiet\")\n return tmpDir\n}\n```\n\nThis happens 279 times!\n\n## 3. Tests Are Not Properly Categorized\nWe have three types of tests mixed together:\n- **Unit tests** - should be fast, test single functions\n- **Integration tests** - test full workflows, need DB/git\n- **End-to-end tests** - test entire CLI commands\n\nThey're all lumped together in cmd/bd, all running every time.\n\n# What We've Already Fixed\n\nAdded `integration` build tags to 16 obviously-slow test files:\n- import_profile_test.go (performance benchmarking tests)\n- export_mtime_test.go (tests with time.Sleep calls)\n- cli_fast_test.go (full CLI integration tests)\n- delete_test.go, import_uncommitted_test.go, sync_local_only_test.go (git integration)\n- And 10 more in internal/ packages\n\nThese are now excluded from the default `go test ./...` run.\n\n# Proposed Solutions\n\n## Option 1: Shared Test Fixtures (Quick Win)\nCreate a shared test database that multiple tests can use:\n```go\nvar testDB *sqlite.SQLiteStorage\nvar testDBOnce sync.Once\n\nfunc getSharedTestDB(t *testing.T) storage.Storage {\n testDBOnce.Do(func() {\n // Create one DB for all tests\n })\n return testDB\n}\n```\n\n**Pros**: Easy to implement, immediate speedup\n**Cons**: Tests become less isolated, harder to debug failures\n\n## Option 2: Table-Driven Tests (Medium Win)\nCollapse similar tests into table-driven tests:\n```go\nfunc TestCreate(t *testing.T) {\n tests := []struct{\n name string\n args []string\n want string\n }{\n {\"basic issue\", []string{\"create\", \"Test\"}, \"created\"},\n {\"with description\", []string{\"create\", \"Test\", \"-d\", \"desc\"}, \"created\"},\n // ... 50 more cases\n }\n \n db := setupOnce(t) // Setup once, not 50 times\n for _, tt := range tests {\n t.Run(tt.name, func(t *testing.T) {\n // test using shared db\n })\n }\n}\n```\n\n**Pros**: Dramatically reduces setup overhead, tests run in parallel\n**Cons**: Requires refactoring, tests share more state\n\n## Option 3: Split cmd/bd Tests Into Packages (Big Win)\nMove tests into focused packages:\n- `cmd/bd/internal/clitests` - CLI integration tests (mark with integration tag)\n- `cmd/bd/internal/unittests` - Fast unit tests\n- Keep only essential tests in cmd/bd\n\n**Pros**: Clean separation, easy to run just fast tests\n**Cons**: Requires significant refactoring\n\n## Option 4: Parallel Execution (Quick Win)\nAdd `t.Parallel()` to independent tests:\n```go\nfunc TestSomething(t *testing.T) {\n t.Parallel() // Run this test concurrently with others\n // ...\n}\n```\n\n**Pros**: Easy to add, can cut time in half on multi-core machines\n**Cons**: Doesn't reduce actual test work, just parallelizes it\n\n## Option 5: In-Memory Databases (Medium Win)\nUse `:memory:` SQLite databases instead of file-based:\n```go\nstore, err := sqlite.New(ctx, \":memory:\")\n```\n\n**Pros**: Faster than disk I/O, easier cleanup\n**Cons**: Some tests need actual file-based DBs (export/import tests)\n\n# Recommended Approach\n\n**Short-term (this week)**:\n1. Add `t.Parallel()` to all independent tests in cmd/bd\n2. Use `:memory:` databases where possible\n3. Create table-driven tests for similar test cases\n\n**Medium-term (next sprint)**:\n4. Split cmd/bd tests into focused packages\n5. Mark more integration tests appropriately\n\n**Long-term (backlog)**:\n6. Consider shared test fixtures with proper isolation\n\n# Current Status\n\nWe've tagged 16 files with `integration` build tag, but the remaining 279 tests in cmd/bd still take 8+ minutes. This issue tracks fixing the cmd/bd test performance specifically.\n\n# Target\n\nGet `go test ./...` (without `-short` or `-tags=integration`) down to **under 30 seconds**.\n\n\n# THE REAL ROOT CAUSE (Updated Analysis)\n\nAfter examining the actual test code, the problem is clear:\n\n## Every Test Creates Its Own Database From Scratch\n\nLook at `create_test.go`:\n```go\nfunc TestCreate_BasicIssue(t *testing.T) {\n tmpDir := t.TempDir() // ← Creates temp dir\n testDB := filepath.Join(tmpDir, \".beads\", \"beads.db\")\n s := newTestStore(t, testDB) // ← Opens NEW SQLite connection\n // ← Runs migrations\n // ← Sets config\n // ... actual test (3 lines)\n}\n\nfunc TestCreate_WithDescription(t *testing.T) {\n tmpDir := t.TempDir() // ← Creates ANOTHER temp dir\n testDB := filepath.Join(tmpDir, \".beads\", \"beads.db\")\n s := newTestStore(t, testDB) // ← Opens ANOTHER SQLite connection\n // ... actual test (3 lines)\n}\n```\n\n**This happens 279 times!**\n\n## These Tests Don't Need Isolation!\n\nMost tests are just checking:\n- \"Can I create an issue with a title?\"\n- \"Can I create an issue with a description?\"\n- \"Can I add labels?\"\n\nThey don't conflict with each other. They could all share ONE database!\n\n## The Fix: Test Suites with Shared Setup\n\nInstead of:\n```go\nfunc TestCreate_BasicIssue(t *testing.T) {\n s := newTestStore(t, t.TempDir()+\"/db\") // ← Expensive!\n // test\n}\n\nfunc TestCreate_WithDesc(t *testing.T) {\n s := newTestStore(t, t.TempDir()+\"/db\") // ← Expensive!\n // test\n}\n```\n\nDo this:\n```go\nfunc TestCreate(t *testing.T) {\n // ONE setup for all subtests\n s := newTestStore(t, t.TempDir()+\"/db\")\n \n t.Run(\"basic_issue\", func(t *testing.T) {\n t.Parallel() // Can run concurrently - tests don't conflict\n // test using shared `s`\n })\n \n t.Run(\"with_description\", func(t *testing.T) {\n t.Parallel()\n // test using shared `s`\n })\n \n // ... 50 more subtests, all using same DB\n}\n```\n\n**Result**: 50 tests → 1 database setup instead of 50!\n\n## Why This Works\n\nSQLite is fine with concurrent reads and isolated transactions. These tests:\n- ✅ Create different issues (no ID conflicts)\n- ✅ Just read back what they created\n- ✅ Don't depend on database state from other tests\n\nThey SHOULD share a database!\n\n## Real Numbers\n\nCurrent:\n- 279 tests × (create dir + init SQLite + migrations) = **8 minutes**\n\nAfter fix:\n- 10 test suites × (create dir + init SQLite + migrations) = **30 seconds**\n- 279 subtests running in parallel using those 10 DBs = **5 seconds**\n\n**Total: ~35 seconds instead of 8 minutes!**\n\n## Implementation Plan\n\n1. **Group related tests** into suites (Create, List, Update, Delete, etc.)\n2. **One setup per suite** instead of per test\n3. **Use t.Run() for subtests** with t.Parallel()\n4. **Keep tests that actually need isolation** separate (export/import tests, git operations)\n\nThis is way better than shuffling tests into folders!","notes":"## Progress Update (2025-11-21)\n\n✅ **Completed**:\n- Audited all 280 tests, created TEST_SUITE_AUDIT.md (bd-c49)\n- Refactored create_test.go to shared DB pattern (bd-y6d)\n- Proven the pattern works: 11 tests now run in 0.04s with 1 DB instead of 11\n\n❌ **Current Reality**:\n- Overall test suite: Still 8+ minutes (no meaningful change)\n- Only 1 of 76 test files refactored\n- Saved ~10 DB initializations out of 280\n\n## Acceptance Criteria (REALISTIC)\n\nThis task is NOT complete until:\n- [ ] All P1 files refactored (create ✅, dep, stale, comments, list, ready)\n- [ ] Test suite runs in \u003c 2 minutes\n- [ ] Measured and verified actual speedup\n\n## Next Steps\n\n1. Refactor remaining 5 P1 files: dep_test.go, stale_test.go, comments_test.go, list_test.go, ready_test.go\n2. Measure actual time improvement after each file\n3. Continue with P2 files if needed to hit \u003c2min target","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-21T11:37:47.886207-05:00","updated_at":"2025-11-21T16:07:50.844972-05:00","dependencies":[{"issue_id":"bd-1rh","depends_on_id":"bd-c49","type":"blocks","created_at":"2025-11-21T11:49:26.347518-05:00","created_by":"daemon"}]}
|
||
{"id":"bd-nq41","title":"Fix Homebrew warning about Ruby file location","description":"Homebrew warning: Found Ruby file outside steveyegge/beads tap formula directory.\nWarning points to: /opt/homebrew/Library/Taps/steveyegge/homebrew-beads/bd.rb\nIt should likely be inside a Formula/ directory or similar structure expected by Homebrew taps.\n","status":"open","priority":2,"issue_type":"chore","created_at":"2025-11-20T18:56:21.226579-05:00","updated_at":"2025-11-20T18:56:21.226579-05:00"}
|
||
{"id":"bd-da96-baseline-lint","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```","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"}
|
||
{"id":"bd-736d","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"}
|
||
{"id":"bd-xwo","title":"Fix validatePreExport to use content hash instead of mtime","description":"validatePreExport() in integrity.go:70 still uses isJSONLNewer() (mtime-based), creating inconsistent behavior. Auto-import correctly uses hasJSONLChanged() (hash-based) but export validation still uses the old mtime approach. This can cause false positive blocks after git operations.\n\nFix: Replace isJSONLNewer() call with hasJSONLChanged() in validatePreExport().\n\nImpact: Without this fix, the bd-khnb solution is incomplete - we prevent resurrection but still have export blocking issues.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T21:31:03.183164-05:00","updated_at":"2025-11-20T21:34:00.200803-05:00","closed_at":"2025-11-20T21:34:00.200803-05:00","dependencies":[{"issue_id":"bd-xwo","depends_on_id":"bd-khnb","type":"blocks","created_at":"2025-11-20T21:31:03.184049-05:00","created_by":"daemon"}]}
|
||
{"id":"bd-5xt","title":"Log errors from timer-triggered flushes instead of discarding","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-20T21:22:06.694953-05:00","updated_at":"2025-11-21T10:59:00.406689-05:00","closed_at":"2025-11-20T21:35:53.117434-05:00"}
|
||
{"id":"bd-hdt","title":"Implement auto-merge functionality in duplicates command","description":"The duplicates.go file has a TODO at line 95 to implement the performMerge function for automatic duplicate merging. Currently it just prints a warning message. This would automate the merge process instead of just suggesting commands.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-21T18:55:02.828619-05:00","updated_at":"2025-11-21T18:55:02.828619-05:00"}
|
||
{"id":"bd-ar2.9","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":"open","priority":3,"issue_type":"task","created_at":"2025-11-21T10:26:09.734162-05:00","updated_at":"2025-11-21T10:26:09.734162-05:00","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-r46","title":"Support --reason flag in daemon mode for reopen command","description":"The reopen.go command has a TODO at line 61 to add reason as a comment once RPC supports AddComment. Currently --reason flag is ignored in daemon mode with a warning.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-21T18:55:10.773626-05:00","updated_at":"2025-11-21T18:55:10.773626-05:00"}
|
||
{"id":"bd-49kw","title":"Workaround for FastMCP outputSchema bug in Claude Code","description":"The beads MCP server (v0.23.1) successfully connects to Claude Code, but all tools fail to load with a schema validation error due to a bug in FastMCP 2.13.1.\n\nError: \"Invalid literal value, expected \\\"object\\\"\" in outputSchema.\n\nRoot Cause: FastMCP generates outputSchema with $ref at root level without \"type\": \"object\" for self-referential models (Issue).\n\nWorkaround: Use slash commands (/beads:ready) or wait for FastMCP fix.\n","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-20T18:55:39.041831-05:00","updated_at":"2025-11-20T18:55:39.041831-05:00"}
|
||
{"id":"bd-t3b","title":"Add test coverage for internal/config package","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T21:21:22.91657-05:00","updated_at":"2025-11-20T21:21:22.91657-05:00","dependencies":[{"issue_id":"bd-t3b","depends_on_id":"bd-ge7","type":"blocks","created_at":"2025-11-20T21:21:31.201036-05:00","created_by":"daemon"}]}
|
||
{"id":"bd-77gm","title":"Import reports misleading '0 created, 0 updated' when actually importing all issues","description":"When running 'bd import' on a fresh database (no existing issues), the command reports 'Import complete: 0 created, 0 updated' even though it successfully imported all issues from the JSONL file.\n\n**Steps to reproduce:**\n1. Delete .beads/beads.db\n2. Run: bd import .beads/issues.jsonl\n3. Observe output: 'Import complete: 0 created, 0 updated'\n4. Run: bd list\n5. Confirm: All issues are actually present in the database\n\n**Expected behavior:**\nReport the actual number of issues imported, e.g., 'Import complete: 523 created, 0 updated'\n\n**Actual behavior:**\n'Import complete: 0 created, 0 updated' (misleading - makes user think import failed)\n\n**Impact:**\n- Users think import failed when it succeeded\n- Confusing during database sync operations (e.g., after git pull)\n- Makes debugging harder (can't tell if import actually worked)\n\n**Context:**\nDiscovered during VC session when syncing database after git pull. The misleading message caused confusion about whether the database was properly synced with the canonical JSONL file.","status":"open","priority":2,"issue_type":"bug","created_at":"2025-11-09T16:20:13.191156-08:00","updated_at":"2025-11-09T16:20:13.191156-08:00"}
|
||
{"id":"bd-4ri","title":"Fix TestFallbackToDirectModeEnablesFlush deadlock causing 10min test timeout","description":"## Problem\n\nTestFallbackToDirectModeEnablesFlush in direct_mode_test.go deadlocks for 9m59s before timing out, causing the entire test suite to take 10+ minutes instead of \u003c10 seconds.\n\n## Root Cause\n\nDatabase lock contention between test cleanup and flushToJSONL():\n- Test cleanup (line 36) tries to close DB via defer\n- flushToJSONL() (line 132) is still accessing DB\n- Results in deadlock: database/sql.(*DB).Close() waits for mutex while GetJSONLFileHash() holds it\n\n## Stack Trace Evidence\n\n```\ngoroutine 512 [sync.Mutex.Lock, 9 minutes]:\ndatabase/sql.(*DB).Close(0x14000643790)\n .../database/sql/sql.go:927 +0x84\ngithub.com/steveyegge/beads/cmd/bd.TestFallbackToDirectModeEnablesFlush.func1()\n .../direct_mode_test.go:36 +0xf4\n\nWhile goroutine running flushToJSONL() holds DB connection via GetJSONLFileHash()\n```\n\n## Impact\n\n- Test suite: 10+ minutes → should be \u003c10 seconds\n- ALL other tests pass in ~4 seconds\n- This ONE test accounts for 99.9% of test runtime\n\n## Related\n\nThis is the EXACT same issue documented in MAIN_TEST_REFACTOR_NOTES.md for why main_test.go refactoring was deferred - global state manipulation + DB cleanup = deadlock.\n\n## Fix Approaches\n\n1. **Add proper cleanup sequencing** - stop flush goroutines BEFORE closing DB\n2. **Use test-specific DB lifecycle** - ensure flush completes before cleanup\n3. **Mock the flush mechanism** - avoid real DB for testing this code path \n4. **Add explicit timeout handling** - fail fast with clear error instead of hanging\n\n## Files\n\n- cmd/bd/direct_mode_test.go:36-132\n- cmd/bd/autoflush.go:353 (validateJSONLIntegrity)\n- cmd/bd/autoflush.go:508 (flushToJSONLWithState)\n\n## Acceptance\n\n- Test passes without timeout\n- Test suite completes in \u003c10 seconds\n- No deadlock between cleanup and flush operations","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-21T20:09:00.794372-05:00","updated_at":"2025-11-21T20:09:00.794372-05:00"}
|
||
{"id":"bd-7yg","title":"Git merge driver uses invalid placeholders (%L, %R instead of %A, %B)","description":"## Problem\n\nThe beads git merge driver is configured with invalid Git placeholders:\n\n```\ngit config merge.beads.driver \"bd merge %A %O %L %R\"\n```\n\nGit doesn't recognize `%L` or `%R` as valid merge driver placeholders. The valid placeholders are:\n- `%O` = base (common ancestor)\n- `%A` = current version (ours)\n- `%B` = other version (theirs)\n\n## Impact\n\n- Affects ALL users when they have `.beads/beads.jsonl` merge conflicts\n- Automatic JSONL merge fails with error: \"error reading left file: failed to open file: open 7: no such file or directory\"\n- Users must manually resolve conflicts instead of getting automatic merge\n\n## Root Cause\n\nThe `bd init` command (or wherever the merge driver is configured) is using non-standard placeholders. When Git encounters `%L` and `%R`, it either passes them literally or interprets them incorrectly.\n\n## Fix\n\nUpdate the merge driver configuration to:\n```\ngit config merge.beads.driver \"bd merge %A %O %A %B\"\n```\n\nWhere:\n- 1st `%A` = output file (current file, will be overwritten)\n- `%O` = base (common ancestor)\n- 2nd `%A` = left/current version\n- `%B` = right/other version\n\n## Action Items\n\n1. Fix `bd init` (or equivalent setup command) to use correct placeholders\n2. Add migration/warning for existing users with misconfigured merge driver\n3. Update documentation with correct merge driver setup\n4. Consider adding validation when `bd init` is run","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-21T19:51:55.747608-05:00","updated_at":"2025-11-21T19:51:55.747608-05:00"}
|
||
{"id":"bd-1pj6","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"}
|
||
{"id":"bd-4aao","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"}
|
||
{"id":"bd-o78","title":"Enhance `bd doctor` to verify Claude Code integration","description":"Add checks to `bd doctor` that verify Claude Code integration is properly set up when .claude/ directory or Claude environment is detected.","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-11T23:30:05.782406-08:00","updated_at":"2025-11-12T00:12:07.717579-08:00","dependencies":[{"issue_id":"bd-o78","depends_on_id":"bd-90v","type":"parent-child","created_at":"2025-11-11T23:31:27.886095-08:00","created_by":"daemon"}]}
|
||
{"id":"bd-lm2q","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"}
|
||
{"id":"bd-t4u1","title":"False positive detection by Kaspersky Antivirus (Trojan)","description":"Kaspersky Antivirus falsely detects beads (bd.exe v0.23.1) as a Trojan (PDM:Trojan.Win32.Generic) and removes it.\nEvent: Malicious object detected\nComponent: System Watcher\nObject name: bd.exe\n","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-20T18:56:12.498187-05:00","updated_at":"2025-11-20T18:56:12.498187-05:00"}
|
||
{"id":"bd-581b80b3","title":"bd find-duplicates - AI-powered duplicate detection","description":"Find semantically duplicate issues.\n\nApproaches:\n1. Mechanical: Exact title/description matching\n2. Embeddings: Cosine similarity (cheap, scalable)\n3. AI: LLM-based semantic comparison (expensive, accurate)\n\nUses embeddings by default for \u003e100 issues.\n\nFiles: cmd/bd/find_duplicates.go (new)","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-29T20:49:49.126801-07:00","updated_at":"2025-10-30T17:12:58.218673-07:00"}
|
||
{"id":"bd-b55e2ac2","title":"Fix autoimport tests for content-hash collision scoring","description":"## Overview\nThree autoimport tests are failing after bd-cbed9619.4 because they expect behavior based on the old reference-counting collision resolution, but the system now uses deterministic content-hash scoring.\n\n## Failing Tests\n1. `TestAutoImportMultipleCollisionsRemapped` - expects local versions preserved\n2. `TestAutoImportAllCollisionsRemapped` - expects local versions preserved \n3. `TestAutoImportCollisionRemapMultipleFields` - expects specific collision resolution behavior\n\n## Root Cause\nThese tests were written when ScoreCollisions used reference counting to determine which version to keep. Now it uses content-hash comparison (introduced in commit 2e87329), which produces different but deterministic results.\n\n## Example\nOld behavior: Issue with more references would be kept\nNew behavior: Issue with lexicographically lower content hash is kept\n\n## Solution\nUpdate each test to:\n1. Verify the new content-hash based behavior is correct\n2. Check that the remapped issue (not necessarily local/remote) has the expected content\n3. Ensure dependencies are preserved on the correct remapped issue\n\n## Acceptance Criteria\n- All three autoimport tests pass\n- Tests verify content-hash determinism (same collision always resolves the same way)\n- Tests check dependency preservation on remapped issues\n- Test documentation explains content-hash scoring expectations\n\n## Files to Modify\n- `cmd/bd/autoimport_collision_test.go`\n\n## Testing\nRun: `go test ./cmd/bd -run \"TestAutoImport.*Collision\" -v`","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-28T19:17:28.358028-07:00","updated_at":"2025-10-30T17:12:58.179059-07:00"}
|
||
{"id":"bd-lln","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._","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-21T10:25:33.533653-05:00","updated_at":"2025-11-21T19:50:54.018403-05:00","closed_at":"2025-11-21T19:31:21.876949-05:00","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-ola6","title":"Implement transaction retry logic for SQLITE_BUSY","description":"BEGIN IMMEDIATE fails immediately on SQLITE_BUSY instead of retrying with exponential backoff.\n\nLocation: internal/storage/sqlite/sqlite.go:223-225\n\nProblem:\n- Under concurrent write load, BEGIN IMMEDIATE can fail with SQLITE_BUSY\n- Current implementation fails immediately instead of retrying\n- Results in spurious failures under normal concurrent usage\n\nSolution: Implement exponential backoff retry:\n- Retry up to N times (e.g., 5)\n- Backoff: 10ms, 20ms, 40ms, 80ms, 160ms\n- Check for context cancellation between retries\n- Only retry on SQLITE_BUSY/database locked errors\n\nImpact: Spurious failures under concurrent write load\n\nEffort: 3 hours","status":"open","priority":1,"issue_type":"feature","created_at":"2025-11-16T14:51:31.247147-08:00","updated_at":"2025-11-16T14:51:31.247147-08:00"}
|
||
{"id":"bd-98c4e1fa.1","title":"Update AGENTS.md with event-driven mode","description":"Document BEADS_DAEMON_MODE env var. Explain opt-in during Phase 1. Add troubleshooting for watcher failures.","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-29T23:05:13.986452-07:00","updated_at":"2025-10-31T20:36:49.381832-07:00"}
|
||
{"id":"bd-ee1","title":"Add security tests for WriteFile permissions in doctor command","description":"Test coverage gap identified by automated analysis (vc-217).\n\n**Original Issue:** [deleted:bd-da96-baseline-lint]\n\nIn cmd/bd/doctor/gitignore.go:98, os.WriteFile uses 0644 permissions, flagged by gosec G306 as potentially too permissive.\n\nAdd tests to verify:\n- File is created with appropriate permissions (0600 or less)\n- Existing file permissions are not loosened\n- File ownership is correct\n- Sensitive data handling if .gitignore contains secrets\n\nThis ensures .gitignore files are created with secure permissions to prevent unauthorized access.\n\n_This issue was automatically created by AI test coverage analysis._","status":"open","priority":1,"issue_type":"task","created_at":"2025-11-21T10:25:33.529153-05:00","updated_at":"2025-11-21T15:51:09.352377-05:00","dependencies":[{"issue_id":"bd-ee1","depends_on_id":"bd-da96-baseline-lint","type":"discovered-from","created_at":"2025-11-21T10:25:33.530705-05:00","created_by":"ai-supervisor"}]}
|