From 38ae26d9e9a1844246b408a407eb0f86f861e101 Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Wed, 15 Oct 2025 02:07:33 -0700 Subject: [PATCH] docs: Add critical bug warning banner to README (bd-228) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CRITICAL: Auto-import silently overwrites local changes without collision detection. Changes: - Added prominent warning banner at top of README - Documents data corruption risk for multi-developer workflows - Provides --no-auto-import workaround - References bd-228 for tracking and updates This affects anyone using bd with multiple developers or agent swarms. Local updates/closes can be silently reverted by auto-import after git pull. Also includes: - ULTRATHINK_BD224.md analysis document (bd-224, bd-225) - Updated issues.jsonl with bd-224, bd-225, bd-226, bd-227, bd-228 πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .beads/issues.jsonl | 425 ++++++++++++++++++++++---------------------- README.md | 16 ++ ULTRATHINK_BD224.md | 373 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 604 insertions(+), 210 deletions(-) create mode 100644 ULTRATHINK_BD224.md diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 831d8c25..5704c57b 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,210 +1,215 @@ -{"id":"bd-1","title":"Critical bug","description":"","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-12T00:43:03.453438-07:00","updated_at":"2025-10-15T01:08:12.759903-07:00","closed_at":"2025-10-12T20:20:06.977679-07:00"} -{"id":"bd-10","title":"Add PostgreSQL backend","description":"Implement PostgreSQL storage backend as alternative to SQLite for larger teams","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-10-12T14:32:19.163526-07:00","updated_at":"2025-10-15T01:08:12.761037-07:00","closed_at":"2025-10-12T15:07:47.937992-07:00","dependencies":[{"issue_id":"bd-10","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-12T14:35:59.213222-07:00","created_by":"stevey"}]} -{"id":"bd-100","title":"parallel_test_10","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:46.946477-07:00","updated_at":"2025-10-15T01:08:12.761324-07:00"} -{"id":"bd-101","title":"parallel_test_3","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:46.971429-07:00","updated_at":"2025-10-15T01:08:12.761499-07:00"} -{"id":"bd-102","title":"parallel_test_8","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:46.997449-07:00","updated_at":"2025-10-15T01:08:12.761659-07:00"} -{"id":"bd-103","title":"parallel_test_9","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:46.998608-07:00","updated_at":"2025-10-15T01:08:12.763251-07:00"} -{"id":"bd-104","title":"parallel_26","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:51.254662-07:00","updated_at":"2025-10-15T01:08:12.763492-07:00"} -{"id":"bd-105","title":"parallel_31","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:51.255055-07:00","updated_at":"2025-10-15T01:08:12.763672-07:00"} -{"id":"bd-106","title":"parallel_32","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:51.255348-07:00","updated_at":"2025-10-15T01:08:12.766689-07:00"} -{"id":"bd-107","title":"parallel_33","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:51.255454-07:00","updated_at":"2025-10-15T01:08:12.766893-07:00"} -{"id":"bd-108","title":"parallel_28","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:51.255731-07:00","updated_at":"2025-10-15T01:08:12.767074-07:00"} -{"id":"bd-109","title":"parallel_29","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:51.255867-07:00","updated_at":"2025-10-15T01:08:12.767239-07:00"} -{"id":"bd-11","title":"Test issue to verify fix","description":"This should be bd-11 if the fix works","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-12T14:40:21.419082-07:00","updated_at":"2025-10-15T01:08:12.767402-07:00","closed_at":"2025-10-12T14:40:32.963312-07:00"} -{"id":"bd-110","title":"parallel_27","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:51.255932-07:00","updated_at":"2025-10-15T01:08:12.767566-07:00"} -{"id":"bd-111","title":"parallel_30","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:51.258491-07:00","updated_at":"2025-10-15T01:08:12.767744-07:00"} -{"id":"bd-112","title":"parallel_35","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:51.258879-07:00","updated_at":"2025-10-15T01:08:12.768068-07:00"} -{"id":"bd-113","title":"parallel_34","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:51.265162-07:00","updated_at":"2025-10-15T01:08:12.768245-07:00"} -{"id":"bd-114","title":"stress_3","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.092233-07:00","updated_at":"2025-10-15T01:08:12.768401-07:00"} -{"id":"bd-115","title":"stress_5","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.092311-07:00","updated_at":"2025-10-15T01:08:12.768561-07:00"} -{"id":"bd-116","title":"stress_10","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.093319-07:00","updated_at":"2025-10-15T01:08:12.768734-07:00"} -{"id":"bd-117","title":"stress_2","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.093453-07:00","updated_at":"2025-10-15T01:08:12.768931-07:00"} -{"id":"bd-118","title":"stress_8","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.093516-07:00","updated_at":"2025-10-15T01:08:12.769089-07:00"} -{"id":"bd-119","title":"stress_13","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.094405-07:00","updated_at":"2025-10-15T01:08:12.769269-07:00"} -{"id":"bd-12","title":"Implement collision detection in import","description":"Create collision.go with detectCollisions() function. Compare incoming JSONL issues against DB state. Distinguish between: (1) exact match (idempotent), (2) ID match but different content (collision), (3) new issue. Return list of colliding issues.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-12T14:40:56.056588-07:00","updated_at":"2025-10-15T01:08:12.769476-07:00","closed_at":"2025-10-12T16:06:25.575038-07:00","dependencies":[{"issue_id":"bd-12","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-12T14:41:07.947358-07:00","created_by":"stevey"}]} -{"id":"bd-120","title":"stress_14","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.094519-07:00","updated_at":"2025-10-15T01:08:12.769641-07:00"} -{"id":"bd-121","title":"stress_1","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.095805-07:00","updated_at":"2025-10-15T01:08:12.771379-07:00"} -{"id":"bd-122","title":"stress_7","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.096461-07:00","updated_at":"2025-10-15T01:08:12.771615-07:00"} -{"id":"bd-123","title":"stress_17","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.096904-07:00","updated_at":"2025-10-15T01:08:12.771831-07:00"} -{"id":"bd-124","title":"stress_6","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.097331-07:00","updated_at":"2025-10-15T01:08:12.772021-07:00"} -{"id":"bd-125","title":"stress_19","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.098391-07:00","updated_at":"2025-10-15T01:08:12.7722-07:00"} -{"id":"bd-126","title":"stress_20","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.098827-07:00","updated_at":"2025-10-15T01:08:12.772375-07:00"} -{"id":"bd-127","title":"stress_15","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.099861-07:00","updated_at":"2025-10-15T01:08:12.772596-07:00"} -{"id":"bd-128","title":"stress_24","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.100328-07:00","updated_at":"2025-10-15T01:08:12.772789-07:00"} -{"id":"bd-129","title":"stress_18","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.100957-07:00","updated_at":"2025-10-15T01:08:12.772979-07:00"} -{"id":"bd-13","title":"Implement reference scoring algorithm","description":"Count references for each colliding issue: text mentions in descriptions/notes/design fields + dependency references. Sort collisions by score ascending (fewest refs first). This minimizes total updates during renumbering.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-12T14:40:56.204518-07:00","updated_at":"2025-10-15T01:08:12.773151-07:00","closed_at":"2025-10-12T16:26:46.572201-07:00","dependencies":[{"issue_id":"bd-13","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-12T14:41:07.951605-07:00","created_by":"stevey"}]} -{"id":"bd-130","title":"stress_22","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.101073-07:00","updated_at":"2025-10-15T01:08:12.773322-07:00"} -{"id":"bd-131","title":"stress_28","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.101635-07:00","updated_at":"2025-10-15T01:08:12.773481-07:00"} -{"id":"bd-132","title":"stress_25","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.101763-07:00","updated_at":"2025-10-15T01:08:12.773659-07:00"} -{"id":"bd-133","title":"stress_29","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.102151-07:00","updated_at":"2025-10-15T01:08:12.773818-07:00"} -{"id":"bd-134","title":"stress_26","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.102208-07:00","updated_at":"2025-10-15T01:08:12.773988-07:00"} -{"id":"bd-135","title":"stress_9","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.103216-07:00","updated_at":"2025-10-15T01:08:12.774142-07:00"} -{"id":"bd-136","title":"stress_30","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.103737-07:00","updated_at":"2025-10-15T01:08:12.774292-07:00"} -{"id":"bd-137","title":"stress_32","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.104085-07:00","updated_at":"2025-10-15T01:08:12.774449-07:00"} -{"id":"bd-138","title":"stress_16","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.104635-07:00","updated_at":"2025-10-15T01:08:12.774603-07:00"} -{"id":"bd-139","title":"stress_27","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.105136-07:00","updated_at":"2025-10-15T01:08:12.774769-07:00"} -{"id":"bd-14","title":"Implement ID remapping with reference updates","description":"Allocate new IDs for colliding issues. Update all text field references using word-boundary regex (\\bbd-10\\b). Update dependency records. Build id_mapping for reporting. Handle chain dependencies properly.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-12T14:40:56.367596-07:00","updated_at":"2025-10-15T01:08:12.77492-07:00","closed_at":"2025-10-12T16:35:13.159992-07:00","dependencies":[{"issue_id":"bd-14","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-12T14:41:07.956041-07:00","created_by":"stevey"}]} -{"id":"bd-140","title":"stress_31","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.105666-07:00","updated_at":"2025-10-15T01:08:12.775094-07:00"} -{"id":"bd-141","title":"stress_35","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.106196-07:00","updated_at":"2025-10-15T01:08:12.77528-07:00"} -{"id":"bd-142","title":"stress_37","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.106722-07:00","updated_at":"2025-10-15T01:08:12.775446-07:00"} -{"id":"bd-143","title":"stress_34","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.107203-07:00","updated_at":"2025-10-15T01:08:12.775601-07:00"} -{"id":"bd-144","title":"stress_36","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.108466-07:00","updated_at":"2025-10-15T01:08:12.775754-07:00"} -{"id":"bd-145","title":"stress_21","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.108868-07:00","updated_at":"2025-10-15T01:08:12.775907-07:00"} -{"id":"bd-146","title":"stress_38","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.109501-07:00","updated_at":"2025-10-15T01:08:12.776085-07:00"} -{"id":"bd-147","title":"stress_42","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.109907-07:00","updated_at":"2025-10-15T01:08:12.776241-07:00"} -{"id":"bd-148","title":"stress_43","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.109971-07:00","updated_at":"2025-10-15T01:08:12.776399-07:00"} -{"id":"bd-149","title":"stress_39","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.110079-07:00","updated_at":"2025-10-15T01:08:12.776554-07:00"} -{"id":"bd-15","title":"Add --resolve-collisions flag and user reporting","description":"Add import flags: --resolve-collisions (auto-fix) and --dry-run (preview). Display clear report: collisions detected, remappings applied (oldβ†’new with scores), reference counts updated. Default behavior: fail on collision (safe).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-12T14:40:56.534721-07:00","updated_at":"2025-10-15T01:08:12.776725-07:00","closed_at":"2025-10-12T16:47:11.491645-07:00","dependencies":[{"issue_id":"bd-15","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-12T14:41:07.961157-07:00","created_by":"stevey"}]} -{"id":"bd-150","title":"stress_45","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.110194-07:00","updated_at":"2025-10-15T01:08:12.776884-07:00"} -{"id":"bd-151","title":"stress_46","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.110798-07:00","updated_at":"2025-10-15T01:08:12.777038-07:00"} -{"id":"bd-152","title":"stress_48","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.111726-07:00","updated_at":"2025-10-15T01:08:12.777225-07:00"} -{"id":"bd-153","title":"stress_44","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.111834-07:00","updated_at":"2025-10-15T01:08:12.777377-07:00"} -{"id":"bd-154","title":"stress_40","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.112308-07:00","updated_at":"2025-10-15T01:08:12.777529-07:00"} -{"id":"bd-155","title":"stress_41","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.113413-07:00","updated_at":"2025-10-15T01:08:12.777684-07:00"} -{"id":"bd-156","title":"stress_12","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.114106-07:00","updated_at":"2025-10-15T01:08:12.777867-07:00"} -{"id":"bd-157","title":"stress_47","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.114674-07:00","updated_at":"2025-10-15T01:08:12.77804-07:00"} -{"id":"bd-158","title":"stress_49","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.115792-07:00","updated_at":"2025-10-15T01:08:12.778242-07:00"} -{"id":"bd-159","title":"stress_50","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.115854-07:00","updated_at":"2025-10-15T01:08:12.778397-07:00"} -{"id":"bd-16","title":"Write comprehensive collision resolution tests","description":"Test cases: simple collision, multiple collisions, dependency updates, text reference updates, chain dependencies, edge cases (partial ID matches, case sensitivity, triple merges). Add to import_test.go and collision_test.go.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-12T14:40:56.702127-07:00","updated_at":"2025-10-15T01:08:12.77855-07:00","closed_at":"2025-10-12T16:54:25.273886-07:00","dependencies":[{"issue_id":"bd-16","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-12T14:41:07.965816-07:00","created_by":"stevey"}]} -{"id":"bd-160","title":"stress_33","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.117101-07:00","updated_at":"2025-10-15T01:08:12.778702-07:00"} -{"id":"bd-161","title":"stress_23","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.122506-07:00","updated_at":"2025-10-15T01:08:12.778854-07:00"} -{"id":"bd-162","title":"stress_11","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.13063-07:00","updated_at":"2025-10-15T01:08:12.779012-07:00"} -{"id":"bd-163","title":"stress_4","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:55.131872-07:00","updated_at":"2025-10-15T01:08:12.779194-07:00"} -{"id":"bd-164","title":"Add visual indicators for nodes with multiple parents in dep tree","description":"When a node appears in the dependency tree via multiple paths (diamond dependencies), add a visual indicator like (*) or (multiple parents) to help users understand the graph structure. This would make it clear when deduplication has occurred. Example: 'bd-503: Shared dependency (*) [P1] (open)'","status":"open","priority":3,"issue_type":"feature","created_at":"2025-10-14T03:10:49.222828-07:00","updated_at":"2025-10-15T01:08:12.779365-07:00","dependencies":[{"issue_id":"bd-164","depends_on_id":"bd-85","type":"discovered-from","created_at":"2025-10-14T03:11:00.326599-07:00","created_by":"stevey"}]} -{"id":"bd-165","title":"Add --show-all-paths flag to bd dep tree","description":"Currently bd dep tree deduplicates nodes when multiple paths exist (diamond dependencies). Add optional --show-all-paths flag to display the full graph with all paths, showing duplicates. Useful for debugging complex dependency structures and understanding all relationships.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-10-14T03:10:50.337481-07:00","updated_at":"2025-10-15T01:08:12.780274-07:00","dependencies":[{"issue_id":"bd-165","depends_on_id":"bd-85","type":"discovered-from","created_at":"2025-10-14T03:11:00.3313-07:00","created_by":"stevey"}]} -{"id":"bd-166","title":"Make maxDepth configurable in bd dep tree command","description":"Currently maxDepth is hardcoded to 50 in GetDependencyTree. Add --max-depth flag to bd dep tree command to allow users to control recursion depth. Default should remain 50 for safety, but users with very deep trees or wanting shallow views should be able to configure it.","status":"open","priority":4,"issue_type":"feature","created_at":"2025-10-14T03:10:51.883256-07:00","updated_at":"2025-10-15T01:08:12.780467-07:00","dependencies":[{"issue_id":"bd-166","depends_on_id":"bd-85","type":"discovered-from","created_at":"2025-10-14T03:11:00.336267-07:00","created_by":"stevey"}]} -{"id":"bd-167","title":"Test issue with --deps flag","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T03:24:21.100585-07:00","updated_at":"2025-10-15T01:08:12.782309-07:00","closed_at":"2025-10-14T03:24:46.260976-07:00","dependencies":[{"issue_id":"bd-167","depends_on_id":"bd-89","type":"discovered-from","created_at":"2025-10-14T03:24:21.100912-07:00","created_by":"stevey"}]} -{"id":"bd-168","title":"Another test with multiple deps","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T03:24:32.746757-07:00","updated_at":"2025-10-15T01:08:12.782523-07:00","closed_at":"2025-10-14T03:24:46.261275-07:00","dependencies":[{"issue_id":"bd-168","depends_on_id":"bd-89","type":"blocks","created_at":"2025-10-14T03:24:32.747029-07:00","created_by":"stevey"},{"issue_id":"bd-168","depends_on_id":"bd-90","type":"blocks","created_at":"2025-10-14T03:24:32.747181-07:00","created_by":"stevey"}]} -{"id":"bd-169","title":"Fix: bd init --prefix test -q flag not recognized","description":"The init command doesn't recognize the -q flag. When running 'bd init --prefix test -q', it fails silently or behaves unexpectedly. The flag should either be implemented for quiet mode or removed from documentation if not supported.","status":"open","priority":2,"issue_type":"bug","created_at":"2025-10-14T12:33:51.614293-07:00","updated_at":"2025-10-15T01:08:12.782748-07:00"} -{"id":"bd-17","title":"Update documentation for collision resolution","description":"Update README.md with collision resolution section. Update CLAUDE.md with new workflow. Document --resolve-collisions and --dry-run flags. Add example scenarios showing branch merge workflows.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-12T14:40:56.866649-07:00","updated_at":"2025-10-15T01:08:12.782924-07:00","closed_at":"2025-10-12T17:06:14.930928-07:00","dependencies":[{"issue_id":"bd-17","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-12T14:41:07.970302-07:00","created_by":"stevey"}]} -{"id":"bd-170","title":"Add OAuth2 support","description":"Implement OAuth2 authentication flow with support for Google and GitHub providers.","design":"- Create OAuth2 provider interface\n- Implement Google provider\n- Implement GitHub provider\n- Add callback handler\n- Store tokens securely","acceptance_criteria":"- Users can authenticate with Google\n- Users can authenticate with GitHub\n- Tokens are stored securely in database\n- Token refresh works automatically","status":"closed","priority":1,"issue_type":"feature","assignee":"alice","created_at":"2025-10-14T12:40:30.990247-07:00","updated_at":"2025-10-15T01:08:12.783094-07:00","closed_at":"2025-10-14T12:40:50.292308-07:00"} -{"id":"bd-171","title":"Add rate limiting to auth endpoints","description":"Auth endpoints are vulnerable to brute force attacks. Need to add rate limiting.","status":"closed","priority":0,"issue_type":"bug","assignee":"bob","created_at":"2025-10-14T12:40:30.996332-07:00","updated_at":"2025-10-15T01:08:12.783396-07:00","closed_at":"2025-10-14T12:40:50.293099-07:00"} -{"id":"bd-172","title":"Improve session management","description":"Current session management is basic. Need to improve with better expiration handling.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T12:40:30.997104-07:00","updated_at":"2025-10-15T01:08:12.783557-07:00","closed_at":"2025-10-14T12:40:50.29329-07:00"} -{"id":"bd-173","title":"Refactor parseMarkdownFile to reduce cyclomatic complexity","description":"The parseMarkdownFile function in cmd/bd/markdown.go has a cyclomatic complexity of 38, which exceeds the recommended threshold of 30. This makes the function harder to understand, test, and maintain.","design":"Split the function into smaller, focused units:\n\n1. parseMarkdownFile(filepath) - Main entry point, handles file I/O\n2. parseMarkdownContent(scanner) - Core parsing logic\n3. processIssueSection(issue, section, content) - Handle section finalization (current switch statement)\n4. parseLabels(content) []string - Extract labels from content\n5. parseDependencies(content) []string - Extract dependencies from content\n6. parsePriority(content) int - Parse and validate priority\n\nBenefits:\n- Each function has a single responsibility\n- Easier to test individual components\n- Lower cognitive load when reading code\n- Better encapsulation of parsing logic","acceptance_criteria":"- parseMarkdownFile complexity \u003c 15\n- New helper functions each have complexity \u003c 10\n- All existing tests still pass\n- No change in functionality or behavior\n- Code coverage maintained or improved","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-14T12:51:21.241236-07:00","updated_at":"2025-10-15T01:08:12.78372-07:00","closed_at":"2025-10-14T12:55:35.140001-07:00","dependencies":[{"issue_id":"bd-173","depends_on_id":"bd-91","type":"discovered-from","created_at":"2025-10-14T12:51:21.24297-07:00","created_by":"stevey"}]} -{"id":"bd-174","title":"Add OAuth2 support","description":"Implement OAuth2 authentication flow with support for Google and GitHub providers.","design":"- Create OAuth2 provider interface\n- Implement Google provider\n- Implement GitHub provider\n- Add callback handler\n- Store tokens securely","acceptance_criteria":"- Users can authenticate with Google\n- Users can authenticate with GitHub\n- Tokens are stored securely in database\n- Token refresh works automatically","status":"closed","priority":1,"issue_type":"feature","assignee":"alice","created_at":"2025-10-14T12:55:09.226351-07:00","updated_at":"2025-10-15T01:08:12.784175-07:00","closed_at":"2025-10-14T12:55:17.818093-07:00"} -{"id":"bd-175","title":"Add rate limiting to auth endpoints","description":"Auth endpoints are vulnerable to brute force attacks. Need to add rate limiting.","status":"closed","priority":0,"issue_type":"bug","assignee":"bob","created_at":"2025-10-14T12:55:09.228394-07:00","updated_at":"2025-10-15T01:08:12.784331-07:00","closed_at":"2025-10-14T12:55:17.819352-07:00"} -{"id":"bd-176","title":"Improve session management","description":"Current session management is basic. Need to improve with better expiration handling.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T12:55:09.228919-07:00","updated_at":"2025-10-15T01:08:12.784477-07:00","closed_at":"2025-10-14T12:55:17.819557-07:00"} -{"id":"bd-177","title":"Add OAuth2 support","description":"Implement OAuth2 authentication flow with support for Google and GitHub providers.","design":"- Create OAuth2 provider interface\n- Implement Google provider\n- Implement GitHub provider\n- Add callback handler\n- Store tokens securely","acceptance_criteria":"- Users can authenticate with Google\n- Users can authenticate with GitHub\n- Tokens are stored securely in database\n- Token refresh works automatically","status":"closed","priority":1,"issue_type":"feature","assignee":"alice","created_at":"2025-10-14T13:01:35.935497-07:00","updated_at":"2025-10-15T01:08:12.784602-07:00","closed_at":"2025-10-14T13:01:35.950067-07:00"} -{"id":"bd-178","title":"Add rate limiting to auth endpoints","description":"Auth endpoints are vulnerable to brute force attacks. Need to add rate limiting.","status":"closed","priority":0,"issue_type":"bug","assignee":"bob","created_at":"2025-10-14T13:01:35.937662-07:00","updated_at":"2025-10-15T01:08:12.784729-07:00","closed_at":"2025-10-14T13:01:35.950387-07:00"} -{"id":"bd-179","title":"Improve session management","description":"Current session management is basic. Need to improve with better expiration handling.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T13:01:35.93812-07:00","updated_at":"2025-10-15T01:08:12.786099-07:00","closed_at":"2025-10-14T13:01:35.950517-07:00"} -{"id":"bd-18","title":"Add design/notes/acceptance_criteria fields to update command","description":"Currently bd update only supports status, priority, title, assignee. Add support for --design, --notes, --acceptance-criteria flags. This makes it easier to add detailed designs to issues after creation.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-12T14:40:57.032395-07:00","updated_at":"2025-10-15T01:08:12.786275-07:00","closed_at":"2025-10-12T17:10:53.958318-07:00"} -{"id":"bd-180","title":"Investigate vector/semantic search for issue discovery","description":"From GH issue #2 RFC discussion: Evaluate if vector/semantic search over issues would provide value for beads.\n\n**Use case:** Find semantically related issues (e.g., 'login broken' finds 'authentication failure', 'session expired').\n\n**Questions to answer:**\n1. What workflows would this enable that we can't do now?\n2. Is dataset size (typically 50-200 issues) large enough to benefit?\n3. Do structured features (deps, tags, types) already provide better relationships?\n4. What's the maintenance cost (embeddings, storage, recomputation)?\n\n**Alternatives to consider:**\n- Improve 'bd list' filtering with regex/boolean queries\n- Add 'bd related \u003cid\u003e' showing deps + mentions + same tags\n- Export to JSON and pipe to external AI tools\n\n**Decision:** Only implement if clear use case emerges. Don't add complexity for theoretical benefits.\n\n**Context:** Part of evaluating Turso RFC ideas (GH #2). Vector search was proposed but unclear if needed for typical beads usage.","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:16:51.769118-07:00","updated_at":"2025-10-15T01:08:12.786418-07:00"} -{"id":"bd-181","title":"Implement storage driver interface for pluggable backends","description":"Create abstraction layer for storage to support multiple backends (SQLite, Postgres, Turso, in-memory testing, etc.).\n\n**Current state:** All storage logic hardcoded to SQLite in internal/storage/sqlite/sqlite.go\n\n**Proposed design:**\n\n```go\n// internal/storage/storage.go\ntype Store interface {\n // Issue CRUD\n CreateIssue(issue *Issue) error\n GetIssue(id string) (*Issue, error)\n UpdateIssue(id string, updates *Issue) error\n DeleteIssue(id string) error\n ListIssues(filter *Filter) ([]*Issue, error)\n \n // Dependencies\n AddDependency(from, to string, depType DependencyType) error\n RemoveDependency(from, to string, depType DependencyType) error\n GetDependencies(id string) ([]*Dependency, error)\n \n // Counters, stats\n GetNextID(prefix string) (string, error)\n GetStats() (*Stats, error)\n \n Close() error\n}\n```\n\n**Benefits:**\n- Better testing (mock/in-memory stores)\n- Future flexibility (Postgres, cloud APIs, etc.)\n- Clean architecture (business logic decoupled from storage)\n- Enable Turso or other backends without refactoring everything\n\n**Implementation steps:**\n1. Define Store interface in internal/storage/storage.go\n2. Refactor SQLiteStore to implement interface\n3. Update all commands to use interface, not concrete type\n4. Add MemoryStore for testing\n5. Add driver selection via config (storage.driver = sqlite|turso|postgres)\n6. Update tests to use interface\n\n**Note:** This is valuable even without adopting Turso. Good architecture practice.\n\n**Context:** From GH issue #2 RFC evaluation. Driver interface is low-cost, high-value regardless of whether we add alternative backends.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-14T14:20:38.678143-07:00","updated_at":"2025-10-15T01:08:12.78656-07:00"} -{"id":"bd-182","title":"Investigate auto-export debounce not triggering","description":"Auto-export to JSONL did not trigger automatically after creating bd-180 and bd-181. Had to manually run 'bd export' to sync.\n\n**Expected behavior:** Auto-export should trigger ~5 seconds after CRUD operations (per CLAUDE.md documentation).\n\n**Actual behavior:** Issues bd-180 and bd-181 were created but JSONL was not updated until manual 'bd export' was run.\n\n**Investigation needed:**\n1. Check if auto-flush goroutine is running\n2. Verify debounce timer is being triggered on CreateIssue()\n3. Check for errors/panics in background export\n4. Verify auto-flush is enabled by default\n5. Check if there's a race condition with shutdown\n\n**Impact:** HIGH - Data loss risk if users create issues and don't realize they haven't synced to Git.\n\n**Testing:**\n```bash\n# Create issue and wait 10 seconds\nbd create \"Test\" -p 4\nsleep 10\ngrep \"Test\" .beads/issues.jsonl # Should find it\n```\n\n**Workaround:** Manually run 'bd export' after CRUD operations.\n\n**Context:** Discovered during GH issue #2 RFC evaluation while creating bd-180 and bd-181.","notes":"**Investigation Results:**\n\nThe auto-export feature IS working correctly in the current codebase (v0.9.5). Testing shows:\n\nβœ… Storage layer marks issues dirty correctly (lines 415-423, 593-601, 633-641 in sqlite.go)\nβœ… CLI calls markDirtyAndScheduleFlush() after CRUD operations (lines 766, 1000, 1055 in main.go)\nβœ… Debounce timer (5s) triggers and exports to JSONL successfully\nβœ… Tested: Created bd-196, auto-exported within 6 seconds\n\n**Root Cause:**\nThe issue was caused by running an **old bd binary** that didn't have the complete auto-export implementation. After rebuilding (`go build -o bd ./cmd/bd`), auto-export works perfectly.\n\n**Resolution:**\nUsers experiencing this issue need to:\n1. Rebuild bd: `go build -o bd ./cmd/bd`\n2. Install updated binary: `sudo mv bd /usr/local/bin/` (or appropriate path)\n3. Verify: `bd version` should show 0.9.5+\n\n**Additional Notes:**\n- Auto-export uses 5-second debounce (configurable at main.go:36)\n- Exports are atomic (writes to .tmp, then renames)\n- Only dirty issues are exported (incremental updates)\n- Works correctly in production use\n\n**Follow-up:**\nConsider adding a version check warning if user's binary is outdated (bd-408).","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-14T14:25:22.256823-07:00","updated_at":"2025-10-15T01:08:12.786854-07:00"} -{"id":"bd-183","title":"Plugin manifest has invalid 'engines' field causing marketplace install failure","description":"The plugin.json manifest includes an 'engines' field that Claude Code doesn't recognize. This causes the plugin to fail validation when installed via /plugin marketplace add.\n\nError: Plugin beads has an invalid manifest file at .claude-plugin/plugin.json. Validation errors: : Unrecognized key(s) in object: 'engines'\n\nFix: Remove the 'engines' field from plugin.json\n\nThe engines field was added to specify minimum beads version requirements, but Claude Code's plugin manifest schema doesn't support it. We should document version requirements in PLUGIN.md instead.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-14T17:11:11.515979-07:00","updated_at":"2025-10-15T01:08:12.787016-07:00"} -{"id":"bd-184","title":"race_test_4","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T23:43:42.39436-07:00","updated_at":"2025-10-15T01:08:12.787147-07:00"} -{"id":"bd-185","title":"race_test_8","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T23:43:42.396837-07:00","updated_at":"2025-10-15T01:08:12.787273-07:00"} -{"id":"bd-186","title":"race_test_5","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T23:43:42.398506-07:00","updated_at":"2025-10-15T01:08:12.787398-07:00"} -{"id":"bd-187","title":"race_test_16","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T23:43:42.40014-07:00","updated_at":"2025-10-15T01:08:12.787521-07:00"} -{"id":"bd-188","title":"race_test_17","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T23:43:42.402127-07:00","updated_at":"2025-10-15T01:08:12.787643-07:00"} -{"id":"bd-189","title":"race_test_10","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T23:43:42.403758-07:00","updated_at":"2025-10-15T01:08:12.787769-07:00"} -{"id":"bd-19","title":"Fix import zero-value field handling","description":"Import uses zero-value checks (Priority != 0) to determine field updates. This prevents setting priority to 0 or clearing string fields. Export/import round-trip not fully idempotent for zero values. Consider JSON presence detection or explicit preserve-existing semantics. Location: cmd/bd/import.go:95-106","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-10-12T15:13:17.895083-07:00","updated_at":"2025-10-15T01:08:12.787907-07:00"} -{"id":"bd-190","title":"race_test_11","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T23:43:42.460348-07:00","updated_at":"2025-10-15T01:08:12.788028-07:00"} -{"id":"bd-191","title":"final_test_10","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T23:44:09.846149-07:00","updated_at":"2025-10-15T01:08:12.78815-07:00"} -{"id":"bd-192","title":"final_test_7","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T23:44:09.8493-07:00","updated_at":"2025-10-15T01:08:12.788277-07:00"} -{"id":"bd-193","title":"stress_test_5","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T23:44:27.558376-07:00","updated_at":"2025-10-15T01:08:12.7884-07:00"} -{"id":"bd-194","title":"stress_test_6","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T23:44:27.565808-07:00","updated_at":"2025-10-15T01:08:12.788522-07:00"} -{"id":"bd-195","title":"stress_test_1","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T23:44:27.614965-07:00","updated_at":"2025-10-15T01:08:12.788642-07:00"} -{"id":"bd-196","title":"Test2 auto-export","description":"","status":"closed","priority":4,"issue_type":"task","created_at":"2025-10-15T01:08:12.788761-07:00","updated_at":"2025-10-15T01:08:12.788761-07:00"} -{"id":"bd-197","title":"Add version mismatch warning for outdated binaries","description":"When bd detects that the database was created/modified by a newer version, warn the user that they may be running an outdated binary.\n\n**Problem:** Users may run old bd binaries without realizing it, leading to confusing behavior (e.g., missing features like auto-export).\n\n**Solution:** Store schema version or bd version in metadata table, check on startup, warn if mismatch.\n\n**Implementation:**\n1. Add `schema_version` or `bd_version` to metadata table during init\n2. Check version in PersistentPreRun (cmd/bd/main.go)\n3. Warn if binary version \u003c DB version\n4. Suggest: 'Your bd binary (v0.9.3) is older than this database (v0.9.5). Rebuild: go build -o bd ./cmd/bd'\n\n**Edge cases:**\n- Dev builds (show commit hash?)\n- Backwards compatibility (older DBs should work with newer binaries)\n- Don't warn on every command (maybe once per session?)\n\n**Related:** Fixes confusion from bd-182 (auto-export not working with old binary)","notes":"**Implementation Complete:**\n\nβœ… Added version metadata storage during `bd init` (init.go:59-63)\nβœ… Added `checkVersionMismatch()` function (main.go:301-345)\nβœ… Integrated version check into PersistentPreRun (main.go:98-99)\nβœ… Tested both scenarios:\n - Outdated binary: Clear warning with rebuild instructions\n - Newer binary: Info message that DB will be auto-upgraded\nβœ… No warnings on subsequent runs (version updated automatically)\n\n**How it works:**\n1. On `bd init`: Stores current version in metadata table\n2. On every command: Checks stored version vs binary version\n3. If mismatch:\n - Binary \u003c DB version β†’ Warn: outdated binary\n - Binary \u003e DB version β†’ Info: auto-upgrading DB\n4. Always updates stored version to current (future-proof)\n\n**Files modified:**\n- cmd/bd/init.go: Store version on init\n- cmd/bd/main.go: checkVersionMismatch() + integration\n\n**Testing:**\n```bash\n# Simulate old binary\nsqlite3 .beads/default.db \"UPDATE metadata SET value='0.9.99' WHERE key='bd_version';\"\nbd ready # Shows warning\n\n# Normal use (versions match)\nbd ready # No warning\n```\n\n**Edge cases handled:**\n- Empty version (old DB): Silently upgrade\n- Metadata errors: Skip check (defensive)\n- Dev builds: String comparison (works for 0.9.5 vs 0.9.6)\n\nFixes bd-182 confusion (users won't run outdated binaries unknowingly).","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-15T01:08:12.788913-07:00","updated_at":"2025-10-15T01:08:12.788913-07:00","dependencies":[{"issue_id":"bd-197","depends_on_id":"bd-182","type":"discovered-from","created_at":"2025-10-15T01:08:12.811298-07:00","created_by":"auto-import"}]} -{"id":"bd-198","title":"Add label management commands to CLI","description":"Currently labels can only be managed programmatically via the storage API. Add CLI commands to add, remove, and filter by labels.","acceptance_criteria":"Can add/remove/list labels via CLI, can filter issues by label, labels persist to JSONL","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-15T01:50:18.575625-07:00","updated_at":"2025-10-15T01:50:18.575625-07:00"} -{"id":"bd-199","title":"Investigate and fix import timeout with 208 issues","description":"bd import times out after 2 minutes when importing 208 issues from JSONL. This is unacceptable for a tool designed to scale to 100k+ issues.","design":"\n## Reproduction\n```bash\ncd ~/src/beads\nbd import .beads/issues.jsonl # Hangs/times out after 2 minutes\n```\n\nCurrent database state:\n- 208 issues in bd.db (2MB)\n- 208 lines in issues.jsonl (100KB)\n- WAL mode enabled\n\n## Symptoms\n- Import starts but never completes\n- No error message, just hangs\n- Timeout after 2 minutes (artificially imposed in testing)\n- Happens even when database already contains the issues (idempotent import)\n\n## Likely Causes\n1. **Transaction size** - All 208 issues in one transaction?\n2. **Lock contention** - WAL checkpoint blocking?\n3. **N+1 queries** - Dependency checking for each issue?\n4. **Missing indexes** - Slow lookups during collision detection?\n5. **Auto-flush interaction** - Background flush goroutine conflicting?\n\n## Performance Target\nShould handle:\n- 1000 issues in \u003c 5 seconds\n- 10,000 issues in \u003c 30 seconds \n- 100,000 issues in \u003c 5 minutes\n\n## Investigation Steps\n1. Add timing instrumentation to import phases\n2. Profile the import operation\n3. Check for lock contention in WAL mode\n4. Review collision detection performance\n5. Test with PRAGMA synchronous = NORMAL\n6. Consider batching imports (e.g., 100 issues per transaction)\n","acceptance_criteria":"\n- Can import 208 issues in \u003c 5 seconds\n- Can import 1000 issues in \u003c 30 seconds\n- Add performance logging to identify bottlenecks\n- Add --batch-size flag for tuning\n- Document performance characteristics\n- Integration test with large import\n","status":"open","priority":0,"issue_type":"bug","created_at":"2025-10-15T01:56:41.546786-07:00","updated_at":"2025-10-15T01:56:41.546786-07:00"} -{"id":"bd-2","title":"Verify auto-export works","description":"","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-12T00:43:03.457453-07:00","updated_at":"2025-10-15T01:08:12.789064-07:00","closed_at":"2025-10-12T14:15:04.00695-07:00"} -{"id":"bd-20","title":"Add --strict flag for dependency import failures","description":"Currently dependency import errors are warnings (logged to stderr, execution continues). Missing targets or cycles may indicate JSONL corruption. Add --strict flag to fail on any dependency errors for data integrity validation. Location: cmd/bd/import.go:159-164","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-12T15:13:18.954834-07:00","updated_at":"2025-10-15T01:08:12.789192-07:00"} -{"id":"bd-21","title":"Simplify getNextID SQL query parameters","description":"Query passes prefix four times to same SQL query. Works but fragile if query changes. Consider simplifying SQL to require fewer parameters. Location: internal/storage/sqlite/sqlite.go:73-78","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-12T15:13:20.114733-07:00","updated_at":"2025-10-15T01:08:12.789328-07:00"} -{"id":"bd-22","title":"Add validation/warning for malformed issue IDs","description":"getNextID silently ignores non-numeric ID suffixes (e.g., bd-foo). CAST returns NULL for invalid strings. Consider detecting and warning about malformed IDs in database. Location: internal/storage/sqlite/sqlite.go:79-82","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-12T15:13:21.195975-07:00","updated_at":"2025-10-15T01:08:12.789455-07:00"} -{"id":"bd-23","title":"Optimize export dependency queries (N+1 problem)","description":"Export triggers separate GetDependencyRecords() per issue. For large DBs (1000+ issues), this is N+1 queries. Add GetAllDependencyRecords() to fetch all dependencies in one query. Location: cmd/bd/export.go:52-59, import.go:138-142","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-12T15:13:22.325113-07:00","updated_at":"2025-10-15T01:08:12.789577-07:00"} -{"id":"bd-24","title":"Support ID space partitioning for parallel worker agents","description":"Enable external orchestrators (like AI worker swarms) to control issue ID assignment. Add --id flag to 'bd create' for explicit ID specification. Optionally support 'bd config set next_id N' to set the starting point for auto-increment. Storage layer already supports pre-assigned IDs (sqlite.go:52-71), just need CLI wiring. This keeps beads simple while letting orchestrators implement their own ID partitioning strategies to minimize merge conflicts. Complementary to bd-9's collision resolution.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-12T16:10:37.808226-07:00","updated_at":"2025-10-15T01:08:12.791336-07:00","closed_at":"2025-10-13T23:18:01.637695-07:00"} -{"id":"bd-25","title":"Add transaction support to storage layer for atomic multi-operation workflows","description":"Currently each storage method (CreateIssue, UpdateIssue, etc.) starts its own transaction. This makes it impossible to perform atomic multi-step operations like collision resolution. Add support for passing *sql.Tx through the storage interface, or create transaction-aware versions of methods. This would make remapCollisions and other batch operations truly atomic.","status":"closed","priority":4,"issue_type":"feature","created_at":"2025-10-12T16:39:00.66572-07:00","updated_at":"2025-10-15T01:08:12.791514-07:00","closed_at":"2025-10-13T22:53:56.401108-07:00"} -{"id":"bd-26","title":"Optimize reference updates to avoid loading all issues into memory","description":"In updateReferences(), we call SearchIssues with no filter to get ALL issues for updating references. For large databases (10k+ issues), this loads everything into memory. Options: 1) Use batched processing with LIMIT/OFFSET, 2) Use SQL UPDATE with REPLACE() directly, 3) Stream results instead of loading all at once. Located in collision.go:266","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-12T16:39:10.327861-07:00","updated_at":"2025-10-15T01:08:12.791693-07:00"} -{"id":"bd-27","title":"Cache compiled regexes in replaceIDReferences for performance","description":"replaceIDReferences() compiles the same regex patterns on every call. With 100 issues and 10 ID mappings, that's 1000 regex compilations. Pre-compile regexes once and reuse. Can use a struct with compiled regex, placeholder, and newID. Located in collision.go:329. Estimated performance improvement: 10-100x for large batches.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-12T16:39:18.305517-07:00","updated_at":"2025-10-15T01:08:12.79186-07:00","closed_at":"2025-10-13T23:50:25.865317-07:00"} -{"id":"bd-28","title":"Improve error handling in dependency removal during remapping","description":"In updateDependencyReferences(), RemoveDependency errors are caught and ignored with continue (line 392). Comment says 'if dependency doesn't exist' but this catches ALL errors including real failures. Should check error type with errors.Is(err, ErrDependencyNotFound) and only ignore not-found errors, returning other errors properly.","status":"open","priority":3,"issue_type":"bug","created_at":"2025-10-12T16:39:26.78219-07:00","updated_at":"2025-10-15T01:08:12.791995-07:00"} -{"id":"bd-29","title":"Use safer placeholder pattern in replaceIDReferences","description":"Currently uses __PLACEHOLDER_0__ which could theoretically collide with user text. Use a truly unique placeholder like null bytes: \\x00REMAP\\x00_0_\\x00 which are unlikely to appear in normal text. Located in collision.go:324. Very low probability issue but worth fixing for completeness.","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-12T16:39:33.665449-07:00","updated_at":"2025-10-15T01:08:12.792128-07:00"} -{"id":"bd-3","title":"Normal task","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-12T00:43:03.461615-07:00","updated_at":"2025-10-15T01:08:12.79227-07:00","closed_at":"2025-10-12T00:43:30.283178-07:00"} -{"id":"bd-30","title":"Remove unused issueMap in scoreCollisions","description":"scoreCollisions() creates issueMap and populates it (lines 135-138) but never uses it. Either remove it or add a TODO comment explaining future use. Located in collision.go:135-138. Cosmetic cleanup.","status":"open","priority":4,"issue_type":"chore","created_at":"2025-10-12T16:39:40.101611-07:00","updated_at":"2025-10-15T01:08:12.792409-07:00"} -{"id":"bd-31","title":"Test issue for design field","description":"Testing the new update flags","design":"## Design Plan\\n- Add flags to update command\\n- Test thoroughly\\n- Document changes","acceptance_criteria":"- All three fields (design, notes, acceptance-criteria) can be updated\\n- Changes persist in database\\n- bd show displays the fields correctly","notes":"Implementation complete. All tests passing.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-12T17:09:22.147446-07:00","updated_at":"2025-10-15T01:08:12.792543-07:00","closed_at":"2025-10-12T17:10:32.828906-07:00"} -{"id":"bd-32","title":"bd should auto-detect .beads/*.db in current directory","description":"When bd is run without --db flag, it defaults to beads' own database instead of looking for a .beads/*.db file in the current working directory. This causes confusion when working on other projects that use beads for issue tracking (like vc).\n\nExpected behavior: bd should search for .beads/*.db in cwd and use that if found, before falling back to default beads database.\n\nExample: Running 'bd ready' in /Users/stevey/src/vc/vc/ should automatically find and use .beads/vc.db without requiring --db flag every time.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-13T21:15:16.866255-07:00","updated_at":"2025-10-15T01:08:12.792677-07:00","closed_at":"2025-10-13T21:30:47.456341-07:00"} -{"id":"bd-33","title":"Document or automate JSONL sync workflow for git collaboration","description":"When using beads across multiple machines/environments via git, there's a workflow gap:\n\n1. Machine A: Create issues β†’ stored in .beads/project.db\n2. Machine A: bd export -o .beads/issues.jsonl\n3. Machine A: git add .beads/issues.jsonl \u0026\u0026 git commit \u0026\u0026 git push\n4. Machine B: git pull\n5. Machine B: ??? issues.jsonl exists but project.db is empty/stale\n\nThe missing step is: bd import --db .beads/project.db -i .beads/issues.jsonl\n\nThis needs to be either:\na) Documented clearly in workflow docs\nb) Automated (e.g., git hook, or bd auto-imports if jsonl is newer than db)\nc) Both\n\nReal-world impact: User had Claude Code on GCP VM create vc issues from BOOTSTRAP.md. They were exported to issues.jsonl and committed. But on local machine, vc.db was empty until manual import was run.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-13T21:15:30.271236-07:00","updated_at":"2025-10-15T01:08:12.792814-07:00","closed_at":"2025-10-13T22:47:51.587822-07:00"} -{"id":"bd-34","title":"Implement reserved database name _.db","description":"Auto-detection now skips .beads/_.db to prevent pollution when beads dogfoods itself. This allows beads to use its own issue tracker without interfering with other projects using beads in the same directory tree. Implementation includes filtering in findDatabase(), stopping directory walk when .beads/ is found, and documentation in README.md and CLAUDE.md.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-13T21:46:15.189582-07:00","updated_at":"2025-10-15T01:08:12.792956-07:00","closed_at":"2025-10-13T21:54:26.388271-07:00"} -{"id":"bd-35","title":"Auto-flush JSONL on CRUD operations with 5-second debounce","description":"Implemented automatic write-through from SQLite to JSONL with 5-second debouncing. After any CRUD operation (create, update, close, dep add/remove), changes are scheduled to flush to JSONL after 5 seconds of inactivity. On process exit, any pending changes are flushed immediately. This prevents .db and .jsonl from getting out of sync, solving the workflow gap where agents forget to run 'bd export'. Can be disabled with --no-auto-flush flag. Addresses bd-33.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-13T22:21:13.94705-07:00","updated_at":"2025-10-15T01:08:12.79309-07:00","closed_at":"2025-10-13T22:22:38.359968-07:00"} -{"id":"bd-36","title":"Handle missing JSONL directory in findJSONLPath","description":"findJSONLPath() assumes the database directory exists. If someone runs bd init to create a new database but the .beads directory doesn't exist yet, the glob operations might fail silently. Add os.MkdirAll(dbDir, 0755) to ensure directory exists before globbing. Located in cmd/bd/main.go:188-201.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-10-13T22:34:35.944346-07:00","updated_at":"2025-10-15T01:08:12.793213-07:00","closed_at":"2025-10-13T22:50:53.269614-07:00"} -{"id":"bd-37","title":"Refactor duplicate flush logic in PersistentPostRun","description":"PersistentPostRun contains a complete copy of the flush logic instead of calling flushToJSONL(). This violates DRY principle and makes maintenance harder. Refactor to use flushToJSONL() with a force parameter to bypass isDirty check, or extract shared logic into a helper function. Located in cmd/bd/main.go:104-138.","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-13T22:34:43.429201-07:00","updated_at":"2025-10-15T01:08:12.793463-07:00","closed_at":"2025-10-14T00:15:14.782393-07:00"} -{"id":"bd-38","title":"Add visibility for auto-flush failures","description":"flushToJSONL() writes warnings to stderr when flush fails, but calling code has no way to know if flush succeeded or failed. This means a command could return success even though JSONL is now out of sync. Consider maintaining a 'last flush status' variable or counter for failed flushes, and warn user after multiple consecutive failures (e.g., 3+). Located in cmd/bd/main.go:227-307.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-13T22:34:52.440117-07:00","updated_at":"2025-10-15T01:08:12.793599-07:00","closed_at":"2025-10-13T23:22:47.805211-07:00"} -{"id":"bd-39","title":"Optimize auto-flush to use incremental updates","description":"Every flush exports ALL issues and ALL dependencies, even if only one issue changed. For large projects (1000+ issues), this could be expensive. Current approach guarantees consistency, which is fine for MVP, but future optimization could track which issues changed and use incremental updates. Located in cmd/bd/main.go:255-276.","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-10-13T22:34:59.26425-07:00","updated_at":"2025-10-15T01:08:12.79372-07:00","closed_at":"2025-10-14T00:08:51.834812-07:00"} -{"id":"bd-4","title":"Low priority chore","description":"","status":"open","priority":4,"issue_type":"chore","created_at":"2025-10-12T10:50:49.500051-07:00","updated_at":"2025-10-15T01:08:12.795369-07:00","dependencies":[{"issue_id":"bd-4","depends_on_id":"bd-8","type":"parent-child","created_at":"2025-10-12T10:51:08.399915-07:00","created_by":"stevey"}]} -{"id":"bd-40","title":"Make auto-flush debounce duration configurable","description":"flushDebounce is hardcoded to 5 seconds. Make it configurable via environment variable BEADS_FLUSH_DEBOUNCE (e.g., '500ms', '10s'). Current 5-second value is reasonable for interactive use, but CI/automated scenarios might want faster flush. Add getDebounceDuration() helper function. Located in cmd/bd/main.go:31.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-10-13T22:35:06.126282-07:00","updated_at":"2025-10-15T01:08:12.795508-07:00"} -{"id":"bd-41","title":"Add godoc comments for auto-flush functions","description":"Add comprehensive godoc comments for findJSONLPath(), markDirtyAndScheduleFlush(), and flushToJSONL() explaining behavior, concurrency considerations, and error handling. Include notes about debouncing behavior (timer resets on each write, flush occurs 5s after LAST operation) and flush-on-exit guarantees. Located in cmd/bd/main.go:188-307.","status":"open","priority":4,"issue_type":"chore","created_at":"2025-10-13T22:35:13.518442-07:00","updated_at":"2025-10-15T01:08:12.795647-07:00"} -{"id":"bd-42","title":"Add test coverage for auto-flush feature","description":"Add comprehensive tests for auto-flush functionality:\\n- Test that markDirtyAndScheduleFlush() is called after CRUD operations\\n- Test debounce timing (rapid operations result in single flush)\\n- Test --no-auto-flush flag disables feature\\n- Test flush on program exit\\n- Test concurrent operations don't cause races\\n- Test error scenarios (disk full, permission denied, etc.)\\n- Test import command triggers auto-flush\\n\\nCurrent implementation has no test coverage for the auto-flush feature. Located in cmd/bd/main_test.go (to be created).","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-13T22:35:22.079794-07:00","updated_at":"2025-10-15T01:08:12.795779-07:00","closed_at":"2025-10-13T23:36:28.90411-07:00"} -{"id":"bd-43","title":"Test auto-sync feature","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-13T22:47:41.738165-07:00","updated_at":"2025-10-15T01:08:12.795909-07:00","closed_at":"2025-10-13T22:48:02.844213-07:00"} -{"id":"bd-44","title":"Regular auto-ID issue","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-13T23:16:29.970089-07:00","updated_at":"2025-10-15T01:08:12.796026-07:00","closed_at":"2025-10-13T23:16:45.231439-07:00"} -{"id":"bd-45","title":"Test flush tracking","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-13T23:22:18.472476-07:00","updated_at":"2025-10-15T01:08:12.796146-07:00","closed_at":"2025-10-13T23:22:31.397095-07:00"} -{"id":"bd-46","title":"Test export cancels timer","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-13T23:26:20.523923-07:00","updated_at":"2025-10-15T01:08:12.796266-07:00","closed_at":"2025-10-13T23:26:35.813165-07:00"} -{"id":"bd-47","title":"Test incremental export","description":"Testing bd-39 implementation","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T00:06:24.42044-07:00","updated_at":"2025-10-15T01:08:12.796398-07:00","closed_at":"2025-10-14T00:14:45.968261-07:00"} -{"id":"bd-48","title":"Test incremental 2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T00:07:14.157987-07:00","updated_at":"2025-10-15T01:08:12.796524-07:00","closed_at":"2025-10-14T00:14:45.968593-07:00"} -{"id":"bd-49","title":"Final test","description":"Testing with new binary","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T00:07:46.650341-07:00","updated_at":"2025-10-15T01:08:12.79664-07:00","closed_at":"2025-10-14T00:14:45.968699-07:00"} -{"id":"bd-5","title":"Test issue","description":"Testing prefix","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-12T10:50:50.942964-07:00","updated_at":"2025-10-15T01:08:12.796796-07:00","closed_at":"2025-10-13T23:20:41.816853-07:00","dependencies":[{"issue_id":"bd-5","depends_on_id":"bd-8","type":"parent-child","created_at":"2025-10-12T10:51:08.404381-07:00","created_by":"stevey"}]} -{"id":"bd-50","title":"Test label dirty tracking","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T00:14:25.484565-07:00","updated_at":"2025-10-15T01:08:12.796929-07:00","closed_at":"2025-10-14T00:14:45.968771-07:00"} -{"id":"bd-51","title":"Test hash-based import","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T00:16:00.850055-07:00","updated_at":"2025-10-15T01:08:12.79705-07:00","closed_at":"2025-10-14T00:19:19.355078-07:00"} -{"id":"bd-52","title":"Create Claude Code plugin for beads","description":"Package beads as a Claude Code plugin for easy installation via /plugin command.\n\nContext: GitHub issue #28 - https://github.com/steveyegge/beads/issues/28\n\nCurrent state:\n- MCP server exists in integrations/beads-mcp/\n- No plugin packaging yet\n\nDeliverables:\n1. .claude-plugin/plugin.json with metadata\n2. .claude-plugin/marketplace.json for distribution\n3. Custom slash commands (/bd-ready, /bd-create, /bd-show, etc.)\n4. Bundle MCP server configuration\n5. Optional: Pre-configured hooks for auto-sync\n6. Documentation for installation and usage\n\nBenefits:\n- Makes beads instantly discoverable in Claude Code ecosystem\n- Single-command installation vs. manual setup\n- Bundled cohesive experience\n- Lowers adoption barrier significantly\n\nReferences:\n- https://www.anthropic.com/news/claude-code-plugins\n- https://docs.claude.com/en/docs/claude-code/plugins","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-14T00:21:46.229671-07:00","updated_at":"2025-10-15T01:08:12.797174-07:00","closed_at":"2025-10-14T00:29:31.174835-07:00"} -{"id":"bd-53","title":"Research Claude Code plugin structure and requirements","description":"Study the plugin format, required files, and best practices.\n\nTasks:\n- Review official plugin documentation\n- Examine example plugins if available\n- Document plugin.json schema\n- Understand marketplace.json requirements\n- Identify slash command format","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T00:21:47.327014-07:00","updated_at":"2025-10-15T01:08:12.797304-07:00","closed_at":"2025-10-14T00:29:31.179483-07:00","dependencies":[{"issue_id":"bd-53","depends_on_id":"bd-52","type":"parent-child","created_at":"2025-10-14T17:11:11.537724-07:00","created_by":"auto-import"}]} -{"id":"bd-54","title":"Create plugin metadata files","description":"Create .claude-plugin/plugin.json and marketplace.json.\n\nRequirements:\n- Name, description, version, author\n- MCP server configuration bundling\n- License and repository info\n- Installation instructions","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T00:21:48.404838-07:00","updated_at":"2025-10-15T01:08:12.798846-07:00","closed_at":"2025-10-14T00:32:51.521595-07:00","dependencies":[{"issue_id":"bd-54","depends_on_id":"bd-52","type":"parent-child","created_at":"2025-10-14T17:11:11.537903-07:00","created_by":"auto-import"}]} -{"id":"bd-55","title":"Design and implement slash commands","description":"Create useful slash commands for beads workflow.\n\nProposed commands:\n- /bd-ready - Show ready work\n- /bd-create - Create new issue interactively\n- /bd-show - Show issue details\n- /bd-update - Update issue status\n- /bd-close - Close issue\n- /bd-workflow - Show full agent workflow guide\n\nEach command should provide a good UX and leverage the MCP server tools.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T00:22:04.773185-07:00","updated_at":"2025-10-15T01:08:12.79901-07:00","dependencies":[{"issue_id":"bd-55","depends_on_id":"bd-52","type":"parent-child","created_at":"2025-10-14T17:11:11.538059-07:00","created_by":"auto-import"}]} -{"id":"bd-56","title":"Write plugin documentation","description":"Create comprehensive documentation for the plugin.\n\nContents:\n- Installation instructions\n- Available commands\n- MCP tools reference\n- Configuration options\n- Examples and workflows\n- Troubleshooting guide","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T00:22:05.619682-07:00","updated_at":"2025-10-15T01:08:12.799151-07:00","closed_at":"2025-10-14T00:35:43.188168-07:00","dependencies":[{"issue_id":"bd-56","depends_on_id":"bd-52","type":"parent-child","created_at":"2025-10-14T17:11:11.538197-07:00","created_by":"auto-import"}]} -{"id":"bd-57","title":"Test plugin installation and functionality","description":"Verify the plugin works end-to-end.\n\nTest cases:\n- Fresh installation via /plugin command\n- All slash commands work correctly\n- MCP server tools are accessible\n- Configuration options work\n- Documentation is accurate\n- Works in both terminal and VS Code","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T00:22:06.46476-07:00","updated_at":"2025-10-15T01:08:12.799281-07:00","dependencies":[{"issue_id":"bd-57","depends_on_id":"bd-52","type":"parent-child","created_at":"2025-10-14T17:11:11.538331-07:00","created_by":"auto-import"}]} -{"id":"bd-58","title":"Parent's blocker should block children in ready work calculation","description":"GitHub issue #19: If epic1 blocks epic2, children of epic2 should also be considered blocked when calculating ready work. Currently epic2's children show as ready even though their parent is blocked. This breaks the natural hierarchy of dependencies and can cause agents to work on tasks out of order.\n\nExpected: ready work calculation should traverse up parent-child hierarchy and check if any ancestor has blocking dependencies.\n\nSee: https://github.com/anthropics/claude-code/issues/19","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-14T00:22:07.567867-07:00","updated_at":"2025-10-15T01:08:12.799413-07:00"} -{"id":"bd-59","title":"Add composite index on dependencies(depends_on_id, type)","description":"The hierarchical blocking query does:\nJOIN dependencies d ON d.depends_on_id = bt.issue_id\nWHERE d.type = 'parent-child'\n\nCurrently we only have idx_dependencies_depends_on (line 41 in schema.go), which covers depends_on_id but not the type filter.\n\n**Impact:**\n- Query has to scan ALL dependencies for a given depends_on_id, then filter by type\n- With 10k+ issues and many dependencies, this could cause slowdowns\n- The blocker propagation happens recursively, amplifying the cost\n\n**Solution:**\nAdd composite index: CREATE INDEX idx_dependencies_depends_on_type ON dependencies(depends_on_id, type)\n\n**Testing:**\nRun EXPLAIN QUERY PLAN on GetReadyWork query before/after to verify index usage.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T00:22:08.949261-07:00","updated_at":"2025-10-15T01:08:12.799553-07:00"} -{"id":"bd-6","title":"Add migration scripts for GitHub Issues","description":"Create scripts to import from GitHub Issues API or exported JSON","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-12T10:50:52.140018-07:00","updated_at":"2025-10-15T01:08:12.799685-07:00","dependencies":[{"issue_id":"bd-6","depends_on_id":"bd-8","type":"parent-child","created_at":"2025-10-12T10:51:08.40857-07:00","created_by":"stevey"}]} -{"id":"bd-60","title":"Update ready_issues VIEW to use hierarchical blocking","description":"The ready_issues VIEW (schema.go:97-108) uses the OLD blocking logic that doesn't propagate through parent-child hierarchies.\n\n**Problem:**\n- GetReadyWork() function now uses recursive CTE with propagation\n- But the ready_issues VIEW still uses simple NOT EXISTS check\n- Any code using the VIEW will get DIFFERENT results than GetReadyWork()\n- This creates inconsistency and confusion\n\n**Impact:**\n- Unknown if the VIEW is actually used anywhere in the codebase\n- If it is used, it's returning incorrect results (showing children as ready when parent is blocked)\n\n**Solution:**\nEither:\n1. Update VIEW to match GetReadyWork logic (complex CTE in a view)\n2. Drop the VIEW entirely if unused\n3. Make VIEW call GetReadyWork as a function (if SQLite supports it)\n\n**Investigation needed:**\nGrep for 'ready_issues' to see if the view is actually used.","notes":"**Investigation results:**\nGrepped the codebase - the ready_issues VIEW appears in:\n- schema.go (definition)\n- WORKFLOW.md, DESIGN.md (documentation)\n- No actual Go code queries it directly\n\n**Conclusion:** The VIEW is defined but appears UNUSED by actual code. GetReadyWork() function is used instead.\n\n**Recommended solution:** Drop the VIEW entirely to avoid confusion. It serves no purpose if unused and creates a maintenance burden (needs to stay in sync with GetReadyWork logic).\n\n**Alternative:** If we want to keep it for direct SQL access, update the VIEW definition to match the new recursive CTE logic.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-14T00:22:19.075914-07:00","updated_at":"2025-10-15T01:08:12.799814-07:00"} -{"id":"bd-61","title":"Add test for deep hierarchy blocking (50+ levels)","description":"Current tests verify 2-level depth (grandparent β†’ parent β†’ child). The depth limit is hardcoded to 50 in the recursive CTE, but we don't test edge cases near that limit.\n\n**Test cases needed:**\n1. Verify 50-level deep hierarchy works correctly\n2. Verify depth limit prevents runaway recursion\n3. Measure performance impact of deep hierarchies\n4. Consider if 50 is the right limit (why not 100? why not 20?)\n\n**Rationale:**\n- Most hierarchies are 2-5 levels deep\n- But pathological cases (malicious or accidental) could create 50+ level nesting\n- Need to ensure graceful degradation, not catastrophic failure\n\n**Implementation:**\nAdd TestDeepHierarchyBlocking to ready_test.go","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T00:22:20.33128-07:00","updated_at":"2025-10-15T01:08:12.799955-07:00"} -{"id":"bd-62","title":"Document hierarchical blocking behavior in README","description":"The fix for bd-58 changes user-visible behavior: children of blocked epics are now automatically blocked.\n\n**What needs documenting:**\n1. README.md dependency section should explain blocking propagation\n2. Clarify that 'blocks' + 'parent-child' together create transitive blocking\n3. Note that 'related' and 'discovered-from' do NOT propagate blocking\n4. Add example showing epic β†’ child blocking propagation\n\n**Example to add:**\n```bash\n# If epic is blocked, children are too\nbd create \"Epic 1\" -t epic -p 1\nbd create \"Task 1\" -t task -p 1\nbd dep add task-1 epic-1 --type parent-child\n\n# Block the epic\nbd create \"Blocker\" -t task -p 0\nbd dep add epic-1 blocker-1 --type blocks\n\n# Now both epic-1 AND task-1 are blocked\nbd ready # Neither will show up\n```","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T01:14:45.357198-07:00","updated_at":"2025-10-15T01:08:12.800086-07:00","closed_at":"2025-10-14T01:20:31.049608-07:00"} -{"id":"bd-63","title":"Add EXPLAIN QUERY PLAN tests for ready work query","description":"Verify that the hierarchical blocking query uses proper indexes and doesn't do full table scans.\n\n**Queries to analyze:**\n1. The recursive CTE (both base case and recursive case)\n2. The final SELECT with NOT EXISTS\n3. Impact of various filters (status, priority, assignee)\n\n**Implementation:**\nAdd test function that:\n- Runs EXPLAIN QUERY PLAN on GetReadyWork query\n- Parses output to verify no SCAN TABLE operations\n- Documents expected query plan in comments\n- Fails if query plan degrades\n\n**Benefits:**\n- Catch performance regressions in tests\n- Document expected query behavior\n- Ensure indexes are being used\n\nRelated to: bd-59 (composite index on depends_on_id, type)","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T01:19:37.745731-07:00","updated_at":"2025-10-15T01:08:12.800335-07:00","closed_at":"2025-10-14T01:19:50.064461-07:00"} -{"id":"bd-64","title":"Verify and test Claude Code plugin","description":"Address remaining items from code review:\n\nCritical:\n1. Test plugin installation locally with /plugin marketplace add\n2. Verify ${CLAUDE_PLUGIN_ROOT} variable works correctly\n3. Test each slash command works\n4. Test @task-agent execution\n5. Verify MCP server connects properly\n\nDocumentation:\n1. Clarify 'one-command installation' vs prerequisites\n2. Add note about plugin development status\n3. Verify all paths and examples work\n\nNice-to-have:\n1. Add icon for marketplace (optional)\n2. Add categories field to plugin.json\n3. Add engines field for version compatibility","notes":"PLUGIN IMPLEMENTATION COMPLETE - READY FOR TESTING\n\nWhat was built:\nβœ… .claude-plugin/plugin.json - Plugin metadata with MCP server config\nβœ… .claude-plugin/marketplace.json - Marketplace configuration\nβœ… 9 slash commands in .claude-plugin/commands/:\n - bd-ready, bd-create, bd-show, bd-update, bd-close\n - bd-workflow, bd-init, bd-stats, bd-version\nβœ… Task agent in .claude-plugin/agents/task-agent.md\nβœ… PLUGIN.md - Comprehensive documentation\nβœ… README.md - Updated with plugin section\nβœ… Version sync - All components at 0.9.2\n\nTesting Instructions for Next Agent:\n=====================================\n\n1. INSTALL PLUGIN FROM GITHUB:\n /plugin marketplace add steveyegge/beads\n /plugin install beads\n \n2. RESTART CLAUDE CODE (required for MCP server)\n\n3. TEST SLASH COMMANDS:\n /bd-version # Check versions (should show 0.9.2)\n /bd-workflow # Show workflow guide\n /bd-stats # Show project stats\n /bd-ready # Find ready work\n /bd-create \"Test plugin\" task 2\n /bd-show bd-\u003cid\u003e\n \n4. TEST MCP SERVER:\n /mcp # Verify 'beads' server appears\n \n5. TEST TASK AGENT:\n @task-agent # If supported in Claude Code\n \n6. VERIFY:\n - All commands work without errors\n - MCP tools are accessible\n - Version checking works\n - Documentation is accurate\n\nExpected Issues:\n- May need to adjust MCP server path variable (${CLAUDE_PLUGIN_ROOT})\n- Task agent syntax might differ\n- Some commands may need refinement based on actual usage\n\nIf testing fails, check:\n- bd CLI is in PATH: which bd\n- uv is installed: which uv\n- MCP server logs in Claude Code\n- PLUGIN.md troubleshooting section\n\nCommit references:\n- 9f38375: feat: Add Claude Code plugin for beads\n- d25fc53: feat: Add version compatibility checking\n- c0f1044: fix: Sync all component versions to 0.9.2\n- a5c71f0: feat: Add version bump script\n- a612b92: docs: Add version management to CLAUDE.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T01:23:23.041743-07:00","updated_at":"2025-10-15T01:08:12.811809-07:00","closed_at":"2025-10-15T01:08:12.811809-07:00","dependencies":[{"issue_id":"bd-64","depends_on_id":"bd-71","type":"parent-child","created_at":"2025-10-14T01:24:35.859964-07:00","created_by":"stevey"}]} -{"id":"bd-65","title":"Document versioning and release strategy","description":"Create comprehensive versioning strategy for beads ecosystem.\n\nComponents to document:\n1. bd CLI (Go binary) - main version number\n2. Plugin (Claude Code) - tracks CLI version\n3. MCP server (Python) - bundled with plugin\n4. Release workflow - how to sync all three\n\nDecisions to make:\n- Should plugin.json auto-update from bd CLI version?\n- Should we have a VERSION file at repo root?\n- How to handle breaking changes across components?\n- What's the update notification strategy?\n\nReferences:\n- plugin.json engines field now requires bd \u003e=0.9.0\n- /bd-version command added for checking compatibility\n- PLUGIN.md now documents update workflow","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T01:23:32.02232-07:00","updated_at":"2025-10-15T01:08:12.800654-07:00","closed_at":"2025-10-14T01:32:38.263621-07:00","dependencies":[{"issue_id":"bd-65","depends_on_id":"bd-71","type":"parent-child","created_at":"2025-10-14T01:24:35.864429-07:00","created_by":"stevey"}]} -{"id":"bd-66","title":"Sync versions to 0.9.2 across all components","description":"Version mismatch discovered: bd CLI is 0.9.2 but other components still at 0.9.0 or 1.0.0.\n\nCurrent state:\n- bd CLI (cmd/bd/version.go): 0.9.2 βœ“\n- Plugin (.claude-plugin/plugin.json): 0.9.0 βœ—\n- MCP Server (integrations/beads-mcp): 1.0.0 βœ—\n- README.md: 0.9.0 βœ—\n\nFiles to update:\n1. .claude-plugin/plugin.json\n2. integrations/beads-mcp/pyproject.toml\n3. README.md (all mentions)\n4. PLUGIN.md (if any mentions)\n5. CHANGELOG.md (add 0.9.1 and 0.9.2 entries)\n\nRoot cause: Version bumps only updated version.go, not other components.\nSolution needed: Script or process to sync versions across all files.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-14T01:23:40.61527-07:00","updated_at":"2025-10-15T01:08:12.80079-07:00","closed_at":"2025-10-14T01:33:10.337387-07:00","dependencies":[{"issue_id":"bd-66","depends_on_id":"bd-71","type":"parent-child","created_at":"2025-10-14T01:24:35.869311-07:00","created_by":"stevey"}]} -{"id":"bd-67","title":"Create version bump script","description":"Create scripts/bump-version.sh to automate version syncing across all components.\n\nThe script should:\n1. Take a version number as argument (e.g., ./scripts/bump-version.sh 0.9.3)\n2. Update all version files:\n - cmd/bd/version.go (Version constant)\n - .claude-plugin/plugin.json (version field)\n - .claude-plugin/marketplace.json (plugins[].version)\n - integrations/beads-mcp/pyproject.toml (version field)\n - README.md (Alpha version mention)\n - PLUGIN.md (version requirements)\n3. Validate semantic versioning format\n4. Show diff preview before applying\n5. Optionally create git commit with standard message\n\nThis prevents the version mismatch issue that occurred when only version.go was updated.\n\nRelated: bd-66 (version sync issue)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T01:23:48.488537-07:00","updated_at":"2025-10-15T01:08:12.800914-07:00","closed_at":"2025-10-14T01:33:52.447248-07:00","dependencies":[{"issue_id":"bd-67","depends_on_id":"bd-71","type":"parent-child","created_at":"2025-10-14T01:24:35.873665-07:00","created_by":"stevey"}]} -{"id":"bd-68","title":"Add system-wide/multi-repo support for beads","description":"GitHub issue #4 requests ability to use beads across multiple projects and for system-wide task tracking.\n\nCurrent limitation: beads is per-repository isolated. Each project has its own .beads/ directory and issues cannot reference issues in other projects.\n\nPotential approaches:\n1. Global beads instance in ~/.beads/global.db for cross-project work\n2. Project references - allow issues to link across repos\n3. Multi-project workspace support - one beads instance managing multiple repos\n4. Integration with existing MCP server to provide remote multi-project access\n\nUse cases:\n- System administrators tracking work across multiple machines/repos\n- Developers working on a dozen+ projects simultaneously\n- Cross-cutting concerns that span multiple repositories\n- Global todo list with project-specific subtasks\n\nRelated:\n- GitHub issue #4: https://github.com/steveyegge/beads/issues/4\n- Comparison to membank MCP which already supports multi-project via centralized server\n- MCP server at integrations/beads-mcp/ could be extended for this\n\nSee also: Testing framework for plugins (also from GH #4)","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-14T01:23:57.134825-07:00","updated_at":"2025-10-15T01:08:12.801079-07:00","dependencies":[{"issue_id":"bd-68","depends_on_id":"bd-71","type":"parent-child","created_at":"2025-10-14T01:24:35.87799-07:00","created_by":"stevey"}]} -{"id":"bd-69","title":"Add coverage threshold to CI pipeline","description":"Current CI runs tests with coverage but doesn't enforce minimum threshold. Add step to fail if coverage drops below target.\n\nCurrent coverage: 60%\nRecommended thresholds:\n- Warn: 55%\n- Fail: 50%\n\nThis prevents coverage regression while allowing gradual improvement toward 80% target for 1.0.\n\nImplementation:\n1. Add coverage check step after test run\n2. Use 'go tool cover -func=coverage.out' to get total\n3. Parse percentage and compare to threshold\n4. Optionally: Use codecov's built-in threshold features\n\nRelated to test coverage improvement work (upcoming issue).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T01:24:06.079067-07:00","updated_at":"2025-10-15T01:08:12.801221-07:00","dependencies":[{"issue_id":"bd-69","depends_on_id":"bd-71","type":"parent-child","created_at":"2025-10-14T01:24:35.882631-07:00","created_by":"stevey"}]} -{"id":"bd-7","title":"Add performance benchmarks document","description":"Document actual performance metrics with hyperfine tests","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-12T10:50:53.294516-07:00","updated_at":"2025-10-15T01:08:12.801357-07:00","dependencies":[{"issue_id":"bd-7","depends_on_id":"bd-8","type":"parent-child","created_at":"2025-10-12T10:51:08.412835-07:00","created_by":"stevey"}]} -{"id":"bd-70","title":"Increase test coverage for auto-flush and auto-import features","description":"Critical features have 0% test coverage despite being core workflow functionality.\n\n**Uncovered areas (0% coverage):**\n\nAuto-flush/Auto-import (dirty tracking):\n- MarkIssueDirty / MarkIssuesDirty\n- GetDirtyIssues / GetDirtyIssueCount\n- ClearDirtyIssues / ClearDirtyIssuesByID\n- Auto-flush debouncing logic\n- Auto-import hash comparison\n\nDatabase/file discovery:\n- FindDatabasePath (finds .beads/*.db in directory tree)\n- FindJSONLPath (finds issues.jsonl)\n- findDatabaseInTree helper\n\nLabel operations:\n- AddLabel / RemoveLabel\n- GetLabels / GetIssuesByLabel\n\nEvents/Comments:\n- AddComment\n- GetEvents\n- GetStatistics\n\nMetadata storage:\n- SetMetadata / GetMetadata (used for import hash tracking)\n\nCLI output formatting:\n- outputJSON\n- printCollisionReport / printRemappingReport\n- createIssuesFromMarkdown\n\n**Priority areas:**\n1. Auto-flush/import (highest risk - core workflow)\n2. Database discovery (second - affects all operations)\n3. Labels/events (lower priority - less commonly used)\n\n**Test approach:**\n- Add unit tests for dirty tracking in sqlite package\n- Add integration tests for auto-flush timing and debouncing\n- Add tests for import hash detection and idempotency\n- Add tests for database discovery edge cases (permissions, nested dirs)\n\n**Target:** Get overall coverage from 60% β†’ 75%, focus on cmd/bd (currently 24.1%)\n\n**Note:** These features work well in practice (dogfooding proves it) but edge cases (disk full, permissions, concurrent access, race conditions) are untested.","notes":"Test coverage significantly improved! Added comprehensive test suites:\n\n**Tests Added:**\n1. βœ… Dirty tracking (dirty_test.go): 8 tests\n - MarkIssueDirty, MarkIssuesDirty, GetDirtyIssues, ClearDirtyIssues\n - GetDirtyIssueCount, ClearDirtyIssuesByID\n - Ordering and timestamp update tests\n - Coverage: 75-100% for all functions\n\n2. βœ… Metadata storage (sqlite_test.go): 4 tests\n - SetMetadata, GetMetadata with various scenarios\n - Coverage: 100%\n\n3. βœ… Label operations (labels_test.go): 9 tests\n - AddLabel, RemoveLabel, GetLabels, GetIssuesByLabel\n - Duplicate handling, empty cases, dirty marking\n - Coverage: 71-82%\n\n4. βœ… Events \u0026 Comments (events_test.go): 7 tests\n - AddComment, GetEvents with limits\n - Timestamp updates, dirty marking\n - Multiple event types in history\n - Coverage: 73-92%\n\n5. βœ… Database/JSONL discovery (beads_test.go): 8 tests\n - FindDatabasePath with env var, tree search, home default\n - FindJSONLPath with existing files, defaults, multiple files\n - Coverage: 89-100%\n\n**Coverage Results:**\n- Overall: 70.3% (up from ~60%)\n- beads package: 90.6%\n- sqlite package: 74.7% (up from 60.8%)\n- types package: 100%\n\n**Impact:**\nAll priority 1 features now have solid test coverage. Auto-flush/import, metadata storage, labels, and events are thoroughly tested with edge cases covered.\n\nFiles created:\n- internal/storage/sqlite/dirty_test.go (8 tests)\n- internal/storage/sqlite/labels_test.go (9 tests)\n- internal/storage/sqlite/events_test.go (7 tests)\n- beads_test.go (8 tests)\n\nFiles modified:\n- internal/storage/sqlite/sqlite_test.go (added 4 metadata tests)\n\n**Next Steps (if desired):**\n- CLI output formatting tests (outputJSON, printCollisionReport, etc.)\n- Integration tests for auto-flush debouncing timing\n- More edge cases for concurrent access","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T01:24:15.473927-07:00","updated_at":"2025-10-15T01:16:00.571791-07:00","closed_at":"2025-10-15T01:16:00.571791-07:00","dependencies":[{"issue_id":"bd-70","depends_on_id":"bd-71","type":"parent-child","created_at":"2025-10-14T01:24:35.887151-07:00","created_by":"stevey"}]} -{"id":"bd-71","title":"Code review follow-up: Post-PR #8 merge improvements","description":"Follow-up tasks from the ultrathink code review of PR #8 merge (bd-62).\n\n**Context:** PR #8 successfully merged atomic counter + dirty tracking. Core functionality is solid but several improvements identified.\n\n**Critical (P0-P1):**\n- bd-64: Fix SyncAllCounters performance bottleneck (P0)\n- bd-65: Add migration for issue_counters table (P1)\n- bd-66: Make import counter sync failure fatal (P1)\n\n**Nice to have (P2-P3):**\n- bd-67: Update test comments (P2)\n- bd-68: Add performance benchmarks (P2)\n- bd-69: Add metrics/logging (P3)\n- bd-70: Add EXPLAIN QUERY PLAN tests (P3)\n\n**Overall assessment:** 4/5 stars - Excellent implementation with one critical performance issue. After bd-64 is fixed, this becomes 5/5.\n\n**Review document:** Available if needed","notes":"Status update: All P0-P1 critical tasks completed! bd-64 (performance), bd-65 (migration), bd-66 (fatal error), bd-67 (comments) are all done. Atomic counter implementation is now production-ready. Remaining tasks are P2-P3 enhancements.","status":"open","priority":1,"issue_type":"epic","created_at":"2025-10-14T01:24:27.716237-07:00","updated_at":"2025-10-15T01:08:12.801635-07:00"} -{"id":"bd-72","title":"Test performance - issue 1","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T01:27:53.520056-07:00","updated_at":"2025-10-15T01:08:12.802128-07:00"} -{"id":"bd-73","title":"Performance test 1","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T01:27:59.931707-07:00","updated_at":"2025-10-15T01:08:12.802284-07:00"} -{"id":"bd-74","title":"Performance test 2","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T01:27:59.936642-07:00","updated_at":"2025-10-15T01:08:12.80241-07:00"} -{"id":"bd-75","title":"Performance test 3","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T01:27:59.941591-07:00","updated_at":"2025-10-15T01:08:12.802532-07:00"} -{"id":"bd-76","title":"Performance test 4","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T01:27:59.946053-07:00","updated_at":"2025-10-15T01:08:12.8027-07:00"} -{"id":"bd-77","title":"Performance test 5","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T01:27:59.950618-07:00","updated_at":"2025-10-15T01:08:12.802824-07:00"} -{"id":"bd-78","title":"Performance test 6","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T01:27:59.955773-07:00","updated_at":"2025-10-15T01:08:12.802946-07:00"} -{"id":"bd-79","title":"Performance test 7","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T01:27:59.96021-07:00","updated_at":"2025-10-15T01:08:12.803068-07:00"} -{"id":"bd-8","title":"Reach 1.0 release milestone","description":"Stabilize API, finalize documentation, comprehensive testing","status":"open","priority":1,"issue_type":"epic","created_at":"2025-10-12T10:50:54.457348-07:00","updated_at":"2025-10-15T01:08:12.803184-07:00"} -{"id":"bd-80","title":"Performance test 8","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T01:27:59.964861-07:00","updated_at":"2025-10-15T01:08:12.803307-07:00"} -{"id":"bd-81","title":"Performance test 9","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T01:27:59.969882-07:00","updated_at":"2025-10-15T01:08:12.803426-07:00"} -{"id":"bd-82","title":"Performance test 10","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T01:27:59.974738-07:00","updated_at":"2025-10-15T01:08:12.80356-07:00"} -{"id":"bd-83","title":"Add external_ref field for tracking GitHub issues","description":"Add optional external_ref field to issues table to track external references like 'gh-9', 'jira-ABC', etc. Includes schema migration, CLI flags (--external-ref for create/update), and tests. This enables linking bd issues to GitHub issues for better workflow integration.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-14T02:27:01.187087-07:00","updated_at":"2025-10-15T01:08:12.803682-07:00","closed_at":"2025-10-14T02:34:54.508385-07:00"} -{"id":"bd-84","title":"Auto-import fails in git workflows due to mtime issues","description":"The auto-import mechanism (autoImportIfNewer) relies on file modification time comparison between JSONL and DB. This breaks in git workflows because git does not preserve original file modification times - pulled files get fresh mtimes based on checkout time.\n\nRoot causes:\n1. Git checkout sets mtime to 'now', not original commit time\n2. Auto-import compares JSONL mtime vs DB mtime (line 181 in main.go)\n3. If DB was recently modified (agents working), mtime check fails\n4. Auto-import silently returns without feedback\n5. Agents continue with stale database state\n\nThis caused issues in VC project where 3 parallel agents:\n- Pulled updated .beads/issues.jsonl from git\n- Auto-import didn't trigger (JSONL appeared older than DB)\n- Agents couldn't find their assigned issues\n- Agents exported from wrong database, corrupting JSONL","design":"Recommended approach: Checksum-based sync (option 3 from original design)\n\n## Solution: Hash-based content comparison\n\nReplace mtime comparison with JSONL content hash comparison:\n\n1. **Compute JSONL hash on startup**:\n - SHA256 hash of .beads/issues.jsonl contents\n - Fast enough for typical repos (\u003c1MB = ~20ms)\n - Only computed once per command invocation\n\n2. **Store last import hash in DB**:\n - Add metadata table if not exists: CREATE TABLE IF NOT EXISTS metadata (key TEXT PRIMARY KEY, value TEXT)\n - Store hash after successful import: INSERT OR REPLACE INTO metadata (key, value) VALUES ('last_import_hash', '\u003chash\u003e')\n - Query on startup: SELECT value FROM metadata WHERE key = 'last_import_hash'\n\n3. **Compare hashes instead of mtimes**:\n - If JSONL hash != stored hash: auto-import (content changed)\n - If JSONL hash == stored hash: skip import (no changes)\n - If no stored hash: fall back to mtime comparison (backward compat)\n\n4. **Update autoImportIfNewer() in cmd/bd/main.go**:\n - Lines 155-279 currently use mtime comparison (line 181)\n - Replace with hash comparison\n - Keep mtime as fallback for old DBs without metadata table\n\n## Implementation Details\n\n### New storage interface method:\n```go\n// In internal/storage/storage.go\ntype Storage interface {\n // ... existing methods ...\n GetMetadata(ctx context.Context, key string) (string, error)\n SetMetadata(ctx context.Context, key, value string) error\n}\n```\n\n### Migration:\n```go\n// In internal/storage/sqlite/sqlite.go init\nCREATE TABLE IF NOT EXISTS metadata (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n);\n```\n\n### Updated autoImportIfNewer():\n```go\nfunc autoImportIfNewer() {\n jsonlPath := findJSONLPath()\n \n // Check if JSONL exists\n jsonlData, err := os.ReadFile(jsonlPath)\n if err != nil {\n return // No JSONL, skip\n }\n \n // Compute current hash\n hasher := sha256.New()\n hasher.Write(jsonlData)\n currentHash := hex.EncodeToString(hasher.Sum(nil))\n \n // Get last import hash from DB\n ctx := context.Background()\n lastHash, err := store.GetMetadata(ctx, \"last_import_hash\")\n if err != nil {\n // No metadata support (old DB) - fall back to mtime comparison\n autoImportIfNewerByMtime()\n return\n }\n \n // Compare hashes\n if currentHash == lastHash {\n return // No changes, skip import\n }\n \n // Content changed - import\n if err := importJSONLSilent(jsonlPath, jsonlData); err != nil {\n return // Import failed, skip\n }\n \n // Store new hash\n _ = store.SetMetadata(ctx, \"last_import_hash\", currentHash)\n}\n```\n\n## Benefits\n\n- **Git-proof**: Works regardless of file timestamps\n- **Universal**: Works with git, Dropbox, rsync, manual edits\n- **Backward compatible**: Falls back to mtime for old DBs\n- **Efficient**: SHA256 is fast (~20ms for 1MB)\n- **Accurate**: Only imports when content actually changed\n- **No user action**: Fully automatic, invisible\n\n## Performance Optimization\n\nFor very large repos (\u003e10MB JSONL):\n- Only hash if mtime changed (combine both checks)\n- Use incremental hashing if metadata table tracks line count\n- Consider sampling hash (first 1MB + last 1MB)\n\nBut start simple - full hash is fast enough for 99% of use cases.\n\n## Rollout Plan\n\n1. Add metadata table + Get/SetMetadata methods (backward compatible)\n2. Update autoImportIfNewer() with hash logic + mtime fallback\n3. Test with old and new DBs\n4. Ship in next minor version (v0.10.0)\n5. Document in CHANGELOG as \"more reliable auto-import\"\n6. Git hooks remain optional but unnecessary for most users","acceptance_criteria":"- Auto-import works correctly after git pull\n- Agents in parallel workflows see consistent database state\n- Clear feedback when import is needed\n- Performance acceptable for large databases\n- Works in both git and non-git workflows\n- Documentation updated with multi-agent best practices","status":"in_progress","priority":1,"issue_type":"bug","created_at":"2025-10-14T02:37:34.073953-07:00","updated_at":"2025-10-15T01:08:12.805014-07:00"} -{"id":"bd-85","title":"GH-1: Fix bd dep tree graph display issues","description":"Tree display has several issues: 1) Epic items may not expand all sub-items, 2) Subitems repeat multiple times at same level, 3) Items with multiple blockers appear multiple times. The tree visualization doesn't properly handle graph structures with multiple dependencies.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-14T02:44:28.702222-07:00","updated_at":"2025-10-15T01:08:12.805722-07:00","closed_at":"2025-10-14T03:06:51.74719-07:00","external_ref":"gh-1"} -{"id":"bd-86","title":"GH-2: Evaluate optional Turso backend for collaboration","description":"RFC proposal for optional Turso/libSQL backend to enable: database branching, near-real-time sync between agents/humans, native vector search, browser-ready persistence (WASM/OPFS), and concurrent writes. Would be opt-in, keeping current JSONL+SQLite as default. Requires storage driver interface.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-10-14T02:44:51.932233-07:00","updated_at":"2025-10-15T01:08:12.806002-07:00","external_ref":"gh-2"} -{"id":"bd-87","title":"GH-3: Debug zsh killed error on bd init","description":"User reports 'zsh: killed bd init' when running bd init or just bd command. Likely a crash or signal. Need to reproduce and investigate cause.","status":"open","priority":1,"issue_type":"bug","created_at":"2025-10-14T02:44:53.054411-07:00","updated_at":"2025-10-15T01:08:12.806129-07:00","external_ref":"gh-3"} -{"id":"bd-88","title":"GH-4: Consider system-wide/multi-repo beads usage","description":"User wants to use beads across multiple repositories and for sysadmin tasks. Currently beads is project-scoped (.beads/ directory). Explore options for system-wide issue tracking that spans multiple repos. Related question: how does beads compare to membank MCP?","status":"open","priority":3,"issue_type":"feature","created_at":"2025-10-14T02:44:54.343447-07:00","updated_at":"2025-10-15T01:08:12.80626-07:00","external_ref":"gh-4"} -{"id":"bd-89","title":"GH-6: Fix race condition in parallel issue creation","description":"Creating multiple issues rapidly in parallel causes 'UNIQUE constraint failed: issues.id' error. The ID generation has a race condition. Reproducible with: for i in {26..35}; do ./bd create parallel_ 2\u003e\u00261 \u0026 done","status":"open","priority":0,"issue_type":"bug","created_at":"2025-10-14T02:44:55.510776-07:00","updated_at":"2025-10-15T01:08:12.806403-07:00","closed_at":"2025-10-14T02:58:22.645874-07:00","external_ref":"gh-6"} -{"id":"bd-9","title":"Build collision resolution tooling for distributed branch workflows","description":"When branches diverge and both create issues, auto-incrementing IDs collide on merge. Build excellent tooling to detect collisions during import, auto-renumber issues with fewer dependencies, update all references in descriptions and dependency links, and provide clear user feedback. Goal: keep beautiful brevity of numeric IDs (bd-302) while handling distributed creation gracefully.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-12T13:39:34.608218-07:00","updated_at":"2025-10-15T01:08:12.806543-07:00"} -{"id":"bd-90","title":"GH-7: Package available in AUR (beads-git)","description":"Community member created AUR package for Arch Linux: https://aur.archlinux.org/packages/beads-git. This is informational - no action needed, but good to track for release process and documentation.","status":"open","priority":4,"issue_type":"chore","created_at":"2025-10-14T02:44:56.4535-07:00","updated_at":"2025-10-15T01:08:12.806673-07:00","external_ref":"gh-7"} -{"id":"bd-91","title":"GH-9: Support markdown files in bd create","description":"Request to support markdown files as input to bd create, which would parse the markdown and split it into multiple issues. Use case: developers keep feature drafts in markdown files in version control, then want to convert them into issues. Example: bd create -f feature-draft.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-14T02:44:57.405586-07:00","updated_at":"2025-10-15T01:08:12.80681-07:00","closed_at":"2025-10-14T12:42:14.457949-07:00","external_ref":"gh-9"} -{"id":"bd-92","title":"GH-11: Add Docker support for hosted/shared instance","description":"Request for Docker container hosting to use beads across multiple dev machines. Would need to consider: centralized database (PostgreSQL?), authentication, concurrent access, API server, etc. This is a significant architectural change from the current local-first model.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-14T02:44:58.469094-07:00","updated_at":"2025-10-15T01:08:12.806944-07:00","external_ref":"gh-11"} -{"id":"bd-93","title":"GH-18: Add --deps flag to bd create for one-command issue creation","description":"Request to add dependency specification to bd create command instead of requiring separate 'bd dep add' command. Proposed syntax: bd create 'Fix bug' --deps discovered-from=bd-20. This would be especially useful for aider integration and reducing command verbosity.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-14T02:44:59.610192-07:00","updated_at":"2025-10-15T01:08:12.807074-07:00","closed_at":"2025-10-14T03:26:59.536349-07:00","external_ref":"gh-18"} -{"id":"bd-94","title":"parallel_test_1","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:46.913771-07:00","updated_at":"2025-10-15T01:08:12.807208-07:00"} -{"id":"bd-95","title":"parallel_test_4","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:46.920107-07:00","updated_at":"2025-10-15T01:08:12.807336-07:00"} -{"id":"bd-96","title":"parallel_test_7","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:46.920612-07:00","updated_at":"2025-10-15T01:08:12.807484-07:00"} -{"id":"bd-97","title":"parallel_test_6","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:46.931334-07:00","updated_at":"2025-10-15T01:08:12.807604-07:00"} -{"id":"bd-98","title":"parallel_test_5","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:46.932369-07:00","updated_at":"2025-10-15T01:08:12.807726-07:00"} -{"id":"bd-99","title":"parallel_test_2","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T02:55:46.946379-07:00","updated_at":"2025-10-15T01:08:12.80787-07:00"} -{"id":"test-100","title":"Test issue with explicit ID","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-13T23:16:20.601292-07:00","updated_at":"2025-10-15T01:08:12.808007-07:00","closed_at":"2025-10-13T23:16:45.231096-07:00"} -{"id":"test-500","title":"Root issue for dep tree test","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T03:03:20.195117-07:00","updated_at":"2025-10-15T01:08:12.808146-07:00","closed_at":"2025-10-14T03:06:42.688954-07:00","dependencies":[{"issue_id":"test-500","depends_on_id":"test-501","type":"blocks","created_at":"2025-10-14T03:03:28.960169-07:00","created_by":"stevey"},{"issue_id":"test-500","depends_on_id":"test-502","type":"blocks","created_at":"2025-10-14T03:03:28.964808-07:00","created_by":"stevey"}]} -{"id":"test-501","title":"Dependency A","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T03:03:21.377968-07:00","updated_at":"2025-10-15T01:08:12.808298-07:00","closed_at":"2025-10-14T03:06:42.693557-07:00","dependencies":[{"issue_id":"test-501","depends_on_id":"test-503","type":"blocks","created_at":"2025-10-14T03:03:28.969145-07:00","created_by":"stevey"}]} -{"id":"test-502","title":"Dependency B","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T03:03:21.383498-07:00","updated_at":"2025-10-15T01:08:12.808426-07:00","closed_at":"2025-10-14T03:06:42.697908-07:00","dependencies":[{"issue_id":"test-502","depends_on_id":"test-503","type":"blocks","created_at":"2025-10-14T03:03:28.973659-07:00","created_by":"stevey"}]} -{"id":"test-503","title":"Shared dependency C","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T03:03:21.388441-07:00","updated_at":"2025-10-15T01:08:12.808551-07:00","closed_at":"2025-10-14T03:06:42.702632-07:00"} -{"id":"test-600","title":"Epic test","description":"","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-14T03:06:14.495832-07:00","updated_at":"2025-10-15T01:08:12.808681-07:00","closed_at":"2025-10-14T03:06:42.706851-07:00","dependencies":[{"issue_id":"test-600","depends_on_id":"test-601","type":"parent-child","created_at":"2025-10-14T03:06:15.846921-07:00","created_by":"stevey"},{"issue_id":"test-600","depends_on_id":"test-602","type":"parent-child","created_at":"2025-10-14T03:06:15.851564-07:00","created_by":"stevey"}]} -{"id":"test-601","title":"Task A under epic","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T03:06:14.500446-07:00","updated_at":"2025-10-15T01:08:12.808818-07:00","closed_at":"2025-10-14T03:06:42.71108-07:00","dependencies":[{"issue_id":"test-601","depends_on_id":"test-603","type":"blocks","created_at":"2025-10-14T03:06:15.856369-07:00","created_by":"stevey"}]} -{"id":"test-602","title":"Task B under epic","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T03:06:14.504917-07:00","updated_at":"2025-10-15T01:08:12.808937-07:00","closed_at":"2025-10-14T03:06:42.715283-07:00","dependencies":[{"issue_id":"test-602","depends_on_id":"test-604","type":"blocks","created_at":"2025-10-14T03:06:15.860979-07:00","created_by":"stevey"}]} -{"id":"test-603","title":"Sub-task under A","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T03:06:14.509748-07:00","updated_at":"2025-10-15T01:08:12.809072-07:00","closed_at":"2025-10-14T03:06:42.719842-07:00"} -{"id":"test-604","title":"Sub-task under B","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T03:06:14.514628-07:00","updated_at":"2025-10-15T01:08:12.8092-07:00","closed_at":"2025-10-14T03:06:42.724998-07:00"} -{"id":"worker2-500","title":"Another explicit ID","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-13T23:16:29.978183-07:00","updated_at":"2025-10-15T01:08:12.80932-07:00","closed_at":"2025-10-13T23:16:45.231376-07:00"} +{"id":"bd-1","title":"Critical bug","description":"","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-14T14:43:06.864214-07:00","updated_at":"2025-10-15T01:58:29.735229-07:00"} +{"id":"bd-10","title":"Add PostgreSQL backend","description":"Implement PostgreSQL storage backend as alternative to SQLite for larger teams","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-10-14T14:43:06.864973-07:00","updated_at":"2025-10-15T01:58:29.738063-07:00","dependencies":[{"issue_id":"bd-10","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-14T14:43:06.953462-07:00","created_by":"auto-import"}]} +{"id":"bd-100","title":"parallel_test_10","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.865466-07:00","updated_at":"2025-10-15T01:58:29.738516-07:00"} +{"id":"bd-101","title":"parallel_test_3","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.865941-07:00","updated_at":"2025-10-15T01:58:29.739269-07:00"} +{"id":"bd-102","title":"parallel_test_8","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.866351-07:00","updated_at":"2025-10-15T01:58:29.739644-07:00"} +{"id":"bd-103","title":"parallel_test_9","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.866766-07:00","updated_at":"2025-10-15T01:58:29.740052-07:00"} +{"id":"bd-104","title":"parallel_26","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.867135-07:00","updated_at":"2025-10-15T01:58:29.740451-07:00"} +{"id":"bd-105","title":"parallel_31","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.867504-07:00","updated_at":"2025-10-15T01:58:29.740929-07:00"} +{"id":"bd-106","title":"parallel_32","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.867912-07:00","updated_at":"2025-10-15T01:58:29.741529-07:00"} +{"id":"bd-107","title":"parallel_33","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.868261-07:00","updated_at":"2025-10-15T01:58:29.742117-07:00"} +{"id":"bd-108","title":"parallel_28","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.868652-07:00","updated_at":"2025-10-15T01:58:29.742665-07:00"} +{"id":"bd-109","title":"parallel_29","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.869141-07:00","updated_at":"2025-10-15T01:58:29.743374-07:00"} +{"id":"bd-11","title":"Test issue to verify fix","description":"This should be bd-11 if the fix works","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.869567-07:00","updated_at":"2025-10-15T01:58:29.743863-07:00"} +{"id":"bd-110","title":"parallel_27","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.870054-07:00","updated_at":"2025-10-15T01:58:29.74453-07:00"} +{"id":"bd-111","title":"parallel_30","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.870667-07:00","updated_at":"2025-10-15T01:58:29.745002-07:00"} +{"id":"bd-112","title":"parallel_35","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.871125-07:00","updated_at":"2025-10-15T01:58:29.745627-07:00"} +{"id":"bd-113","title":"parallel_34","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.871584-07:00","updated_at":"2025-10-15T01:58:29.746227-07:00"} +{"id":"bd-114","title":"stress_3","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.872088-07:00","updated_at":"2025-10-15T01:58:29.746724-07:00"} +{"id":"bd-115","title":"stress_5","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.872613-07:00","updated_at":"2025-10-15T01:58:29.747202-07:00"} +{"id":"bd-116","title":"stress_10","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.873092-07:00","updated_at":"2025-10-15T01:58:29.747697-07:00"} +{"id":"bd-117","title":"stress_2","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.873579-07:00","updated_at":"2025-10-15T01:58:29.748086-07:00"} +{"id":"bd-118","title":"stress_8","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.874023-07:00","updated_at":"2025-10-15T01:58:29.748768-07:00"} +{"id":"bd-119","title":"stress_13","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.874463-07:00","updated_at":"2025-10-15T01:58:29.749366-07:00"} +{"id":"bd-12","title":"Implement collision detection in import","description":"Create collision.go with detectCollisions() function. Compare incoming JSONL issues against DB state. Distinguish between: (1) exact match (idempotent), (2) ID match but different content (collision), (3) new issue. Return list of colliding issues.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.874895-07:00","updated_at":"2025-10-15T01:58:29.749957-07:00","dependencies":[{"issue_id":"bd-12","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-14T14:43:06.954086-07:00","created_by":"auto-import"}]} +{"id":"bd-120","title":"stress_14","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.875538-07:00","updated_at":"2025-10-15T01:58:29.750345-07:00"} +{"id":"bd-121","title":"stress_1","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.876034-07:00","updated_at":"2025-10-15T01:58:29.750821-07:00"} +{"id":"bd-122","title":"stress_7","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.876508-07:00","updated_at":"2025-10-15T01:58:29.751204-07:00"} +{"id":"bd-123","title":"stress_17","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.876927-07:00","updated_at":"2025-10-15T01:58:29.751715-07:00"} +{"id":"bd-124","title":"stress_6","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.877385-07:00","updated_at":"2025-10-15T01:58:29.75217-07:00"} +{"id":"bd-125","title":"stress_19","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.877833-07:00","updated_at":"2025-10-15T01:58:29.752575-07:00"} +{"id":"bd-126","title":"stress_20","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.87826-07:00","updated_at":"2025-10-15T01:58:29.753006-07:00"} +{"id":"bd-127","title":"stress_15","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.878743-07:00","updated_at":"2025-10-15T01:58:29.753451-07:00"} +{"id":"bd-128","title":"stress_24","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.879101-07:00","updated_at":"2025-10-15T01:58:29.754135-07:00"} +{"id":"bd-129","title":"stress_18","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.879443-07:00","updated_at":"2025-10-15T01:58:29.754557-07:00"} +{"id":"bd-13","title":"Implement reference scoring algorithm","description":"Count references for each colliding issue: text mentions in descriptions/notes/design fields + dependency references. Sort collisions by score ascending (fewest refs first). This minimizes total updates during renumbering.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.879771-07:00","updated_at":"2025-10-15T01:58:29.755152-07:00","dependencies":[{"issue_id":"bd-13","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-14T14:43:06.954498-07:00","created_by":"auto-import"}]} +{"id":"bd-130","title":"stress_22","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.880115-07:00","updated_at":"2025-10-15T01:58:29.755751-07:00"} +{"id":"bd-131","title":"stress_28","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.880453-07:00","updated_at":"2025-10-15T01:58:29.756429-07:00"} +{"id":"bd-132","title":"stress_25","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.880807-07:00","updated_at":"2025-10-15T01:58:29.75726-07:00"} +{"id":"bd-133","title":"stress_29","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.88123-07:00","updated_at":"2025-10-15T01:58:29.757715-07:00"} +{"id":"bd-134","title":"stress_26","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.881844-07:00","updated_at":"2025-10-15T01:58:29.758375-07:00"} +{"id":"bd-135","title":"stress_9","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.882401-07:00","updated_at":"2025-10-15T01:58:29.758762-07:00"} +{"id":"bd-136","title":"stress_30","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.882972-07:00","updated_at":"2025-10-15T01:58:29.759153-07:00"} +{"id":"bd-137","title":"stress_32","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.88358-07:00","updated_at":"2025-10-15T01:58:29.75953-07:00"} +{"id":"bd-138","title":"stress_16","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.8839-07:00","updated_at":"2025-10-15T01:58:29.75994-07:00"} +{"id":"bd-139","title":"stress_27","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.884314-07:00","updated_at":"2025-10-15T01:58:29.760462-07:00"} +{"id":"bd-14","title":"Implement ID remapping with reference updates","description":"Allocate new IDs for colliding issues. Update all text field references using word-boundary regex (\\bbd-10\\b). Update dependency records. Build id_mapping for reporting. Handle chain dependencies properly.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.884715-07:00","updated_at":"2025-10-15T01:58:29.761252-07:00","dependencies":[{"issue_id":"bd-14","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-14T14:43:06.954903-07:00","created_by":"auto-import"}]} +{"id":"bd-140","title":"stress_31","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.885327-07:00","updated_at":"2025-10-15T01:58:29.76171-07:00"} +{"id":"bd-141","title":"stress_35","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.885862-07:00","updated_at":"2025-10-15T01:58:29.770522-07:00"} +{"id":"bd-142","title":"stress_37","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.886257-07:00","updated_at":"2025-10-15T01:58:29.792086-07:00"} +{"id":"bd-143","title":"stress_34","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.886598-07:00","updated_at":"2025-10-15T01:58:29.808806-07:00"} +{"id":"bd-144","title":"stress_36","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.886974-07:00","updated_at":"2025-10-15T01:58:29.810889-07:00"} +{"id":"bd-145","title":"stress_21","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.887329-07:00","updated_at":"2025-10-15T01:58:29.811348-07:00"} +{"id":"bd-146","title":"stress_38","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.887758-07:00","updated_at":"2025-10-15T01:58:29.849699-07:00"} +{"id":"bd-147","title":"stress_42","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.888374-07:00","updated_at":"2025-10-15T01:58:29.851-07:00"} +{"id":"bd-148","title":"stress_43","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.888824-07:00","updated_at":"2025-10-15T01:58:29.855933-07:00"} +{"id":"bd-149","title":"stress_39","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.889456-07:00","updated_at":"2025-10-15T01:58:29.86182-07:00"} +{"id":"bd-15","title":"Add --resolve-collisions flag and user reporting","description":"Add import flags: --resolve-collisions (auto-fix) and --dry-run (preview). Display clear report: collisions detected, remappings applied (oldβ†’new with scores), reference counts updated. Default behavior: fail on collision (safe).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.889982-07:00","updated_at":"2025-10-15T01:58:29.863934-07:00","dependencies":[{"issue_id":"bd-15","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-14T14:43:06.955291-07:00","created_by":"auto-import"}]} +{"id":"bd-150","title":"stress_45","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.890307-07:00","updated_at":"2025-10-15T01:58:29.877674-07:00"} +{"id":"bd-151","title":"stress_46","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.89072-07:00","updated_at":"2025-10-15T01:58:29.898572-07:00"} +{"id":"bd-152","title":"stress_48","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.891313-07:00","updated_at":"2025-10-15T01:58:29.901135-07:00"} +{"id":"bd-153","title":"stress_44","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.891907-07:00","updated_at":"2025-10-15T01:58:29.913516-07:00"} +{"id":"bd-154","title":"stress_40","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.892231-07:00","updated_at":"2025-10-15T01:58:29.92738-07:00"} +{"id":"bd-155","title":"stress_41","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.892591-07:00","updated_at":"2025-10-15T01:58:29.930933-07:00"} +{"id":"bd-156","title":"stress_12","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.892947-07:00","updated_at":"2025-10-15T01:58:29.931419-07:00"} +{"id":"bd-157","title":"stress_47","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.893312-07:00","updated_at":"2025-10-15T01:58:29.931842-07:00"} +{"id":"bd-158","title":"stress_49","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.893755-07:00","updated_at":"2025-10-15T01:58:29.933778-07:00"} +{"id":"bd-159","title":"stress_50","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.894144-07:00","updated_at":"2025-10-15T01:58:29.937324-07:00"} +{"id":"bd-16","title":"Write comprehensive collision resolution tests","description":"Test cases: simple collision, multiple collisions, dependency updates, text reference updates, chain dependencies, edge cases (partial ID matches, case sensitivity, triple merges). Add to import_test.go and collision_test.go.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.894813-07:00","updated_at":"2025-10-15T01:58:29.939657-07:00","dependencies":[{"issue_id":"bd-16","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-14T14:43:06.955691-07:00","created_by":"auto-import"}]} +{"id":"bd-160","title":"stress_33","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.895578-07:00","updated_at":"2025-10-15T01:58:29.940381-07:00"} +{"id":"bd-161","title":"stress_23","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.896284-07:00","updated_at":"2025-10-15T01:58:29.940842-07:00"} +{"id":"bd-162","title":"stress_11","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.896638-07:00","updated_at":"2025-10-15T01:58:29.941604-07:00"} +{"id":"bd-163","title":"stress_4","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.89714-07:00","updated_at":"2025-10-15T01:58:29.942194-07:00"} +{"id":"bd-164","title":"Add visual indicators for nodes with multiple parents in dep tree","description":"When a node appears in the dependency tree via multiple paths (diamond dependencies), add a visual indicator like (*) or (multiple parents) to help users understand the graph structure. This would make it clear when deduplication has occurred. Example: 'bd-503: Shared dependency (*) [P1] (open)'","status":"open","priority":3,"issue_type":"feature","created_at":"2025-10-14T14:43:06.897533-07:00","updated_at":"2025-10-15T01:58:29.942892-07:00","dependencies":[{"issue_id":"bd-164","depends_on_id":"bd-85","type":"discovered-from","created_at":"2025-10-14T14:43:06.95608-07:00","created_by":"auto-import"}]} +{"id":"bd-165","title":"Add --show-all-paths flag to bd dep tree","description":"Currently bd dep tree deduplicates nodes when multiple paths exist (diamond dependencies). Add optional --show-all-paths flag to display the full graph with all paths, showing duplicates. Useful for debugging complex dependency structures and understanding all relationships.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-10-14T14:43:06.897954-07:00","updated_at":"2025-10-15T01:58:29.957201-07:00","dependencies":[{"issue_id":"bd-165","depends_on_id":"bd-85","type":"discovered-from","created_at":"2025-10-14T14:43:06.956472-07:00","created_by":"auto-import"}]} +{"id":"bd-166","title":"Make maxDepth configurable in bd dep tree command","description":"Currently maxDepth is hardcoded to 50 in GetDependencyTree. Add --max-depth flag to bd dep tree command to allow users to control recursion depth. Default should remain 50 for safety, but users with very deep trees or wanting shallow views should be able to configure it.","status":"open","priority":4,"issue_type":"feature","created_at":"2025-10-14T14:43:06.898547-07:00","updated_at":"2025-10-15T01:58:29.958218-07:00","dependencies":[{"issue_id":"bd-166","depends_on_id":"bd-85","type":"discovered-from","created_at":"2025-10-14T14:43:06.956876-07:00","created_by":"auto-import"}]} +{"id":"bd-167","title":"Test issue with --deps flag","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.899116-07:00","updated_at":"2025-10-15T01:58:29.963978-07:00","dependencies":[{"issue_id":"bd-167","depends_on_id":"bd-89","type":"discovered-from","created_at":"2025-10-14T14:43:06.957327-07:00","created_by":"auto-import"}]} +{"id":"bd-168","title":"Another test with multiple deps","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.899631-07:00","updated_at":"2025-10-15T01:58:29.965055-07:00","dependencies":[{"issue_id":"bd-168","depends_on_id":"bd-89","type":"blocks","created_at":"2025-10-14T14:43:06.957934-07:00","created_by":"auto-import"},{"issue_id":"bd-168","depends_on_id":"bd-90","type":"blocks","created_at":"2025-10-14T14:43:06.958441-07:00","created_by":"auto-import"}]} +{"id":"bd-169","title":"Fix: bd init --prefix test -q flag not recognized","description":"The init command doesn't recognize the -q flag. When running 'bd init --prefix test -q', it fails silently or behaves unexpectedly. The flag should either be implemented for quiet mode or removed from documentation if not supported.","status":"open","priority":2,"issue_type":"bug","created_at":"2025-10-14T14:43:06.899974-07:00","updated_at":"2025-10-15T01:58:29.965582-07:00"} +{"id":"bd-17","title":"Update documentation for collision resolution","description":"Update README.md with collision resolution section. Update CLAUDE.md with new workflow. Document --resolve-collisions and --dry-run flags. Add example scenarios showing branch merge workflows.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.900315-07:00","updated_at":"2025-10-15T01:58:29.966083-07:00","dependencies":[{"issue_id":"bd-17","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-14T14:43:06.959024-07:00","created_by":"auto-import"}]} +{"id":"bd-170","title":"Add OAuth2 support","description":"Implement OAuth2 authentication flow with support for Google and GitHub providers.","design":"- Create OAuth2 provider interface\n- Implement Google provider\n- Implement GitHub provider\n- Add callback handler\n- Store tokens securely","acceptance_criteria":"- Users can authenticate with Google\n- Users can authenticate with GitHub\n- Tokens are stored securely in database\n- Token refresh works automatically","status":"closed","priority":1,"issue_type":"feature","assignee":"alice","created_at":"2025-10-14T14:43:06.900641-07:00","updated_at":"2025-10-15T01:58:29.966505-07:00"} +{"id":"bd-171","title":"Add rate limiting to auth endpoints","description":"Auth endpoints are vulnerable to brute force attacks. Need to add rate limiting.","status":"closed","priority":0,"issue_type":"bug","assignee":"bob","created_at":"2025-10-14T14:43:06.900983-07:00","updated_at":"2025-10-15T01:58:29.966921-07:00"} +{"id":"bd-172","title":"Improve session management","description":"Current session management is basic. Need to improve with better expiration handling.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.901432-07:00","updated_at":"2025-10-15T01:58:29.967441-07:00"} +{"id":"bd-173","title":"Refactor parseMarkdownFile to reduce cyclomatic complexity","description":"The parseMarkdownFile function in cmd/bd/markdown.go has a cyclomatic complexity of 38, which exceeds the recommended threshold of 30. This makes the function harder to understand, test, and maintain.","design":"Split the function into smaller, focused units:\n\n1. parseMarkdownFile(filepath) - Main entry point, handles file I/O\n2. parseMarkdownContent(scanner) - Core parsing logic\n3. processIssueSection(issue, section, content) - Handle section finalization (current switch statement)\n4. parseLabels(content) []string - Extract labels from content\n5. parseDependencies(content) []string - Extract dependencies from content\n6. parsePriority(content) int - Parse and validate priority\n\nBenefits:\n- Each function has a single responsibility\n- Easier to test individual components\n- Lower cognitive load when reading code\n- Better encapsulation of parsing logic","acceptance_criteria":"- parseMarkdownFile complexity \u003c 15\n- New helper functions each have complexity \u003c 10\n- All existing tests still pass\n- No change in functionality or behavior\n- Code coverage maintained or improved","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.902086-07:00","updated_at":"2025-10-15T01:58:29.968062-07:00","dependencies":[{"issue_id":"bd-173","depends_on_id":"bd-91","type":"discovered-from","created_at":"2025-10-14T14:43:06.959447-07:00","created_by":"auto-import"}]} +{"id":"bd-174","title":"Add OAuth2 support","description":"Implement OAuth2 authentication flow with support for Google and GitHub providers.","design":"- Create OAuth2 provider interface\n- Implement Google provider\n- Implement GitHub provider\n- Add callback handler\n- Store tokens securely","acceptance_criteria":"- Users can authenticate with Google\n- Users can authenticate with GitHub\n- Tokens are stored securely in database\n- Token refresh works automatically","status":"closed","priority":1,"issue_type":"feature","assignee":"alice","created_at":"2025-10-14T14:43:06.90268-07:00","updated_at":"2025-10-15T01:58:29.968676-07:00"} +{"id":"bd-175","title":"Add rate limiting to auth endpoints","description":"Auth endpoints are vulnerable to brute force attacks. Need to add rate limiting.","status":"closed","priority":0,"issue_type":"bug","assignee":"bob","created_at":"2025-10-14T14:43:06.903236-07:00","updated_at":"2025-10-15T01:58:29.969245-07:00"} +{"id":"bd-176","title":"Improve session management","description":"Current session management is basic. Need to improve with better expiration handling.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.903785-07:00","updated_at":"2025-10-15T01:58:29.969952-07:00"} +{"id":"bd-177","title":"Add OAuth2 support","description":"Implement OAuth2 authentication flow with support for Google and GitHub providers.","design":"- Create OAuth2 provider interface\n- Implement Google provider\n- Implement GitHub provider\n- Add callback handler\n- Store tokens securely","acceptance_criteria":"- Users can authenticate with Google\n- Users can authenticate with GitHub\n- Tokens are stored securely in database\n- Token refresh works automatically","status":"closed","priority":1,"issue_type":"feature","assignee":"alice","created_at":"2025-10-14T14:43:06.904366-07:00","updated_at":"2025-10-15T01:58:29.970372-07:00"} +{"id":"bd-178","title":"Add rate limiting to auth endpoints","description":"Auth endpoints are vulnerable to brute force attacks. Need to add rate limiting.","status":"closed","priority":0,"issue_type":"bug","assignee":"bob","created_at":"2025-10-14T14:43:06.904917-07:00","updated_at":"2025-10-15T01:58:29.970794-07:00"} +{"id":"bd-179","title":"Improve session management","description":"Current session management is basic. Need to improve with better expiration handling.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.905375-07:00","updated_at":"2025-10-15T01:58:29.971185-07:00"} +{"id":"bd-18","title":"Add design/notes/acceptance_criteria fields to update command","description":"Currently bd update only supports status, priority, title, assignee. Add support for --design, --notes, --acceptance-criteria flags. This makes it easier to add detailed designs to issues after creation.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-14T14:43:06.905787-07:00","updated_at":"2025-10-15T01:58:29.972554-07:00"} +{"id":"bd-180","title":"Investigate vector/semantic search for issue discovery","description":"From GH issue #2 RFC discussion: Evaluate if vector/semantic search over issues would provide value for beads.\n\n**Use case:** Find semantically related issues (e.g., 'login broken' finds 'authentication failure', 'session expired').\n\n**Questions to answer:**\n1. What workflows would this enable that we can't do now?\n2. Is dataset size (typically 50-200 issues) large enough to benefit?\n3. Do structured features (deps, tags, types) already provide better relationships?\n4. What's the maintenance cost (embeddings, storage, recomputation)?\n\n**Alternatives to consider:**\n- Improve 'bd list' filtering with regex/boolean queries\n- Add 'bd related \u003cid\u003e' showing deps + mentions + same tags\n- Export to JSON and pipe to external AI tools\n\n**Decision:** Only implement if clear use case emerges. Don't add complexity for theoretical benefits.\n\n**Context:** Part of evaluating Turso RFC ideas (GH #2). Vector search was proposed but unclear if needed for typical beads usage.","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.90617-07:00","updated_at":"2025-10-15T01:58:29.973365-07:00"} +{"id":"bd-181","title":"Implement storage driver interface for pluggable backends","description":"Create abstraction layer for storage to support multiple backends (SQLite, Postgres, Turso, in-memory testing, etc.).\n\n**Current state:** All storage logic hardcoded to SQLite in internal/storage/sqlite/sqlite.go\n\n**Proposed design:**\n\n```go\n// internal/storage/storage.go\ntype Store interface {\n // Issue CRUD\n CreateIssue(issue *Issue) error\n GetIssue(id string) (*Issue, error)\n UpdateIssue(id string, updates *Issue) error\n DeleteIssue(id string) error\n ListIssues(filter *Filter) ([]*Issue, error)\n \n // Dependencies\n AddDependency(from, to string, depType DependencyType) error\n RemoveDependency(from, to string, depType DependencyType) error\n GetDependencies(id string) ([]*Dependency, error)\n \n // Counters, stats\n GetNextID(prefix string) (string, error)\n GetStats() (*Stats, error)\n \n Close() error\n}\n```\n\n**Benefits:**\n- Better testing (mock/in-memory stores)\n- Future flexibility (Postgres, cloud APIs, etc.)\n- Clean architecture (business logic decoupled from storage)\n- Enable Turso or other backends without refactoring everything\n\n**Implementation steps:**\n1. Define Store interface in internal/storage/storage.go\n2. Refactor SQLiteStore to implement interface\n3. Update all commands to use interface, not concrete type\n4. Add MemoryStore for testing\n5. Add driver selection via config (storage.driver = sqlite|turso|postgres)\n6. Update tests to use interface\n\n**Note:** This is valuable even without adopting Turso. Good architecture practice.\n\n**Context:** From GH issue #2 RFC evaluation. Driver interface is low-cost, high-value regardless of whether we add alternative backends.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-14T14:43:06.906511-07:00","updated_at":"2025-10-15T01:58:29.974121-07:00"} +{"id":"bd-182","title":"Investigate auto-export debounce not triggering","description":"Auto-export to JSONL did not trigger automatically after creating bd-180 and bd-181. Had to manually run 'bd export' to sync.\n\n**Expected behavior:** Auto-export should trigger ~5 seconds after CRUD operations (per CLAUDE.md documentation).\n\n**Actual behavior:** Issues bd-180 and bd-181 were created but JSONL was not updated until manual 'bd export' was run.\n\n**Investigation needed:**\n1. Check if auto-flush goroutine is running\n2. Verify debounce timer is being triggered on CreateIssue()\n3. Check for errors/panics in background export\n4. Verify auto-flush is enabled by default\n5. Check if there's a race condition with shutdown\n\n**Impact:** HIGH - Data loss risk if users create issues and don't realize they haven't synced to Git.\n\n**Testing:**\n```bash\n# Create issue and wait 10 seconds\nbd create \"Test\" -p 4\nsleep 10\ngrep \"Test\" .beads/issues.jsonl # Should find it\n```\n\n**Workaround:** Manually run 'bd export' after CRUD operations.\n\n**Context:** Discovered during GH issue #2 RFC evaluation while creating bd-180 and bd-181.","notes":"**Investigation Results:**\n\nThe auto-export feature IS working correctly in the current codebase (v0.9.5). Testing shows:\n\nβœ… Storage layer marks issues dirty correctly (lines 415-423, 593-601, 633-641 in sqlite.go)\nβœ… CLI calls markDirtyAndScheduleFlush() after CRUD operations (lines 766, 1000, 1055 in main.go)\nβœ… Debounce timer (5s) triggers and exports to JSONL successfully\nβœ… Tested: Created bd-196, auto-exported within 6 seconds\n\n**Root Cause:**\nThe issue was caused by running an **old bd binary** that didn't have the complete auto-export implementation. After rebuilding (`go build -o bd ./cmd/bd`), auto-export works perfectly.\n\n**Resolution:**\nUsers experiencing this issue need to:\n1. Rebuild bd: `go build -o bd ./cmd/bd`\n2. Install updated binary: `sudo mv bd /usr/local/bin/` (or appropriate path)\n3. Verify: `bd version` should show 0.9.5+\n\n**Additional Notes:**\n- Auto-export uses 5-second debounce (configurable at main.go:36)\n- Exports are atomic (writes to .tmp, then renames)\n- Only dirty issues are exported (incremental updates)\n- Works correctly in production use\n\n**Follow-up:**\nConsider adding a version check warning if user's binary is outdated (bd-408).","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-14T14:43:06.906901-07:00","updated_at":"2025-10-15T01:58:29.977661-07:00"} +{"id":"bd-183","title":"Plugin manifest has invalid 'engines' field causing marketplace install failure","description":"The plugin.json manifest includes an 'engines' field that Claude Code doesn't recognize. This causes the plugin to fail validation when installed via /plugin marketplace add.\n\nError: Plugin beads has an invalid manifest file at .claude-plugin/plugin.json. Validation errors: : Unrecognized key(s) in object: 'engines'\n\nFix: Remove the 'engines' field from plugin.json\n\nThe engines field was added to specify minimum beads version requirements, but Claude Code's plugin manifest schema doesn't support it. We should document version requirements in PLUGIN.md instead.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-14T15:47:14.09898-07:00","updated_at":"2025-10-15T01:58:29.985573-07:00","closed_at":"2025-10-14T15:47:18.699148-07:00"} +{"id":"bd-184","title":"race_test_4","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-15T01:07:02.006879-07:00","updated_at":"2025-10-15T01:58:29.990093-07:00"} +{"id":"bd-185","title":"race_test_8","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-15T01:07:02.007447-07:00","updated_at":"2025-10-15T01:58:29.99812-07:00"} +{"id":"bd-186","title":"race_test_5","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-15T01:07:02.007814-07:00","updated_at":"2025-10-15T01:58:29.998741-07:00"} +{"id":"bd-187","title":"race_test_16","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-15T01:07:02.008177-07:00","updated_at":"2025-10-15T01:58:30.003933-07:00"} +{"id":"bd-188","title":"race_test_17","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-15T01:07:02.008525-07:00","updated_at":"2025-10-15T01:58:30.005029-07:00"} +{"id":"bd-189","title":"race_test_10","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-15T01:07:02.008903-07:00","updated_at":"2025-10-15T01:58:30.005718-07:00"} +{"id":"bd-19","title":"Fix import zero-value field handling","description":"Import uses zero-value checks (Priority != 0) to determine field updates. This prevents setting priority to 0 or clearing string fields. Export/import round-trip not fully idempotent for zero values. Consider JSON presence detection or explicit preserve-existing semantics. Location: cmd/bd/import.go:95-106","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-10-14T14:43:06.907261-07:00","updated_at":"2025-10-15T01:58:30.006336-07:00"} +{"id":"bd-190","title":"race_test_11","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-15T01:07:02.009797-07:00","updated_at":"2025-10-15T01:58:30.007588-07:00"} +{"id":"bd-191","title":"final_test_10","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-15T01:07:02.010151-07:00","updated_at":"2025-10-15T01:58:30.009493-07:00"} +{"id":"bd-192","title":"final_test_7","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-15T01:07:02.010504-07:00","updated_at":"2025-10-15T01:58:30.019232-07:00"} +{"id":"bd-193","title":"stress_test_5","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-15T01:07:02.010847-07:00","updated_at":"2025-10-15T01:58:30.023171-07:00"} +{"id":"bd-194","title":"stress_test_6","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-15T01:07:02.011186-07:00","updated_at":"2025-10-15T01:58:30.026717-07:00"} +{"id":"bd-195","title":"stress_test_1","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-15T01:07:02.011549-07:00","updated_at":"2025-10-15T01:58:30.027585-07:00"} +{"id":"bd-196","title":"Test2 auto-export","description":"","status":"closed","priority":4,"issue_type":"task","created_at":"2025-10-15T01:07:02.011907-07:00","updated_at":"2025-10-15T01:58:30.028707-07:00"} +{"id":"bd-197","title":"Add version mismatch warning for outdated binaries","description":"When bd detects that the database was created/modified by a newer version, warn the user that they may be running an outdated binary.\n\n**Problem:** Users may run old bd binaries without realizing it, leading to confusing behavior (e.g., missing features like auto-export).\n\n**Solution:** Store schema version or bd version in metadata table, check on startup, warn if mismatch.\n\n**Implementation:**\n1. Add `schema_version` or `bd_version` to metadata table during init\n2. Check version in PersistentPreRun (cmd/bd/main.go)\n3. Warn if binary version \u003c DB version\n4. Suggest: 'Your bd binary (v0.9.3) is older than this database (v0.9.5). Rebuild: go build -o bd ./cmd/bd'\n\n**Edge cases:**\n- Dev builds (show commit hash?)\n- Backwards compatibility (older DBs should work with newer binaries)\n- Don't warn on every command (maybe once per session?)\n\n**Related:** Fixes confusion from bd-182 (auto-export not working with old binary)","notes":"**Implementation Complete:**\n\nβœ… Added version metadata storage during `bd init` (init.go:59-63)\nβœ… Added `checkVersionMismatch()` function (main.go:301-345)\nβœ… Integrated version check into PersistentPreRun (main.go:98-99)\nβœ… Tested both scenarios:\n - Outdated binary: Clear warning with rebuild instructions\n - Newer binary: Info message that DB will be auto-upgraded\nβœ… No warnings on subsequent runs (version updated automatically)\n\n**How it works:**\n1. On `bd init`: Stores current version in metadata table\n2. On every command: Checks stored version vs binary version\n3. If mismatch:\n - Binary \u003c DB version β†’ Warn: outdated binary\n - Binary \u003e DB version β†’ Info: auto-upgrading DB\n4. Always updates stored version to current (future-proof)\n\n**Files modified:**\n- cmd/bd/init.go: Store version on init\n- cmd/bd/main.go: checkVersionMismatch() + integration\n\n**Testing:**\n```bash\n# Simulate old binary\nsqlite3 .beads/default.db \"UPDATE metadata SET value='0.9.99' WHERE key='bd_version';\"\nbd ready # Shows warning\n\n# Normal use (versions match)\nbd ready # No warning\n```\n\n**Edge cases handled:**\n- Empty version (old DB): Silently upgrade\n- Metadata errors: Skip check (defensive)\n- Dev builds: String comparison (works for 0.9.5 vs 0.9.6)\n\nFixes bd-182 confusion (users won't run outdated binaries unknowingly).","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-15T01:07:02.012291-07:00","updated_at":"2025-10-15T01:58:30.030043-07:00","dependencies":[{"issue_id":"bd-197","depends_on_id":"bd-182","type":"discovered-from","created_at":"2025-10-15T01:07:02.078326-07:00","created_by":"auto-import"}]} +{"id":"bd-198","title":"Add label management commands to CLI","description":"Currently labels can only be managed programmatically via the storage API. Add CLI commands to add, remove, and filter by labels.","acceptance_criteria":"Can add/remove/list labels via CLI, can filter issues by label, labels persist to JSONL","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-15T01:10:48.43357-07:00","updated_at":"2025-10-15T01:57:59.013482-07:00"} +{"id":"bd-199","title":"Investigate and fix import timeout with 208 issues","description":"bd import times out after 2 minutes when importing 208 issues from JSONL. This is unacceptable for a tool designed to scale to 100k+ issues.","design":"\n## Reproduction\n```bash\ncd ~/src/beads\nbd import .beads/issues.jsonl # Hangs/times out after 2 minutes\n```\n\nCurrent database state:\n- 208 issues in bd.db (2MB)\n- 208 lines in issues.jsonl (100KB)\n- WAL mode enabled\n\n## Symptoms\n- Import starts but never completes\n- No error message, just hangs\n- Timeout after 2 minutes (artificially imposed in testing)\n- Happens even when database already contains the issues (idempotent import)\n\n## Likely Causes\n1. **Transaction size** - All 208 issues in one transaction?\n2. **Lock contention** - WAL checkpoint blocking?\n3. **N+1 queries** - Dependency checking for each issue?\n4. **Missing indexes** - Slow lookups during collision detection?\n5. **Auto-flush interaction** - Background flush goroutine conflicting?\n\n## Performance Target\nShould handle:\n- 1000 issues in \u003c 5 seconds\n- 10,000 issues in \u003c 30 seconds \n- 100,000 issues in \u003c 5 minutes\n\n## Investigation Steps\n1. Add timing instrumentation to import phases\n2. Profile the import operation\n3. Check for lock contention in WAL mode\n4. Review collision detection performance\n5. Test with PRAGMA synchronous = NORMAL\n6. Consider batching imports (e.g., 100 issues per transaction)\n","acceptance_criteria":"\n- Can import 208 issues in \u003c 5 seconds\n- Can import 1000 issues in \u003c 30 seconds\n- Add performance logging to identify bottlenecks\n- Add --batch-size flag for tuning\n- Document performance characteristics\n- Integration test with large import\n","status":"open","priority":0,"issue_type":"bug","created_at":"2025-10-15T01:11:08.998901-07:00","updated_at":"2025-10-15T01:57:59.015932-07:00"} +{"id":"bd-2","title":"Verify auto-export works","description":"","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-14T14:43:06.907657-07:00","updated_at":"2025-10-15T01:58:30.032546-07:00"} +{"id":"bd-20","title":"Add --strict flag for dependency import failures","description":"Currently dependency import errors are warnings (logged to stderr, execution continues). Missing targets or cycles may indicate JSONL corruption. Add --strict flag to fail on any dependency errors for data integrity validation. Location: cmd/bd/import.go:159-164","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-14T14:43:06.90826-07:00","updated_at":"2025-10-15T01:58:30.033084-07:00"} +{"id":"bd-21","title":"Simplify getNextID SQL query parameters","description":"Query passes prefix four times to same SQL query. Works but fragile if query changes. Consider simplifying SQL to require fewer parameters. Location: internal/storage/sqlite/sqlite.go:73-78","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.908906-07:00","updated_at":"2025-10-15T01:58:30.033747-07:00"} +{"id":"bd-22","title":"Add validation/warning for malformed issue IDs","description":"getNextID silently ignores non-numeric ID suffixes (e.g., bd-foo). CAST returns NULL for invalid strings. Consider detecting and warning about malformed IDs in database. Location: internal/storage/sqlite/sqlite.go:79-82","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.909504-07:00","updated_at":"2025-10-15T01:58:30.0367-07:00"} +{"id":"bd-224","title":"Data model allows inconsistent status/closed_at states","description":"Issue bd-89 demonstrates a data model inconsistency: an issue can have status='open' but also have a closed_at timestamp set. This creates a liminal state that violates the expected invariant that closed_at should only be set when status='closed'.\n\nRoot causes:\n1. Import (bd import) updates status field independently from closed_at field\n2. UpdateIssue allows status changes without managing closed_at\n3. No database constraint enforcing the invariant\n4. Export includes both fields independently in JSONL\n\nCurrent behavior:\n- bd close: Sets status='closed' AND closed_at (correct)\n- bd update --status open: Sets status='open' but leaves closed_at unchanged (creates inconsistency)\n- bd import: Can import inconsistent data from JSONL\n\nImpact:\n- 'bd ready' shows issues that appear closed (have closed_at)\n- Confusing for users and downstream tools\n- Stats may be inaccurate\n\nPotential solutions:\nA) Add CHECK constraint: (status = 'closed') = (closed_at IS NOT NULL)\nB) Update import/update logic to enforce invariant in application code\nC) Add a 'reopened' event that explicitly clears closed_at\nD) Remove closed_at field entirely (calculate from events or use status only)\n\nSee bd-89 for concrete example.","status":"in_progress","priority":1,"issue_type":"bug","created_at":"2025-10-15T01:36:21.971783-07:00","updated_at":"2025-10-15T01:58:30.039395-07:00"} +{"id":"bd-225","title":"Ultrathink: Choose solution for status/closed_at inconsistency (bd-224)","description":"Deep analysis of solution options for bd-224 data model inconsistency issue.\n\nContext:\n- Target users: individual devs and small teams\n- Future: swarms of agent workers\n- Brand-new codebase with few users (can break things)\n- Issue: status='open' with closed_at!=NULL creates liminal state\n\nOptions to evaluate:\nA) Database CHECK constraint\nB) Application-level enforcement \nC) Add explicit reopened event\nD) Remove closed_at field entirely\n\nAnalysis framework:\n1. Simplicity (mental model for devs)\n2. Robustness (hard to break, especially for agent swarms)\n3. Migration cost (schema changes, data cleanup)\n4. Future extensibility\n5. Performance\n6. Consistency guarantees\n\nNeed to determine best approach given tradeoffs.","notes":"Analysis complete. Recommendation: Hybrid approach with DB CHECK constraint + smart UpdateIssue + import enforcement + reopen command.\n\nKey insights:\n- DB constraint provides defense-in-depth perfect for agent swarms\n- Statistics calculation currently uses 'closed_at IS NOT NULL' which is BROKEN by inconsistent data\n- UpdateIssue and Import don't manage the invariant\n- EventReopened exists but is unused\n\nSee ULTRATHINK_BD224.md for full analysis.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-15T01:47:25.564925-07:00","updated_at":"2025-10-15T01:58:30.041321-07:00","closed_at":"2025-10-15T01:49:43.078431-07:00","dependencies":[{"issue_id":"bd-225","depends_on_id":"bd-224","type":"discovered-from","created_at":"2025-10-15T01:47:25.567014-07:00","created_by":"stevey"}]} +{"id":"bd-226","title":"Epic: Fix status/closed_at inconsistency (bd-224 solution)","description":"Implement hybrid solution to enforce status/closed_at invariant:\n- Database CHECK constraint\n- Smart UpdateIssue logic\n- Import enforcement\n- Reopen command\n\nThis is a data integrity issue that affects statistics and will cause problems for agent swarms. The hybrid approach provides defense-in-depth.\n\nSee ULTRATHINK_BD224.md for full analysis and rationale.\n\nParent of all implementation tasks for this fix.","status":"open","priority":1,"issue_type":"epic","created_at":"2025-10-15T01:58:41.041574-07:00","updated_at":"2025-10-15T01:58:41.041574-07:00"} +{"id":"bd-227","title":"Audit and document all inconsistent issues in database","description":"Before we add the constraint, we need to know what data is inconsistent.\n\nSteps:\n1. Query database for status/closed_at mismatches\n2. Document each case (how many, which issues, patterns)\n3. Decide on cleanup strategy (trust status vs trust closed_at)\n4. Create SQL script for cleanup\n\nOutput: Document with counts and cleanup SQL ready to review.\n\nThis unblocks the migration work.","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-15T01:58:50.908363-07:00","updated_at":"2025-10-15T01:58:50.908363-07:00","dependencies":[{"issue_id":"bd-227","depends_on_id":"bd-226","type":"parent-child","created_at":"2025-10-15T01:58:50.909081-07:00","created_by":"stevey"}]} +{"id":"bd-228","title":"Critical: Auto-import silently overwrites local changes without collision detection","description":"## Problem\n\nAuto-import is silently overwriting local changes when pulling from Git, without using collision detection or warning the user.\n\n## Evidence\n\nIssue bd-89 timeline:\n1. 08:07:31 - Manual update: set status=in_progress\n2. 08:13:08 - Manual close: set status=closed, closed_at set\n3. 08:33:25 - **Auto-import silently overwrote to status=open** (discarded local change)\n4. 08:57:59 - Auto-import overwrote again\n5. 08:58:30 - Auto-import overwrote again\n\nQuery shows 10+ issues with multiple auto-import overwrites, including bd-198, bd-199, bd-200-206.\n\n## Root Cause Hypothesis\n\nWhen two clones both modify issue N:\n- Clone A: modifies bd-89, exports to JSONL, commits\n- Clone B: also modifies bd-89 differently, pulls from A\n- Auto-import uses UpdateIssue which **unconditionally overwrites**\n- Clone B's local changes are silently lost\n- No collision detection warning\n- References and work context corrupted\n\n## Impact\n\n- **Data loss**: Local changes silently discarded\n- **Corruption**: Issue state doesn't reflect actual work done\n- **Lost references**: Comments/deps referencing lost state are now wrong\n- **Trust**: Can't trust the database reflects reality\n- **Agent swarms**: Catastrophic for parallel workers\n\n## Expected Behavior\n\nAuto-import should:\n1. Detect collisions (same ID, different content)\n2. Warn user or fail import\n3. Offer resolution options (--resolve-collisions)\n4. Never silently overwrite without user confirmation\n\n## Current Behavior\n\nAuto-import silently overwrites using UpdateIssue, no collision detection.\n\n## Reproduction\n\n1. Clone A: bd update bd-1 --status in_progress\n2. Clone A: git add .beads/issues.jsonl \u0026\u0026 git commit \u0026\u0026 git push\n3. Clone B: bd update bd-1 --status closed \n4. Clone B: git pull (triggers auto-import)\n5. Result: bd-1 status silently reverted to in_progress, closed state lost\n\n## Files Involved\n\n- cmd/bd/main.go: auto-import trigger logic\n- cmd/bd/import.go: import without collision detection\n- internal/storage/sqlite/sqlite.go: UpdateIssue unconditionally overwrites","status":"open","priority":0,"issue_type":"bug","created_at":"2025-10-15T02:06:30.671918-07:00","updated_at":"2025-10-15T02:06:30.671918-07:00"} +{"id":"bd-23","title":"Optimize export dependency queries (N+1 problem)","description":"Export triggers separate GetDependencyRecords() per issue. For large DBs (1000+ issues), this is N+1 queries. Add GetAllDependencyRecords() to fetch all dependencies in one query. Location: cmd/bd/export.go:52-59, import.go:138-142","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.910124-07:00","updated_at":"2025-10-15T01:58:30.041954-07:00"} +{"id":"bd-24","title":"Support ID space partitioning for parallel worker agents","description":"Enable external orchestrators (like AI worker swarms) to control issue ID assignment. Add --id flag to 'bd create' for explicit ID specification. Optionally support 'bd config set next_id N' to set the starting point for auto-increment. Storage layer already supports pre-assigned IDs (sqlite.go:52-71), just need CLI wiring. This keeps beads simple while letting orchestrators implement their own ID partitioning strategies to minimize merge conflicts. Complementary to bd-9's collision resolution.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-14T14:43:06.910467-07:00","updated_at":"2025-10-15T01:58:30.042402-07:00"} +{"id":"bd-25","title":"Add transaction support to storage layer for atomic multi-operation workflows","description":"Currently each storage method (CreateIssue, UpdateIssue, etc.) starts its own transaction. This makes it impossible to perform atomic multi-step operations like collision resolution. Add support for passing *sql.Tx through the storage interface, or create transaction-aware versions of methods. This would make remapCollisions and other batch operations truly atomic.","status":"closed","priority":4,"issue_type":"feature","created_at":"2025-10-14T14:43:06.910892-07:00","updated_at":"2025-10-15T01:58:30.043082-07:00"} +{"id":"bd-26","title":"Optimize reference updates to avoid loading all issues into memory","description":"In updateReferences(), we call SearchIssues with no filter to get ALL issues for updating references. For large databases (10k+ issues), this loads everything into memory. Options: 1) Use batched processing with LIMIT/OFFSET, 2) Use SQL UPDATE with REPLACE() directly, 3) Stream results instead of loading all at once. Located in collision.go:266","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.911497-07:00","updated_at":"2025-10-15T01:58:30.043529-07:00"} +{"id":"bd-27","title":"Cache compiled regexes in replaceIDReferences for performance","description":"replaceIDReferences() compiles the same regex patterns on every call. With 100 issues and 10 ID mappings, that's 1000 regex compilations. Pre-compile regexes once and reuse. Can use a struct with compiled regex, placeholder, and newID. Located in collision.go:329. Estimated performance improvement: 10-100x for large batches.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.911892-07:00","updated_at":"2025-10-15T01:58:30.044175-07:00"} +{"id":"bd-28","title":"Improve error handling in dependency removal during remapping","description":"In updateDependencyReferences(), RemoveDependency errors are caught and ignored with continue (line 392). Comment says 'if dependency doesn't exist' but this catches ALL errors including real failures. Should check error type with errors.Is(err, ErrDependencyNotFound) and only ignore not-found errors, returning other errors properly.","status":"open","priority":3,"issue_type":"bug","created_at":"2025-10-14T14:43:06.912228-07:00","updated_at":"2025-10-15T01:58:30.04686-07:00"} +{"id":"bd-29","title":"Use safer placeholder pattern in replaceIDReferences","description":"Currently uses __PLACEHOLDER_0__ which could theoretically collide with user text. Use a truly unique placeholder like null bytes: \\x00REMAP\\x00_0_\\x00 which are unlikely to appear in normal text. Located in collision.go:324. Very low probability issue but worth fixing for completeness.","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.912567-07:00","updated_at":"2025-10-15T01:58:30.047261-07:00"} +{"id":"bd-3","title":"Normal task","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.912905-07:00","updated_at":"2025-10-15T01:58:30.047663-07:00"} +{"id":"bd-30","title":"Remove unused issueMap in scoreCollisions","description":"scoreCollisions() creates issueMap and populates it (lines 135-138) but never uses it. Either remove it or add a TODO comment explaining future use. Located in collision.go:135-138. Cosmetic cleanup.","status":"open","priority":4,"issue_type":"chore","created_at":"2025-10-14T14:43:06.913242-07:00","updated_at":"2025-10-15T01:58:30.048056-07:00"} +{"id":"bd-31","title":"Test issue for design field","description":"Testing the new update flags","design":"## Design Plan\\n- Add flags to update command\\n- Test thoroughly\\n- Document changes","acceptance_criteria":"- All three fields (design, notes, acceptance-criteria) can be updated\\n- Changes persist in database\\n- bd show displays the fields correctly","notes":"Implementation complete. All tests passing.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.91361-07:00","updated_at":"2025-10-15T01:58:30.048624-07:00"} +{"id":"bd-32","title":"bd should auto-detect .beads/*.db in current directory","description":"When bd is run without --db flag, it defaults to beads' own database instead of looking for a .beads/*.db file in the current working directory. This causes confusion when working on other projects that use beads for issue tracking (like vc).\n\nExpected behavior: bd should search for .beads/*.db in cwd and use that if found, before falling back to default beads database.\n\nExample: Running 'bd ready' in /Users/stevey/src/vc/vc/ should automatically find and use .beads/vc.db without requiring --db flag every time.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-14T14:43:06.914075-07:00","updated_at":"2025-10-15T01:58:30.049086-07:00"} +{"id":"bd-33","title":"Document or automate JSONL sync workflow for git collaboration","description":"When using beads across multiple machines/environments via git, there's a workflow gap:\n\n1. Machine A: Create issues β†’ stored in .beads/project.db\n2. Machine A: bd export -o .beads/issues.jsonl\n3. Machine A: git add .beads/issues.jsonl \u0026\u0026 git commit \u0026\u0026 git push\n4. Machine B: git pull\n5. Machine B: ??? issues.jsonl exists but project.db is empty/stale\n\nThe missing step is: bd import --db .beads/project.db -i .beads/issues.jsonl\n\nThis needs to be either:\na) Documented clearly in workflow docs\nb) Automated (e.g., git hook, or bd auto-imports if jsonl is newer than db)\nc) Both\n\nReal-world impact: User had Claude Code on GCP VM create vc issues from BOOTSTRAP.md. They were exported to issues.jsonl and committed. But on local machine, vc.db was empty until manual import was run.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.914655-07:00","updated_at":"2025-10-15T01:58:30.049864-07:00"} +{"id":"bd-34","title":"Implement reserved database name _.db","description":"Auto-detection now skips .beads/_.db to prevent pollution when beads dogfoods itself. This allows beads to use its own issue tracker without interfering with other projects using beads in the same directory tree. Implementation includes filtering in findDatabase(), stopping directory walk when .beads/ is found, and documentation in README.md and CLAUDE.md.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-14T14:43:06.915077-07:00","updated_at":"2025-10-15T01:58:30.050522-07:00"} +{"id":"bd-35","title":"Auto-flush JSONL on CRUD operations with 5-second debounce","description":"Implemented automatic write-through from SQLite to JSONL with 5-second debouncing. After any CRUD operation (create, update, close, dep add/remove), changes are scheduled to flush to JSONL after 5 seconds of inactivity. On process exit, any pending changes are flushed immediately. This prevents .db and .jsonl from getting out of sync, solving the workflow gap where agents forget to run 'bd export'. Can be disabled with --no-auto-flush flag. Addresses bd-33.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-14T14:43:06.915626-07:00","updated_at":"2025-10-15T01:58:30.051131-07:00"} +{"id":"bd-36","title":"Handle missing JSONL directory in findJSONLPath","description":"findJSONLPath() assumes the database directory exists. If someone runs bd init to create a new database but the .beads directory doesn't exist yet, the glob operations might fail silently. Add os.MkdirAll(dbDir, 0755) to ensure directory exists before globbing. Located in cmd/bd/main.go:188-201.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-10-14T14:43:06.916198-07:00","updated_at":"2025-10-15T01:58:30.052385-07:00"} +{"id":"bd-37","title":"Refactor duplicate flush logic in PersistentPostRun","description":"PersistentPostRun contains a complete copy of the flush logic instead of calling flushToJSONL(). This violates DRY principle and makes maintenance harder. Refactor to use flushToJSONL() with a force parameter to bypass isDirty check, or extract shared logic into a helper function. Located in cmd/bd/main.go:104-138.","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.916555-07:00","updated_at":"2025-10-15T01:58:30.053154-07:00"} +{"id":"bd-38","title":"Add visibility for auto-flush failures","description":"flushToJSONL() writes warnings to stderr when flush fails, but calling code has no way to know if flush succeeded or failed. This means a command could return success even though JSONL is now out of sync. Consider maintaining a 'last flush status' variable or counter for failed flushes, and warn user after multiple consecutive failures (e.g., 3+). Located in cmd/bd/main.go:227-307.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-14T14:43:06.916932-07:00","updated_at":"2025-10-15T01:58:30.053646-07:00"} +{"id":"bd-39","title":"Optimize auto-flush to use incremental updates","description":"Every flush exports ALL issues and ALL dependencies, even if only one issue changed. For large projects (1000+ issues), this could be expensive. Current approach guarantees consistency, which is fine for MVP, but future optimization could track which issues changed and use incremental updates. Located in cmd/bd/main.go:255-276.","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-10-14T14:43:06.917357-07:00","updated_at":"2025-10-15T01:58:30.054143-07:00"} +{"id":"bd-4","title":"Low priority chore","description":"","status":"open","priority":4,"issue_type":"chore","created_at":"2025-10-14T14:43:06.917877-07:00","updated_at":"2025-10-15T01:58:30.054661-07:00","dependencies":[{"issue_id":"bd-4","depends_on_id":"bd-8","type":"parent-child","created_at":"2025-10-14T14:43:06.959864-07:00","created_by":"auto-import"}]} +{"id":"bd-40","title":"Make auto-flush debounce duration configurable","description":"flushDebounce is hardcoded to 5 seconds. Make it configurable via environment variable BEADS_FLUSH_DEBOUNCE (e.g., '500ms', '10s'). Current 5-second value is reasonable for interactive use, but CI/automated scenarios might want faster flush. Add getDebounceDuration() helper function. Located in cmd/bd/main.go:31.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-10-14T14:43:06.919549-07:00","updated_at":"2025-10-15T01:58:30.05508-07:00"} +{"id":"bd-41","title":"Add godoc comments for auto-flush functions","description":"Add comprehensive godoc comments for findJSONLPath(), markDirtyAndScheduleFlush(), and flushToJSONL() explaining behavior, concurrency considerations, and error handling. Include notes about debouncing behavior (timer resets on each write, flush occurs 5s after LAST operation) and flush-on-exit guarantees. Located in cmd/bd/main.go:188-307.","status":"open","priority":4,"issue_type":"chore","created_at":"2025-10-14T14:43:06.920127-07:00","updated_at":"2025-10-15T01:58:30.055452-07:00"} +{"id":"bd-42","title":"Add test coverage for auto-flush feature","description":"Add comprehensive tests for auto-flush functionality:\\n- Test that markDirtyAndScheduleFlush() is called after CRUD operations\\n- Test debounce timing (rapid operations result in single flush)\\n- Test --no-auto-flush flag disables feature\\n- Test flush on program exit\\n- Test concurrent operations don't cause races\\n- Test error scenarios (disk full, permission denied, etc.)\\n- Test import command triggers auto-flush\\n\\nCurrent implementation has no test coverage for the auto-flush feature. Located in cmd/bd/main_test.go (to be created).","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.920746-07:00","updated_at":"2025-10-15T01:58:30.055882-07:00"} +{"id":"bd-43","title":"Test auto-sync feature","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.921495-07:00","updated_at":"2025-10-15T01:58:30.066389-07:00"} +{"id":"bd-44","title":"Regular auto-ID issue","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.921829-07:00","updated_at":"2025-10-15T01:58:30.06874-07:00"} +{"id":"bd-45","title":"Test flush tracking","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.922242-07:00","updated_at":"2025-10-15T01:58:30.070881-07:00"} +{"id":"bd-46","title":"Test export cancels timer","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.922822-07:00","updated_at":"2025-10-15T01:58:30.084977-07:00"} +{"id":"bd-47","title":"Test incremental export","description":"Testing bd-39 implementation","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.923382-07:00","updated_at":"2025-10-15T01:58:30.088922-07:00"} +{"id":"bd-48","title":"Test incremental 2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.923957-07:00","updated_at":"2025-10-15T01:58:30.090325-07:00"} +{"id":"bd-49","title":"Final test","description":"Testing with new binary","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.924274-07:00","updated_at":"2025-10-15T01:58:30.091641-07:00"} +{"id":"bd-5","title":"Test issue","description":"Testing prefix","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.924607-07:00","updated_at":"2025-10-15T01:58:30.092902-07:00","dependencies":[{"issue_id":"bd-5","depends_on_id":"bd-8","type":"parent-child","created_at":"2025-10-14T14:43:06.960259-07:00","created_by":"auto-import"}]} +{"id":"bd-50","title":"Test label dirty tracking","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.924971-07:00","updated_at":"2025-10-15T01:58:30.093325-07:00"} +{"id":"bd-51","title":"Test hash-based import","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.925369-07:00","updated_at":"2025-10-15T01:58:30.093721-07:00"} +{"id":"bd-52","title":"Create Claude Code plugin for beads","description":"Package beads as a Claude Code plugin for easy installation via /plugin command.\n\nContext: GitHub issue #28 - https://github.com/steveyegge/beads/issues/28\n\nCurrent state:\n- MCP server exists in integrations/beads-mcp/\n- No plugin packaging yet\n\nDeliverables:\n1. .claude-plugin/plugin.json with metadata\n2. .claude-plugin/marketplace.json for distribution\n3. Custom slash commands (/bd-ready, /bd-create, /bd-show, etc.)\n4. Bundle MCP server configuration\n5. Optional: Pre-configured hooks for auto-sync\n6. Documentation for installation and usage\n\nBenefits:\n- Makes beads instantly discoverable in Claude Code ecosystem\n- Single-command installation vs. manual setup\n- Bundled cohesive experience\n- Lowers adoption barrier significantly\n\nReferences:\n- https://www.anthropic.com/news/claude-code-plugins\n- https://docs.claude.com/en/docs/claude-code/plugins","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-14T14:43:06.925906-07:00","updated_at":"2025-10-15T01:58:30.094162-07:00"} +{"id":"bd-53","title":"Research Claude Code plugin structure and requirements","description":"Study the plugin format, required files, and best practices.\n\nTasks:\n- Review official plugin documentation\n- Examine example plugins if available\n- Document plugin.json schema\n- Understand marketplace.json requirements\n- Identify slash command format","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.92648-07:00","updated_at":"2025-10-15T01:58:30.094559-07:00","dependencies":[{"issue_id":"bd-53","depends_on_id":"bd-52","type":"parent-child","created_at":"2025-10-14T14:46:10.735591-07:00","created_by":"auto-import"}]} +{"id":"bd-54","title":"Create plugin metadata files","description":"Create .claude-plugin/plugin.json and marketplace.json.\n\nRequirements:\n- Name, description, version, author\n- MCP server configuration bundling\n- License and repository info\n- Installation instructions","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.926978-07:00","updated_at":"2025-10-15T01:58:30.094923-07:00","dependencies":[{"issue_id":"bd-54","depends_on_id":"bd-52","type":"parent-child","created_at":"2025-10-14T14:46:10.736046-07:00","created_by":"auto-import"}]} +{"id":"bd-55","title":"Design and implement slash commands","description":"Create useful slash commands for beads workflow.\n\nProposed commands:\n- /bd-ready - Show ready work\n- /bd-create - Create new issue interactively\n- /bd-show - Show issue details\n- /bd-update - Update issue status\n- /bd-close - Close issue\n- /bd-workflow - Show full agent workflow guide\n\nEach command should provide a good UX and leverage the MCP server tools.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.927312-07:00","updated_at":"2025-10-15T01:58:30.09529-07:00","dependencies":[{"issue_id":"bd-55","depends_on_id":"bd-52","type":"parent-child","created_at":"2025-10-14T14:46:10.736614-07:00","created_by":"auto-import"}]} +{"id":"bd-56","title":"Write plugin documentation","description":"Create comprehensive documentation for the plugin.\n\nContents:\n- Installation instructions\n- Available commands\n- MCP tools reference\n- Configuration options\n- Examples and workflows\n- Troubleshooting guide","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.927713-07:00","updated_at":"2025-10-15T01:58:30.095645-07:00","dependencies":[{"issue_id":"bd-56","depends_on_id":"bd-52","type":"parent-child","created_at":"2025-10-14T14:46:10.736986-07:00","created_by":"auto-import"}]} +{"id":"bd-57","title":"Test plugin installation and functionality","description":"Verify the plugin works end-to-end.\n\nTest cases:\n- Fresh installation via /plugin command\n- All slash commands work correctly\n- MCP server tools are accessible\n- Configuration options work\n- Documentation is accurate\n- Works in both terminal and VS Code","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.928041-07:00","updated_at":"2025-10-15T01:58:30.09717-07:00","dependencies":[{"issue_id":"bd-57","depends_on_id":"bd-52","type":"parent-child","created_at":"2025-10-14T14:46:10.737369-07:00","created_by":"auto-import"}]} +{"id":"bd-58","title":"Parent's blocker should block children in ready work calculation","description":"GitHub issue #19: If epic1 blocks epic2, children of epic2 should also be considered blocked when calculating ready work. Currently epic2's children show as ready even though their parent is blocked. This breaks the natural hierarchy of dependencies and can cause agents to work on tasks out of order.\n\nExpected: ready work calculation should traverse up parent-child hierarchy and check if any ancestor has blocking dependencies.\n\nSee: https://github.com/anthropics/claude-code/issues/19","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-14T14:43:06.928389-07:00","updated_at":"2025-10-15T01:58:30.097658-07:00"} +{"id":"bd-59","title":"Add composite index on dependencies(depends_on_id, type)","description":"The hierarchical blocking query does:\nJOIN dependencies d ON d.depends_on_id = bt.issue_id\nWHERE d.type = 'parent-child'\n\nCurrently we only have idx_dependencies_depends_on (line 41 in schema.go), which covers depends_on_id but not the type filter.\n\n**Impact:**\n- Query has to scan ALL dependencies for a given depends_on_id, then filter by type\n- With 10k+ issues and many dependencies, this could cause slowdowns\n- The blocker propagation happens recursively, amplifying the cost\n\n**Solution:**\nAdd composite index: CREATE INDEX idx_dependencies_depends_on_type ON dependencies(depends_on_id, type)\n\n**Testing:**\nRun EXPLAIN QUERY PLAN on GetReadyWork query before/after to verify index usage.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.929017-07:00","updated_at":"2025-10-15T01:58:30.098066-07:00"} +{"id":"bd-6","title":"Add migration scripts for GitHub Issues","description":"Create scripts to import from GitHub Issues API or exported JSON","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-14T14:43:06.929582-07:00","updated_at":"2025-10-15T01:58:30.098467-07:00","dependencies":[{"issue_id":"bd-6","depends_on_id":"bd-8","type":"parent-child","created_at":"2025-10-14T14:43:06.960703-07:00","created_by":"auto-import"}]} +{"id":"bd-60","title":"Update ready_issues VIEW to use hierarchical blocking","description":"The ready_issues VIEW (schema.go:97-108) uses the OLD blocking logic that doesn't propagate through parent-child hierarchies.\n\n**Problem:**\n- GetReadyWork() function now uses recursive CTE with propagation\n- But the ready_issues VIEW still uses simple NOT EXISTS check\n- Any code using the VIEW will get DIFFERENT results than GetReadyWork()\n- This creates inconsistency and confusion\n\n**Impact:**\n- Unknown if the VIEW is actually used anywhere in the codebase\n- If it is used, it's returning incorrect results (showing children as ready when parent is blocked)\n\n**Solution:**\nEither:\n1. Update VIEW to match GetReadyWork logic (complex CTE in a view)\n2. Drop the VIEW entirely if unused\n3. Make VIEW call GetReadyWork as a function (if SQLite supports it)\n\n**Investigation needed:**\nGrep for 'ready_issues' to see if the view is actually used.","notes":"**Investigation results:**\nGrepped the codebase - the ready_issues VIEW appears in:\n- schema.go (definition)\n- WORKFLOW.md, DESIGN.md (documentation)\n- No actual Go code queries it directly\n\n**Conclusion:** The VIEW is defined but appears UNUSED by actual code. GetReadyWork() function is used instead.\n\n**Recommended solution:** Drop the VIEW entirely to avoid confusion. It serves no purpose if unused and creates a maintenance burden (needs to stay in sync with GetReadyWork logic).\n\n**Alternative:** If we want to keep it for direct SQL access, update the VIEW definition to match the new recursive CTE logic.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-14T14:43:06.930111-07:00","updated_at":"2025-10-15T01:58:30.098854-07:00"} +{"id":"bd-61","title":"Add test for deep hierarchy blocking (50+ levels)","description":"Current tests verify 2-level depth (grandparent β†’ parent β†’ child). The depth limit is hardcoded to 50 in the recursive CTE, but we don't test edge cases near that limit.\n\n**Test cases needed:**\n1. Verify 50-level deep hierarchy works correctly\n2. Verify depth limit prevents runaway recursion\n3. Measure performance impact of deep hierarchies\n4. Consider if 50 is the right limit (why not 100? why not 20?)\n\n**Rationale:**\n- Most hierarchies are 2-5 levels deep\n- But pathological cases (malicious or accidental) could create 50+ level nesting\n- Need to ensure graceful degradation, not catastrophic failure\n\n**Implementation:**\nAdd TestDeepHierarchyBlocking to ready_test.go","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.930479-07:00","updated_at":"2025-10-15T01:58:30.099257-07:00"} +{"id":"bd-62","title":"Document hierarchical blocking behavior in README","description":"The fix for bd-58 changes user-visible behavior: children of blocked epics are now automatically blocked.\n\n**What needs documenting:**\n1. README.md dependency section should explain blocking propagation\n2. Clarify that 'blocks' + 'parent-child' together create transitive blocking\n3. Note that 'related' and 'discovered-from' do NOT propagate blocking\n4. Add example showing epic β†’ child blocking propagation\n\n**Example to add:**\n```bash\n# If epic is blocked, children are too\nbd create \"Epic 1\" -t epic -p 1\nbd create \"Task 1\" -t task -p 1\nbd dep add task-1 epic-1 --type parent-child\n\n# Block the epic\nbd create \"Blocker\" -t task -p 0\nbd dep add epic-1 blocker-1 --type blocks\n\n# Now both epic-1 AND task-1 are blocked\nbd ready # Neither will show up\n```","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.930812-07:00","updated_at":"2025-10-15T01:58:30.099685-07:00"} +{"id":"bd-63","title":"Add EXPLAIN QUERY PLAN tests for ready work query","description":"Verify that the hierarchical blocking query uses proper indexes and doesn't do full table scans.\n\n**Queries to analyze:**\n1. The recursive CTE (both base case and recursive case)\n2. The final SELECT with NOT EXISTS\n3. Impact of various filters (status, priority, assignee)\n\n**Implementation:**\nAdd test function that:\n- Runs EXPLAIN QUERY PLAN on GetReadyWork query\n- Parses output to verify no SCAN TABLE operations\n- Documents expected query plan in comments\n- Fails if query plan degrades\n\n**Benefits:**\n- Catch performance regressions in tests\n- Document expected query behavior\n- Ensure indexes are being used\n\nRelated to: bd-59 (composite index on depends_on_id, type)","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.931295-07:00","updated_at":"2025-10-15T01:58:30.100066-07:00"} +{"id":"bd-64","title":"Verify and test Claude Code plugin","description":"Address remaining items from code review:\n\nCritical:\n1. Test plugin installation locally with /plugin marketplace add\n2. Verify ${CLAUDE_PLUGIN_ROOT} variable works correctly\n3. Test each slash command works\n4. Test @task-agent execution\n5. Verify MCP server connects properly\n\nDocumentation:\n1. Clarify 'one-command installation' vs prerequisites\n2. Add note about plugin development status\n3. Verify all paths and examples work\n\nNice-to-have:\n1. Add icon for marketplace (optional)\n2. Add categories field to plugin.json\n3. Add engines field for version compatibility","notes":"PLUGIN IMPLEMENTATION COMPLETE - READY FOR TESTING\n\nWhat was built:\nβœ… .claude-plugin/plugin.json - Plugin metadata with MCP server config\nβœ… .claude-plugin/marketplace.json - Marketplace configuration\nβœ… 9 slash commands in .claude-plugin/commands/:\n - bd-ready, bd-create, bd-show, bd-update, bd-close\n - bd-workflow, bd-init, bd-stats, bd-version\nβœ… Task agent in .claude-plugin/agents/task-agent.md\nβœ… PLUGIN.md - Comprehensive documentation\nβœ… README.md - Updated with plugin section\nβœ… Version sync - All components at 0.9.2\n\nTesting Instructions for Next Agent:\n=====================================\n\n1. INSTALL PLUGIN FROM GITHUB:\n /plugin marketplace add steveyegge/beads\n /plugin install beads\n \n2. RESTART CLAUDE CODE (required for MCP server)\n\n3. TEST SLASH COMMANDS:\n /bd-version # Check versions (should show 0.9.2)\n /bd-workflow # Show workflow guide\n /bd-stats # Show project stats\n /bd-ready # Find ready work\n /bd-create \"Test plugin\" task 2\n /bd-show bd-\u003cid\u003e\n \n4. TEST MCP SERVER:\n /mcp # Verify 'beads' server appears\n \n5. TEST TASK AGENT:\n @task-agent # If supported in Claude Code\n \n6. VERIFY:\n - All commands work without errors\n - MCP tools are accessible\n - Version checking works\n - Documentation is accurate\n\nExpected Issues:\n- May need to adjust MCP server path variable (${CLAUDE_PLUGIN_ROOT})\n- Task agent syntax might differ\n- Some commands may need refinement based on actual usage\n\nIf testing fails, check:\n- bd CLI is in PATH: which bd\n- uv is installed: which uv\n- MCP server logs in Claude Code\n- PLUGIN.md troubleshooting section\n\nCommit references:\n- 9f38375: feat: Add Claude Code plugin for beads\n- d25fc53: feat: Add version compatibility checking\n- c0f1044: fix: Sync all component versions to 0.9.2\n- a5c71f0: feat: Add version bump script\n- a612b92: docs: Add version management to CLAUDE.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.931639-07:00","updated_at":"2025-10-15T01:58:30.101943-07:00","dependencies":[{"issue_id":"bd-64","depends_on_id":"bd-71","type":"parent-child","created_at":"2025-10-14T14:43:06.961374-07:00","created_by":"auto-import"}]} +{"id":"bd-65","title":"Document versioning and release strategy","description":"Create comprehensive versioning strategy for beads ecosystem.\n\nComponents to document:\n1. bd CLI (Go binary) - main version number\n2. Plugin (Claude Code) - tracks CLI version\n3. MCP server (Python) - bundled with plugin\n4. Release workflow - how to sync all three\n\nDecisions to make:\n- Should plugin.json auto-update from bd CLI version?\n- Should we have a VERSION file at repo root?\n- How to handle breaking changes across components?\n- What's the update notification strategy?\n\nReferences:\n- plugin.json engines field now requires bd \u003e=0.9.0\n- /bd-version command added for checking compatibility\n- PLUGIN.md now documents update workflow","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.932054-07:00","updated_at":"2025-10-15T01:58:30.102872-07:00","dependencies":[{"issue_id":"bd-65","depends_on_id":"bd-71","type":"parent-child","created_at":"2025-10-14T14:43:06.961927-07:00","created_by":"auto-import"}]} +{"id":"bd-66","title":"Sync versions to 0.9.2 across all components","description":"Version mismatch discovered: bd CLI is 0.9.2 but other components still at 0.9.0 or 1.0.0.\n\nCurrent state:\n- bd CLI (cmd/bd/version.go): 0.9.2 βœ“\n- Plugin (.claude-plugin/plugin.json): 0.9.0 βœ—\n- MCP Server (integrations/beads-mcp): 1.0.0 βœ—\n- README.md: 0.9.0 βœ—\n\nFiles to update:\n1. .claude-plugin/plugin.json\n2. integrations/beads-mcp/pyproject.toml\n3. README.md (all mentions)\n4. PLUGIN.md (if any mentions)\n5. CHANGELOG.md (add 0.9.1 and 0.9.2 entries)\n\nRoot cause: Version bumps only updated version.go, not other components.\nSolution needed: Script or process to sync versions across all files.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-14T14:43:06.932512-07:00","updated_at":"2025-10-15T01:58:30.10331-07:00","dependencies":[{"issue_id":"bd-66","depends_on_id":"bd-71","type":"parent-child","created_at":"2025-10-14T14:43:06.962388-07:00","created_by":"auto-import"}]} +{"id":"bd-67","title":"Create version bump script","description":"Create scripts/bump-version.sh to automate version syncing across all components.\n\nThe script should:\n1. Take a version number as argument (e.g., ./scripts/bump-version.sh 0.9.3)\n2. Update all version files:\n - cmd/bd/version.go (Version constant)\n - .claude-plugin/plugin.json (version field)\n - .claude-plugin/marketplace.json (plugins[].version)\n - integrations/beads-mcp/pyproject.toml (version field)\n - README.md (Alpha version mention)\n - PLUGIN.md (version requirements)\n3. Validate semantic versioning format\n4. Show diff preview before applying\n5. Optionally create git commit with standard message\n\nThis prevents the version mismatch issue that occurred when only version.go was updated.\n\nRelated: bd-66 (version sync issue)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.933094-07:00","updated_at":"2025-10-15T01:58:30.10388-07:00","dependencies":[{"issue_id":"bd-67","depends_on_id":"bd-71","type":"parent-child","created_at":"2025-10-14T14:43:06.962804-07:00","created_by":"auto-import"}]} +{"id":"bd-68","title":"Add system-wide/multi-repo support for beads","description":"GitHub issue #4 requests ability to use beads across multiple projects and for system-wide task tracking.\n\nCurrent limitation: beads is per-repository isolated. Each project has its own .beads/ directory and issues cannot reference issues in other projects.\n\nPotential approaches:\n1. Global beads instance in ~/.beads/global.db for cross-project work\n2. Project references - allow issues to link across repos\n3. Multi-project workspace support - one beads instance managing multiple repos\n4. Integration with existing MCP server to provide remote multi-project access\n\nUse cases:\n- System administrators tracking work across multiple machines/repos\n- Developers working on a dozen+ projects simultaneously\n- Cross-cutting concerns that span multiple repositories\n- Global todo list with project-specific subtasks\n\nRelated:\n- GitHub issue #4: https://github.com/steveyegge/beads/issues/4\n- Comparison to membank MCP which already supports multi-project via centralized server\n- MCP server at integrations/beads-mcp/ could be extended for this\n\nSee also: Testing framework for plugins (also from GH #4)","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-14T14:43:06.933446-07:00","updated_at":"2025-10-15T01:58:30.104311-07:00","dependencies":[{"issue_id":"bd-68","depends_on_id":"bd-71","type":"parent-child","created_at":"2025-10-14T14:43:06.963228-07:00","created_by":"auto-import"}]} +{"id":"bd-69","title":"Add coverage threshold to CI pipeline","description":"Current CI runs tests with coverage but doesn't enforce minimum threshold. Add step to fail if coverage drops below target.\n\nCurrent coverage: 60%\nRecommended thresholds:\n- Warn: 55%\n- Fail: 50%\n\nThis prevents coverage regression while allowing gradual improvement toward 80% target for 1.0.\n\nImplementation:\n1. Add coverage check step after test run\n2. Use 'go tool cover -func=coverage.out' to get total\n3. Parse percentage and compare to threshold\n4. Optionally: Use codecov's built-in threshold features\n\nRelated to test coverage improvement work (upcoming issue).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.93378-07:00","updated_at":"2025-10-15T01:58:30.104779-07:00","dependencies":[{"issue_id":"bd-69","depends_on_id":"bd-71","type":"parent-child","created_at":"2025-10-14T14:43:06.963643-07:00","created_by":"auto-import"}]} +{"id":"bd-7","title":"Add performance benchmarks document","description":"Document actual performance metrics with hyperfine tests","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.934101-07:00","updated_at":"2025-10-15T01:58:30.105223-07:00","dependencies":[{"issue_id":"bd-7","depends_on_id":"bd-8","type":"parent-child","created_at":"2025-10-14T14:43:06.964048-07:00","created_by":"auto-import"}]} +{"id":"bd-70","title":"Increase test coverage for auto-flush and auto-import features","description":"Critical features have 0% test coverage despite being core workflow functionality.\n\n**Uncovered areas (0% coverage):**\n\nAuto-flush/Auto-import (dirty tracking):\n- MarkIssueDirty / MarkIssuesDirty\n- GetDirtyIssues / GetDirtyIssueCount\n- ClearDirtyIssues / ClearDirtyIssuesByID\n- Auto-flush debouncing logic\n- Auto-import hash comparison\n\nDatabase/file discovery:\n- FindDatabasePath (finds .beads/*.db in directory tree)\n- FindJSONLPath (finds issues.jsonl)\n- findDatabaseInTree helper\n\nLabel operations:\n- AddLabel / RemoveLabel\n- GetLabels / GetIssuesByLabel\n\nEvents/Comments:\n- AddComment\n- GetEvents\n- GetStatistics\n\nMetadata storage:\n- SetMetadata / GetMetadata (used for import hash tracking)\n\nCLI output formatting:\n- outputJSON\n- printCollisionReport / printRemappingReport\n- createIssuesFromMarkdown\n\n**Priority areas:**\n1. Auto-flush/import (highest risk - core workflow)\n2. Database discovery (second - affects all operations)\n3. Labels/events (lower priority - less commonly used)\n\n**Test approach:**\n- Add unit tests for dirty tracking in sqlite package\n- Add integration tests for auto-flush timing and debouncing\n- Add tests for import hash detection and idempotency\n- Add tests for database discovery edge cases (permissions, nested dirs)\n\n**Target:** Get overall coverage from 60% β†’ 75%, focus on cmd/bd (currently 24.1%)\n\n**Note:** These features work well in practice (dogfooding proves it) but edge cases (disk full, permissions, concurrent access, race conditions) are untested.","notes":"Test coverage significantly improved! Added comprehensive test suites:\n\n**Tests Added:**\n1. βœ… Dirty tracking (dirty_test.go): 8 tests\n - MarkIssueDirty, MarkIssuesDirty, GetDirtyIssues, ClearDirtyIssues\n - GetDirtyIssueCount, ClearDirtyIssuesByID\n - Ordering and timestamp update tests\n - Coverage: 75-100% for all functions\n\n2. βœ… Metadata storage (sqlite_test.go): 4 tests\n - SetMetadata, GetMetadata with various scenarios\n - Coverage: 100%\n\n3. βœ… Label operations (labels_test.go): 9 tests\n - AddLabel, RemoveLabel, GetLabels, GetIssuesByLabel\n - Duplicate handling, empty cases, dirty marking\n - Coverage: 71-82%\n\n4. βœ… Events \u0026 Comments (events_test.go): 7 tests\n - AddComment, GetEvents with limits\n - Timestamp updates, dirty marking\n - Multiple event types in history\n - Coverage: 73-92%\n\n5. βœ… Database/JSONL discovery (beads_test.go): 8 tests\n - FindDatabasePath with env var, tree search, home default\n - FindJSONLPath with existing files, defaults, multiple files\n - Coverage: 89-100%\n\n**Coverage Results:**\n- Overall: 70.3% (up from ~60%)\n- beads package: 90.6%\n- sqlite package: 74.7% (up from 60.8%)\n- types package: 100%\n\n**Impact:**\nAll priority 1 features now have solid test coverage. Auto-flush/import, metadata storage, labels, and events are thoroughly tested with edge cases covered.\n\nFiles created:\n- internal/storage/sqlite/dirty_test.go (8 tests)\n- internal/storage/sqlite/labels_test.go (9 tests)\n- internal/storage/sqlite/events_test.go (7 tests)\n- beads_test.go (8 tests)\n\nFiles modified:\n- internal/storage/sqlite/sqlite_test.go (added 4 metadata tests)\n\n**Next Steps (if desired):**\n- CLI output formatting tests (outputJSON, printCollisionReport, etc.)\n- Integration tests for auto-flush debouncing timing\n- More edge cases for concurrent access","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.934425-07:00","updated_at":"2025-10-15T01:58:30.106259-07:00","dependencies":[{"issue_id":"bd-70","depends_on_id":"bd-71","type":"parent-child","created_at":"2025-10-14T14:43:06.96447-07:00","created_by":"auto-import"}]} +{"id":"bd-71","title":"Code review follow-up: Post-PR #8 merge improvements","description":"Follow-up tasks from the ultrathink code review of PR #8 merge (bd-62).\n\n**Context:** PR #8 successfully merged atomic counter + dirty tracking. Core functionality is solid but several improvements identified.\n\n**Critical (P0-P1):**\n- bd-64: Fix SyncAllCounters performance bottleneck (P0)\n- bd-65: Add migration for issue_counters table (P1)\n- bd-66: Make import counter sync failure fatal (P1)\n\n**Nice to have (P2-P3):**\n- bd-67: Update test comments (P2)\n- bd-68: Add performance benchmarks (P2)\n- bd-69: Add metrics/logging (P3)\n- bd-70: Add EXPLAIN QUERY PLAN tests (P3)\n\n**Overall assessment:** 4/5 stars - Excellent implementation with one critical performance issue. After bd-64 is fixed, this becomes 5/5.\n\n**Review document:** Available if needed","notes":"Status update: All P0-P1 critical tasks completed! bd-64 (performance), bd-65 (migration), bd-66 (fatal error), bd-67 (comments) are all done. Atomic counter implementation is now production-ready. Remaining tasks are P2-P3 enhancements.","status":"open","priority":1,"issue_type":"epic","created_at":"2025-10-14T14:43:06.934829-07:00","updated_at":"2025-10-15T01:58:30.106651-07:00"} +{"id":"bd-72","title":"Test performance - issue 1","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.935489-07:00","updated_at":"2025-10-15T01:58:30.107023-07:00"} +{"id":"bd-73","title":"Performance test 1","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.936059-07:00","updated_at":"2025-10-15T01:58:30.107404-07:00"} +{"id":"bd-74","title":"Performance test 2","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.936377-07:00","updated_at":"2025-10-15T01:58:30.107821-07:00"} +{"id":"bd-75","title":"Performance test 3","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.936719-07:00","updated_at":"2025-10-15T01:58:30.108241-07:00"} +{"id":"bd-76","title":"Performance test 4","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.937049-07:00","updated_at":"2025-10-15T01:58:30.108696-07:00"} +{"id":"bd-77","title":"Performance test 5","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.937471-07:00","updated_at":"2025-10-15T01:58:30.109279-07:00"} +{"id":"bd-78","title":"Performance test 6","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.937812-07:00","updated_at":"2025-10-15T01:58:30.109874-07:00"} +{"id":"bd-79","title":"Performance test 7","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.938343-07:00","updated_at":"2025-10-15T01:58:30.110319-07:00"} +{"id":"bd-8","title":"Reach 1.0 release milestone","description":"Stabilize API, finalize documentation, comprehensive testing","status":"open","priority":1,"issue_type":"epic","created_at":"2025-10-14T14:43:06.938911-07:00","updated_at":"2025-10-15T01:58:30.110732-07:00"} +{"id":"bd-80","title":"Performance test 8","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.939443-07:00","updated_at":"2025-10-15T01:58:30.11119-07:00"} +{"id":"bd-81","title":"Performance test 9","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.939983-07:00","updated_at":"2025-10-15T01:58:30.111663-07:00"} +{"id":"bd-82","title":"Performance test 10","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-14T14:43:06.940364-07:00","updated_at":"2025-10-15T01:58:30.112073-07:00"} +{"id":"bd-83","title":"Add external_ref field for tracking GitHub issues","description":"Add optional external_ref field to issues table to track external references like 'gh-9', 'jira-ABC', etc. Includes schema migration, CLI flags (--external-ref for create/update), and tests. This enables linking bd issues to GitHub issues for better workflow integration.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-14T14:43:06.940708-07:00","updated_at":"2025-10-15T01:58:30.112503-07:00"} +{"id":"bd-84","title":"Auto-import fails in git workflows due to mtime issues","description":"The auto-import mechanism (autoImportIfNewer) relies on file modification time comparison between JSONL and DB. This breaks in git workflows because git does not preserve original file modification times - pulled files get fresh mtimes based on checkout time.\n\nRoot causes:\n1. Git checkout sets mtime to 'now', not original commit time\n2. Auto-import compares JSONL mtime vs DB mtime (line 181 in main.go)\n3. If DB was recently modified (agents working), mtime check fails\n4. Auto-import silently returns without feedback\n5. Agents continue with stale database state\n\nThis caused issues in VC project where 3 parallel agents:\n- Pulled updated .beads/issues.jsonl from git\n- Auto-import didn't trigger (JSONL appeared older than DB)\n- Agents couldn't find their assigned issues\n- Agents exported from wrong database, corrupting JSONL","design":"Recommended approach: Checksum-based sync (option 3 from original design)\n\n## Solution: Hash-based content comparison\n\nReplace mtime comparison with JSONL content hash comparison:\n\n1. **Compute JSONL hash on startup**:\n - SHA256 hash of .beads/issues.jsonl contents\n - Fast enough for typical repos (\u003c1MB = ~20ms)\n - Only computed once per command invocation\n\n2. **Store last import hash in DB**:\n - Add metadata table if not exists: CREATE TABLE IF NOT EXISTS metadata (key TEXT PRIMARY KEY, value TEXT)\n - Store hash after successful import: INSERT OR REPLACE INTO metadata (key, value) VALUES ('last_import_hash', '\u003chash\u003e')\n - Query on startup: SELECT value FROM metadata WHERE key = 'last_import_hash'\n\n3. **Compare hashes instead of mtimes**:\n - If JSONL hash != stored hash: auto-import (content changed)\n - If JSONL hash == stored hash: skip import (no changes)\n - If no stored hash: fall back to mtime comparison (backward compat)\n\n4. **Update autoImportIfNewer() in cmd/bd/main.go**:\n - Lines 155-279 currently use mtime comparison (line 181)\n - Replace with hash comparison\n - Keep mtime as fallback for old DBs without metadata table\n\n## Implementation Details\n\n### New storage interface method:\n```go\n// In internal/storage/storage.go\ntype Storage interface {\n // ... existing methods ...\n GetMetadata(ctx context.Context, key string) (string, error)\n SetMetadata(ctx context.Context, key, value string) error\n}\n```\n\n### Migration:\n```go\n// In internal/storage/sqlite/sqlite.go init\nCREATE TABLE IF NOT EXISTS metadata (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n);\n```\n\n### Updated autoImportIfNewer():\n```go\nfunc autoImportIfNewer() {\n jsonlPath := findJSONLPath()\n \n // Check if JSONL exists\n jsonlData, err := os.ReadFile(jsonlPath)\n if err != nil {\n return // No JSONL, skip\n }\n \n // Compute current hash\n hasher := sha256.New()\n hasher.Write(jsonlData)\n currentHash := hex.EncodeToString(hasher.Sum(nil))\n \n // Get last import hash from DB\n ctx := context.Background()\n lastHash, err := store.GetMetadata(ctx, \"last_import_hash\")\n if err != nil {\n // No metadata support (old DB) - fall back to mtime comparison\n autoImportIfNewerByMtime()\n return\n }\n \n // Compare hashes\n if currentHash == lastHash {\n return // No changes, skip import\n }\n \n // Content changed - import\n if err := importJSONLSilent(jsonlPath, jsonlData); err != nil {\n return // Import failed, skip\n }\n \n // Store new hash\n _ = store.SetMetadata(ctx, \"last_import_hash\", currentHash)\n}\n```\n\n## Benefits\n\n- **Git-proof**: Works regardless of file timestamps\n- **Universal**: Works with git, Dropbox, rsync, manual edits\n- **Backward compatible**: Falls back to mtime for old DBs\n- **Efficient**: SHA256 is fast (~20ms for 1MB)\n- **Accurate**: Only imports when content actually changed\n- **No user action**: Fully automatic, invisible\n\n## Performance Optimization\n\nFor very large repos (\u003e10MB JSONL):\n- Only hash if mtime changed (combine both checks)\n- Use incremental hashing if metadata table tracks line count\n- Consider sampling hash (first 1MB + last 1MB)\n\nBut start simple - full hash is fast enough for 99% of use cases.\n\n## Rollout Plan\n\n1. Add metadata table + Get/SetMetadata methods (backward compatible)\n2. Update autoImportIfNewer() with hash logic + mtime fallback\n3. Test with old and new DBs\n4. Ship in next minor version (v0.10.0)\n5. Document in CHANGELOG as \"more reliable auto-import\"\n6. Git hooks remain optional but unnecessary for most users","acceptance_criteria":"- Auto-import works correctly after git pull\n- Agents in parallel workflows see consistent database state\n- Clear feedback when import is needed\n- Performance acceptable for large databases\n- Works in both git and non-git workflows\n- Documentation updated with multi-agent best practices","status":"in_progress","priority":1,"issue_type":"bug","created_at":"2025-10-14T14:43:06.941275-07:00","updated_at":"2025-10-15T01:58:30.114444-07:00"} +{"id":"bd-85","title":"GH-1: Fix bd dep tree graph display issues","description":"Tree display has several issues: 1) Epic items may not expand all sub-items, 2) Subitems repeat multiple times at same level, 3) Items with multiple blockers appear multiple times. The tree visualization doesn't properly handle graph structures with multiple dependencies.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-14T14:43:06.941898-07:00","updated_at":"2025-10-15T01:58:30.114868-07:00","external_ref":"gh-1"} +{"id":"bd-86","title":"GH-2: Evaluate optional Turso backend for collaboration","description":"RFC proposal for optional Turso/libSQL backend to enable: database branching, near-real-time sync between agents/humans, native vector search, browser-ready persistence (WASM/OPFS), and concurrent writes. Would be opt-in, keeping current JSONL+SQLite as default. Requires storage driver interface.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-10-14T14:43:06.942254-07:00","updated_at":"2025-10-15T01:58:30.11535-07:00","external_ref":"gh-2"} +{"id":"bd-87","title":"GH-3: Debug zsh killed error on bd init","description":"User reports 'zsh: killed bd init' when running bd init or just bd command. Likely a crash or signal. Need to reproduce and investigate cause.","status":"open","priority":1,"issue_type":"bug","created_at":"2025-10-14T14:43:06.942576-07:00","updated_at":"2025-10-15T01:58:30.115833-07:00","external_ref":"gh-3"} +{"id":"bd-88","title":"GH-4: Consider system-wide/multi-repo beads usage","description":"User wants to use beads across multiple repositories and for sysadmin tasks. Currently beads is project-scoped (.beads/ directory). Explore options for system-wide issue tracking that spans multiple repos. Related question: how does beads compare to membank MCP?","status":"open","priority":3,"issue_type":"feature","created_at":"2025-10-14T14:43:06.942895-07:00","updated_at":"2025-10-15T01:58:30.116196-07:00","external_ref":"gh-4"} +{"id":"bd-89","title":"GH-6: Fix race condition in parallel issue creation","description":"Creating multiple issues rapidly in parallel causes 'UNIQUE constraint failed: issues.id' error. The ID generation has a race condition. Reproducible with: for i in {26..35}; do ./bd create parallel_ 2\u003e\u00261 \u0026 done","status":"open","priority":0,"issue_type":"bug","created_at":"2025-10-14T14:43:06.943239-07:00","updated_at":"2025-10-15T01:58:30.116562-07:00","closed_at":"2025-10-15T01:13:08.412107-07:00","external_ref":"gh-6"} +{"id":"bd-9","title":"Build collision resolution tooling for distributed branch workflows","description":"When branches diverge and both create issues, auto-incrementing IDs collide on merge. Build excellent tooling to detect collisions during import, auto-renumber issues with fewer dependencies, update all references in descriptions and dependency links, and provide clear user feedback. Goal: keep beautiful brevity of numeric IDs (bd-302) while handling distributed creation gracefully.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-14T14:43:06.943629-07:00","updated_at":"2025-10-15T01:58:30.117069-07:00"} +{"id":"bd-90","title":"GH-7: Package available in AUR (beads-git)","description":"Community member created AUR package for Arch Linux: https://aur.archlinux.org/packages/beads-git. This is informational - no action needed, but good to track for release process and documentation.","status":"open","priority":4,"issue_type":"chore","created_at":"2025-10-14T14:43:06.943974-07:00","updated_at":"2025-10-15T01:58:30.117502-07:00","external_ref":"gh-7"} +{"id":"bd-91","title":"GH-9: Support markdown files in bd create","description":"Request to support markdown files as input to bd create, which would parse the markdown and split it into multiple issues. Use case: developers keep feature drafts in markdown files in version control, then want to convert them into issues. Example: bd create -f feature-draft.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-14T14:43:06.944561-07:00","updated_at":"2025-10-15T01:58:30.117933-07:00","external_ref":"gh-9"} +{"id":"bd-92","title":"GH-11: Add Docker support for hosted/shared instance","description":"Request for Docker container hosting to use beads across multiple dev machines. Would need to consider: centralized database (PostgreSQL?), authentication, concurrent access, API server, etc. This is a significant architectural change from the current local-first model.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-14T14:43:06.945147-07:00","updated_at":"2025-10-15T01:58:30.118431-07:00","external_ref":"gh-11"} +{"id":"bd-93","title":"GH-18: Add --deps flag to bd create for one-command issue creation","description":"Request to add dependency specification to bd create command instead of requiring separate 'bd dep add' command. Proposed syntax: bd create 'Fix bug' --deps discovered-from=bd-20. This would be especially useful for aider integration and reducing command verbosity.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-14T14:43:06.945679-07:00","updated_at":"2025-10-15T01:58:30.119057-07:00","external_ref":"gh-18"} +{"id":"bd-94","title":"parallel_test_1","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.946176-07:00","updated_at":"2025-10-15T01:58:30.119438-07:00"} +{"id":"bd-95","title":"parallel_test_4","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.946509-07:00","updated_at":"2025-10-15T01:58:30.119902-07:00"} +{"id":"bd-96","title":"parallel_test_7","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.946887-07:00","updated_at":"2025-10-15T01:58:30.120265-07:00"} +{"id":"bd-97","title":"parallel_test_6","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.947256-07:00","updated_at":"2025-10-15T01:58:30.120633-07:00"} +{"id":"bd-98","title":"parallel_test_5","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.947803-07:00","updated_at":"2025-10-15T01:58:30.121037-07:00"} +{"id":"bd-99","title":"parallel_test_2","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.948343-07:00","updated_at":"2025-10-15T01:58:30.121394-07:00"} +{"id":"test-100","title":"Test issue with explicit ID","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.948874-07:00","updated_at":"2025-10-15T01:58:30.121807-07:00"} +{"id":"test-500","title":"Root issue for dep tree test","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.949236-07:00","updated_at":"2025-10-15T01:58:30.122369-07:00","dependencies":[{"issue_id":"test-500","depends_on_id":"test-501","type":"blocks","created_at":"2025-10-14T14:43:06.965046-07:00","created_by":"auto-import"},{"issue_id":"test-500","depends_on_id":"test-502","type":"blocks","created_at":"2025-10-14T14:43:06.965697-07:00","created_by":"auto-import"}]} +{"id":"test-501","title":"Dependency A","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.94957-07:00","updated_at":"2025-10-15T01:58:30.122943-07:00","dependencies":[{"issue_id":"test-501","depends_on_id":"test-503","type":"blocks","created_at":"2025-10-14T14:43:06.966217-07:00","created_by":"auto-import"}]} +{"id":"test-502","title":"Dependency B","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.949896-07:00","updated_at":"2025-10-15T01:58:30.123361-07:00","dependencies":[{"issue_id":"test-502","depends_on_id":"test-503","type":"blocks","created_at":"2025-10-14T14:43:06.966666-07:00","created_by":"auto-import"}]} +{"id":"test-503","title":"Shared dependency C","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.950234-07:00","updated_at":"2025-10-15T01:58:30.12378-07:00"} +{"id":"test-600","title":"Epic test","description":"","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-14T14:43:06.950813-07:00","updated_at":"2025-10-15T01:58:30.124216-07:00","dependencies":[{"issue_id":"test-600","depends_on_id":"test-601","type":"parent-child","created_at":"2025-10-14T14:43:06.967085-07:00","created_by":"auto-import"},{"issue_id":"test-600","depends_on_id":"test-602","type":"parent-child","created_at":"2025-10-14T14:43:06.967444-07:00","created_by":"auto-import"}]} +{"id":"test-601","title":"Task A under epic","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.951197-07:00","updated_at":"2025-10-15T01:58:30.124754-07:00","dependencies":[{"issue_id":"test-601","depends_on_id":"test-603","type":"blocks","created_at":"2025-10-14T14:43:06.967826-07:00","created_by":"auto-import"}]} +{"id":"test-602","title":"Task B under epic","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.951793-07:00","updated_at":"2025-10-15T01:58:30.125352-07:00","dependencies":[{"issue_id":"test-602","depends_on_id":"test-604","type":"blocks","created_at":"2025-10-14T14:43:06.968317-07:00","created_by":"auto-import"}]} +{"id":"test-603","title":"Sub-task under A","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.952283-07:00","updated_at":"2025-10-15T01:58:30.125784-07:00"} +{"id":"test-604","title":"Sub-task under B","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.952684-07:00","updated_at":"2025-10-15T01:58:30.126152-07:00"} +{"id":"worker2-500","title":"Another explicit ID","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-14T14:43:06.953035-07:00","updated_at":"2025-10-15T01:58:30.126506-07:00"} diff --git a/README.md b/README.md index 26d82bcd..48499d89 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,22 @@ **Give your coding agent a memory upgrade** +> **🚨 CRITICAL BUG - DATA CORRUPTION RISK (bd-228)** +> +> Auto-import silently overwrites local changes when pulling from Git, without collision detection or warning. This affects multi-developer workflows and agent swarms. **Your local work may be silently discarded.** +> +> **Impact**: Manual updates and closes can be reverted by auto-import after `git pull`. +> +> **Workaround**: Disable auto-import with `--no-auto-import` flag until fixed: +> ```bash +> bd --no-auto-import ready +> bd --no-auto-import update bd-1 --status closed +> ``` +> +> **Status**: P0 bug being investigated. See issue bd-228 for details and progress. +> +> --- + > **⚠️ Alpha Status**: This project is in active development. The core features work well, but expect API changes before 1.0. Use for development/internal projects first. Beads is a lightweight memory system for coding agents, using a graph-based issue tracker. Four kinds of dependencies work to chain your issues together like beads, making them easy for agents to follow for long distances, and reliably perform complex task streams in the right order. diff --git a/ULTRATHINK_BD224.md b/ULTRATHINK_BD224.md new file mode 100644 index 00000000..5d2ce958 --- /dev/null +++ b/ULTRATHINK_BD224.md @@ -0,0 +1,373 @@ +# Ultrathink: Solving status/closed_at Inconsistency (bd-224) + +**Date**: 2025-10-15 +**Context**: Individual devs, small teams, future agent swarms, new codebase +**Problem**: Data model allows `status='open'` with `closed_at != NULL` (liminal state) + +## Executive Summary + +**Recommended Solution**: **Hybrid approach - Database CHECK constraint + Application enforcement** + +This provides defense-in-depth perfect for agent swarms while keeping the model simple for individual developers. + +--- + +## Current State Analysis + +### Where closed_at is Used + +1. **GetIssue**: Returns it to callers +2. **CloseIssue**: Sets `closed_at = now()` when closing +3. **SearchIssues**: Includes in results +4. **GetStatistics** ⚠️ **CRITICAL**: + ```sql + SELECT AVG((julianday(closed_at) - julianday(created_at)) * 24) + FROM issues + WHERE closed_at IS NOT NULL + ``` + Uses `closed_at IS NOT NULL` NOT `status='closed'` for lead time calculation! + +### Impact of Inconsistency + +- **Statistics are wrong**: Issues with `status='open'` but `closed_at != NULL` pollute lead time metrics +- **User confusion**: bd ready shows "closed" issues +- **Agent workflows**: Unpredictable behavior when agents query by status vs closed_at +- **Data integrity**: Can't trust the data model + +### Root Cause: Import & Update Don't Manage Invariant + +**Import** (cmd/bd/import.go:206-207): +```go +if _, ok := rawData["status"]; ok { + updates["status"] = issue.Status // ← Updates status +} +// ⚠️ Does NOT clear/set closed_at +``` + +**UpdateIssue** (internal/storage/sqlite/sqlite.go:509-624): +- Updates any field in the map +- Does NOT automatically manage closed_at when status changes +- Records EventClosed but doesn't enforce the invariant + +**Concrete example (bd-89)**: +1. Issue closed properly: `status='closed'`, `closed_at='2025-10-15 08:13:08'` +2. JSONL had old state: `status='open'`, `closed_at='2025-10-14 02:58:22'` (inconsistent!) +3. Auto-import updated status to 'open' but left closed_at set +4. Result: Inconsistent state in database + +--- + +## Solution Options + +### Option A: Database CHECK Constraint ⭐ **RECOMMENDED FOUNDATION** + +```sql +ALTER TABLE issues ADD CONSTRAINT chk_closed_at_status + CHECK ((status = 'closed') = (closed_at IS NOT NULL)); +``` + +**Pros:** +- βœ… Enforces invariant at database level (most robust) +- βœ… Catches bugs in ANY code path (future-proof) +- βœ… Works across all clients (CLI, MCP, future integrations) +- βœ… Simple to understand for developers +- βœ… **Perfect for agent swarms**: Can't break it with buggy code +- βœ… Prevents inconsistent exports (can't write bad data to JSONL) + +**Cons:** +- ⚠️ Requires migration +- ⚠️ Need to fix existing inconsistent data first +- ⚠️ Update operations must manage closed_at (but we should do this anyway!) + +**Migration complexity**: LOW - few users, can break things + +### Option B: Application-Level Enforcement Only + +Make UpdateIssue and Import smart about status changes. + +**Pros:** +- βœ… No schema change needed +- βœ… Flexible for edge cases + +**Cons:** +- ❌ Easy to forget in new code paths +- ❌ Doesn't protect against direct SQL manipulation +- ❌ Multiple places to maintain (import, update, close, etc.) +- ❌ **Bad for agent swarms**: One buggy agent breaks the model +- ❌ Still allows export of inconsistent data + +**Verdict**: Not robust enough alone + +### Option C: Add Explicit Reopened Support + +Add `bd reopen` command that uses EventReopened and manages closed_at. + +**Pros:** +- βœ… Makes reopening explicit and trackable +- βœ… EventReopened already defined (types.go:150) but unused + +**Cons:** +- ⚠️ Doesn't solve the fundamental invariant problem +- ⚠️ Still need to decide: clear closed_at or keep it? +- ⚠️ More complex model if we keep historical closed_at + +**Verdict**: Good addition, but doesn't solve root cause + +### Option D: Remove closed_at Entirely + +Make events table the single source of truth. + +**Pros:** +- βœ… Simplest data model +- βœ… No invariant to maintain +- βœ… Events are authoritative + +**Cons:** +- ❌ **Performance**: Lead time calculation requires JOIN + subquery + ```sql + SELECT AVG( + (julianday(e.created_at) - julianday(i.created_at)) * 24 + ) + FROM issues i + JOIN events e ON i.id = e.issue_id + WHERE e.event_type = 'closed' + ``` +- ❌ Events could be missing/corrupted (no referential integrity on event_type) +- ❌ More complex queries throughout codebase +- ❌ **Statistics would be slower** (critical for dashboard UIs) + +**Verdict**: Too much complexity/performance cost for the benefit + +--- + +## Recommended Solution: **Hybrid Approach** + +Combine **Option A (DB constraint)** + **Application enforcement** + **Option C (reopen command)** + +### Part 1: Database Constraint (Foundation) + +```sql +-- Migration: First clean up existing inconsistent data +UPDATE issues +SET closed_at = NULL +WHERE status != 'closed' AND closed_at IS NOT NULL; + +UPDATE issues +SET closed_at = CURRENT_TIMESTAMP +WHERE status = 'closed' AND closed_at IS NULL; + +-- Add the constraint +ALTER TABLE issues ADD CONSTRAINT chk_closed_at_status + CHECK ((status = 'closed') = (closed_at IS NOT NULL)); +``` + +### Part 2: UpdateIssue Smart Status Management + +Modify `internal/storage/sqlite/sqlite.go:509-624`: + +```go +func (s *SQLiteStorage) UpdateIssue(ctx context.Context, id string, updates map[string]interface{}, actor string) error { + // ... existing validation ... + + // Smart closed_at management based on status changes + if statusVal, ok := updates["status"]; ok { + newStatus := statusVal.(string) + + if newStatus == string(types.StatusClosed) { + // Changing to closed: ensure closed_at is set + if _, hasClosedAt := updates["closed_at"]; !hasClosedAt { + updates["closed_at"] = time.Now() + } + } else { + // Changing from closed to something else: clear closed_at + if oldIssue.Status == types.StatusClosed { + updates["closed_at"] = nil // This will set it to NULL + eventType = types.EventReopened + } + } + } + + // ... rest of existing code ... +} +``` + +### Part 3: Import Enforcement + +Modify `cmd/bd/import.go:206-231`: + +```go +if _, ok := rawData["status"]; ok { + updates["status"] = issue.Status + + // Enforce closed_at invariant + if issue.Status == types.StatusClosed { + // Status is closed: ensure closed_at is set + if issue.ClosedAt == nil { + now := time.Now() + updates["closed_at"] = now + } else { + updates["closed_at"] = *issue.ClosedAt + } + } else { + // Status is not closed: ensure closed_at is NULL + updates["closed_at"] = nil + } +} +``` + +### Part 4: Add Reopen Command + +Create `cmd/bd/reopen.go`: + +```go +var reopenCmd = &cobra.Command{ + Use: "reopen [id...]", + Short: "Reopen one or more closed issues", + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + ctx := context.Background() + reason, _ := cmd.Flags().GetString("reason") + if reason == "" { + reason = "Reopened" + } + + for _, id := range args { + // Use UpdateIssue which now handles closed_at automatically + updates := map[string]interface{}{ + "status": "open", + } + if err := store.UpdateIssue(ctx, id, updates, getUser()); err != nil { + fmt.Fprintf(os.Stderr, "Error reopening %s: %v\n", id, err) + continue + } + + // Add comment explaining why + if reason != "" { + store.AddComment(ctx, id, getUser(), reason) + } + } + + markDirtyAndScheduleFlush() + }, +} + +func init() { + reopenCmd.Flags().StringP("reason", "r", "", "Reason for reopening") + rootCmd.AddCommand(reopenCmd) +} +``` + +--- + +## Why This Solution Wins + +### For Individual Devs & Small Teams +- **Simple mental model**: `closed_at` is set ⟺ issue is closed +- **Hard to break**: DB constraint catches mistakes +- **Explicit reopen**: `bd reopen bd-89` is clearer than `bd update bd-89 --status open` +- **No manual management**: Don't think about closed_at, it's automatic + +### For Agent Swarms +- **Robust**: DB constraint prevents any agent from creating inconsistent state +- **Race-safe**: Constraint is atomic, checked at commit time +- **Self-healing**: UpdateIssue automatically fixes the relationship +- **Import-safe**: Can't import inconsistent JSONL (constraint rejects it) + +### For New Codebase +- **Can break things**: Migration is easy with few users +- **Sets precedent**: Shows we value data integrity +- **Future-proof**: New features can't violate the invariant +- **Performance**: No query changes needed, closed_at stays fast + +--- + +## Migration Plan + +### Step 1: Clean Existing Data +```sql +-- Find inconsistent issues +SELECT id, status, closed_at FROM issues +WHERE (status = 'closed') != (closed_at IS NOT NULL); + +-- Fix them (choose one strategy) +-- Strategy A: Trust status field +UPDATE issues SET closed_at = NULL +WHERE status != 'closed' AND closed_at IS NOT NULL; + +UPDATE issues SET closed_at = CURRENT_TIMESTAMP +WHERE status = 'closed' AND closed_at IS NULL; + +-- Strategy B: Trust closed_at field +UPDATE issues SET status = 'closed' +WHERE status != 'closed' AND closed_at IS NOT NULL; + +UPDATE issues SET status = 'open' +WHERE status = 'closed' AND closed_at IS NULL; +``` + +**Recommendation**: Use Strategy A (trust status) since status is more often correct. + +### Step 2: Add Constraint +```sql +-- Test first +SELECT id FROM issues +WHERE (status = 'closed') != (closed_at IS NOT NULL); +-- Should return 0 rows + +-- Add constraint +ALTER TABLE issues ADD CONSTRAINT chk_closed_at_status + CHECK ((status = 'closed') = (closed_at IS NOT NULL)); +``` + +### Step 3: Update Code +1. Modify UpdateIssue (sqlite.go) +2. Modify Import (import.go) +3. Add reopen command +4. Add migration function to schema.go + +### Step 4: Test +```bash +# Test the constraint rejects bad writes +sqlite3 .beads/bd.db "UPDATE issues SET closed_at = NULL WHERE id = 'bd-1' AND status = 'closed';" +# Should fail with constraint violation + +# Test update handles it automatically +bd update bd-89 --status open +bd show bd-89 --json | jq '{status, closed_at}' +# Should show: {"status": "open", "closed_at": null} + +# Test reopen +bd create "Test issue" -p 1 +bd close bd-226 +bd reopen bd-226 --reason "Need more work" +# Should work without errors +``` + +--- + +## Alternative Considered: Soft Close with closed_at History + +Keep closed_at as "first time closed" and use events for current state. + +**Why rejected**: +- More complex model (two sources of truth) +- Unclear semantics (what does closed_at mean?) +- Lead time calculation becomes ambiguous (first close? most recent?) +- Doesn't simplify the problem + +--- + +## Conclusion + +The **hybrid approach** (DB constraint + smart UpdateIssue + import enforcement + reopen command) is the best solution because: + +1. **Defense in depth**: Multiple layers prevent inconsistency +2. **Hard to break**: Perfect for agent swarms +3. **Simple for users**: Automatic management of closed_at +4. **Low migration cost**: Can break things in new codebase +5. **Clear semantics**: closed_at = "currently closed" (not historical) +6. **Performance**: No query changes needed + +The DB constraint is the key insight: it makes the system robust against future bugs, new code paths, and agent mistakes. Combined with smart application code, it creates a self-healing system that's hard to misuse. + +This aligns perfectly with beads' goals: simple for individual devs, robust for agent swarms.