From ef31d98b43c0f60ebf45bb8836a61f8fc77525b5 Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Thu, 16 Oct 2025 19:14:05 -0700 Subject: [PATCH] Fix bd-666: Replace N+1 query pattern in auto-import with batch fetch - Batch fetch all existing issues with SearchIssues() upfront - Use O(1) map lookup instead of O(n) GetIssue() calls - Improves performance dramatically with 1000+ issues - All tests pass --- .beads/issues.jsonl | 564 +++++++++++++++++++++++++----------- DUPLICATES_REPORT.md | 656 ++++++++++++++++++++++++++++++++++++++++++ REVIEW_BD379.md | 177 ++++++++++++ analyze_duplicates.sh | 13 + close_duplicates.sh | 149 ++++++++++ cmd/bd/main.go | 18 +- 6 files changed, 1413 insertions(+), 164 deletions(-) create mode 100644 DUPLICATES_REPORT.md create mode 100644 REVIEW_BD379.md create mode 100755 analyze_duplicates.sh create mode 100755 close_duplicates.sh diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 54648b24..3b6f360a 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,5 +1,5 @@ {"id":"bd-1","title":"Critical bug","description":"","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T17:49:54.066425-07:00","updated_at":"2025-10-16T18:12:45.464398-07:00","closed_at":"2025-10-16T17:49:54.066425-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-16T17:49:54.068556-07:00","updated_at":"2025-10-16T18:12:45.465642-07:00","closed_at":"2025-10-16T17:49:54.068556-07:00","dependencies":[{"issue_id":"bd-10","depends_on_id":"bd-379","type":"parent-child","created_at":"2025-10-16T17:49:54.714291-07:00","created_by":"auto-import"},{"issue_id":"bd-10","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-16T17:49:54.714895-07:00","created_by":"auto-import"}]} +{"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-16T14:33:21.013791-07:00","closed_at":"2025-10-15T03:01:29.497885-07:00","dependencies":[{"issue_id":"bd-10","depends_on_id":"bd-553","type":"parent-child","created_at":"2025-10-16T18:54:29.860061-07:00","created_by":"import-remap"},{"issue_id":"bd-10","depends_on_id":"bd-662","type":"parent-child","created_at":"2025-10-16T18:57:16.872256-07:00","created_by":"import-remap"},{"issue_id":"bd-10","depends_on_id":"bd-660","type":"parent-child","created_at":"2025-10-16T18:57:16.876237-07:00","created_by":"import-remap"},{"issue_id":"bd-10","depends_on_id":"bd-379","type":"parent-child","created_at":"2025-10-16T18:57:16.950743-07:00","created_by":"auto-import"},{"issue_id":"bd-10","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-16T18:57:16.952523-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-16T17:49:54.069968-07:00","updated_at":"2025-10-16T18:12:45.466188-07:00"} {"id":"bd-101","title":"parallel_test_3","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.070418-07:00","updated_at":"2025-10-16T18:12:45.466663-07:00"} {"id":"bd-102","title":"parallel_test_8","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.072176-07:00","updated_at":"2025-10-16T18:12:45.467162-07:00"} @@ -15,68 +15,68 @@ {"id":"bd-111","title":"parallel_30","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.082144-07:00","updated_at":"2025-10-16T18:12:45.474016-07:00"} {"id":"bd-112","title":"parallel_35","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.082567-07:00","updated_at":"2025-10-16T18:12:45.474617-07:00"} {"id":"bd-113","title":"parallel_34","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.084041-07:00","updated_at":"2025-10-16T18:12:45.475153-07:00"} -{"id":"bd-114","title":"stress_3","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.085572-07:00","updated_at":"2025-10-16T18:12:45.475685-07:00"} -{"id":"bd-115","title":"stress_5","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.085984-07:00","updated_at":"2025-10-16T18:12:45.476151-07:00"} -{"id":"bd-116","title":"stress_10","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.086747-07:00","updated_at":"2025-10-16T18:12:45.476568-07:00"} -{"id":"bd-117","title":"stress_2","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.090061-07:00","updated_at":"2025-10-16T18:12:45.477001-07:00"} -{"id":"bd-118","title":"stress_8","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.090425-07:00","updated_at":"2025-10-16T18:12:45.477417-07:00"} -{"id":"bd-119","title":"stress_13","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.091404-07:00","updated_at":"2025-10-16T18:12:45.477838-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-16T17:49:54.092402-07:00","updated_at":"2025-10-16T18:12:45.478266-07:00","closed_at":"2025-10-16T17:49:54.092402-07:00","dependencies":[{"issue_id":"bd-12","depends_on_id":"bd-379","type":"parent-child","created_at":"2025-10-16T17:49:54.71543-07:00","created_by":"auto-import"},{"issue_id":"bd-12","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-16T17:49:54.716001-07:00","created_by":"auto-import"}]} -{"id":"bd-120","title":"stress_14","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.092838-07:00","updated_at":"2025-10-16T18:12:45.478695-07:00"} -{"id":"bd-121","title":"stress_1","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.094259-07:00","updated_at":"2025-10-16T18:12:45.47915-07:00"} -{"id":"bd-122","title":"stress_7","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.097667-07:00","updated_at":"2025-10-16T18:12:45.479534-07:00"} -{"id":"bd-123","title":"stress_17","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.099612-07:00","updated_at":"2025-10-16T18:12:45.479989-07:00"} -{"id":"bd-124","title":"stress_6","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.100172-07:00","updated_at":"2025-10-16T18:12:45.480391-07:00"} -{"id":"bd-125","title":"stress_19","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.101079-07:00","updated_at":"2025-10-16T18:12:45.480798-07:00"} -{"id":"bd-126","title":"stress_20","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.101496-07:00","updated_at":"2025-10-16T18:12:45.481199-07:00"} -{"id":"bd-127","title":"stress_15","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.101872-07:00","updated_at":"2025-10-16T18:12:45.481599-07:00"} -{"id":"bd-128","title":"stress_24","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.106612-07:00","updated_at":"2025-10-16T18:12:45.481987-07:00"} -{"id":"bd-129","title":"stress_18","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.112376-07:00","updated_at":"2025-10-16T18:12:45.482367-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-16T17:49:54.112774-07:00","updated_at":"2025-10-16T18:12:45.482766-07:00","closed_at":"2025-10-16T17:49:54.112774-07:00","dependencies":[{"issue_id":"bd-13","depends_on_id":"bd-379","type":"parent-child","created_at":"2025-10-16T17:49:54.716779-07:00","created_by":"auto-import"},{"issue_id":"bd-13","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-16T17:49:54.71754-07:00","created_by":"auto-import"}]} -{"id":"bd-130","title":"stress_22","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.113164-07:00","updated_at":"2025-10-16T18:12:45.483192-07:00"} -{"id":"bd-131","title":"stress_28","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.114025-07:00","updated_at":"2025-10-16T18:12:45.485154-07:00"} -{"id":"bd-132","title":"stress_25","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.114354-07:00","updated_at":"2025-10-16T18:12:45.48572-07:00"} -{"id":"bd-133","title":"stress_29","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.114809-07:00","updated_at":"2025-10-16T18:12:45.486242-07:00"} -{"id":"bd-134","title":"stress_26","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.115609-07:00","updated_at":"2025-10-16T18:12:45.486655-07:00"} -{"id":"bd-135","title":"stress_9","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.11763-07:00","updated_at":"2025-10-16T18:12:45.487309-07:00"} -{"id":"bd-136","title":"stress_30","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.119244-07:00","updated_at":"2025-10-16T18:12:45.48786-07:00"} -{"id":"bd-137","title":"stress_32","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.119749-07:00","updated_at":"2025-10-16T18:12:45.488317-07:00"} -{"id":"bd-138","title":"stress_16","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.120629-07:00","updated_at":"2025-10-16T18:12:45.488771-07:00"} -{"id":"bd-139","title":"stress_27","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.122424-07:00","updated_at":"2025-10-16T18:12:45.489299-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-16T17:49:54.123776-07:00","updated_at":"2025-10-16T18:12:45.489877-07:00","closed_at":"2025-10-16T17:49:54.123776-07:00","dependencies":[{"issue_id":"bd-14","depends_on_id":"bd-379","type":"parent-child","created_at":"2025-10-16T17:49:54.718022-07:00","created_by":"auto-import"},{"issue_id":"bd-14","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-16T17:49:54.740437-07:00","created_by":"auto-import"}]} -{"id":"bd-140","title":"stress_31","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.124343-07:00","updated_at":"2025-10-16T18:12:45.490659-07:00"} -{"id":"bd-141","title":"stress_35","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.124782-07:00","updated_at":"2025-10-16T18:12:45.491904-07:00"} -{"id":"bd-142","title":"stress_37","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.125303-07:00","updated_at":"2025-10-16T18:12:45.492438-07:00"} -{"id":"bd-143","title":"stress_34","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.125694-07:00","updated_at":"2025-10-16T18:12:45.492987-07:00"} -{"id":"bd-144","title":"stress_36","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.126104-07:00","updated_at":"2025-10-16T18:12:45.493523-07:00"} -{"id":"bd-145","title":"stress_21","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.128753-07:00","updated_at":"2025-10-16T18:12:45.501265-07:00"} -{"id":"bd-146","title":"stress_38","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.136686-07:00","updated_at":"2025-10-16T18:12:45.50234-07:00"} -{"id":"bd-147","title":"stress_42","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.137318-07:00","updated_at":"2025-10-16T18:12:45.504435-07:00"} -{"id":"bd-148","title":"stress_43","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.151644-07:00","updated_at":"2025-10-16T18:12:45.511898-07:00"} -{"id":"bd-149","title":"stress_39","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.160076-07:00","updated_at":"2025-10-16T18:12:45.51271-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-16T17:49:54.160717-07:00","updated_at":"2025-10-16T18:12:45.520273-07:00","closed_at":"2025-10-16T17:49:54.160717-07:00","dependencies":[{"issue_id":"bd-15","depends_on_id":"bd-379","type":"parent-child","created_at":"2025-10-16T17:49:54.750415-07:00","created_by":"auto-import"},{"issue_id":"bd-15","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-16T17:49:54.761925-07:00","created_by":"auto-import"}]} -{"id":"bd-150","title":"stress_45","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.162016-07:00","updated_at":"2025-10-16T18:12:45.522946-07:00"} -{"id":"bd-151","title":"stress_46","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.16275-07:00","updated_at":"2025-10-16T18:12:45.5237-07:00"} -{"id":"bd-152","title":"stress_48","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.163198-07:00","updated_at":"2025-10-16T18:12:45.525245-07:00"} -{"id":"bd-153","title":"stress_44","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.163673-07:00","updated_at":"2025-10-16T18:12:45.529064-07:00"} -{"id":"bd-154","title":"stress_40","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.164134-07:00","updated_at":"2025-10-16T18:12:45.52956-07:00"} -{"id":"bd-155","title":"stress_41","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.164642-07:00","updated_at":"2025-10-16T18:12:45.530159-07:00"} -{"id":"bd-156","title":"stress_12","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.165126-07:00","updated_at":"2025-10-16T18:12:45.530665-07:00"} -{"id":"bd-157","title":"stress_47","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.165682-07:00","updated_at":"2025-10-16T18:12:45.531215-07:00"} -{"id":"bd-158","title":"stress_49","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.166111-07:00","updated_at":"2025-10-16T18:12:45.531715-07:00"} -{"id":"bd-159","title":"stress_50","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.166661-07:00","updated_at":"2025-10-16T18:12:45.532407-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-16T17:49:54.167012-07:00","updated_at":"2025-10-16T18:12:45.532837-07:00","closed_at":"2025-10-16T17:49:54.167012-07:00","dependencies":[{"issue_id":"bd-16","depends_on_id":"bd-379","type":"parent-child","created_at":"2025-10-16T17:49:54.762662-07:00","created_by":"auto-import"},{"issue_id":"bd-16","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-16T17:49:54.763205-07:00","created_by":"auto-import"}]} -{"id":"bd-160","title":"stress_33","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.167372-07:00","updated_at":"2025-10-16T18:12:45.533243-07:00"} -{"id":"bd-161","title":"stress_23","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.167812-07:00","updated_at":"2025-10-16T18:12:45.533664-07:00"} -{"id":"bd-162","title":"stress_11","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.168297-07:00","updated_at":"2025-10-16T18:12:45.534096-07:00"} -{"id":"bd-163","title":"stress_4","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.168988-07:00","updated_at":"2025-10-16T18:12:45.534562-07:00"} +{"id":"bd-114","title":"stress_3","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.872088-07:00","updated_at":"2025-10-16T19:08:52.515661-07:00","closed_at":"2025-10-16T19:08:52.515661-07:00"} +{"id":"bd-115","title":"stress_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.872613-07:00","updated_at":"2025-10-16T19:08:52.478839-07:00","closed_at":"2025-10-16T19:08:52.478839-07:00"} +{"id":"bd-116","title":"stress_10","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.873092-07:00","updated_at":"2025-10-16T19:08:52.430536-07:00","closed_at":"2025-10-16T19:08:52.430536-07:00"} +{"id":"bd-117","title":"stress_2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.873579-07:00","updated_at":"2025-10-16T19:08:52.381285-07:00","closed_at":"2025-10-16T19:08:52.381285-07:00"} +{"id":"bd-118","title":"stress_8","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.874023-07:00","updated_at":"2025-10-16T19:08:52.316135-07:00","closed_at":"2025-10-16T19:08:52.316135-07:00"} +{"id":"bd-119","title":"stress_13","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.874463-07:00","updated_at":"2025-10-16T19:08:52.247499-07:00","closed_at":"2025-10-16T19:08:52.247499-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-16T14:33:21.042557-07:00","closed_at":"2025-10-15T03:01:29.510225-07:00","dependencies":[{"issue_id":"bd-12","depends_on_id":"bd-553","type":"parent-child","created_at":"2025-10-16T18:54:29.903345-07:00","created_by":"import-remap"},{"issue_id":"bd-12","depends_on_id":"bd-662","type":"parent-child","created_at":"2025-10-16T18:57:16.798978-07:00","created_by":"import-remap"},{"issue_id":"bd-12","depends_on_id":"bd-660","type":"parent-child","created_at":"2025-10-16T18:57:16.803823-07:00","created_by":"import-remap"},{"issue_id":"bd-12","depends_on_id":"bd-379","type":"parent-child","created_at":"2025-10-16T18:57:16.954154-07:00","created_by":"auto-import"},{"issue_id":"bd-12","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-16T18:57:16.955359-07:00","created_by":"auto-import"}]} +{"id":"bd-120","title":"stress_14","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.875538-07:00","updated_at":"2025-10-16T19:08:52.203683-07:00","closed_at":"2025-10-16T19:08:52.203683-07:00"} +{"id":"bd-121","title":"stress_1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.876034-07:00","updated_at":"2025-10-16T19:08:52.098815-07:00","closed_at":"2025-10-16T19:08:52.098815-07:00"} +{"id":"bd-122","title":"stress_7","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.876508-07:00","updated_at":"2025-10-16T19:08:51.943675-07:00","closed_at":"2025-10-16T19:08:51.943675-07:00"} +{"id":"bd-123","title":"stress_17","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.876927-07:00","updated_at":"2025-10-16T19:08:51.890061-07:00","closed_at":"2025-10-16T19:08:51.890061-07:00"} +{"id":"bd-124","title":"stress_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.877385-07:00","updated_at":"2025-10-16T19:08:51.851235-07:00","closed_at":"2025-10-16T19:08:51.851235-07:00"} +{"id":"bd-125","title":"stress_19","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.877833-07:00","updated_at":"2025-10-16T19:08:51.795348-07:00","closed_at":"2025-10-16T19:08:51.795348-07:00"} +{"id":"bd-126","title":"stress_20","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.87826-07:00","updated_at":"2025-10-16T19:08:51.692363-07:00","closed_at":"2025-10-16T19:08:51.692363-07:00"} +{"id":"bd-127","title":"stress_15","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.878743-07:00","updated_at":"2025-10-16T19:08:51.593701-07:00","closed_at":"2025-10-16T19:08:51.593701-07:00"} +{"id":"bd-128","title":"stress_24","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.879101-07:00","updated_at":"2025-10-16T19:08:51.518855-07:00","closed_at":"2025-10-16T19:08:51.518855-07:00"} +{"id":"bd-129","title":"stress_18","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.879443-07:00","updated_at":"2025-10-16T19:08:51.421528-07:00","closed_at":"2025-10-16T19:08:51.421528-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-16T14:33:21.049662-07:00","closed_at":"2025-10-15T03:01:29.515608-07:00","dependencies":[{"issue_id":"bd-13","depends_on_id":"bd-553","type":"parent-child","created_at":"2025-10-16T18:54:29.841316-07:00","created_by":"import-remap"},{"issue_id":"bd-13","depends_on_id":"bd-662","type":"parent-child","created_at":"2025-10-16T18:57:16.762755-07:00","created_by":"import-remap"},{"issue_id":"bd-13","depends_on_id":"bd-660","type":"parent-child","created_at":"2025-10-16T18:57:16.764984-07:00","created_by":"import-remap"},{"issue_id":"bd-13","depends_on_id":"bd-379","type":"parent-child","created_at":"2025-10-16T18:57:16.956088-07:00","created_by":"auto-import"},{"issue_id":"bd-13","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-16T18:57:16.956813-07:00","created_by":"auto-import"}]} +{"id":"bd-130","title":"stress_22","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.880115-07:00","updated_at":"2025-10-16T19:08:51.357565-07:00","closed_at":"2025-10-16T19:08:51.357565-07:00"} +{"id":"bd-131","title":"stress_28","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.880453-07:00","updated_at":"2025-10-16T19:08:51.290043-07:00","closed_at":"2025-10-16T19:08:51.290043-07:00"} +{"id":"bd-132","title":"stress_25","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.880807-07:00","updated_at":"2025-10-16T19:08:51.243565-07:00","closed_at":"2025-10-16T19:08:51.243565-07:00"} +{"id":"bd-133","title":"stress_29","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.88123-07:00","updated_at":"2025-10-16T19:08:51.153344-07:00","closed_at":"2025-10-16T19:08:51.153344-07:00"} +{"id":"bd-134","title":"stress_26","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.881844-07:00","updated_at":"2025-10-16T19:08:51.08941-07:00","closed_at":"2025-10-16T19:08:51.08941-07:00"} +{"id":"bd-135","title":"stress_9","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.882401-07:00","updated_at":"2025-10-16T19:08:51.037572-07:00","closed_at":"2025-10-16T19:08:51.037572-07:00"} +{"id":"bd-136","title":"stress_30","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.882972-07:00","updated_at":"2025-10-16T19:08:51.00286-07:00","closed_at":"2025-10-16T19:08:51.00286-07:00"} +{"id":"bd-137","title":"stress_32","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.88358-07:00","updated_at":"2025-10-16T19:08:50.959206-07:00","closed_at":"2025-10-16T19:08:50.959206-07:00"} +{"id":"bd-138","title":"stress_16","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.8839-07:00","updated_at":"2025-10-16T19:08:50.911251-07:00","closed_at":"2025-10-16T19:08:50.911251-07:00"} +{"id":"bd-139","title":"stress_27","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.884314-07:00","updated_at":"2025-10-16T19:08:50.869108-07:00","closed_at":"2025-10-16T19:08:50.869108-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-16T14:33:21.056511-07:00","closed_at":"2025-10-15T03:01:29.522602-07:00","dependencies":[{"issue_id":"bd-14","depends_on_id":"bd-553","type":"parent-child","created_at":"2025-10-16T18:54:29.831817-07:00","created_by":"import-remap"},{"issue_id":"bd-14","depends_on_id":"bd-662","type":"parent-child","created_at":"2025-10-16T18:57:16.824801-07:00","created_by":"import-remap"},{"issue_id":"bd-14","depends_on_id":"bd-660","type":"parent-child","created_at":"2025-10-16T18:57:16.828637-07:00","created_by":"import-remap"},{"issue_id":"bd-14","depends_on_id":"bd-379","type":"parent-child","created_at":"2025-10-16T18:57:16.957485-07:00","created_by":"auto-import"},{"issue_id":"bd-14","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-16T18:57:16.958323-07:00","created_by":"auto-import"}]} +{"id":"bd-140","title":"stress_31","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.885327-07:00","updated_at":"2025-10-16T19:08:50.797148-07:00","closed_at":"2025-10-16T19:08:50.797148-07:00"} +{"id":"bd-141","title":"stress_35","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.885862-07:00","updated_at":"2025-10-16T19:08:50.687407-07:00","closed_at":"2025-10-16T19:08:50.687407-07:00"} +{"id":"bd-142","title":"stress_37","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.886257-07:00","updated_at":"2025-10-16T19:08:50.541157-07:00","closed_at":"2025-10-16T19:08:50.541157-07:00"} +{"id":"bd-143","title":"stress_34","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.886598-07:00","updated_at":"2025-10-16T19:08:50.453505-07:00","closed_at":"2025-10-16T19:08:50.453505-07:00"} +{"id":"bd-144","title":"stress_36","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.886974-07:00","updated_at":"2025-10-16T19:08:50.399142-07:00","closed_at":"2025-10-16T19:08:50.399142-07:00"} +{"id":"bd-145","title":"stress_21","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.887329-07:00","updated_at":"2025-10-16T19:08:50.349166-07:00","closed_at":"2025-10-16T19:08:50.349166-07:00"} +{"id":"bd-146","title":"stress_38","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.887758-07:00","updated_at":"2025-10-16T19:08:50.292479-07:00","closed_at":"2025-10-16T19:08:50.292479-07:00"} +{"id":"bd-147","title":"stress_42","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.888374-07:00","updated_at":"2025-10-16T19:08:50.250543-07:00","closed_at":"2025-10-16T19:08:50.250543-07:00"} +{"id":"bd-148","title":"stress_43","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.888824-07:00","updated_at":"2025-10-16T19:08:50.208806-07:00","closed_at":"2025-10-16T19:08:50.208806-07:00"} +{"id":"bd-149","title":"stress_39","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.889456-07:00","updated_at":"2025-10-16T19:08:50.161942-07:00","closed_at":"2025-10-16T19:08:50.161942-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-16T14:33:21.063261-07:00","closed_at":"2025-10-15T03:01:29.527446-07:00","dependencies":[{"issue_id":"bd-15","depends_on_id":"bd-553","type":"parent-child","created_at":"2025-10-16T18:54:29.845689-07:00","created_by":"import-remap"},{"issue_id":"bd-15","depends_on_id":"bd-662","type":"parent-child","created_at":"2025-10-16T18:57:16.843557-07:00","created_by":"import-remap"},{"issue_id":"bd-15","depends_on_id":"bd-660","type":"parent-child","created_at":"2025-10-16T18:57:16.847286-07:00","created_by":"import-remap"},{"issue_id":"bd-15","depends_on_id":"bd-379","type":"parent-child","created_at":"2025-10-16T18:57:16.959194-07:00","created_by":"auto-import"},{"issue_id":"bd-15","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-16T18:57:16.959804-07:00","created_by":"auto-import"}]} +{"id":"bd-150","title":"stress_45","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.890307-07:00","updated_at":"2025-10-16T19:08:50.118843-07:00","closed_at":"2025-10-16T19:08:50.118843-07:00"} +{"id":"bd-151","title":"stress_46","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.89072-07:00","updated_at":"2025-10-16T19:08:50.014341-07:00","closed_at":"2025-10-16T19:08:50.014341-07:00"} +{"id":"bd-152","title":"stress_48","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.891313-07:00","updated_at":"2025-10-16T19:08:49.868708-07:00","closed_at":"2025-10-16T19:08:49.868708-07:00"} +{"id":"bd-153","title":"stress_44","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.891907-07:00","updated_at":"2025-10-16T19:08:49.831911-07:00","closed_at":"2025-10-16T19:08:49.831911-07:00"} +{"id":"bd-154","title":"stress_40","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.892231-07:00","updated_at":"2025-10-16T19:08:49.786897-07:00","closed_at":"2025-10-16T19:08:49.786897-07:00"} +{"id":"bd-155","title":"stress_41","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.892591-07:00","updated_at":"2025-10-16T19:08:49.714137-07:00","closed_at":"2025-10-16T19:08:49.714137-07:00"} +{"id":"bd-156","title":"stress_12","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.892947-07:00","updated_at":"2025-10-16T19:08:49.665789-07:00","closed_at":"2025-10-16T19:08:49.665789-07:00"} +{"id":"bd-157","title":"stress_47","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.893312-07:00","updated_at":"2025-10-16T19:08:49.617638-07:00","closed_at":"2025-10-16T19:08:49.617638-07:00"} +{"id":"bd-158","title":"stress_49","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.893755-07:00","updated_at":"2025-10-16T19:08:49.52025-07:00","closed_at":"2025-10-16T19:08:49.52025-07:00"} +{"id":"bd-159","title":"stress_50","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.894144-07:00","updated_at":"2025-10-16T19:08:49.457848-07:00","closed_at":"2025-10-16T19:08:49.457848-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-16T14:33:21.069086-07:00","closed_at":"2025-10-15T03:01:29.531644-07:00","dependencies":[{"issue_id":"bd-16","depends_on_id":"bd-553","type":"parent-child","created_at":"2025-10-16T18:54:29.847189-07:00","created_by":"import-remap"},{"issue_id":"bd-16","depends_on_id":"bd-662","type":"parent-child","created_at":"2025-10-16T18:57:16.84837-07:00","created_by":"import-remap"},{"issue_id":"bd-16","depends_on_id":"bd-660","type":"parent-child","created_at":"2025-10-16T18:57:16.850431-07:00","created_by":"import-remap"},{"issue_id":"bd-16","depends_on_id":"bd-379","type":"parent-child","created_at":"2025-10-16T18:57:16.960901-07:00","created_by":"auto-import"},{"issue_id":"bd-16","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-16T18:57:16.961406-07:00","created_by":"auto-import"}]} +{"id":"bd-160","title":"stress_33","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.895578-07:00","updated_at":"2025-10-16T19:08:49.438555-07:00","closed_at":"2025-10-16T19:08:49.438555-07:00"} +{"id":"bd-161","title":"stress_23","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.896284-07:00","updated_at":"2025-10-16T19:08:49.410293-07:00","closed_at":"2025-10-16T19:08:49.410293-07:00"} +{"id":"bd-162","title":"stress_11","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.896638-07:00","updated_at":"2025-10-16T19:08:49.329569-07:00","closed_at":"2025-10-16T19:08:49.329569-07:00"} +{"id":"bd-163","title":"stress_4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-14T14:43:06.89714-07:00","updated_at":"2025-10-16T19:08:49.290621-07:00","closed_at":"2025-10-16T19:08:49.290621-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-16T17:49:54.169537-07:00","updated_at":"2025-10-16T18:12:45.535094-07:00","dependencies":[{"issue_id":"bd-164","depends_on_id":"bd-85","type":"discovered-from","created_at":"2025-10-16T17:49:54.767107-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-16T17:49:54.170076-07:00","updated_at":"2025-10-16T18:12:45.535828-07:00","dependencies":[{"issue_id":"bd-165","depends_on_id":"bd-85","type":"discovered-from","created_at":"2025-10-16T17:49:54.768421-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-16T17:49:54.170631-07:00","updated_at":"2025-10-16T18:12:45.536703-07:00","dependencies":[{"issue_id":"bd-166","depends_on_id":"bd-85","type":"discovered-from","created_at":"2025-10-16T17:49:54.769479-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-16T17:49:54.171237-07:00","updated_at":"2025-10-16T18:12:45.537279-07:00","closed_at":"2025-10-16T17:49:54.171237-07:00","dependencies":[{"issue_id":"bd-167","depends_on_id":"bd-89","type":"discovered-from","created_at":"2025-10-16T17:49:54.769969-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-16T17:49:54.17185-07:00","updated_at":"2025-10-16T18:12:45.537776-07:00","closed_at":"2025-10-16T17:49:54.17185-07:00","dependencies":[{"issue_id":"bd-168","depends_on_id":"bd-89","type":"blocks","created_at":"2025-10-16T17:49:54.770811-07:00","created_by":"auto-import"},{"issue_id":"bd-168","depends_on_id":"bd-90","type":"blocks","created_at":"2025-10-16T17:49:54.772027-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-16T17:49:54.173861-07:00","updated_at":"2025-10-16T18:12:45.538219-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-16T17:49:54.174394-07:00","updated_at":"2025-10-16T18:12:45.538694-07:00","closed_at":"2025-10-16T17:49:54.174394-07:00","dependencies":[{"issue_id":"bd-17","depends_on_id":"bd-379","type":"parent-child","created_at":"2025-10-16T17:49:54.772947-07:00","created_by":"auto-import"},{"issue_id":"bd-17","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-16T17:49:54.773718-07:00","created_by":"auto-import"}]} +{"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-16T14:33:21.087196-07:00","closed_at":"2025-10-15T03:01:29.536352-07:00","dependencies":[{"issue_id":"bd-17","depends_on_id":"bd-553","type":"parent-child","created_at":"2025-10-16T18:54:29.862878-07:00","created_by":"import-remap"},{"issue_id":"bd-17","depends_on_id":"bd-662","type":"parent-child","created_at":"2025-10-16T18:57:16.747108-07:00","created_by":"import-remap"},{"issue_id":"bd-17","depends_on_id":"bd-660","type":"parent-child","created_at":"2025-10-16T18:57:16.749901-07:00","created_by":"import-remap"},{"issue_id":"bd-17","depends_on_id":"bd-379","type":"parent-child","created_at":"2025-10-16T18:57:16.962426-07:00","created_by":"auto-import"},{"issue_id":"bd-17","depends_on_id":"bd-9","type":"parent-child","created_at":"2025-10-16T18:57:16.963219-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-16T17:49:54.17617-07:00","updated_at":"2025-10-16T18:12:45.539166-07:00","closed_at":"2025-10-16T17:49:54.17617-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-16T17:49:54.176783-07:00","updated_at":"2025-10-16T18:12:45.539867-07:00","closed_at":"2025-10-16T17:49:54.176783-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-16T17:49:54.177221-07:00","updated_at":"2025-10-16T18:12:45.540353-07:00","closed_at":"2025-10-16T17:49:54.177221-07:00"} @@ -138,14 +138,14 @@ {"id":"bd-222","title":"P2: Consider batching API for bulk issue creation","description":"Current CreateIssue acquires a dedicated connection for each call. For bulk imports or agent workflows creating many issues, a batched API could improve performance:\n\nCreateIssues(ctx, issues []*Issue, actor string) error\n\nThis would:\n- Acquire one connection\n- Use one IMMEDIATE transaction\n- Insert all issues atomically\n- Reduce connection overhead\n\nNot urgent - current approach is correct and fast enough for typical use.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-16T17:49:54.226484-07:00","updated_at":"2025-10-16T18:12:45.587369-07:00"} {"id":"bd-223","title":"P3: Consider early context check in CreateIssue","description":"CreateIssue starts an IMMEDIATE transaction before checking if context is cancelled. If a client cancels early, we've already acquired the write lock.\n\nConsider adding:\n if err := ctx.Err(); err != nil {\n return err\n }\n\nBetween validation (line 318) and acquiring connection (line 331).\n\nLow priority - the busy_timeout and deferred cleanup handle this gracefully, but an early check would be slightly more efficient.","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-16T17:49:54.226885-07:00","updated_at":"2025-10-16T18:12:45.601427-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-16T17:49:54.227291-07:00","updated_at":"2025-10-16T18:12:45.601946-07:00"} -{"id":"bd-225","title":"Ultrathink: Choose solution for status/closed_at inconsistency (bd-224)","description":"Deep analysis of solution options for bd-373 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-16T17:49:54.227815-07:00","updated_at":"2025-10-16T18:12:45.602622-07:00","closed_at":"2025-10-16T17:49:54.227815-07:00","dependencies":[{"issue_id":"bd-225","depends_on_id":"bd-391","type":"discovered-from","created_at":"2025-10-16T17:49:54.776428-07:00","created_by":"auto-import"}]} +{"id":"bd-225","title":"Ultrathink: Choose solution for status/closed_at inconsistency (bd-224)","description":"Deep analysis of solution options for bd-391 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-16T14:57:48.914026-07:00","closed_at":"2025-10-15T01:49:43.078431-07:00","dependencies":[{"issue_id":"bd-225","depends_on_id":"bd-391","type":"discovered-from","created_at":"2025-10-16T18:57:16.964195-07:00","created_by":"auto-import"}]} {"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-16T17:49:54.228245-07:00","updated_at":"2025-10-16T18:12:45.603252-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-16T17:49:54.228852-07:00","updated_at":"2025-10-16T18:12:45.603822-07:00"} -{"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-356, bd-199, bd-358-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":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T17:49:54.229303-07:00","updated_at":"2025-10-16T18:12:45.604258-07:00","closed_at":"2025-10-16T17:49:54.229303-07:00"} -{"id":"bd-229","title":"Investigate data recovery for issues overwritten by auto-import bug","description":"Auto-import bug (bd-376) has been silently overwriting local changes since the feature was introduced. We need to investigate if any important data was lost and if it can be recovered.\n\n## Data Sources for Recovery\n\n1. **Git history of .beads/issues.jsonl** - May contain older versions with lost changes\n2. **Events table** - Has full audit trail with old_value/new_value\n3. **Commit messages** - May reference work that was done but later overwritten\n\n## Investigation Steps\n\n1. Check events table for patterns:\n - Look for auto-import events that changed status from closed → open\n - Look for manual updates followed by auto-import reverts\n - Identify issues with suspicious event sequences\n\n2. Git archaeology:\n - Check git log for .beads/issues.jsonl\n - Look for commits where status=closed was changed to status=open\n - Compare git history vs current database state\n\n3. Document lost work:\n - Create list of issues that were closed but reverted to open\n - Identify any critical work that was marked done but lost\n - Check if any issue references are now broken\n\n## Recovery Actions\n\nIf significant data loss is found:\n- Create script to reconstruct lost state from events table\n- Manually review and restore critical closed issues\n- Document lessons learned for preventing future data loss\n\n## Example Query\n\n```sql\n-- Find issues where status was manually changed then reverted by auto-import\nSELECT \n issue_id,\n GROUP_CONCAT(event_type || ':' || actor, ' -\u003e ') as event_chain\nFROM events \nWHERE issue_id IN (\n SELECT DISTINCT issue_id \n FROM events \n WHERE actor = 'auto-import' AND event_type = 'status_changed'\n)\nGROUP BY issue_id\nHAVING event_chain LIKE '%stevey%auto-import%';\n```","notes":"Investigation complete. Successfully recovered 3 valuable issues (bd-367, bd-233) from 22 total lost. Historical context preserved in bd-89 notes. Auto-import collision detection (bd-376) now prevents future data loss.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.230133-07:00","updated_at":"2025-10-16T18:12:45.604729-07:00","closed_at":"2025-10-16T17:49:54.230133-07:00","dependencies":[{"issue_id":"bd-229","depends_on_id":"bd-228","type":"discovered-from","created_at":"2025-10-16T17:49:54.776992-07:00","created_by":"auto-import"}]} +{"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-364, bd-199, bd-369-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":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-15T02:06:30.671918-07:00","updated_at":"2025-10-16T14:57:48.856488-07:00","closed_at":"2025-10-15T02:11:30.794518-07:00"} +{"id":"bd-229","title":"Investigate data recovery for issues overwritten by auto-import bug","description":"Auto-import bug (bd-552) has been silently overwriting local changes since the feature was introduced. We need to investigate if any important data was lost and if it can be recovered.\n\n## Data Sources for Recovery\n\n1. **Git history of .beads/issues.jsonl** - May contain older versions with lost changes\n2. **Events table** - Has full audit trail with old_value/new_value\n3. **Commit messages** - May reference work that was done but later overwritten\n\n## Investigation Steps\n\n1. Check events table for patterns:\n - Look for auto-import events that changed status from closed → open\n - Look for manual updates followed by auto-import reverts\n - Identify issues with suspicious event sequences\n\n2. Git archaeology:\n - Check git log for .beads/issues.jsonl\n - Look for commits where status=closed was changed to status=open\n - Compare git history vs current database state\n\n3. Document lost work:\n - Create list of issues that were closed but reverted to open\n - Identify any critical work that was marked done but lost\n - Check if any issue references are now broken\n\n## Recovery Actions\n\nIf significant data loss is found:\n- Create script to reconstruct lost state from events table\n- Manually review and restore critical closed issues\n- Document lessons learned for preventing future data loss\n\n## Example Query\n\n```sql\n-- Find issues where status was manually changed then reverted by auto-import\nSELECT \n issue_id,\n GROUP_CONCAT(event_type || ':' || actor, ' -\u003e ') as event_chain\nFROM events \nWHERE issue_id IN (\n SELECT DISTINCT issue_id \n FROM events \n WHERE actor = 'auto-import' AND event_type = 'status_changed'\n)\nGROUP BY issue_id\nHAVING event_chain LIKE '%stevey%auto-import%';\n```","notes":"Investigation complete. Successfully recovered 3 valuable issues (bd-536, bd-233) from 22 total lost. Historical context preserved in bd-89 notes. Auto-import collision detection (bd-552) now prevents future data loss.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-15T02:10:40.724826-07:00","updated_at":"2025-10-16T18:54:29.622747-07:00","closed_at":"2025-10-15T02:22:30.426785-07:00","dependencies":[{"issue_id":"bd-229","depends_on_id":"bd-228","type":"discovered-from","created_at":"2025-10-16T18:57:16.966798-07:00","created_by":"auto-import"}]} {"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-16T17:49:54.231595-07:00","updated_at":"2025-10-16T18:12:45.60519-07:00","closed_at":"2025-10-16T17:49:54.231595-07:00"} {"id":"bd-230","title":"Code review: Auto-import collision detection fix (bd-228)","description":"Request thorough code review of the auto-import collision detection implementation.\n\n## Files Changed\n- cmd/bd/main.go: autoImportIfNewer() and new autoImportWithoutCollisionDetection()\n\n## Review Focus Areas\n\n### 1. Correctness\n- Does collision detection properly identify conflicts?\n- Are colliding issues correctly filtered from import?\n- Is the fallback function correct for non-SQLite backends?\n\n### 2. Edge Cases\n- What happens if DetectCollisions() fails?\n- What if all issues are collisions?\n- What if JSONL is malformed?\n- Race conditions with concurrent auto-imports?\n\n### 3. User Experience\n- Is the warning message clear and actionable?\n- Should we log to a file instead of/in addition to stderr?\n- Should there be a --auto-resolve flag?\n\n### 4. Performance\n- Does collision detection add significant latency?\n- Will this work with 1000+ issues?\n- Any unnecessary N+1 queries?\n\n### 5. Testing Gaps\n- Do we need integration tests for collision scenarios?\n- Should we test the warning output?\n- Test autoImportWithoutCollisionDetection() fallback?\n\n## Questions for Reviewer\n1. Should auto-import be more aggressive (auto-resolve) or more conservative (fail)?\n2. Should we add a counter for how many times collisions occurred?\n3. Should there be a config option to disable collision detection?\n4. Is the warning too verbose for typical workflows?\n\n## Current Behavior\n- Skips colliding issues (preserves local)\n- Prints warning to stderr\n- Suggests manual resolution command\n- Continues with non-colliding issues","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.232066-07:00","updated_at":"2025-10-16T18:12:45.605659-07:00"} -{"id":"bd-231","title":"Add integration tests for auto-import collision detection","description":"The auto-import collision detection fix (bd-376) needs comprehensive integration tests.\n\n## Test Scenarios Needed\n\n### 1. Basic Collision Detection\n```go\nTestAutoImportWithCollisions\n- Setup: Create issue in DB with status=closed\n- Simulate: Git pull with JSONL containing same issue with status=open\n- Verify: Local changes preserved, warning printed, issue still closed\n```\n\n### 2. Multiple Collisions\n```go\nTestAutoImportWithMultipleCollisions\n- Setup: 5 issues with local modifications\n- Simulate: JSONL with 3 colliding, 2 matching\n- Verify: 3 skipped, 2 updated, appropriate warnings\n```\n\n### 3. No Collisions (Happy Path)\n```go\nTestAutoImportWithoutCollisions\n- Setup: Clean database\n- Simulate: JSONL with new issues + exact matches\n- Verify: All imported successfully, no warnings\n```\n\n### 4. All Collisions\n```go\nTestAutoImportAllCollisions\n- Setup: Every issue has local modifications\n- Simulate: JSONL with conflicting versions\n- Verify: All skipped, warning lists all issues\n```\n\n### 5. Collision Detection Failure\n```go\nTestAutoImportCollisionDetectionError\n- Setup: Mock DetectCollisions() to return error\n- Verify: Import skipped entirely (safe failure mode)\n```\n\n### 6. Hash-Based Skip\n```go\nTestAutoImportHashUnchanged\n- Setup: JSONL hash matches last_import_hash\n- Verify: No collision detection runs, fast path\n```\n\n### 7. Fallback for Non-SQLite\n```go\nTestAutoImportWithoutCollisionDetection\n- Setup: Mock non-SQLite storage backend\n- Verify: Falls back to old behavior, no collision detection\n```\n\n## Test Infrastructure Needed\n\n1. **Helper functions:**\n - createTestDBWithIssues()\n - writeJSONLFile()\n - captureStderrWarnings()\n - simulateGitPull()\n\n2. **Fixtures:**\n - sample-collisions.jsonl\n - sample-exact-matches.jsonl\n - sample-mixed.jsonl\n\n3. **Assertions:**\n - assertIssueState(id, expectedStatus)\n - assertWarningContains(text)\n - assertCollisionCount(n)\n\n## Acceptance Criteria\n- All 7 test scenarios implemented\n- Tests pass consistently\n- Code coverage \u003e80% for autoImportIfNewer()\n- Tests run in \u003c5 seconds total\n- Clear test names and documentation","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.232539-07:00","updated_at":"2025-10-16T18:12:45.606082-07:00"} +{"id":"bd-231","title":"Add integration tests for auto-import collision detection","description":"The auto-import collision detection fix (bd-552) needs comprehensive integration tests.\n\n## Test Scenarios Needed\n\n### 1. Basic Collision Detection\n```go\nTestAutoImportWithCollisions\n- Setup: Create issue in DB with status=closed\n- Simulate: Git pull with JSONL containing same issue with status=open\n- Verify: Local changes preserved, warning printed, issue still closed\n```\n\n### 2. Multiple Collisions\n```go\nTestAutoImportWithMultipleCollisions\n- Setup: 5 issues with local modifications\n- Simulate: JSONL with 3 colliding, 2 matching\n- Verify: 3 skipped, 2 updated, appropriate warnings\n```\n\n### 3. No Collisions (Happy Path)\n```go\nTestAutoImportWithoutCollisions\n- Setup: Clean database\n- Simulate: JSONL with new issues + exact matches\n- Verify: All imported successfully, no warnings\n```\n\n### 4. All Collisions\n```go\nTestAutoImportAllCollisions\n- Setup: Every issue has local modifications\n- Simulate: JSONL with conflicting versions\n- Verify: All skipped, warning lists all issues\n```\n\n### 5. Collision Detection Failure\n```go\nTestAutoImportCollisionDetectionError\n- Setup: Mock DetectCollisions() to return error\n- Verify: Import skipped entirely (safe failure mode)\n```\n\n### 6. Hash-Based Skip\n```go\nTestAutoImportHashUnchanged\n- Setup: JSONL hash matches last_import_hash\n- Verify: No collision detection runs, fast path\n```\n\n### 7. Fallback for Non-SQLite\n```go\nTestAutoImportWithoutCollisionDetection\n- Setup: Mock non-SQLite storage backend\n- Verify: Falls back to old behavior, no collision detection\n```\n\n## Test Infrastructure Needed\n\n1. **Helper functions:**\n - createTestDBWithIssues()\n - writeJSONLFile()\n - captureStderrWarnings()\n - simulateGitPull()\n\n2. **Fixtures:**\n - sample-collisions.jsonl\n - sample-exact-matches.jsonl\n - sample-mixed.jsonl\n\n3. **Assertions:**\n - assertIssueState(id, expectedStatus)\n - assertWarningContains(text)\n - assertCollisionCount(n)\n\n## Acceptance Criteria\n- All 7 test scenarios implemented\n- Tests pass consistently\n- Code coverage \u003e80% for autoImportIfNewer()\n- Tests run in \u003c5 seconds total\n- Clear test names and documentation","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-15T02:12:49.315295-07:00","updated_at":"2025-10-16T18:54:29.586691-07:00","closed_at":"2025-10-15T13:36:12.426347-07:00"} {"id":"bd-232","title":"Consider batching API for bulk issue creation (recovered from bd-222)","description":"Current CreateIssue acquires a dedicated connection for each call. For bulk imports or agent workflows creating many issues, a batched API could improve performance:\n\nCreateIssues(ctx, issues []*Issue, actor string) error\n\nThis would:\n- Acquire one connection\n- Use one IMMEDIATE transaction\n- Insert all issues atomically\n- Reduce connection overhead\n\nNot urgent - current approach is correct and fast enough for typical use.\n\n**Recovered from:** bd-360 (lost in auto-import bug, see LOST_ISSUES_RECOVERY.md)","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-16T17:49:54.232959-07:00","updated_at":"2025-10-16T18:12:45.606662-07:00"} {"id":"bd-233","title":"Consider early context check in CreateIssue (recovered from bd-223)","description":"CreateIssue starts an IMMEDIATE transaction before checking if context is cancelled. If a client cancels early, we've already acquired the write lock.\n\nConsider adding:\n if err := ctx.Err(); err != nil {\n return err\n }\n\nBetween validation (line 318) and acquiring connection (line 331).\n\nLow priority - the busy_timeout and deferred cleanup handle this gracefully, but an early check would be slightly more efficient.\n\n**Recovered from:** bd-223 (lost in auto-import bug, see LOST_ISSUES_RECOVERY.md)","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-16T17:49:54.233359-07:00","updated_at":"2025-10-16T18:12:45.607183-07:00"} {"id":"bd-234","title":"Add database CHECK constraint for status/closed_at invariant","description":"Add database-level constraint to enforce: (status = 'closed') = (closed_at IS NOT NULL)\n\nPrerequisites: Clean existing inconsistent data first\n\nChanges:\n- Add migration to schema.go\n- Constraint prevents ANY code path from creating inconsistent state\n- Foundation for robust agent-proof system","design":"Migration SQL:\n```sql\n-- First clean up existing inconsistent data\nUPDATE issues SET closed_at = NULL\nWHERE status != 'closed' AND closed_at IS NOT NULL;\n\nUPDATE issues SET closed_at = CURRENT_TIMESTAMP\nWHERE status = 'closed' AND closed_at IS NULL;\n\n-- Add the constraint\nALTER TABLE issues ADD CONSTRAINT chk_closed_at_status\n CHECK ((status = 'closed') = (closed_at IS NOT NULL));\n```\n\nImplementation in schema.go migrations.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.233818-07:00","updated_at":"2025-10-16T18:12:45.607814-07:00","closed_at":"2025-10-16T17:49:54.233818-07:00","dependencies":[{"issue_id":"bd-234","depends_on_id":"bd-237","type":"blocks","created_at":"2025-10-16T17:49:54.77767-07:00","created_by":"auto-import"},{"issue_id":"bd-234","depends_on_id":"bd-391","type":"parent-child","created_at":"2025-10-16T17:49:54.779525-07:00","created_by":"auto-import"}]} @@ -154,7 +154,7 @@ {"id":"bd-237","title":"Add Issue.Validate() closed_at invariant check","description":"Add validation logic to types.Issue.Validate() to check closed_at invariant before database operations.\n\nThis provides application-level validation that complements the database constraint.","design":"```go\nfunc (i *Issue) Validate() error {\n // ... existing validation ...\n\n // Enforce closed_at invariant (bd-391)\n if i.Status == StatusClosed \u0026\u0026 i.ClosedAt == nil {\n return fmt.Errorf(\"closed issues must have closed_at timestamp\")\n }\n if i.Status != StatusClosed \u0026\u0026 i.ClosedAt != nil {\n return fmt.Errorf(\"non-closed issues cannot have closed_at timestamp\")\n }\n\n return nil\n}\n```","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.237135-07:00","updated_at":"2025-10-16T18:12:45.609252-07:00","closed_at":"2025-10-16T17:49:54.237135-07:00","dependencies":[{"issue_id":"bd-237","depends_on_id":"bd-238","type":"blocks","created_at":"2025-10-16T17:49:54.787681-07:00","created_by":"auto-import"},{"issue_id":"bd-237","depends_on_id":"bd-391","type":"parent-child","created_at":"2025-10-16T17:49:54.788369-07:00","created_by":"auto-import"}]} {"id":"bd-238","title":"Fix UpdateIssue to auto-manage closed_at on status changes","description":"Modify internal/storage/sqlite/sqlite.go UpdateIssue to automatically manage closed_at when status changes.\n\nWhen status changes TO closed: set closed_at = now()\nWhen status changes FROM closed: set closed_at = nil and emit EventReopened","design":"```go\nfunc (s *SQLiteStorage) UpdateIssue(ctx context.Context, id string, updates map[string]interface{}, actor string) error {\n // ... existing validation ...\n\n // Smart closed_at management based on status changes\n if statusVal, ok := updates[\"status\"]; ok {\n newStatus := statusVal.(string)\n\n if newStatus == string(types.StatusClosed) {\n // Changing to closed: ensure closed_at is set\n if _, hasClosedAt := updates[\"closed_at\"]; !hasClosedAt {\n updates[\"closed_at\"] = time.Now()\n }\n } else {\n // Changing from closed to something else: clear closed_at\n if oldIssue.Status == types.StatusClosed {\n updates[\"closed_at\"] = nil\n eventType = types.EventReopened\n }\n }\n }\n\n // ... rest of existing code ...\n}\n```","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.237841-07:00","updated_at":"2025-10-16T18:12:45.609734-07:00","closed_at":"2025-10-16T17:49:54.237841-07:00","dependencies":[{"issue_id":"bd-238","depends_on_id":"bd-239","type":"blocks","created_at":"2025-10-16T17:49:54.791267-07:00","created_by":"auto-import"},{"issue_id":"bd-238","depends_on_id":"bd-391","type":"parent-child","created_at":"2025-10-16T17:49:54.795364-07:00","created_by":"auto-import"}]} {"id":"bd-239","title":"Fix import.go to normalize closed_at before creating issues","description":"Modify cmd/bd/import.go to enforce closed_at invariant before calling CreateIssue/CreateIssues.\n\nNormalize data: if status=closed, ensure closed_at is set; if status!=closed, ensure closed_at is nil.","design":"```go\nif _, ok := rawData[\"status\"]; ok {\n updates[\"status\"] = issue.Status\n\n // Enforce closed_at invariant\n if issue.Status == types.StatusClosed {\n // Status is closed: ensure closed_at is set\n if issue.ClosedAt == nil {\n now := time.Now()\n updates[\"closed_at\"] = now\n } else {\n updates[\"closed_at\"] = *issue.ClosedAt\n }\n } else {\n // Status is not closed: ensure closed_at is NULL\n updates[\"closed_at\"] = nil\n }\n}\n```","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.239183-07:00","updated_at":"2025-10-16T18:12:45.610397-07:00","closed_at":"2025-10-16T17:49:54.239183-07:00","dependencies":[{"issue_id":"bd-239","depends_on_id":"bd-240","type":"blocks","created_at":"2025-10-16T17:49:54.795896-07:00","created_by":"auto-import"},{"issue_id":"bd-239","depends_on_id":"bd-391","type":"parent-child","created_at":"2025-10-16T17:49:54.796463-07:00","created_by":"auto-import"}]} -{"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-16T17:49:54.240484-07:00","updated_at":"2025-10-16T18:12:45.610826-07:00","closed_at":"2025-10-16T17:49:54.240484-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-553's collision resolution.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-14T14:43:06.910467-07:00","updated_at":"2025-10-16T18:54:29.663156-07:00","closed_at":"2025-10-15T03:01:29.569795-07:00"} {"id":"bd-240","title":"Add CreateIssues interface method to Storage","description":"Add CreateIssues to the Storage interface in storage/storage.go\n\nNon-breaking addition to interface for batch issue creation.","design":"```go\n// storage/storage.go\ntype Storage interface {\n CreateIssue(ctx context.Context, issue *types.Issue, actor string) error\n CreateIssues(ctx context.Context, issues []*types.Issue, actor string) error // NEW\n // ... rest unchanged\n}\n```","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.241184-07:00","updated_at":"2025-10-16T18:12:45.611279-07:00","closed_at":"2025-10-16T17:49:54.241184-07:00","dependencies":[{"issue_id":"bd-240","depends_on_id":"bd-390","type":"parent-child","created_at":"2025-10-16T17:49:54.797737-07:00","created_by":"auto-import"},{"issue_id":"bd-240","depends_on_id":"bd-391","type":"blocks","created_at":"2025-10-16T17:49:54.798641-07:00","created_by":"auto-import"}]} {"id":"bd-241","title":"Add comprehensive unit tests for CreateIssues","description":"Test coverage for CreateIssues:\n- Empty batch\n- Single issue\n- Multiple issues\n- Mixed ID assignment (explicit + auto-generated)\n- Validation errors\n- Duplicate ID errors\n- Rollback on error\n- Verify closed_at invariant enforced","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.241576-07:00","updated_at":"2025-10-16T18:12:45.611725-07:00","closed_at":"2025-10-16T17:49:54.241576-07:00","dependencies":[{"issue_id":"bd-241","depends_on_id":"bd-240","type":"blocks","created_at":"2025-10-16T17:49:54.803679-07:00","created_by":"auto-import"},{"issue_id":"bd-241","depends_on_id":"bd-390","type":"parent-child","created_at":"2025-10-16T17:49:54.80421-07:00","created_by":"auto-import"}]} {"id":"bd-242","title":"Update import.go to use CreateIssues for bulk imports","description":"Modify cmd/bd/import.go to use CreateIssues instead of CreateIssue loop.\n\nAfter bd-391, import already normalizes closed_at, so this is straightforward:\n1. Normalize all issues in batch (closed_at handling)\n2. Call CreateIssues once with full batch\n3. Much simpler than current loop","design":"```go\n// After normalizing all issues\nfor _, issue := range issues {\n if issue.Status == types.StatusClosed {\n if issue.ClosedAt == nil {\n now := time.Now()\n issue.ClosedAt = \u0026now\n }\n } else {\n issue.ClosedAt = nil\n }\n}\n\n// Single batch call (5-15x faster!)\nreturn store.CreateIssues(ctx, issues, \"import\")\n```","notes":"Completed: Replaced CreateIssue loop with single CreateIssues batch call. Added in-memory de-duplication for duplicate IDs within same import (last one wins). Fixed skip-existing logic to only apply to DB issues, not batch duplicates. All 14 import tests pass including performance, collisions, dependencies, and labels.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.242847-07:00","updated_at":"2025-10-16T18:12:45.612129-07:00","closed_at":"2025-10-16T17:49:54.242847-07:00","dependencies":[{"issue_id":"bd-242","depends_on_id":"bd-240","type":"blocks","created_at":"2025-10-16T17:49:54.80702-07:00","created_by":"auto-import"},{"issue_id":"bd-242","depends_on_id":"bd-390","type":"parent-child","created_at":"2025-10-16T17:49:54.808911-07:00","created_by":"auto-import"}]} @@ -187,10 +187,10 @@ {"id":"bd-268","title":"Explore in-memory embedded SQL alternatives to SQLite","description":"Investigate lightweight in-memory embedded SQL databases as alternative backends for environments where SQLite is problematic or considered too heavyweight. This would provide flexibility for different deployment scenarios.","design":"Research options:\n- modernc.org/sqlite (pure Go SQLite implementation, no cgo)\n- rqlite (distributed SQLite with Raft)\n- go-memdb (in-memory database by HashiCorp)\n- badger (embedded key-value store, would need SQL layer)\n- bbolt (embedded key-value store)\n- duckdb (lightweight analytical database)\n\nEvaluate on:\n- Memory footprint vs SQLite\n- cgo dependency (pure Go preferred)\n- SQL compatibility level\n- Transaction support\n- Performance characteristics\n- Maintenance/community status\n- Migration complexity from SQLite\n\nConsider creating a storage abstraction layer to support multiple backends.","acceptance_criteria":"- Document comparison of at least 3 alternatives\n- Benchmark memory usage and performance vs SQLite\n- Assess migration effort for each option\n- Recommendation on whether to support alternatives\n- If yes, prototype storage interface abstraction","notes":"Worth noting: modernc.org/sqlite is a pure Go implementation (no cgo) that might already address the \"heavyweight\" concern, since much of SQLite's overhead comes from cgo calls. Should evaluate this first before exploring completely different database technologies.","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-16T17:49:54.263606-07:00","updated_at":"2025-10-16T18:12:45.626457-07:00"} {"id":"bd-269","title":"Add label and title filtering to bd list","description":"Add --label and --title flags to bd list command for better filtering. Labels backend already exists, just need CLI exposure. Title search needs both backend and CLI implementation.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T17:49:54.264227-07:00","updated_at":"2025-10-16T18:12:45.626917-07:00","closed_at":"2025-10-16T17:49:54.264227-07:00","external_ref":"gh-45"} {"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-16T17:49:54.264924-07:00","updated_at":"2025-10-16T18:12:45.627358-07:00","closed_at":"2025-10-16T17:49:54.264924-07:00"} -{"id":"bd-270","title":"Detect and handle Git merge conflicts in JSONL auto-import","description":"","design":"**Problem**: Git merge conflicts in .beads/issues.jsonl break auto-import silently. When JSONL contains conflict markers (\u003c\u003c\u003c\u003c\u003c\u003c\u003c HEAD, =======, \u003e\u003e\u003e\u003e\u003e\u003e\u003e), JSON parser fails and entire import is skipped. System only shows parse error but doesn't identify it as a merge conflict.\n\n**Impact**: Critical - blocks all auto-import until manually resolved.\n\n**Solution**:\n1. Add pre-parse merge conflict detection in autoImportIfNewer()\n2. Check for conflict markers before JSON parsing\n3. Provide helpful error message with resolution instructions\n4. Consider auto-resolution strategies:\n - Parse each section separately (HEAD vs incoming)\n - Detect collisions between sections\n - Auto-resolve with --resolve-collisions logic\n - OR abort with clear merge resolution instructions\n\n**Code locations**:\n- cmd/bd/main.go:autoImportIfNewer() (lines 164-398)\n- cmd/bd/import.go (manual import with better error handling)\n- internal/storage/sqlite/collision.go (collision detection)","acceptance_criteria":"- Pre-parse detection catches merge conflict markers\n- Clear error message identifies it as merge conflict\n- Error message includes resolution steps\n- Test case with synthetic merge conflict\n- Consider: automatic merge resolution (stretch goal)","status":"closed","priority":0,"issue_type":"bug","assignee":"amp","created_at":"2025-10-16T17:49:54.265385-07:00","updated_at":"2025-10-16T18:12:45.627829-07:00","closed_at":"2025-10-16T17:49:54.265385-07:00"} -{"id":"bd-271","title":"Epic: Git-Based Auto-Sync for Multi-Device Support","description":"Implement git-based auto-sync to enable multi-device workflows while maintaining beads' local-first, lightweight philosophy. Build on existing JSONL export/import infrastructure and collision detection.","design":"See DESIGN-GIT-SYNC.md for comprehensive architectural design.\n\nCore principle: Git + JSONL remains source of truth. No required server. Optional lightweight sync gateway for users who want push-button multi-device support.","acceptance_criteria":"- Phase 1: Enhanced git-based sync (no server) completed\n- Phase 2: Optional bd serve gateway implemented\n- Phase 3: Client gateway integration working\n- Phase 4: Production-ready with CRDT conflict resolution\n- All existing functionality preserved (backward compatible)\n- Documentation complete\n\n---","status":"open","priority":1,"issue_type":"epic","created_at":"2025-10-16T17:49:54.265971-07:00","updated_at":"2025-10-16T18:12:45.628294-07:00","dependencies":[{"issue_id":"bd-271","depends_on_id":"bd-274","type":"parent-child","created_at":"2025-10-16T17:49:54.816074-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-275","type":"parent-child","created_at":"2025-10-16T17:49:54.816632-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-276","type":"parent-child","created_at":"2025-10-16T17:49:54.817265-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-278","type":"parent-child","created_at":"2025-10-16T17:49:54.817762-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-277","type":"parent-child","created_at":"2025-10-16T17:49:54.818229-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-279","type":"parent-child","created_at":"2025-10-16T17:49:54.819054-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-280","type":"parent-child","created_at":"2025-10-16T17:49:54.819536-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-281","type":"parent-child","created_at":"2025-10-16T17:49:54.819989-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-282","type":"parent-child","created_at":"2025-10-16T17:49:54.82082-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-283","type":"parent-child","created_at":"2025-10-16T17:49:54.821267-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-284","type":"parent-child","created_at":"2025-10-16T17:49:54.821733-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-285","type":"parent-child","created_at":"2025-10-16T17:49:54.822218-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-286","type":"parent-child","created_at":"2025-10-16T17:49:54.822723-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-287","type":"parent-child","created_at":"2025-10-16T17:49:54.823204-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-288","type":"parent-child","created_at":"2025-10-16T17:49:54.82431-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-289","type":"parent-child","created_at":"2025-10-16T17:49:54.824853-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-290","type":"parent-child","created_at":"2025-10-16T17:49:54.825328-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-291","type":"parent-child","created_at":"2025-10-16T17:49:54.82583-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-292","type":"parent-child","created_at":"2025-10-16T17:49:54.826782-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-293","type":"parent-child","created_at":"2025-10-16T17:49:54.827271-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-294","type":"parent-child","created_at":"2025-10-16T17:49:54.827797-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-295","type":"parent-child","created_at":"2025-10-16T17:49:54.828287-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-296","type":"parent-child","created_at":"2025-10-16T17:49:54.828752-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-297","type":"parent-child","created_at":"2025-10-16T17:49:54.829395-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-298","type":"parent-child","created_at":"2025-10-16T17:49:54.830195-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-299","type":"parent-child","created_at":"2025-10-16T17:49:54.830697-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-378","type":"parent-child","created_at":"2025-10-16T17:49:54.831224-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-386","type":"parent-child","created_at":"2025-10-16T17:49:54.831672-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-385","type":"parent-child","created_at":"2025-10-16T17:49:54.832124-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-384","type":"parent-child","created_at":"2025-10-16T17:49:54.832554-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-387","type":"parent-child","created_at":"2025-10-16T17:49:54.832995-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-383","type":"parent-child","created_at":"2025-10-16T17:49:54.833571-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-381","type":"parent-child","created_at":"2025-10-16T17:49:54.834193-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-380","type":"parent-child","created_at":"2025-10-16T17:49:54.834642-07:00","created_by":"auto-import"},{"issue_id":"bd-271","depends_on_id":"bd-373","type":"parent-child","created_at":"2025-10-16T17:49:54.835094-07:00","created_by":"auto-import"}]} -{"id":"bd-272","title":"Phase 1: Implement bd sync command","description":"Create bd sync command to manually synchronize with git remote in a single operation.","design":"Command should:\n1. Export pending changes to JSONL\n2. Commit changes to git\n3. Pull from remote (with conflict resolution)\n4. Push local commits to remote\n\nWraps the entire sync workflow in one command for better UX.","acceptance_criteria":"- bd sync command implemented\n- Exports dirty changes to JSONL automatically\n- Commits to git with descriptive message\n- Pulls and handles merge conflicts\n- Auto-imports updated JSONL\n- Pushes to remote\n- Error handling for git failures\n- Tests cover success and failure scenarios\n- Documentation in README.md\n\n---","status":"open","priority":1,"issue_type":"feature","created_at":"2025-10-16T17:49:54.266413-07:00","updated_at":"2025-10-16T18:12:45.628927-07:00"} -{"id":"bd-273","title":"Phase 1: Implement bd daemon command","description":"Create bd daemon command to run background sync process with configurable interval.","design":"Daemon should:\n- Run in background (fork or systemd service)\n- Poll for changes at configurable interval (default: 5 minutes)\n- Export dirty issues to JSONL\n- Auto-commit if --auto-commit flag set\n- Auto-push if --auto-push flag set\n- Pull remote changes periodically\n- Auto-import when remote changes detected\n- Log sync activity\n\nCommand flags:\n- --interval=5m (sync check interval)\n- --auto-commit (automatically commit changes)\n- --auto-push (automatically push commits)\n- --stop (stop running daemon)\n- --status (show daemon status)","acceptance_criteria":"- bd daemon command implemented\n- Background process management working\n- Configurable sync interval\n- Auto-commit functionality\n- Auto-push functionality\n- PID file for process management\n- Graceful shutdown on SIGTERM\n- Logging to file or syslog\n- Status command shows daemon state\n- Tests for daemon lifecycle\n- Documentation in README.md\n\n---","status":"open","priority":1,"issue_type":"feature","created_at":"2025-10-16T17:49:54.266945-07:00","updated_at":"2025-10-16T18:12:45.629532-07:00"} +{"id":"bd-270","title":"Detect and handle Git merge conflicts in JSONL auto-import","description":"","design":"**Problem**: Git merge conflicts in .beads/issues.jsonl break auto-import silently. When JSONL contains conflict markers (\u003c\u003c\u003c\u003c\u003c\u003c\u003c HEAD, =======, \u003e\u003e\u003e\u003e\u003e\u003e\u003e), JSON parser fails and entire import is skipped. System only shows parse error but doesn't identify it as a merge conflict.\n\n**Impact**: Critical - blocks all auto-import until manually resolved.\n\n**Solution**:\n1. Add pre-parse merge conflict detection in autoImportIfNewer()\n2. Check for conflict markers before JSON parsing\n3. Provide helpful error message with resolution instructions\n4. Consider auto-resolution strategies:\n - Parse each section separately (HEAD vs incoming)\n - Detect collisions between sections\n - Auto-resolve with --resolve-collisions logic\n - OR abort with clear merge resolution instructions\n\n**Code locations**:\n- cmd/bd/main.go:autoImportIfNewer() (lines 164-398)\n- cmd/bd/import.go (manual import with better error handling)\n- internal/storage/sqlite/collision.go (collision detection)","acceptance_criteria":"- Pre-parse detection catches merge conflict markers\n- Clear error message identifies it as merge conflict\n- Error message includes resolution steps\n- Test case with synthetic merge conflict\n- Consider: automatic merge resolution (stretch goal)","status":"closed","priority":0,"issue_type":"bug","assignee":"amp","created_at":"2025-10-16T00:32:32.459577-07:00","updated_at":"2025-10-16T14:33:21.29817-07:00","closed_at":"2025-10-16T00:35:43.559463-07:00"} +{"id":"bd-271","title":"Epic: Git-Based Auto-Sync for Multi-Device Support","description":"Implement git-based auto-sync to enable multi-device workflows while maintaining beads' local-first, lightweight philosophy. Build on existing JSONL export/import infrastructure and collision detection.","design":"See DESIGN-GIT-SYNC.md for comprehensive architectural design.\n\nCore principle: Git + JSONL remains source of truth. No required server. Optional lightweight sync gateway for users who want push-button multi-device support.","acceptance_criteria":"- Phase 1: Enhanced git-based sync (no server) completed\n- Phase 2: Optional bd serve gateway implemented\n- Phase 3: Client gateway integration working\n- Phase 4: Production-ready with CRDT conflict resolution\n- All existing functionality preserved (backward compatible)\n- Documentation complete\n\n---","status":"open","priority":1,"issue_type":"epic","created_at":"2025-10-16T01:40:04.227913-07:00","updated_at":"2025-10-16T14:33:21.30742-07:00","dependencies":[{"issue_id":"bd-271","depends_on_id":"bd-274","type":"parent-child","created_at":"2025-10-16T01:40:18.227691-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-275","type":"parent-child","created_at":"2025-10-16T01:40:18.358946-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-276","type":"parent-child","created_at":"2025-10-16T01:40:18.396857-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-278","type":"parent-child","created_at":"2025-10-16T01:40:18.433358-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-277","type":"parent-child","created_at":"2025-10-16T01:40:18.434667-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-279","type":"parent-child","created_at":"2025-10-16T01:40:18.7133-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-280","type":"parent-child","created_at":"2025-10-16T01:40:18.885365-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-281","type":"parent-child","created_at":"2025-10-16T01:40:25.063004-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-282","type":"parent-child","created_at":"2025-10-16T01:40:25.368669-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-283","type":"parent-child","created_at":"2025-10-16T01:40:25.561328-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-284","type":"parent-child","created_at":"2025-10-16T01:40:25.719002-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-285","type":"parent-child","created_at":"2025-10-16T01:40:25.87597-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-286","type":"parent-child","created_at":"2025-10-16T01:40:26.06065-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-287","type":"parent-child","created_at":"2025-10-16T01:40:26.3263-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-288","type":"parent-child","created_at":"2025-10-16T01:40:26.546026-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-289","type":"parent-child","created_at":"2025-10-16T01:40:26.994076-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-290","type":"parent-child","created_at":"2025-10-16T01:40:27.398992-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-291","type":"parent-child","created_at":"2025-10-16T01:40:27.997735-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-292","type":"parent-child","created_at":"2025-10-16T01:40:28.397517-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-293","type":"parent-child","created_at":"2025-10-16T01:40:28.794089-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-294","type":"parent-child","created_at":"2025-10-16T01:40:29.196323-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-295","type":"parent-child","created_at":"2025-10-16T01:40:29.400404-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-296","type":"parent-child","created_at":"2025-10-16T01:40:29.723038-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-297","type":"parent-child","created_at":"2025-10-16T01:40:30.127273-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-298","type":"parent-child","created_at":"2025-10-16T01:40:31.032343-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-299","type":"parent-child","created_at":"2025-10-16T01:40:31.29951-07:00","created_by":"stevey"},{"issue_id":"bd-271","depends_on_id":"bd-386","type":"parent-child","created_at":"2025-10-16T14:57:49.188489-07:00","created_by":"import-remap"},{"issue_id":"bd-271","depends_on_id":"bd-381","type":"parent-child","created_at":"2025-10-16T14:57:49.1986-07:00","created_by":"import-remap"},{"issue_id":"bd-271","depends_on_id":"bd-380","type":"parent-child","created_at":"2025-10-16T14:57:49.199753-07:00","created_by":"import-remap"},{"issue_id":"bd-271","depends_on_id":"bd-548","type":"parent-child","created_at":"2025-10-16T18:54:29.865872-07:00","created_by":"import-remap"},{"issue_id":"bd-271","depends_on_id":"bd-550","type":"parent-child","created_at":"2025-10-16T18:54:29.868939-07:00","created_by":"import-remap"},{"issue_id":"bd-271","depends_on_id":"bd-546","type":"parent-child","created_at":"2025-10-16T18:54:29.86987-07:00","created_by":"import-remap"},{"issue_id":"bd-271","depends_on_id":"bd-551","type":"parent-child","created_at":"2025-10-16T18:54:29.872044-07:00","created_by":"import-remap"},{"issue_id":"bd-271","depends_on_id":"bd-549","type":"parent-child","created_at":"2025-10-16T18:54:29.872974-07:00","created_by":"import-remap"},{"issue_id":"bd-271","depends_on_id":"bd-538","type":"parent-child","created_at":"2025-10-16T18:54:29.883113-07:00","created_by":"import-remap"},{"issue_id":"bd-271","depends_on_id":"bd-649","type":"parent-child","created_at":"2025-10-16T18:57:16.7807-07:00","created_by":"import-remap"},{"issue_id":"bd-271","depends_on_id":"bd-385","type":"parent-child","created_at":"2025-10-16T18:57:16.968099-07:00","created_by":"auto-import"}]} +{"id":"bd-272","title":"Phase 1: Implement bd sync command","description":"Create bd sync command to manually synchronize with git remote in a single operation.","design":"Command should:\n1. Export pending changes to JSONL\n2. Commit changes to git\n3. Pull from remote (with conflict resolution)\n4. Push local commits to remote\n\nWraps the entire sync workflow in one command for better UX.","acceptance_criteria":"- bd sync command implemented\n- Exports dirty changes to JSONL automatically\n- Commits to git with descriptive message\n- Pulls and handles merge conflicts\n- Auto-imports updated JSONL\n- Pushes to remote\n- Error handling for git failures\n- Tests cover success and failure scenarios\n- Documentation in README.md\n\n---","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T01:40:04.246855-07:00","updated_at":"2025-10-16T18:57:26.133042-07:00","closed_at":"2025-10-16T18:57:26.133042-07:00"} +{"id":"bd-273","title":"Phase 1: Implement bd daemon command","description":"Create bd daemon command to run background sync process with configurable interval.","design":"Daemon should:\n- Run in background (fork or systemd service)\n- Poll for changes at configurable interval (default: 5 minutes)\n- Export dirty issues to JSONL\n- Auto-commit if --auto-commit flag set\n- Auto-push if --auto-push flag set\n- Pull remote changes periodically\n- Auto-import when remote changes detected\n- Log sync activity\n\nCommand flags:\n- --interval=5m (sync check interval)\n- --auto-commit (automatically commit changes)\n- --auto-push (automatically push commits)\n- --stop (stop running daemon)\n- --status (show daemon status)","acceptance_criteria":"- bd daemon command implemented\n- Background process management working\n- Configurable sync interval\n- Auto-commit functionality\n- Auto-push functionality\n- PID file for process management\n- Graceful shutdown on SIGTERM\n- Logging to file or syslog\n- Status command shows daemon state\n- Tests for daemon lifecycle\n- Documentation in README.md\n\n---","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T01:40:04.263802-07:00","updated_at":"2025-10-16T18:59:54.489982-07:00","closed_at":"2025-10-16T18:59:54.489982-07:00"} {"id":"bd-274","title":"Phase 1: Create enhanced git hooks examples","description":"Create comprehensive git hooks in examples/git-hooks/ for immediate sync without daemon.","design":"Hooks to create:\n1. post-commit: Force immediate export, amend commit with JSONL changes\n2. post-merge: Auto-import with collision resolution\n3. pre-push: Ensure JSONL is up-to-date\n4. post-checkout: Auto-import when switching branches\n\nInstallation script: examples/git-hooks/install.sh","acceptance_criteria":"- post-commit hook that auto-exports\n- post-merge hook that auto-imports with --resolve-collisions\n- pre-push hook validates JSONL is synced\n- post-checkout hook imports branch changes\n- install.sh script copies hooks to .git/hooks/\n- Documentation in examples/git-hooks/README.md\n- Hooks are executable\n- Error handling in all hooks\n- Tests verify hook behavior\n\n---","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.267478-07:00","updated_at":"2025-10-16T18:12:45.629971-07:00","dependencies":[{"issue_id":"bd-274","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.835711-07:00","created_by":"auto-import"}]} {"id":"bd-275","title":"Phase 1: Implement three-way merge for conflicts","description":"Implement three-way merge algorithm to intelligently resolve conflicts by comparing base, local, and remote versions.","design":"Three-way merge logic:\n- Get base version from git history (last common ancestor)\n- Compare local vs base: if same, use remote (remote changed)\n- Compare remote vs base: if same, use local (local changed)\n- If both changed: mark as conflict for manual resolution\n\nField-by-field merging for Issue type:\n- title, description, design, acceptance_criteria, notes (text fields)\n- status, priority, issue_type (enum fields)\n- labels (set merge - union)\n- dependencies (set merge - union)\n\nReturn MergeResult with:\n- MergedVersion (auto-merged fields)\n- Conflicts (list of fields requiring manual resolution)","acceptance_criteria":"- ThreeWayMerge function implemented\n- GetLastSyncedVersion retrieves git base version\n- Field-by-field merge logic for all Issue fields\n- Union merge for labels and dependencies\n- Conflict detection for incompatible changes\n- MergeResult type defined\n- Integration with import collision detection\n- Tests cover all merge scenarios\n- Documentation in DESIGN-GIT-SYNC.md\n\n---","status":"open","priority":1,"issue_type":"feature","created_at":"2025-10-16T17:49:54.267991-07:00","updated_at":"2025-10-16T18:12:45.630447-07:00","dependencies":[{"issue_id":"bd-275","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.836275-07:00","created_by":"auto-import"}]} {"id":"bd-276","title":"Phase 1: Add version vectors for causal ordering","description":"Add optional version vector metadata to Issues for detecting causal relationships and enabling better conflict resolution.","design":"Add sync_metadata to Issue JSON:\n```json\n{\n \"sync_metadata\": {\n \"version\": 3,\n \"last_modified_by\": \"device-a\",\n \"version_vector\": {\n \"device-a\": 2,\n \"device-b\": 1\n }\n }\n}\n```\n\nVersion vector tracks logical clock per device:\n- Incremented on each update\n- Used to determine causality (happened-before)\n- Enables automatic conflict resolution for concurrent edits\n\nOptional field - backward compatible with existing JSONL.","acceptance_criteria":"- SyncMetadata type defined\n- Version vector in Issue struct (optional)\n- Device ID generation and storage\n- Increment version on update\n- Version vector comparison functions\n- Causal ordering detection\n- Integration with collision detection\n- Backward compatible JSONL parsing\n- Tests for version vector logic\n- Documentation in DESIGN-GIT-SYNC.md\n\n---","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-16T17:49:54.26843-07:00","updated_at":"2025-10-16T18:12:45.631001-07:00","dependencies":[{"issue_id":"bd-276","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.83687-07:00","created_by":"auto-import"}]} @@ -208,7 +208,7 @@ {"id":"bd-287","title":"Phase 2: Create API client library (Go)","description":"Create Go client library for accessing beads gateway API.","design":"Client library should provide:\n- Type-safe API calls\n- Authentication handling\n- Error handling and retries\n- WebSocket subscription\n- Automatic reconnection\n- Context support for cancellation\n\nPackage: github.com/steveyegge/beads/client\n\nExample usage:\n```go\nclient := beads.NewClient(\"http://gateway:8080\", \"api-key\")\nissue, err := client.GetIssue(ctx, \"bd-10\")\n```","acceptance_criteria":"- Go client library package\n- All API endpoints wrapped\n- Type-safe request/response\n- Authentication handling\n- Retry logic for transient errors\n- WebSocket client support\n- Context support\n- Example usage in examples/\n- Tests for client library\n- Documentation in CLIENT.md\n\n---","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-16T17:49:54.276294-07:00","updated_at":"2025-10-16T18:12:45.636876-07:00","dependencies":[{"issue_id":"bd-287","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.846168-07:00","created_by":"auto-import"}]} {"id":"bd-288","title":"Phase 2: Document gateway API","description":"Create comprehensive API documentation for gateway with examples and OpenAPI spec.","design":"Documentation should include:\n- Authentication guide\n- All endpoint descriptions\n- Request/response examples\n- Error codes and handling\n- WebSocket protocol\n- Rate limits\n- Best practices\n\nCreate OpenAPI 3.0 specification for:\n- Automated client generation\n- API testing tools\n- Documentation generation","acceptance_criteria":"- API.md with full documentation\n- OpenAPI 3.0 spec (api-spec.yaml)\n- Request/response examples for all endpoints\n- Authentication examples\n- WebSocket protocol documentation\n- Error response documentation\n- Code examples in multiple languages\n- Postman collection (optional)\n- Link from README.md\n\n---","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.276948-07:00","updated_at":"2025-10-16T18:12:45.637644-07:00","dependencies":[{"issue_id":"bd-288","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.846693-07:00","created_by":"auto-import"}]} {"id":"bd-289","title":"Phase 3: Implement bd config command for gateway","description":"Create bd config command to manage gateway configuration for transparent client-side gateway use.","design":"Config commands:\n- bd config set gateway \u003curl\u003e\n- bd config set api_key \u003ckey\u003e\n- bd config get gateway\n- bd config get api_key\n- bd config unset gateway\n- bd config list\n\nConfig storage: ~/.beads/config.json\n\nConfig keys:\n- gateway_url: URL of gateway server\n- api_key: Authentication key\n- auto_sync: Enable background sync\n- sync_interval: Sync check interval","acceptance_criteria":"- bd config command implemented\n- Set/get/unset/list subcommands\n- Config file at ~/.beads/config.json\n- Validation of config values\n- Secure storage of API key\n- Tests for config operations\n- Documentation in README.md\n\n---","status":"open","priority":1,"issue_type":"feature","created_at":"2025-10-16T17:49:54.27745-07:00","updated_at":"2025-10-16T18:12:45.638324-07:00","dependencies":[{"issue_id":"bd-289","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.847184-07:00","created_by":"auto-import"}]} -{"id":"bd-29","title":"Use safer placeholder pattern in replaceIDReferences","description":"Currently uses bd-324 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-16T17:49:54.27792-07:00","updated_at":"2025-10-16T18:12:45.638775-07:00"} +{"id":"bd-29","title":"Use safer placeholder pattern in replaceIDReferences","description":"Currently uses bd-547 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-16T18:54:29.820249-07:00"} {"id":"bd-290","title":"Phase 3: Add transparent gateway detection","description":"Modify bd commands to transparently use gateway API when configured, with automatic fallback to local storage.","design":"Update storage layer to:\n1. Check for gateway config\n2. If gateway configured, use GatewayClient\n3. If gateway unavailable, fall back to local SQLite\n4. Cache gateway responses for offline use\n\nTransparent for these commands:\n- bd create\n- bd update\n- bd close\n- bd list\n- bd show\n- bd label\n- bd dep\n\nNo changes to command interface - works identically.","acceptance_criteria":"- Gateway detection in storage layer\n- GatewayClient wraps API calls\n- Automatic fallback to local on error\n- Response caching for offline mode\n- All CRUD commands work via gateway\n- Offline mode preserves functionality\n- Tests for gateway mode\n- Tests for fallback behavior\n- Documentation in README.md\n\n---","status":"open","priority":1,"issue_type":"feature","created_at":"2025-10-16T17:49:54.278355-07:00","updated_at":"2025-10-16T18:12:45.639251-07:00","dependencies":[{"issue_id":"bd-290","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.847685-07:00","created_by":"auto-import"}]} {"id":"bd-291","title":"Phase 3: Implement client-side sync daemon","description":"Create client-side background sync daemon for automatic synchronization with gateway.","design":"Sync daemon:\n- Runs in background\n- Polls gateway for updates every 30s\n- Pushes local changes to gateway\n- Handles sync conflicts\n- Logs sync activity\n\nCommands:\n- bd sync-daemon start\n- bd sync-daemon stop\n- bd sync-daemon status\n\nUses gateway WebSocket for real-time updates if available.","acceptance_criteria":"- Client sync daemon implemented\n- Background process management\n- Polling gateway for changes\n- Push local changes to gateway\n- WebSocket subscription for real-time\n- Conflict resolution\n- PID file management\n- Status command\n- Tests for sync daemon\n- Documentation in README.md\n\n---","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-16T17:49:54.279712-07:00","updated_at":"2025-10-16T18:12:45.639696-07:00","dependencies":[{"issue_id":"bd-291","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.848235-07:00","created_by":"auto-import"}]} {"id":"bd-292","title":"Phase 3: Add WebSocket subscription client","description":"Implement WebSocket client for subscribing to gateway notifications and receiving real-time updates.","design":"WebSocket client:\n- Connects to gateway /api/subscribe\n- Sends subscription request with filters\n- Receives event notifications\n- Handles disconnection and reconnection\n- Updates local DB on events\n\nIntegration with sync daemon:\n- Daemon subscribes to all events\n- On notification, triggers immediate sync\n- Reduces polling overhead","acceptance_criteria":"- WebSocket client implementation\n- Subscription with event filters\n- Event handler callbacks\n- Auto-reconnection logic\n- Integration with sync daemon\n- Local DB update on events\n- Connection state management\n- Tests for WebSocket client\n- Documentation in CLIENT.md\n\n---","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-16T17:49:54.280293-07:00","updated_at":"2025-10-16T18:12:45.640105-07:00","dependencies":[{"issue_id":"bd-292","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.848944-07:00","created_by":"auto-import"}]} @@ -228,8 +228,8 @@ {"id":"bd-304","title":"Add tests for git-based restoration","description":"Test compaction stores commit hash, restore command works, handles missing git repo gracefully","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.304867-07:00","updated_at":"2025-10-16T18:12:45.646974-07:00"} {"id":"bd-305","title":"Document git-based restoration feature","description":"Update COMPACTION.md and README.md with restoration workflow and examples","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.319392-07:00","updated_at":"2025-10-16T18:12:45.647421-07:00"} {"id":"bd-306","title":"Concurrent bd commands collide on shared .tmp filename","description":"When multiple bd commands run concurrently (e.g., different agents), they all write to .beads/issues.jsonl.tmp causing race conditions. One command's rename succeeds, consuming the .tmp file, then other commands fail with 'no such file or directory'. Solution: use unique temp filenames with PID or random suffix (e.g., issues.jsonl.tmp.12345).","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T17:49:54.323841-07:00","updated_at":"2025-10-16T18:12:45.648042-07:00","closed_at":"2025-10-16T17:49:54.323841-07:00"} -{"id":"bd-307","title":"Fix circular dependency detection and prevention","description":"Implement robust detection, prevention, and user guidance for circular dependencies that cross edge types. Current system only prevents cycles within \"blocks\" type dependencies, allowing cross-type cycles (e.g., A blocks B, B parent-child A) that can hide work from ready list and confuse dependency visualization.","design":"Analysis shows that cycle prevention is type-specific (blocks only) while detection is type-agnostic. All current operations are safe from infinite loops (depth-limited), but semantic confusion and future maintenance hazards exist. Need validation, warnings, and potentially full cross-type prevention.","acceptance_criteria":"- Cross-type cycles are prevented or warned about\n- Semantic validation prevents child→parent dependencies\n- Users receive clear diagnostic messages\n- Documentation explains cycle handling behavior\n- All existing safe operations remain protected","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T17:49:54.335978-07:00","updated_at":"2025-10-16T18:12:45.648501-07:00","closed_at":"2025-10-16T17:49:54.335978-07:00"} -{"id":"bd-308","title":"parallel_test_7","description":"","design":"Add validation in AddDependency that checks if dep.Type == DepParentChild and validates the direction is correct (parent depends on child, not child on parent). Reject with clear error message if direction is backwards.","acceptance_criteria":"- Child→parent dependencies are rejected with clear error\n- Parent→child dependencies work as expected\n- Error message explains correct direction\n- Tests cover both valid and invalid cases","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.340717-07:00","updated_at":"2025-10-16T18:12:45.648934-07:00","closed_at":"2025-10-16T17:49:54.340717-07:00","dependencies":[{"issue_id":"bd-308","depends_on_id":"bd-307","type":"parent-child","created_at":"2025-10-16T17:49:54.853652-07:00","created_by":"auto-import"}]} +{"id":"bd-307","title":"Fix circular dependency detection and prevention","description":"Implement robust detection, prevention, and user guidance for circular dependencies that cross edge types. Current system only prevents cycles within \"blocks\" type dependencies, allowing cross-type cycles (e.g., A blocks B, B parent-child A) that can hide work from ready list and confuse dependency visualization.","design":"Analysis shows that cycle prevention is type-specific (blocks only) while detection is type-agnostic. All current operations are safe from infinite loops (depth-limited), but semantic confusion and future maintenance hazards exist. Need validation, warnings, and potentially full cross-type prevention.","acceptance_criteria":"- Cross-type cycles are prevented or warned about\n- Semantic validation prevents child→parent dependencies\n- Users receive clear diagnostic messages\n- Documentation explains cycle handling behavior\n- All existing safe operations remain protected","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T10:27:48.21284-07:00","updated_at":"2025-10-16T14:33:21.350483-07:00","closed_at":"2025-10-16T13:32:31.150118-07:00"} +{"id":"bd-308","title":"Add semantic validation for parent-child dependency direction","description":"Prevent backwards parent-child dependencies where child tasks depend on their parent epics. This is semantically incorrect - parents should depend on children completing, not the reverse.","design":"Add validation in AddDependency that checks if dep.Type == DepParentChild and validates the direction is correct (parent depends on child, not child on parent). Reject with clear error message if direction is backwards.","acceptance_criteria":"- Child→parent dependencies are rejected with clear error\n- Parent→child dependencies work as expected\n- Error message explains correct direction\n- Tests cover both valid and invalid cases","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T10:28:24.205615-07:00","updated_at":"2025-10-16T14:33:21.35101-07:00","closed_at":"2025-10-16T13:04:55.724216-07:00","dependencies":[{"issue_id":"bd-308","depends_on_id":"bd-307","type":"parent-child","created_at":"2025-10-16T18:57:16.972828-07:00","created_by":"auto-import"}]} {"id":"bd-309","title":"Add diagnostic warnings when cycles are detected after dep add","description":"Run DetectCycles() after adding dependencies and warn users if cycles exist. Provide clear, actionable messages about which issues form the cycle and potential impact on ready work visibility.","design":"In bd dep add command, after successful dependency addition, call DetectCycles(). If cycles found, print warning to stderr showing cycle path and explanation. Include suggestion to run 'bd dep cycles' for full analysis.","acceptance_criteria":"- Warnings appear after dep add when cycles exist\n- Warning shows cycle path clearly\n- Explains impact on ready work calculation\n- Suggests next steps for user\n- Does not block operation (warning only)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.358617-07:00","updated_at":"2025-10-16T18:12:45.64937-07:00","closed_at":"2025-10-16T17:49:54.358617-07:00","dependencies":[{"issue_id":"bd-309","depends_on_id":"bd-307","type":"parent-child","created_at":"2025-10-16T17:49:54.854436-07:00","created_by":"auto-import"}]} {"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-16T17:49:54.369008-07:00","updated_at":"2025-10-16T18:12:45.649904-07:00","closed_at":"2025-10-16T17:49:54.369008-07:00"} {"id":"bd-310","title":"Document cycle handling behavior and limitations","description":"Add comprehensive documentation explaining which dependency types are checked for cycles, why cross-type cycles matter, what operations are safe, and how users should think about dependency design.","design":"Add comments to AddDependency explaining cycle checking logic. Update README.md with section on cycles. Add to DESIGN.md explaining technical decisions. Include examples of problematic and correct dependency patterns.","acceptance_criteria":"- Code comments explain cycle checking\n- README has user-facing cycle guidance\n- DESIGN.md has technical rationale\n- Examples show good and bad patterns\n- Explains ready work implications","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.369479-07:00","updated_at":"2025-10-16T18:12:45.650374-07:00","closed_at":"2025-10-16T17:49:54.369479-07:00","dependencies":[{"issue_id":"bd-310","depends_on_id":"bd-307","type":"parent-child","created_at":"2025-10-16T17:49:54.854881-07:00","created_by":"auto-import"}]} @@ -239,153 +239,397 @@ {"id":"bd-314","title":"Test issue B","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.37829-07:00","updated_at":"2025-10-16T18:12:45.652502-07:00","closed_at":"2025-10-16T17:49:54.37829-07:00"} {"id":"bd-315","title":"Test issue C","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.382025-07:00","updated_at":"2025-10-16T18:12:45.652948-07:00","closed_at":"2025-10-16T17:49:54.382025-07:00"} {"id":"bd-316","title":"Test issue A","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.393439-07:00","updated_at":"2025-10-16T18:12:45.653416-07:00","closed_at":"2025-10-16T17:49:54.393439-07:00"} -{"id":"bd-317","title":"final_review_test_","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.394198-07:00","updated_at":"2025-10-16T18:12:45.65402-07:00"} -{"id":"bd-318","title":"race_test_3","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.394626-07:00","updated_at":"2025-10-16T18:12:45.65443-07:00"} -{"id":"bd-319","title":"parallel_test_8","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.396287-07:00","updated_at":"2025-10-16T18:12:45.672123-07:00"} +{"id":"bd-317","title":"final_review_test_","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.617035-07:00","updated_at":"2025-10-16T19:08:49.266284-07:00","closed_at":"2025-10-16T19:08:49.266284-07:00"} +{"id":"bd-318","title":"race_test_3","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.62383-07:00","updated_at":"2025-10-16T19:08:49.234273-07:00","closed_at":"2025-10-16T19:08:49.234273-07:00"} +{"id":"bd-319","title":"parallel_test_8","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.630725-07:00","updated_at":"2025-10-16T19:08:49.214964-07:00","closed_at":"2025-10-16T19:08:49.214964-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-16T17:49:54.398438-07:00","updated_at":"2025-10-16T18:12:45.677729-07:00","closed_at":"2025-10-16T17:49:54.398438-07:00"} -{"id":"bd-320","title":"parallel_test_9","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.401954-07:00","updated_at":"2025-10-16T18:12:45.678175-07:00"} +{"id":"bd-320","title":"parallel_test_9","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.631628-07:00","updated_at":"2025-10-16T19:08:49.181522-07:00","closed_at":"2025-10-16T19:08:49.181522-07:00"} {"id":"bd-321","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-16T17:49:54.402877-07:00","updated_at":"2025-10-16T18:12:45.678629-07:00"} -{"id":"bd-322","title":"race_test_4","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.404199-07:00","updated_at":"2025-10-16T18:12:45.679089-07:00"} -{"id":"bd-323","title":"race_test_8","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.406-07:00","updated_at":"2025-10-16T18:12:45.67962-07:00"} -{"id":"bd-324","title":"race_test_5","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.410905-07:00","updated_at":"2025-10-16T18:12:45.680198-07:00"} -{"id":"bd-325","title":"parallel_test_2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.412382-07:00","updated_at":"2025-10-16T18:12:45.680753-07:00","closed_at":"2025-10-16T17:49:54.412382-07:00"} -{"id":"bd-326","title":"race_test_17","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.41513-07:00","updated_at":"2025-10-16T18:12:45.681249-07:00"} -{"id":"bd-327","title":"race_test_10","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.420314-07:00","updated_at":"2025-10-16T18:12:45.681693-07:00"} -{"id":"bd-328","title":"race_test_11","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.427444-07:00","updated_at":"2025-10-16T18:12:45.682153-07:00"} -{"id":"bd-329","title":"race_test_17","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.433397-07:00","updated_at":"2025-10-16T18:12:45.682645-07:00"} +{"id":"bd-322","title":"race_test_4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.635357-07:00","updated_at":"2025-10-16T19:08:49.163558-07:00","closed_at":"2025-10-16T19:08:49.163558-07:00"} +{"id":"bd-323","title":"race_test_8","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.636432-07:00","updated_at":"2025-10-16T19:08:49.14146-07:00","closed_at":"2025-10-16T19:08:49.14146-07:00"} +{"id":"bd-324","title":"race_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.637257-07:00","updated_at":"2025-10-16T19:08:49.079356-07:00","closed_at":"2025-10-16T19:08:49.079356-07:00"} +{"id":"bd-325","title":"race_test_16","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.643077-07:00","updated_at":"2025-10-16T19:08:49.032961-07:00","closed_at":"2025-10-16T19:08:49.032961-07:00"} +{"id":"bd-326","title":"race_test_17","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.645291-07:00","updated_at":"2025-10-16T19:08:48.939085-07:00","closed_at":"2025-10-16T19:08:48.939085-07:00"} +{"id":"bd-327","title":"race_test_10","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.660524-07:00","updated_at":"2025-10-16T19:08:48.872978-07:00","closed_at":"2025-10-16T19:08:48.872978-07:00"} +{"id":"bd-328","title":"race_test_11","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.662708-07:00","updated_at":"2025-10-16T19:08:48.815113-07:00","closed_at":"2025-10-16T19:08:48.815113-07:00"} +{"id":"bd-329","title":"race_test_17","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.663415-07:00","updated_at":"2025-10-16T19:08:48.716639-07:00","closed_at":"2025-10-16T19:08:48.716639-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-16T17:49:54.433792-07:00","updated_at":"2025-10-16T18:12:45.683156-07:00","closed_at":"2025-10-16T17:49:54.433792-07:00"} -{"id":"bd-330","title":"final_test_7","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.440646-07:00","updated_at":"2025-10-16T18:12:45.683668-07:00"} -{"id":"bd-331","title":"stress_test_5","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.441218-07:00","updated_at":"2025-10-16T18:12:45.684061-07:00"} -{"id":"bd-332","title":"stress_test_6","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.441615-07:00","updated_at":"2025-10-16T18:12:45.684546-07:00"} -{"id":"bd-333","title":"stress_test_1","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.442055-07:00","updated_at":"2025-10-16T18:12:45.685214-07:00"} +{"id":"bd-330","title":"final_test_7","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.665684-07:00","updated_at":"2025-10-16T19:08:48.681834-07:00","closed_at":"2025-10-16T19:08:48.681834-07:00"} +{"id":"bd-331","title":"stress_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.668149-07:00","updated_at":"2025-10-16T19:08:48.626148-07:00","closed_at":"2025-10-16T19:08:48.626148-07:00"} +{"id":"bd-332","title":"stress_test_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.680992-07:00","updated_at":"2025-10-16T19:08:48.529144-07:00","closed_at":"2025-10-16T19:08:48.529144-07:00"} +{"id":"bd-333","title":"stress_test_1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.682146-07:00","updated_at":"2025-10-16T19:08:48.41216-07:00","closed_at":"2025-10-16T19:08:48.41216-07:00"} {"id":"bd-334","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-16T17:49:54.443195-07:00","updated_at":"2025-10-16T18:12:45.685677-07:00"} -{"id":"bd-335","title":"parallel_test_10","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.443928-07:00","updated_at":"2025-10-16T18:12:45.686308-07:00"} -{"id":"bd-336","title":"race_test_5","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.446554-07:00","updated_at":"2025-10-16T18:12:45.686773-07:00"} -{"id":"bd-337","title":"race_test_2","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.447204-07:00","updated_at":"2025-10-16T18:12:45.687218-07:00"} -{"id":"bd-338","title":"race_test_7","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.450452-07:00","updated_at":"2025-10-16T18:12:45.687714-07:00"} -{"id":"bd-339","title":"race_test_14","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.45608-07:00","updated_at":"2025-10-16T18:12:45.688967-07:00"} +{"id":"bd-335","title":"parallel_test_10","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.689034-07:00","updated_at":"2025-10-16T19:08:48.366211-07:00","closed_at":"2025-10-16T19:08:48.366211-07:00"} +{"id":"bd-336","title":"race_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.697455-07:00","updated_at":"2025-10-16T19:08:48.32484-07:00","closed_at":"2025-10-16T19:08:48.32484-07:00"} +{"id":"bd-337","title":"race_test_2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.700706-07:00","updated_at":"2025-10-16T19:08:48.245871-07:00","closed_at":"2025-10-16T19:08:48.245871-07:00"} +{"id":"bd-338","title":"race_test_7","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.7088-07:00","updated_at":"2025-10-16T19:08:48.177382-07:00","closed_at":"2025-10-16T19:08:48.177382-07:00"} +{"id":"bd-339","title":"race_test_14","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.715948-07:00","updated_at":"2025-10-16T19:08:48.142467-07:00","closed_at":"2025-10-16T19:08:48.142467-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-16T17:49:54.459088-07:00","updated_at":"2025-10-16T18:12:45.689531-07:00","closed_at":"2025-10-16T17:49:54.459088-07:00"} -{"id":"bd-340","title":"race_test_9","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.461665-07:00","updated_at":"2025-10-16T18:12:45.695832-07:00"} -{"id":"bd-341","title":"race_test_8","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.463213-07:00","updated_at":"2025-10-16T18:12:45.696271-07:00"} -{"id":"bd-342","title":"race_test_11","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.463679-07:00","updated_at":"2025-10-16T18:12:45.69754-07:00"} -{"id":"bd-343","title":"race_test_19","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.464061-07:00","updated_at":"2025-10-16T18:12:45.698775-07:00"} -{"id":"bd-344","title":"race_test_16","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.465152-07:00","updated_at":"2025-10-16T18:12:45.699567-07:00"} -{"id":"bd-345","title":"race_test_18","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.467133-07:00","updated_at":"2025-10-16T18:12:45.70023-07:00"} -{"id":"bd-346","title":"parallel_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.467576-07:00","updated_at":"2025-10-16T18:12:45.701041-07:00","closed_at":"2025-10-16T17:49:54.467576-07:00"} -{"id":"bd-347","title":"parallel_test_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.468584-07:00","updated_at":"2025-10-16T18:12:45.701537-07:00","closed_at":"2025-10-16T17:49:54.468584-07:00"} -{"id":"bd-348","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-16T17:49:54.469067-07:00","updated_at":"2025-10-16T18:12:45.701982-07:00","external_ref":"gh-3"} -{"id":"bd-349","title":"parallel_test_4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.469639-07:00","updated_at":"2025-10-16T18:12:45.702945-07:00","closed_at":"2025-10-16T17:49:54.469639-07:00"} +{"id":"bd-340","title":"race_test_9","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.716781-07:00","updated_at":"2025-10-16T19:08:48.090436-07:00","closed_at":"2025-10-16T19:08:48.090436-07:00"} +{"id":"bd-341","title":"race_test_8","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.719466-07:00","updated_at":"2025-10-16T19:08:48.02026-07:00","closed_at":"2025-10-16T19:08:48.02026-07:00"} +{"id":"bd-342","title":"race_test_11","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.720418-07:00","updated_at":"2025-10-16T19:08:47.937692-07:00","closed_at":"2025-10-16T19:08:47.937692-07:00"} +{"id":"bd-343","title":"race_test_19","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.727492-07:00","updated_at":"2025-10-16T19:08:47.871344-07:00","closed_at":"2025-10-16T19:08:47.871344-07:00"} +{"id":"bd-344","title":"race_test_16","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.732302-07:00","updated_at":"2025-10-16T19:08:47.821007-07:00","closed_at":"2025-10-16T19:08:47.821007-07:00"} +{"id":"bd-345","title":"race_test_18","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.742594-07:00","updated_at":"2025-10-16T19:08:47.715714-07:00","closed_at":"2025-10-16T19:08:47.715714-07:00"} +{"id":"bd-346","title":"race_test_20","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.744437-07:00","updated_at":"2025-10-16T19:08:47.5967-07:00","closed_at":"2025-10-16T19:08:47.5967-07:00"} +{"id":"bd-347","title":"race_test_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.745496-07:00","updated_at":"2025-10-16T19:08:47.536347-07:00","closed_at":"2025-10-16T19:08:47.536347-07:00"} +{"id":"bd-348","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":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T14:57:48.746521-07:00","updated_at":"2025-10-16T19:08:31.772327-07:00","closed_at":"2025-10-16T19:08:31.772327-07:00","external_ref":"gh-3"} +{"id":"bd-349","title":"race_test_12","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.747288-07:00","updated_at":"2025-10-16T19:08:47.491751-07:00","closed_at":"2025-10-16T19:08:47.491751-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-16T17:49:54.470553-07:00","updated_at":"2025-10-16T18:12:45.703382-07:00","closed_at":"2025-10-16T17:49:54.470553-07:00"} -{"id":"bd-350","title":"parallel_test_1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.471168-07:00","updated_at":"2025-10-16T18:12:45.703834-07:00","closed_at":"2025-10-16T17:49:54.471168-07:00"} -{"id":"bd-351","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":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T17:49:54.471547-07:00","updated_at":"2025-10-16T18:12:45.704295-07:00","closed_at":"2025-10-16T17:49:54.471547-07:00","external_ref":"gh-11"} -{"id":"bd-352","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.","notes":"Awaiting user feedback - cannot reproduce locally, waiting for user to provide more details about environment and error message","status":"blocked","priority":1,"issue_type":"bug","created_at":"2025-10-16T17:49:54.471953-07:00","updated_at":"2025-10-16T18:12:45.704754-07:00","external_ref":"gh-3"} -{"id":"bd-353","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":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T17:49:54.472336-07:00","updated_at":"2025-10-16T18:12:45.705242-07:00","closed_at":"2025-10-16T17:49:54.472336-07:00"} -{"id":"bd-354","title":"parallel_test_3","description":"","design":"Review GH-11 requirements:\n- User wants to use beads across multiple dev machines\n- Docker hosting was proposed solution\n\nNew approach:\n- Phase 1: Pure git-based sync (no Docker needed)\n- Phase 2: Optional Docker gateway for convenience\n- Addresses use case without mandating server\n\nUpdate GH-11 with:\n- Link to DESIGN-GIT-SYNC.md\n- Explain git-based approach\n- Note optional Docker gateway\n- Ask for feedback\n\nClose issue when sync features implemented.","acceptance_criteria":"- GH-11 reviewed and understood\n- Comment added explaining sync approach\n- Link to design document\n- User feedback requested\n- Issue closed when Phase 1-2 complete\n- Documentation cross-referenced","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.473506-07:00","updated_at":"2025-10-16T18:12:45.705795-07:00"} -{"id":"bd-355","title":"parallel_test_2","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.475541-07:00","updated_at":"2025-10-16T18:12:45.706368-07:00"} -{"id":"bd-356","title":"parallel_test_5","description":"","acceptance_criteria":"Can add/remove/list labels via CLI, can filter issues by label, labels persist to JSONL","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.478904-07:00","updated_at":"2025-10-16T18:12:45.706789-07:00"} -{"id":"bd-357","title":"Add performance benchmarks document","description":"Document actual performance metrics with hyperfine tests","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-16T17:49:54.480313-07:00","updated_at":"2025-10-16T18:12:45.707188-07:00","closed_at":"2025-10-16T17:49:54.480313-07:00","dependencies":[{"issue_id":"bd-357","depends_on_id":"bd-375","type":"parent-child","created_at":"2025-10-16T17:49:54.855779-07:00","created_by":"auto-import"}]} +{"id":"bd-350","title":"race_test_15","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.748148-07:00","updated_at":"2025-10-16T19:08:47.421242-07:00","closed_at":"2025-10-16T19:08:47.421242-07:00"} +{"id":"bd-351","title":"race_test_13","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.748767-07:00","updated_at":"2025-10-16T19:08:47.340559-07:00","closed_at":"2025-10-16T19:08:47.340559-07:00"} +{"id":"bd-352","title":"race_test_10","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.749464-07:00","updated_at":"2025-10-16T19:08:47.283951-07:00","closed_at":"2025-10-16T19:08:47.283951-07:00"} +{"id":"bd-353","title":"final_test_10","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.750486-07:00","updated_at":"2025-10-16T19:08:47.215039-07:00","closed_at":"2025-10-16T19:08:47.215039-07:00"} +{"id":"bd-354","title":"parallel_test_3","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.751322-07:00","updated_at":"2025-10-16T19:08:47.182577-07:00","closed_at":"2025-10-16T19:08:47.182577-07:00"} +{"id":"bd-355","title":"parallel_test_2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.752315-07:00","updated_at":"2025-10-16T19:08:47.109134-07:00","closed_at":"2025-10-16T19:08:47.109134-07:00"} +{"id":"bd-356","title":"parallel_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.753003-07:00","updated_at":"2025-10-16T19:08:46.996393-07:00","closed_at":"2025-10-16T19:08:46.996393-07:00"} +{"id":"bd-357","title":"parallel_test_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.754125-07:00","updated_at":"2025-10-16T19:08:46.949833-07:00","closed_at":"2025-10-16T19:08:46.949833-07:00","dependencies":[{"issue_id":"bd-357","depends_on_id":"bd-375","type":"parent-child","created_at":"2025-10-16T18:57:16.973776-07:00","created_by":"auto-import"}]} {"id":"bd-358","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-16T17:49:54.483624-07:00","updated_at":"2025-10-16T18:12:45.707718-07:00","external_ref":"gh-11"} -{"id":"bd-359","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.","design":"Federation allows:\n- Multiple gateways sync with each other\n- Each gateway has authoritative set of issues\n- Peer-to-peer sync protocol\n- Conflict resolution across gateways\n\nArchitecture:\n- Gateway-to-gateway API\n- Peer discovery\n- Sync protocol between gateways\n- Distributed conflict resolution\n\nComplex feature - only if team usage emerges.","acceptance_criteria":"- Gateway federation protocol designed\n- Peer discovery mechanism\n- Gateway-to-gateway sync\n- Distributed conflict resolution\n- Tests for federation\n- Documentation in FEDERATION.md\n\n---","status":"open","priority":3,"issue_type":"bug","created_at":"2025-10-16T17:49:54.485716-07:00","updated_at":"2025-10-16T18:12:45.708178-07:00","dependencies":[{"issue_id":"bd-359","depends_on_id":"bd-377","type":"parent-child","created_at":"2025-10-16T17:49:54.856226-07:00","created_by":"auto-import"}]} +{"id":"bd-359","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-16T14:57:48.756031-07:00","updated_at":"2025-10-16T14:57:48.756031-07:00","dependencies":[{"issue_id":"bd-359","depends_on_id":"bd-377","type":"parent-child","created_at":"2025-10-16T18:57:16.974515-07:00","created_by":"auto-import"}]} {"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-16T17:49:54.486468-07:00","updated_at":"2025-10-16T18:12:45.708825-07:00","closed_at":"2025-10-16T17:49:54.486468-07:00"} -{"id":"bd-360","title":"parallel_test_7","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.48689-07:00","updated_at":"2025-10-16T18:12:45.709251-07:00"} -{"id":"bd-361","title":"parallel_test_1","description":"","design":"Add new section: \"Multi-Device Sync\"\n\nContent:\n- Brief overview of git-based sync\n- Link to SYNC.md for details\n- Link to GATEWAY.md for gateway mode\n- Quick start examples\n- Configuration options\n\nKeep brief - detailed docs in separate files.","acceptance_criteria":"- README.md updated with sync section\n- Links to SYNC.md and GATEWAY.md\n- Quick start examples\n- Configuration overview\n- Maintains existing structure\n- All links working\n\n---","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.487295-07:00","updated_at":"2025-10-16T18:12:45.709673-07:00","dependencies":[{"issue_id":"bd-361","depends_on_id":"bd-377","type":"parent-child","created_at":"2025-10-16T17:49:54.856898-07:00","created_by":"auto-import"}]} -{"id":"bd-362","title":"verification_","description":"","design":"Sections:\n1. Introduction\n2. Quick Start\n3. Manual Git Workflow\n4. bd sync Command\n5. bd daemon Background Sync\n6. Git Hooks\n7. Conflict Resolution\n8. Best Practices\n9. Troubleshooting\n10. FAQ\n\nInclude examples, code snippets, and diagrams.","acceptance_criteria":"- SYNC.md created with all sections\n- Quick start guide for new users\n- Detailed workflow examples\n- Conflict resolution guide\n- Best practices section\n- Troubleshooting with solutions\n- FAQ with common questions\n- Code examples working\n- Links from README.md\n\n---","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.487697-07:00","updated_at":"2025-10-16T18:12:45.71008-07:00","dependencies":[{"issue_id":"bd-362","depends_on_id":"bd-377","type":"parent-child","created_at":"2025-10-16T17:49:54.857386-07:00","created_by":"auto-import"}]} -{"id":"bd-363","title":"parallel_test_4","description":"","design":"Sections:\n1. Introduction\n2. Authentication\n3. REST Endpoints\n4. WebSocket Protocol\n5. Error Handling\n6. Rate Limits\n7. Examples\n\nFor each endpoint:\n- URL and method\n- Request parameters\n- Request body schema\n- Response schema\n- Error responses\n- Code example","acceptance_criteria":"- API.md created with all sections\n- All endpoints documented\n- Request/response schemas\n- WebSocket protocol docs\n- Error codes and handling\n- Rate limit documentation\n- Examples in multiple languages\n- Links from README.md\n\n---","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.488106-07:00","updated_at":"2025-10-16T18:12:45.710601-07:00","dependencies":[{"issue_id":"bd-363","depends_on_id":"bd-377","type":"parent-child","created_at":"2025-10-16T17:49:54.857844-07:00","created_by":"auto-import"}]} -{"id":"bd-364","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-16T17:49:54.488682-07:00","updated_at":"2025-10-16T18:12:45.711055-07:00","dependencies":[{"issue_id":"bd-364","depends_on_id":"bd-372","type":"blocks","created_at":"2025-10-16T17:49:54.858304-07:00","created_by":"auto-import"}]} -{"id":"bd-365","title":"Low priority chore","description":"","status":"closed","priority":4,"issue_type":"chore","created_at":"2025-10-16T17:49:54.489847-07:00","updated_at":"2025-10-16T18:12:45.711486-07:00","closed_at":"2025-10-16T17:49:54.489847-07:00","dependencies":[{"issue_id":"bd-365","depends_on_id":"bd-375","type":"parent-child","created_at":"2025-10-16T17:49:54.859054-07:00","created_by":"auto-import"},{"issue_id":"bd-365","depends_on_id":"bd-382","type":"blocks","created_at":"2025-10-16T17:49:54.859485-07:00","created_by":"auto-import"}]} -{"id":"bd-366","title":"Add migration scripts for GitHub Issues","description":"Create scripts to import from GitHub Issues API or exported JSON","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T17:49:54.490276-07:00","updated_at":"2025-10-16T18:12:45.711995-07:00","closed_at":"2025-10-16T17:49:54.490276-07:00","dependencies":[{"issue_id":"bd-366","depends_on_id":"bd-375","type":"parent-child","created_at":"2025-10-16T17:49:54.860063-07:00","created_by":"auto-import"},{"issue_id":"bd-366","depends_on_id":"bd-367","type":"parent-child","created_at":"2025-10-16T17:49:54.860537-07:00","created_by":"auto-import"}]} -{"id":"bd-367","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-16T17:49:54.49132-07:00","updated_at":"2025-10-16T18:12:45.712629-07:00"} -{"id":"bd-368","title":"parallel_test_9","description":"","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":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.491748-07:00","updated_at":"2025-10-16T18:12:45.713105-07:00","closed_at":"2025-10-16T17:49:54.491748-07:00","dependencies":[{"issue_id":"bd-368","depends_on_id":"bd-373","type":"discovered-from","created_at":"2025-10-16T17:49:54.860994-07:00","created_by":"auto-import"}]} -{"id":"bd-369","title":"race_test_4","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.492142-07:00","updated_at":"2025-10-16T18:12:45.713553-07:00"} +{"id":"bd-360","title":"parallel_test_7","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.75773-07:00","updated_at":"2025-10-16T19:08:46.847176-07:00","closed_at":"2025-10-16T19:08:46.847176-07:00"} +{"id":"bd-361","title":"parallel_test_1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.761649-07:00","updated_at":"2025-10-16T19:08:46.773427-07:00","closed_at":"2025-10-16T19:08:46.773427-07:00","dependencies":[{"issue_id":"bd-361","depends_on_id":"bd-377","type":"parent-child","created_at":"2025-10-16T18:57:16.976034-07:00","created_by":"auto-import"}]} +{"id":"bd-362","title":"verification_","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.765482-07:00","updated_at":"2025-10-16T19:08:46.735799-07:00","closed_at":"2025-10-16T19:08:46.735799-07:00","dependencies":[{"issue_id":"bd-362","depends_on_id":"bd-377","type":"parent-child","created_at":"2025-10-16T18:57:16.977145-07:00","created_by":"auto-import"}]} +{"id":"bd-363","title":"parallel_test_4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.770023-07:00","updated_at":"2025-10-16T19:08:46.690735-07:00","closed_at":"2025-10-16T19:08:46.690735-07:00","dependencies":[{"issue_id":"bd-363","depends_on_id":"bd-377","type":"parent-child","created_at":"2025-10-16T18:57:16.977887-07:00","created_by":"auto-import"}]} +{"id":"bd-364","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-16T14:57:48.773386-07:00","updated_at":"2025-10-16T14:57:48.773386-07:00","dependencies":[{"issue_id":"bd-364","depends_on_id":"bd-658","type":"blocks","created_at":"2025-10-16T18:57:16.882878-07:00","created_by":"import-remap"},{"issue_id":"bd-364","depends_on_id":"bd-372","type":"blocks","created_at":"2025-10-16T18:57:16.97843-07:00","created_by":"auto-import"}]} +{"id":"bd-365","title":"final_test_10","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.77507-07:00","updated_at":"2025-10-16T14:57:48.77507-07:00","closed_at":"2025-10-15T16:26:05.243566-07:00","dependencies":[{"issue_id":"bd-365","depends_on_id":"bd-375","type":"parent-child","created_at":"2025-10-16T18:57:16.979085-07:00","created_by":"auto-import"},{"issue_id":"bd-365","depends_on_id":"bd-382","type":"blocks","created_at":"2025-10-16T18:57:16.979601-07:00","created_by":"auto-import"}]} +{"id":"bd-366","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-16T14:57:48.776118-07:00","updated_at":"2025-10-16T14:57:48.776118-07:00","dependencies":[{"issue_id":"bd-366","depends_on_id":"bd-375","type":"parent-child","created_at":"2025-10-16T18:57:16.980104-07:00","created_by":"auto-import"},{"issue_id":"bd-366","depends_on_id":"bd-367","type":"parent-child","created_at":"2025-10-16T18:57:16.980607-07:00","created_by":"auto-import"}]} +{"id":"bd-367","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-16T14:57:48.77756-07:00","updated_at":"2025-10-16T14:57:48.77756-07:00"} +{"id":"bd-368","title":"parallel_test_9","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.780354-07:00","updated_at":"2025-10-16T14:57:48.780354-07:00","closed_at":"2025-10-15T16:26:05.42663-07:00","dependencies":[{"issue_id":"bd-368","depends_on_id":"bd-373","type":"discovered-from","created_at":"2025-10-16T18:57:16.981611-07:00","created_by":"auto-import"}]} +{"id":"bd-369","title":"race_test_4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.781563-07:00","updated_at":"2025-10-16T19:08:46.653781-07:00","closed_at":"2025-10-16T19:08:46.653781-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-16T17:49:54.492548-07:00","updated_at":"2025-10-16T18:12:45.714157-07:00"} -{"id":"bd-370","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-16T17:49:54.493004-07:00","updated_at":"2025-10-16T18:12:45.714607-07:00","dependencies":[{"issue_id":"bd-370","depends_on_id":"bd-369","type":"parent-child","created_at":"2025-10-16T17:49:54.861493-07:00","created_by":"auto-import"},{"issue_id":"bd-370","depends_on_id":"bd-388","type":"parent-child","created_at":"2025-10-16T17:49:54.861929-07:00","created_by":"auto-import"}]} -{"id":"bd-371","title":"Consider batching API for bulk issue creation (recovered from bd-222)","description":"Current CreateIssue acquires a dedicated connection for each call. For bulk imports or agent workflows creating many issues, a batched API could improve performance:\n\nCreateIssues(ctx, issues []*Issue, actor string) error\n\nThis would:\n- Acquire one connection\n- Use one IMMEDIATE transaction\n- Insert all issues atomically\n- Reduce connection overhead\n\nNot urgent - current approach is correct and fast enough for typical use.\n\n**Recovered from:** bd-390 (lost in auto-import bug, see LOST_ISSUES_RECOVERY.md)","notes":"Investigation complete. Successfully recovered 3 valuable issues (bd-371, bd-233) from 22 total lost. Historical context preserved in bd-89 notes. Auto-import collision detection (bd-228) now prevents future data loss.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-16T17:49:54.493561-07:00","updated_at":"2025-10-16T18:12:45.715064-07:00","dependencies":[{"issue_id":"bd-371","depends_on_id":"bd-376","type":"discovered-from","created_at":"2025-10-16T17:49:54.862343-07:00","created_by":"auto-import"}]} -{"id":"bd-372","title":"Add integration tests for auto-import collision detection","description":"The auto-import collision detection fix (bd-228) needs comprehensive integration tests.\n\n## Test Scenarios Needed\n\n### 1. Basic Collision Detection\n```go\nTestAutoImportWithCollisions\n- Setup: Create issue in DB with status=closed\n- Simulate: Git pull with JSONL containing same issue with status=open\n- Verify: Local changes preserved, warning printed, issue still closed\n```\n\n### 2. Multiple Collisions\n```go\nTestAutoImportWithMultipleCollisions\n- Setup: 5 issues with local modifications\n- Simulate: JSONL with 3 colliding, 2 matching\n- Verify: 3 skipped, 2 updated, appropriate warnings\n```\n\n### 3. No Collisions (Happy Path)\n```go\nTestAutoImportWithoutCollisions\n- Setup: Clean database\n- Simulate: JSONL with new issues + exact matches\n- Verify: All imported successfully, no warnings\n```\n\n### 4. All Collisions\n```go\nTestAutoImportAllCollisions\n- Setup: Every issue has local modifications\n- Simulate: JSONL with conflicting versions\n- Verify: All skipped, warning lists all issues\n```\n\n### 5. Collision Detection Failure\n```go\nTestAutoImportCollisionDetectionError\n- Setup: Mock DetectCollisions() to return error\n- Verify: Import skipped entirely (safe failure mode)\n```\n\n### 6. Hash-Based Skip\n```go\nTestAutoImportHashUnchanged\n- Setup: JSONL hash matches last_import_hash\n- Verify: No collision detection runs, fast path\n```\n\n### 7. Fallback for Non-SQLite\n```go\nTestAutoImportWithoutCollisionDetection\n- Setup: Mock non-SQLite storage backend\n- Verify: Falls back to old behavior, no collision detection\n```\n\n## Test Infrastructure Needed\n\n1. **Helper functions:**\n - createTestDBWithIssues()\n - writeJSONLFile()\n - captureStderrWarnings()\n - simulateGitPull()\n\n2. **Fixtures:**\n - sample-collisions.jsonl\n - sample-exact-matches.jsonl\n - sample-mixed.jsonl\n\n3. **Assertions:**\n - assertIssueState(id, expectedStatus)\n - assertWarningContains(text)\n - assertCollisionCount(n)\n\n## Acceptance Criteria\n- All 7 test scenarios implemented\n- Tests pass consistently\n- Code coverage \u003e80% for autoImportIfNewer()\n- Tests run in \u003c5 seconds total\n- Clear test names and documentation","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.493968-07:00","updated_at":"2025-10-16T18:12:45.715535-07:00","dependencies":[{"issue_id":"bd-372","depends_on_id":"bd-376","type":"discovered-from","created_at":"2025-10-16T17:49:54.862791-07:00","created_by":"auto-import"},{"issue_id":"bd-372","depends_on_id":"bd-379","type":"blocks","created_at":"2025-10-16T17:49:54.863239-07:00","created_by":"auto-import"}]} -{"id":"bd-373","title":"Concurrent bd commands collide on shared .tmp filename","description":"When multiple bd commands run concurrently (e.g., different agents), they all write to .beads/issues.jsonl.tmp causing race conditions. One command's rename succeeds, consuming the .tmp file, then other commands fail with 'no such file or directory'. Solution: use unique temp filenames with PID or random suffix (e.g., issues.jsonl.tmp.12345).","notes":"Label management fully implemented with comprehensive test coverage (10 test cases). Provides foundation for better data organization and filtering.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T17:49:54.496208-07:00","updated_at":"2025-10-16T18:12:45.716207-07:00","closed_at":"2025-10-16T17:49:54.496208-07:00"} -{"id":"bd-374","title":"Benchmark cycle detection performance on large dependency graphs","description":"Measure performance impact of cross-type cycle checking on large graphs (1000+ issues). Determine if optimization needed before enabling full prevention. Test various graph structures (sparse, dense, deeply nested).","design":"Create benchmark test with synthetic dependency graphs of varying sizes and structures. Measure AddDependency performance with type-specific vs all-types cycle checking. Document findings and optimization recommendations if needed.","acceptance_criteria":"- Benchmark test covers 100, 1000, 5000 issue graphs\n- Tests sparse and dense dependency patterns\n- Measures time for both checking approaches\n- Documents results in comments or DESIGN.md\n- Recommends optimization if \u003e100ms impact found","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.500873-07:00","updated_at":"2025-10-16T18:12:45.716684-07:00","dependencies":[{"issue_id":"bd-374","depends_on_id":"bd-377","type":"parent-child","created_at":"2025-10-16T17:49:54.863725-07:00","created_by":"auto-import"},{"issue_id":"bd-374","depends_on_id":"bd-307","type":"parent-child","created_at":"2025-10-16T17:49:54.864406-07:00","created_by":"auto-import"}]} -{"id":"bd-375","title":"Reach 1.0 release milestone","description":"Stabilize API, finalize documentation, comprehensive testing","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T17:49:54.505862-07:00","updated_at":"2025-10-16T18:12:45.717116-07:00","closed_at":"2025-10-16T17:49:54.505862-07:00","dependencies":[{"issue_id":"bd-375","depends_on_id":"bd-270","type":"discovered-from","created_at":"2025-10-16T17:49:54.864903-07:00","created_by":"auto-import"}]} -{"id":"bd-376","title":"Add performance benchmarks document","description":"Document actual performance metrics with hyperfine tests","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-16T17:49:54.507263-07:00","updated_at":"2025-10-16T18:12:45.717615-07:00","dependencies":[{"issue_id":"bd-376","depends_on_id":"bd-388","type":"parent-child","created_at":"2025-10-16T17:49:54.865555-07:00","created_by":"auto-import"}]} -{"id":"bd-377","title":"Low priority chore","description":"","design":"Benchmarks for:\n1. JSONL import/export performance\n2. Collision detection performance\n3. Three-way merge performance\n4. Gateway API latency\n5. WebSocket throughput\n6. Concurrent client handling\n7. Large database operations (10k+ issues)\n\nUse Go benchmarking and profiling tools.\n\nTrack performance over time in CI.","acceptance_criteria":"- Benchmark suite implemented\n- All key operations benchmarked\n- CPU and memory profiling\n- Large database benchmarks\n- Concurrent operation benchmarks\n- CI integration for regression detection\n- Performance baseline documented\n- Documentation in PERFORMANCE.md\n\n---","status":"open","priority":4,"issue_type":"chore","created_at":"2025-10-16T17:49:54.509839-07:00","updated_at":"2025-10-16T18:12:45.7181-07:00","dependencies":[{"issue_id":"bd-377","depends_on_id":"bd-388","type":"parent-child","created_at":"2025-10-16T17:49:54.866003-07:00","created_by":"auto-import"}]} -{"id":"bd-378","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","design":"Command should:\n1. Export pending changes to JSONL\n2. Commit changes to git\n3. Pull from remote (with conflict resolution)\n4. Push local commits to remote\n\nWraps the entire sync workflow in one command for better UX.","acceptance_criteria":"- bd sync command implemented\n- Exports dirty changes to JSONL automatically\n- Commits to git with descriptive message\n- Pulls and handles merge conflicts\n- Auto-imports updated JSONL\n- Pushes to remote\n- Error handling for git failures\n- Tests cover success and failure scenarios\n- Documentation in README.md\n\n---","notes":"All tasks completed: bd-64 (performance), bd-65 (migration), bd-66 (version sync), bd-67 (version script), bd-69 (CI coverage), bd-70 (test coverage). Code review follow-up complete.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T17:49:54.510305-07:00","updated_at":"2025-10-16T18:12:45.718664-07:00","closed_at":"2025-10-16T17:49:54.510305-07:00","dependencies":[{"issue_id":"bd-378","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.866456-07:00","created_by":"auto-import"}]} -{"id":"bd-379","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-387) while handling distributed creation gracefully.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T17:49:54.510752-07:00","updated_at":"2025-10-16T18:12:45.719217-07:00","closed_at":"2025-10-16T17:49:54.510752-07:00","dependencies":[{"issue_id":"bd-379","depends_on_id":"bd-228","type":"discovered-from","created_at":"2025-10-16T17:49:54.86707-07:00","created_by":"auto-import"}]} +{"id":"bd-370","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-16T14:57:48.783124-07:00","updated_at":"2025-10-16T14:57:48.783124-07:00","dependencies":[{"issue_id":"bd-370","depends_on_id":"bd-388","type":"parent-child","created_at":"2025-10-16T14:57:49.317257-07:00","created_by":"import-remap"},{"issue_id":"bd-370","depends_on_id":"bd-369","type":"parent-child","created_at":"2025-10-16T18:54:30.080837-07:00","created_by":"auto-import"}]} +{"id":"bd-371","title":"Consider batching API for bulk issue creation (recovered from bd-222)","description":"Current CreateIssue acquires a dedicated connection for each call. For bulk imports or agent workflows creating many issues, a batched API could improve performance:\n\nCreateIssues(ctx, issues []*Issue, actor string) error\n\nThis would:\n- Acquire one connection\n- Use one IMMEDIATE transaction\n- Insert all issues atomically\n- Reduce connection overhead\n\nNot urgent - current approach is correct and fast enough for typical use.\n\n**Recovered from:** bd-390 (lost in auto-import bug, see LOST_ISSUES_RECOVERY.md)","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-16T14:57:48.784477-07:00","updated_at":"2025-10-16T14:57:49.004702-07:00"} +{"id":"bd-372","title":"Add integration tests for auto-import collision detection","description":"The auto-import collision detection fix (bd-552) needs comprehensive integration tests.\n\n## Test Scenarios Needed\n\n### 1. Basic Collision Detection\n```go\nTestAutoImportWithCollisions\n- Setup: Create issue in DB with status=closed\n- Simulate: Git pull with JSONL containing same issue with status=open\n- Verify: Local changes preserved, warning printed, issue still closed\n```\n\n### 2. Multiple Collisions\n```go\nTestAutoImportWithMultipleCollisions\n- Setup: 5 issues with local modifications\n- Simulate: JSONL with 3 colliding, 2 matching\n- Verify: 3 skipped, 2 updated, appropriate warnings\n```\n\n### 3. No Collisions (Happy Path)\n```go\nTestAutoImportWithoutCollisions\n- Setup: Clean database\n- Simulate: JSONL with new issues + exact matches\n- Verify: All imported successfully, no warnings\n```\n\n### 4. All Collisions\n```go\nTestAutoImportAllCollisions\n- Setup: Every issue has local modifications\n- Simulate: JSONL with conflicting versions\n- Verify: All skipped, warning lists all issues\n```\n\n### 5. Collision Detection Failure\n```go\nTestAutoImportCollisionDetectionError\n- Setup: Mock DetectCollisions() to return error\n- Verify: Import skipped entirely (safe failure mode)\n```\n\n### 6. Hash-Based Skip\n```go\nTestAutoImportHashUnchanged\n- Setup: JSONL hash matches last_import_hash\n- Verify: No collision detection runs, fast path\n```\n\n### 7. Fallback for Non-SQLite\n```go\nTestAutoImportWithoutCollisionDetection\n- Setup: Mock non-SQLite storage backend\n- Verify: Falls back to old behavior, no collision detection\n```\n\n## Test Infrastructure Needed\n\n1. **Helper functions:**\n - createTestDBWithIssues()\n - writeJSONLFile()\n - captureStderrWarnings()\n - simulateGitPull()\n\n2. **Fixtures:**\n - sample-collisions.jsonl\n - sample-exact-matches.jsonl\n - sample-mixed.jsonl\n\n3. **Assertions:**\n - assertIssueState(id, expectedStatus)\n - assertWarningContains(text)\n - assertCollisionCount(n)\n\n## Acceptance Criteria\n- All 7 test scenarios implemented\n- Tests pass consistently\n- Code coverage \u003e80% for autoImportIfNewer()\n- Tests run in \u003c5 seconds total\n- Clear test names and documentation","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-16T14:57:48.78612-07:00","updated_at":"2025-10-16T18:54:29.524775-07:00","dependencies":[{"issue_id":"bd-372","depends_on_id":"bd-379","type":"blocks","created_at":"2025-10-16T18:57:16.98266-07:00","created_by":"auto-import"}]} +{"id":"bd-373","title":"Concurrent bd commands collide on shared .tmp filename","description":"When multiple bd commands run concurrently (e.g., different agents), they all write to .beads/issues.jsonl.tmp causing race conditions. One command's rename succeeds, consuming the .tmp file, then other commands fail with 'no such file or directory'. Solution: use unique temp filenames with PID or random suffix (e.g., issues.jsonl.tmp.12345).","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T14:57:48.790027-07:00","updated_at":"2025-10-16T14:57:48.790027-07:00","closed_at":"2025-10-16T14:53:25.431421-07:00"} +{"id":"bd-374","title":"Benchmark cycle detection performance on large dependency graphs","description":"Measure performance impact of cross-type cycle checking on large graphs (1000+ issues). Determine if optimization needed before enabling full prevention. Test various graph structures (sparse, dense, deeply nested).","design":"Create benchmark test with synthetic dependency graphs of varying sizes and structures. Measure AddDependency performance with type-specific vs all-types cycle checking. Document findings and optimization recommendations if needed.","acceptance_criteria":"- Benchmark test covers 100, 1000, 5000 issue graphs\n- Tests sparse and dense dependency patterns\n- Measures time for both checking approaches\n- Documents results in comments or DESIGN.md\n- Recommends optimization if \u003e100ms impact found","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.792813-07:00","updated_at":"2025-10-16T14:57:48.792813-07:00","dependencies":[{"issue_id":"bd-374","depends_on_id":"bd-307","type":"parent-child","created_at":"2025-10-16T14:57:49.23582-07:00","created_by":"import-remap"},{"issue_id":"bd-374","depends_on_id":"bd-659","type":"parent-child","created_at":"2025-10-16T18:57:16.796713-07:00","created_by":"import-remap"},{"issue_id":"bd-374","depends_on_id":"bd-377","type":"parent-child","created_at":"2025-10-16T18:57:16.983416-07:00","created_by":"auto-import"}]} +{"id":"bd-375","title":"stress_test_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.793624-07:00","updated_at":"2025-10-16T14:57:48.793624-07:00","closed_at":"2025-10-15T16:26:05.20809-07:00","dependencies":[{"issue_id":"bd-375","depends_on_id":"bd-270","type":"discovered-from","created_at":"2025-10-16T18:57:16.98406-07:00","created_by":"auto-import"}]} +{"id":"bd-376","title":"Add performance benchmarks document","description":"Document actual performance metrics with hyperfine tests","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-16T14:57:48.794452-07:00","updated_at":"2025-10-16T14:57:48.794452-07:00","dependencies":[{"issue_id":"bd-376","depends_on_id":"bd-388","type":"parent-child","created_at":"2025-10-16T14:57:49.218892-07:00","created_by":"import-remap"}]} +{"id":"bd-377","title":"Low priority chore","description":"","status":"open","priority":4,"issue_type":"chore","created_at":"2025-10-16T14:57:48.796499-07:00","updated_at":"2025-10-16T14:57:48.796499-07:00","dependencies":[{"issue_id":"bd-377","depends_on_id":"bd-388","type":"parent-child","created_at":"2025-10-16T18:57:16.984757-07:00","created_by":"auto-import"}]} +{"id":"bd-378","title":"Phase 1: Implement bd sync command","description":"Create bd sync command to manually synchronize with git remote in a single operation.","design":"Command should:\n1. Export pending changes to JSONL\n2. Commit changes to git\n3. Pull from remote (with conflict resolution)\n4. Push local commits to remote\n\nWraps the entire sync workflow in one command for better UX.","acceptance_criteria":"- bd sync command implemented\n- Exports dirty changes to JSONL automatically\n- Commits to git with descriptive message\n- Pulls and handles merge conflicts\n- Auto-imports updated JSONL\n- Pushes to remote\n- Error handling for git failures\n- Tests cover success and failure scenarios\n- Documentation in README.md\n\n---","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T14:57:48.811221-07:00","updated_at":"2025-10-16T14:57:48.811221-07:00","closed_at":"2025-10-16T12:22:48.022905-07:00","dependencies":[{"issue_id":"bd-378","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T18:57:16.985598-07:00","created_by":"auto-import"}]} +{"id":"bd-379","title":"Code review: Auto-import collision detection fix (bd-228)","description":"Request thorough code review of the auto-import collision detection implementation.\n\n## Files Changed\n- cmd/bd/main.go: autoImportIfNewer() and new autoImportWithoutCollisionDetection()\n\n## Review Focus Areas\n\n### 1. Correctness\n- Does collision detection properly identify conflicts?\n- Are colliding issues correctly filtered from import?\n- Is the fallback function correct for non-SQLite backends?\n\n### 2. Edge Cases\n- What happens if DetectCollisions() fails?\n- What if all issues are collisions?\n- What if JSONL is malformed?\n- Race conditions with concurrent auto-imports?\n\n### 3. User Experience\n- Is the warning message clear and actionable?\n- Should we log to a file instead of/in addition to stderr?\n- Should there be a --auto-resolve flag?\n\n### 4. Performance\n- Does collision detection add significant latency?\n- Will this work with 1000+ issues?\n- Any unnecessary N+1 queries?\n\n### 5. Testing Gaps\n- Do we need integration tests for collision scenarios?\n- Should we test the warning output?\n- Test autoImportWithoutCollisionDetection() fallback?\n\n## Questions for Reviewer\n1. Should auto-import be more aggressive (auto-resolve) or more conservative (fail)?\n2. Should we add a counter for how many times collisions occurred?\n3. Should there be a config option to disable collision detection?\n4. Is the warning too verbose for typical workflows?\n\n## Current Behavior\n- Skips colliding issues (preserves local)\n- Prints warning to stderr\n- Suggests manual resolution command\n- Continues with non-colliding issues","notes":"Review complete. Found 3 P0 bugs and 1 P1 bug. Created bd-663, bd-664, bd-665, bd-666. Full analysis in REVIEW_BD379.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T14:57:48.812015-07:00","updated_at":"2025-10-16T19:04:25.685554-07:00","closed_at":"2025-10-16T19:04:25.682263-07:00","dependencies":[{"issue_id":"bd-379","depends_on_id":"bd-228","type":"discovered-from","created_at":"2025-10-16T18:57:16.986261-07:00","created_by":"auto-import"}]} {"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-16T17:49:54.513101-07:00","updated_at":"2025-10-16T18:12:45.719885-07:00","closed_at":"2025-10-16T17:49:54.513101-07:00"} {"id":"bd-380","title":"Document git-based restoration feature","description":"Update COMPACTION.md and README.md with restoration workflow and examples","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.515642-07:00","updated_at":"2025-10-16T18:12:45.720442-07:00","dependencies":[{"issue_id":"bd-380","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.867561-07:00","created_by":"auto-import"}]} {"id":"bd-381","title":"Add tests for git-based restoration","description":"Test compaction stores commit hash, restore command works, handles missing git repo gracefully","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.516087-07:00","updated_at":"2025-10-16T18:12:45.721-07:00","dependencies":[{"issue_id":"bd-381","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.868045-07:00","created_by":"auto-import"}]} -{"id":"bd-382","title":"parallel_test_8","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.516615-07:00","updated_at":"2025-10-16T18:12:45.721584-07:00","closed_at":"2025-10-16T17:49:54.516615-07:00","dependencies":[{"issue_id":"bd-382","depends_on_id":"bd-368","type":"blocks","created_at":"2025-10-16T17:49:54.869051-07:00","created_by":"auto-import"}]} -{"id":"bd-383","title":"Implement bd restore command","description":"Create new restore command that checks out git commit from compacted_at_commit, reads issue from JSONL, and displays full history","status":"open","priority":1,"issue_type":"feature","created_at":"2025-10-16T17:49:54.517049-07:00","updated_at":"2025-10-16T18:12:45.722181-07:00","dependencies":[{"issue_id":"bd-383","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.869515-07:00","created_by":"auto-import"}]} -{"id":"bd-384","title":"Add compacted_at_commit field to Issue type","description":"Add optional compacted_at_commit string field to store git commit hash when issue is compacted","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.517481-07:00","updated_at":"2025-10-16T18:12:45.722721-07:00","dependencies":[{"issue_id":"bd-384","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.86999-07:00","created_by":"auto-import"}]} -{"id":"bd-385","title":"Git-based restoration for compacted issues","description":"Store git commit hash at compaction time to enable restoration of full issue history from version control. When issues are compacted, record the current git commit hash so users can restore the original uncompacted issue from git history.","status":"open","priority":1,"issue_type":"epic","created_at":"2025-10-16T17:49:54.518336-07:00","updated_at":"2025-10-16T18:12:45.723194-07:00","dependencies":[{"issue_id":"bd-385","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.870519-07:00","created_by":"auto-import"}]} +{"id":"bd-382","title":"parallel_test_8","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T14:57:48.825863-07:00","updated_at":"2025-10-16T14:57:48.825863-07:00","closed_at":"2025-10-15T16:26:05.438754-07:00","dependencies":[{"issue_id":"bd-382","depends_on_id":"bd-544","type":"blocks","created_at":"2025-10-16T18:54:29.855402-07:00","created_by":"import-remap"},{"issue_id":"bd-382","depends_on_id":"bd-655","type":"blocks","created_at":"2025-10-16T18:57:16.820587-07:00","created_by":"import-remap"},{"issue_id":"bd-382","depends_on_id":"bd-368","type":"blocks","created_at":"2025-10-16T18:57:16.986934-07:00","created_by":"auto-import"}]} +{"id":"bd-383","title":"Implement bd restore command","description":"Create new restore command that checks out git commit from compacted_at_commit, reads issue from JSONL, and displays full history","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T14:57:48.831757-07:00","updated_at":"2025-10-16T17:49:15.433942-07:00","closed_at":"2025-10-16T17:49:15.433942-07:00","dependencies":[{"issue_id":"bd-383","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T18:57:16.987677-07:00","created_by":"auto-import"}]} +{"id":"bd-384","title":"Add compacted_at_commit field to Issue type","description":"Add optional compacted_at_commit string field to store git commit hash when issue is compacted","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T14:57:48.834903-07:00","updated_at":"2025-10-16T17:43:54.177763-07:00","closed_at":"2025-10-16T17:43:54.177763-07:00","dependencies":[{"issue_id":"bd-384","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T18:57:16.988287-07:00","created_by":"auto-import"}]} +{"id":"bd-385","title":"Git-based restoration for compacted issues","description":"Store git commit hash at compaction time to enable restoration of full issue history from version control. When issues are compacted, record the current git commit hash so users can restore the original uncompacted issue from git history.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T14:57:48.836877-07:00","updated_at":"2025-10-16T17:44:03.980541-07:00","closed_at":"2025-10-16T17:44:03.980541-07:00","dependencies":[{"issue_id":"bd-385","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T18:57:16.988862-07:00","created_by":"auto-import"}]} {"id":"bd-386","title":"Phase 1: Implement bd daemon command","description":"Create bd daemon command to run background sync process with configurable interval.","design":"Daemon should:\n- Run in background (fork or systemd service)\n- Poll for changes at configurable interval (default: 5 minutes)\n- Export dirty issues to JSONL\n- Auto-commit if --auto-commit flag set\n- Auto-push if --auto-push flag set\n- Pull remote changes periodically\n- Auto-import when remote changes detected\n- Log sync activity\n\nCommand flags:\n- --interval=5m (sync check interval)\n- --auto-commit (automatically commit changes)\n- --auto-push (automatically push commits)\n- --stop (stop running daemon)\n- --status (show daemon status)","acceptance_criteria":"- bd daemon command implemented\n- Background process management working\n- Configurable sync interval\n- Auto-commit functionality\n- Auto-push functionality\n- PID file for process management\n- Graceful shutdown on SIGTERM\n- Logging to file or syslog\n- Status command shows daemon state\n- Tests for daemon lifecycle\n- Documentation in README.md\n\n---","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T17:49:54.5188-07:00","updated_at":"2025-10-16T18:12:45.723597-07:00","closed_at":"2025-10-16T17:49:54.5188-07:00","dependencies":[{"issue_id":"bd-386","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.871028-07:00","created_by":"auto-import"}]} -{"id":"bd-387","title":"Record git commit hash during compaction","description":"Update compact command to capture current git HEAD commit hash and store in compacted_at_commit field","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.521299-07:00","updated_at":"2025-10-16T18:12:45.724017-07:00","dependencies":[{"issue_id":"bd-387","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T17:49:54.872022-07:00","created_by":"auto-import"}]} -{"id":"bd-388","title":"Reach 1.0 release milestone","description":"Stabilize API, finalize documentation, comprehensive testing","status":"open","priority":1,"issue_type":"epic","created_at":"2025-10-16T17:49:54.522583-07:00","updated_at":"2025-10-16T18:12:45.724451-07:00"} +{"id":"bd-387","title":"Record git commit hash during compaction","description":"Update compact command to capture current git HEAD commit hash and store in compacted_at_commit field","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T14:57:48.841348-07:00","updated_at":"2025-10-16T17:43:54.177406-07:00","closed_at":"2025-10-16T17:43:54.177406-07:00","dependencies":[{"issue_id":"bd-387","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T18:57:16.999473-07:00","created_by":"auto-import"}]} +{"id":"bd-388","title":"Reach 1.0 release milestone","description":"Stabilize API, finalize documentation, comprehensive testing","status":"open","priority":1,"issue_type":"epic","created_at":"2025-10-16T14:57:48.842642-07:00","updated_at":"2025-10-16T14:57:48.842642-07:00"} {"id":"bd-389","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-16T17:49:54.525554-07:00","updated_at":"2025-10-16T18:12:45.725151-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-16T17:49:54.535849-07:00","updated_at":"2025-10-16T18:12:45.725591-07:00","closed_at":"2025-10-16T17:49:54.535849-07:00"} -{"id":"bd-390","title":"P2: Consider batching API for bulk issue creation","description":"Current CreateIssue acquires a dedicated connection for each call. For bulk imports or agent workflows creating many issues, a batched API could improve performance:\n\nCreateIssues(ctx, issues []*Issue, actor string) error\n\nThis would:\n- Acquire one connection\n- Use one IMMEDIATE transaction\n- Insert all issues atomically\n- Reduce connection overhead\n\nNot urgent - current approach is correct and fast enough for typical use.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-16T17:49:54.537102-07:00","updated_at":"2025-10-16T18:12:45.726035-07:00"} -{"id":"bd-391","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-16T17:49:54.54157-07:00","updated_at":"2025-10-16T18:12:45.726501-07:00","dependencies":[{"issue_id":"bd-391","depends_on_id":"bd-390","type":"blocks","created_at":"2025-10-16T17:49:54.87261-07:00","created_by":"auto-import"}]} -{"id":"bd-392","title":"Epic: Add intelligent database compaction with Claude Haiku","description":"Implement multi-tier database compaction using Claude Haiku to semantically compress old, closed issues. This keeps the database lightweight and agent-friendly while preserving essential context.\n\nGoals:\n- 70-95% space reduction for eligible issues\n- Full restore capability via snapshots\n- Opt-in with dry-run safety\n- ~$1 per 1,000 issues compacted","acceptance_criteria":"- Schema migration with snapshots table\n- Haiku integration for summarization\n- Two-tier compaction (30d, 90d)\n- CLI with dry-run, restore, stats\n- Full test coverage\n- Documentation complete","status":"open","priority":2,"issue_type":"epic","created_at":"2025-10-16T17:49:54.54202-07:00","updated_at":"2025-10-16T18:12:45.726963-07:00"} +{"id":"bd-390","title":"P2: Consider batching API for bulk issue creation","description":"Current CreateIssue acquires a dedicated connection for each call. For bulk imports or agent workflows creating many issues, a batched API could improve performance:\n\nCreateIssues(ctx, issues []*Issue, actor string) error\n\nThis would:\n- Acquire one connection\n- Use one IMMEDIATE transaction\n- Insert all issues atomically\n- Reduce connection overhead\n\nNot urgent - current approach is correct and fast enough for typical use.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T14:57:48.844729-07:00","updated_at":"2025-10-16T19:08:32.889005-07:00","closed_at":"2025-10-16T19:08:32.889005-07:00"} +{"id":"bd-391","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-16T14:57:48.845572-07:00","updated_at":"2025-10-16T14:57:48.845572-07:00","dependencies":[{"issue_id":"bd-391","depends_on_id":"bd-390","type":"blocks","created_at":"2025-10-16T14:57:49.25003-07:00","created_by":"import-remap"}]} +{"id":"bd-392","title":"Epic: Add intelligent database compaction with Claude Haiku","description":"Implement multi-tier database compaction using Claude Haiku to semantically compress old, closed issues. This keeps the database lightweight and agent-friendly while preserving essential context.\n\nGoals:\n- 70-95% space reduction for eligible issues\n- Full restore capability via snapshots\n- Opt-in with dry-run safety\n- ~$1 per 1,000 issues compacted","acceptance_criteria":"- Schema migration with snapshots table\n- Haiku integration for summarization\n- Two-tier compaction (30d, 90d)\n- CLI with dry-run, restore, stats\n- Full test coverage\n- Documentation complete","status":"closed","priority":2,"issue_type":"epic","created_at":"2025-10-16T14:57:48.846232-07:00","updated_at":"2025-10-16T19:08:30.979788-07:00","closed_at":"2025-10-16T19:08:30.979788-07:00"} {"id":"bd-393","title":"Critical: Auto-import was skipping collisions instead of remapping them","description":"The auto-import mechanism was SKIPPING colliding issues instead of automatically remapping them to new IDs. This caused work from other workers/devices to be LOST during git pull operations.\n\nRoot cause: Lines 283-326 in main.go were filtering out colliding issues instead of calling RemapCollisions() to resolve them.\n\nImpact: Multi-device workflows would silently lose issues when two devices created issues with the same ID.","acceptance_criteria":"- Auto-import detects collisions\n- Calls ScoreCollisions + RemapCollisions automatically\n- Shows remapping notification to user\n- No work is lost from other workers\n- All tests pass","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T17:49:54.562648-07:00","updated_at":"2025-10-16T18:12:45.727384-07:00","closed_at":"2025-10-16T17:49:54.562648-07:00"} {"id":"bd-394","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":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T17:49:54.58042-07:00","updated_at":"2025-10-16T18:12:45.727907-07:00","closed_at":"2025-10-16T17:49:54.58042-07:00","external_ref":"gh-11"} {"id":"bd-395","title":"Record git commit hash during compaction","description":"Update compact command to capture current git HEAD commit hash and store in compacted_at_commit field","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.587809-07:00","updated_at":"2025-10-16T18:12:45.728382-07:00"} -{"id":"bd-396","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-16T17:49:54.589472-07:00","updated_at":"2025-10-16T18:12:45.728825-07:00"} -{"id":"bd-397","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-16T17:49:54.589931-07:00","updated_at":"2025-10-16T18:12:45.729272-07:00"} -{"id":"bd-398","title":"Reach 1.0 release milestone","description":"Stabilize API, finalize documentation, comprehensive testing","status":"open","priority":1,"issue_type":"epic","created_at":"2025-10-16T17:49:54.590353-07:00","updated_at":"2025-10-16T18:12:45.729699-07:00"} -{"id":"bd-399","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-16T17:49:54.598025-07:00","updated_at":"2025-10-16T18:12:45.730175-07:00"} +{"id":"bd-396","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":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T16:03:31.504655-07:00","updated_at":"2025-10-16T19:08:31.286765-07:00","closed_at":"2025-10-16T19:08:31.286765-07:00"} +{"id":"bd-397","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":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T16:03:31.520913-07:00","updated_at":"2025-10-16T19:08:29.845826-07:00","closed_at":"2025-10-16T19:08:29.845826-07:00"} +{"id":"bd-398","title":"Reach 1.0 release milestone","description":"Stabilize API, finalize documentation, comprehensive testing","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T16:03:31.523258-07:00","updated_at":"2025-10-16T19:08:33.062938-07:00","closed_at":"2025-10-16T19:08:33.062938-07:00"} +{"id":"bd-399","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":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T16:03:31.525208-07:00","updated_at":"2025-10-16T19:08:30.058744-07:00","closed_at":"2025-10-16T19:08:30.058744-07:00"} {"id":"bd-4","title":"Low priority chore","description":"","status":"open","priority":4,"issue_type":"chore","created_at":"2025-10-16T17:49:54.59856-07:00","updated_at":"2025-10-16T18:12:45.730603-07:00"} {"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-16T17:49:54.599061-07:00","updated_at":"2025-10-16T18:12:45.731044-07:00"} {"id":"bd-400","title":"Code review: Auto-import collision detection fix (bd-228)","description":"Request thorough code review of the auto-import collision detection implementation.\n\n## Files Changed\n- cmd/bd/main.go: autoImportIfNewer() and new autoImportWithoutCollisionDetection()\n\n## Review Focus Areas\n\n### 1. Correctness\n- Does collision detection properly identify conflicts?\n- Are colliding issues correctly filtered from import?\n- Is the fallback function correct for non-SQLite backends?\n\n### 2. Edge Cases\n- What happens if DetectCollisions() fails?\n- What if all issues are collisions?\n- What if JSONL is malformed?\n- Race conditions with concurrent auto-imports?\n\n### 3. User Experience\n- Is the warning message clear and actionable?\n- Should we log to a file instead of/in addition to stderr?\n- Should there be a --auto-resolve flag?\n\n### 4. Performance\n- Does collision detection add significant latency?\n- Will this work with 1000+ issues?\n- Any unnecessary N+1 queries?\n\n### 5. Testing Gaps\n- Do we need integration tests for collision scenarios?\n- Should we test the warning output?\n- Test autoImportWithoutCollisionDetection() fallback?\n\n## Questions for Reviewer\n1. Should auto-import be more aggressive (auto-resolve) or more conservative (fail)?\n2. Should we add a counter for how many times collisions occurred?\n3. Should there be a config option to disable collision detection?\n4. Is the warning too verbose for typical workflows?\n\n## Current Behavior\n- Skips colliding issues (preserves local)\n- Prints warning to stderr\n- Suggests manual resolution command\n- Continues with non-colliding issues","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.601498-07:00","updated_at":"2025-10-16T18:12:45.731648-07:00"} {"id":"bd-401","title":"Add integration tests for auto-import collision detection","description":"The auto-import collision detection fix (bd-376) needs comprehensive integration tests.\n\n## Test Scenarios Needed\n\n### 1. Basic Collision Detection\n```go\nTestAutoImportWithCollisions\n- Setup: Create issue in DB with status=closed\n- Simulate: Git pull with JSONL containing same issue with status=open\n- Verify: Local changes preserved, warning printed, issue still closed\n```\n\n### 2. Multiple Collisions\n```go\nTestAutoImportWithMultipleCollisions\n- Setup: 5 issues with local modifications\n- Simulate: JSONL with 3 colliding, 2 matching\n- Verify: 3 skipped, 2 updated, appropriate warnings\n```\n\n### 3. No Collisions (Happy Path)\n```go\nTestAutoImportWithoutCollisions\n- Setup: Clean database\n- Simulate: JSONL with new issues + exact matches\n- Verify: All imported successfully, no warnings\n```\n\n### 4. All Collisions\n```go\nTestAutoImportAllCollisions\n- Setup: Every issue has local modifications\n- Simulate: JSONL with conflicting versions\n- Verify: All skipped, warning lists all issues\n```\n\n### 5. Collision Detection Failure\n```go\nTestAutoImportCollisionDetectionError\n- Setup: Mock DetectCollisions() to return error\n- Verify: Import skipped entirely (safe failure mode)\n```\n\n### 6. Hash-Based Skip\n```go\nTestAutoImportHashUnchanged\n- Setup: JSONL hash matches last_import_hash\n- Verify: No collision detection runs, fast path\n```\n\n### 7. Fallback for Non-SQLite\n```go\nTestAutoImportWithoutCollisionDetection\n- Setup: Mock non-SQLite storage backend\n- Verify: Falls back to old behavior, no collision detection\n```\n\n## Test Infrastructure Needed\n\n1. **Helper functions:**\n - createTestDBWithIssues()\n - writeJSONLFile()\n - captureStderrWarnings()\n - simulateGitPull()\n\n2. **Fixtures:**\n - sample-collisions.jsonl\n - sample-exact-matches.jsonl\n - sample-mixed.jsonl\n\n3. **Assertions:**\n - assertIssueState(id, expectedStatus)\n - assertWarningContains(text)\n - assertCollisionCount(n)\n\n## Acceptance Criteria\n- All 7 test scenarios implemented\n- Tests pass consistently\n- Code coverage \u003e80% for autoImportIfNewer()\n- Tests run in \u003c5 seconds total\n- Clear test names and documentation","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.608432-07:00","updated_at":"2025-10-16T18:12:45.732135-07:00","closed_at":"2025-10-16T17:49:54.608432-07:00"} -{"id":"bd-402","title":"Consider batching API for bulk issue creation (recovered from bd-222)","description":"Current CreateIssue acquires a dedicated connection for each call. For bulk imports or agent workflows creating many issues, a batched API could improve performance:\n\nCreateIssues(ctx, issues []*Issue, actor string) error\n\nThis would:\n- Acquire one connection\n- Use one IMMEDIATE transaction\n- Insert all issues atomically\n- Reduce connection overhead\n\nNot urgent - current approach is correct and fast enough for typical use.\n\n**Recovered from:** bd-360 (lost in auto-import bug, see LOST_ISSUES_RECOVERY.md)","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-16T17:49:54.608942-07:00","updated_at":"2025-10-16T18:12:45.732584-07:00"} -{"id":"bd-403","title":"Use safer placeholder pattern in replaceIDReferences","description":"Currently uses bd-324 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-16T17:49:54.609967-07:00","updated_at":"2025-10-16T18:12:45.733076-07:00"} +{"id":"bd-402","title":"Consider batching API for bulk issue creation (recovered from bd-222)","description":"Current CreateIssue acquires a dedicated connection for each call. For bulk imports or agent workflows creating many issues, a batched API could improve performance:\n\nCreateIssues(ctx, issues []*Issue, actor string) error\n\nThis would:\n- Acquire one connection\n- Use one IMMEDIATE transaction\n- Insert all issues atomically\n- Reduce connection overhead\n\nNot urgent - current approach is correct and fast enough for typical use.\n\n**Recovered from:** bd-360 (lost in auto-import bug, see LOST_ISSUES_RECOVERY.md)","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T16:03:31.547562-07:00","updated_at":"2025-10-16T19:08:30.460805-07:00","closed_at":"2025-10-16T19:08:30.460805-07:00"} +{"id":"bd-403","title":"Use safer placeholder pattern in replaceIDReferences","description":"Currently uses bd-324 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":"closed","priority":3,"issue_type":"task","created_at":"2025-10-16T16:03:31.550675-07:00","updated_at":"2025-10-16T19:08:33.611405-07:00","closed_at":"2025-10-16T19:08:33.611405-07:00"} {"id":"bd-404","title":"Git-based restoration for compacted issues","description":"Store git commit hash at compaction time to enable restoration of full issue history from version control. When issues are compacted, record the current git commit hash so users can restore the original uncompacted issue from git history.","status":"open","priority":1,"issue_type":"epic","created_at":"2025-10-16T17:49:54.61486-07:00","updated_at":"2025-10-16T18:12:45.733494-07:00"} {"id":"bd-405","title":"Add compacted_at_commit field to Issue type","description":"Add optional compacted_at_commit string field to store git commit hash when issue is compacted","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.6157-07:00","updated_at":"2025-10-16T18:12:45.733931-07:00"} -{"id":"bd-406","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.","notes":"Awaiting user feedback - cannot reproduce locally, waiting for user to provide more details about environment and error message","status":"blocked","priority":1,"issue_type":"bug","created_at":"2025-10-16T17:49:54.616493-07:00","updated_at":"2025-10-16T18:12:45.734515-07:00","external_ref":"gh-3"} +{"id":"bd-406","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.","notes":"Awaiting user feedback - cannot reproduce locally, waiting for user to provide more details about environment and error message","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T16:03:31.580261-07:00","updated_at":"2025-10-16T19:08:31.687438-07:00","closed_at":"2025-10-16T19:08:31.687438-07:00","external_ref":"gh-3"} {"id":"bd-407","title":"Implement bd restore command","description":"Create new restore command that checks out git commit from compacted_at_commit, reads issue from JSONL, and displays full history","status":"open","priority":1,"issue_type":"feature","created_at":"2025-10-16T17:49:54.617069-07:00","updated_at":"2025-10-16T18:12:45.735118-07:00"} {"id":"bd-408","title":"Add tests for git-based restoration","description":"Test compaction stores commit hash, restore command works, handles missing git repo gracefully","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.617561-07:00","updated_at":"2025-10-16T18:12:45.735554-07:00"} -{"id":"bd-409","title":"Document git-based restoration feature","description":"Update COMPACTION.md and README.md with restoration workflow and examples","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.618022-07:00","updated_at":"2025-10-16T18:12:45.73598-07:00"} +{"id":"bd-409","title":"Document git-based restoration feature","description":"Update COMPACTION.md and README.md with restoration workflow and examples","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T16:03:31.584232-07:00","updated_at":"2025-10-16T19:08:30.92807-07:00","closed_at":"2025-10-16T19:08:30.92807-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-16T17:49:54.618414-07:00","updated_at":"2025-10-16T18:12:45.736391-07:00"} -{"id":"bd-410","title":"Add performance benchmarks document","description":"Document actual performance metrics with hyperfine tests","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-16T17:49:54.618794-07:00","updated_at":"2025-10-16T18:12:45.736797-07:00"} +{"id":"bd-410","title":"Add performance benchmarks document","description":"Document actual performance metrics with hyperfine tests","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-16T16:03:31.585083-07:00","updated_at":"2025-10-16T19:08:29.748215-07:00","closed_at":"2025-10-16T19:08:29.748215-07:00"} {"id":"bd-411","title":"parallel_test_2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.619179-07:00","updated_at":"2025-10-16T18:12:45.73719-07:00","closed_at":"2025-10-16T17:49:54.619179-07:00"} {"id":"bd-412","title":"parallel_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.62252-07:00","updated_at":"2025-10-16T18:12:45.737584-07:00","closed_at":"2025-10-16T17:49:54.62252-07:00"} {"id":"bd-413","title":"parallel_test_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.623561-07:00","updated_at":"2025-10-16T18:12:45.738031-07:00","closed_at":"2025-10-16T17:49:54.623561-07:00"} {"id":"bd-414","title":"parallel_test_4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.625407-07:00","updated_at":"2025-10-16T18:12:45.738631-07:00","closed_at":"2025-10-16T17:49:54.625407-07:00"} {"id":"bd-415","title":"parallel_test_1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.626055-07:00","updated_at":"2025-10-16T18:12:45.739229-07:00","closed_at":"2025-10-16T17:49:54.626055-07:00"} -{"id":"bd-416","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-16T17:49:54.627028-07:00","updated_at":"2025-10-16T18:12:45.739617-07:00"} -{"id":"bd-417","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-16T17:49:54.62747-07:00","updated_at":"2025-10-16T18:12:45.740077-07:00"} -{"id":"bd-418","title":"parallel_test_4","description":"","design":"Sections:\n1. Introduction\n2. Authentication\n3. REST Endpoints\n4. WebSocket Protocol\n5. Error Handling\n6. Rate Limits\n7. Examples\n\nFor each endpoint:\n- URL and method\n- Request parameters\n- Request body schema\n- Response schema\n- Error responses\n- Code example","acceptance_criteria":"- API.md created with all sections\n- All endpoints documented\n- Request/response schemas\n- WebSocket protocol docs\n- Error codes and handling\n- Rate limit documentation\n- Examples in multiple languages\n- Links from README.md\n\n---","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.627919-07:00","updated_at":"2025-10-16T18:12:45.740546-07:00"} +{"id":"bd-416","title":"Add migration scripts for GitHub Issues","description":"Create scripts to import from GitHub Issues API or exported JSON","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T16:03:31.596085-07:00","updated_at":"2025-10-16T19:08:29.648966-07:00","closed_at":"2025-10-16T19:08:29.648966-07:00"} +{"id":"bd-417","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":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T16:03:31.596875-07:00","updated_at":"2025-10-16T19:08:30.584292-07:00","closed_at":"2025-10-16T19:08:30.584292-07:00"} +{"id":"bd-418","title":"parallel_test_4","description":"","design":"Sections:\n1. Introduction\n2. Authentication\n3. REST Endpoints\n4. WebSocket Protocol\n5. Error Handling\n6. Rate Limits\n7. Examples\n\nFor each endpoint:\n- URL and method\n- Request parameters\n- Request body schema\n- Response schema\n- Error responses\n- Code example","acceptance_criteria":"- API.md created with all sections\n- All endpoints documented\n- Request/response schemas\n- WebSocket protocol docs\n- Error codes and handling\n- Rate limit documentation\n- Examples in multiple languages\n- Links from README.md\n\n---","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T16:03:31.597564-07:00","updated_at":"2025-10-16T19:08:46.591226-07:00","closed_at":"2025-10-16T19:08:46.591226-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-16T17:49:54.628327-07:00","updated_at":"2025-10-16T18:12:45.741007-07:00","closed_at":"2025-10-16T17:49:54.628327-07:00"} {"id":"bd-420","title":"Add command to rename issue prefix","description":"Allow users to rename their issue prefix (e.g., from 'knowledge-work-' to 'kw-'). Must update the prefix in all issues and update all text references across all issue fields (title, description, design, acceptance criteria, notes) using regexp. Should validate new prefix format and prevent collisions with existing IDs.","design":"Prefix validation rules:\n- Max length: 8 characters\n- Allowed characters: lowercase letters, numbers, hyphens\n- Must start with a letter\n- Must end with a hyphen (e.g., 'kw-', 'work-')\n- Cannot be empty or just a hyphen\n\nImplementation:\n- Add validation function for prefix format\n- Update all issue IDs in the database\n- Use regexp to find and replace all text references across all fields\n- Atomic operation (rollback on failure)","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T17:49:54.629246-07:00","updated_at":"2025-10-16T18:12:45.741447-07:00","closed_at":"2025-10-16T17:49:54.629246-07:00"} -{"id":"bd-421","title":"Bug: Import creating duplicates instead of deduplicating","description":"Git log shows \"73 issues remapped\" during merge, suggesting --resolve-collisions is creating duplicate issues with new IDs instead of recognizing they're identical and deduplicating them.\n\nEvidence: bd-226, bd-367, bd-396 are all \"Epic: Fix status/closed_at inconsistency\" with identical content but different IDs and timestamps.\n\nRoot cause likely in DetectCollisions or --resolve-collisions logic - it's treating content-identical issues as collisions when they should be exact matches.","design":"**Root Cause Found:**\n\nDetectCollisions only checks if incoming issues exist in the DB. It doesn't deduplicate within the incoming JSONL batch itself.\n\nWhen JSONL contains multiple issues with:\n- Different IDs (bd-226, bd-367, bd-396)\n- Identical content\n- Different timestamps\n\nDetectCollisions treats them all as \"new issues\" because none exist in DB, then --resolve-collisions leaves them as-is.\n\n**Fix:**\nAdd deduplication step in DetectCollisions to detect content-identical issues within the incoming batch and consolidate them before processing.","notes":"**Fixed in commit [pending]**\n\nChanges made:\n1. Added `deduplicateIncomingIssues()` function in collision.go\n2. Modified `DetectCollisions()` to call deduplication before processing\n3. Deduplication consolidates content-identical issues, keeping smallest ID\n4. Added comprehensive test suite in collision_dedup_test.go\n\nResult: Importing JSONL with duplicates now correctly consolidates them instead of creating multiple copies.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T17:49:54.943807-07:00","updated_at":"2025-10-16T18:12:45.741975-07:00","closed_at":"2025-10-16T17:52:35.575954-07:00"} +{"id":"bd-421","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":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T18:05:02.16198-07:00","updated_at":"2025-10-16T18:05:02.16198-07:00","closed_at":"2025-10-16T14:45:50.800075-07:00"} +{"id":"bd-422","title":"Git-based restoration for compacted issues","description":"Store git commit hash at compaction time to enable restoration of full issue history from version control. When issues are compacted, record the current git commit hash so users can restore the original uncompacted issue from git history.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:05:02.163999-07:00","updated_at":"2025-10-16T19:08:32.11885-07:00","closed_at":"2025-10-16T19:08:32.11885-07:00"} +{"id":"bd-423","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":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:05:02.164815-07:00","updated_at":"2025-10-16T19:08:31.206894-07:00","closed_at":"2025-10-16T19:08:31.206894-07:00"} +{"id":"bd-424","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":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:05:02.172587-07:00","updated_at":"2025-10-16T19:08:29.821645-07:00","closed_at":"2025-10-16T19:08:29.821645-07:00"} +{"id":"bd-425","title":"Reach 1.0 release milestone","description":"Stabilize API, finalize documentation, comprehensive testing","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:05:02.174097-07:00","updated_at":"2025-10-16T19:08:33.026058-07:00","closed_at":"2025-10-16T19:08:33.026058-07:00"} +{"id":"bd-426","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":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:05:02.175188-07:00","updated_at":"2025-10-16T19:08:30.034521-07:00","closed_at":"2025-10-16T19:08:30.034521-07:00"} +{"id":"bd-427","title":"Code review: Auto-import collision detection fix (bd-228)","description":"Request thorough code review of the auto-import collision detection implementation.\n\n## Files Changed\n- cmd/bd/main.go: autoImportIfNewer() and new autoImportWithoutCollisionDetection()\n\n## Review Focus Areas\n\n### 1. Correctness\n- Does collision detection properly identify conflicts?\n- Are colliding issues correctly filtered from import?\n- Is the fallback function correct for non-SQLite backends?\n\n### 2. Edge Cases\n- What happens if DetectCollisions() fails?\n- What if all issues are collisions?\n- What if JSONL is malformed?\n- Race conditions with concurrent auto-imports?\n\n### 3. User Experience\n- Is the warning message clear and actionable?\n- Should we log to a file instead of/in addition to stderr?\n- Should there be a --auto-resolve flag?\n\n### 4. Performance\n- Does collision detection add significant latency?\n- Will this work with 1000+ issues?\n- Any unnecessary N+1 queries?\n\n### 5. Testing Gaps\n- Do we need integration tests for collision scenarios?\n- Should we test the warning output?\n- Test autoImportWithoutCollisionDetection() fallback?\n\n## Questions for Reviewer\n1. Should auto-import be more aggressive (auto-resolve) or more conservative (fail)?\n2. Should we add a counter for how many times collisions occurred?\n3. Should there be a config option to disable collision detection?\n4. Is the warning too verbose for typical workflows?\n\n## Current Behavior\n- Skips colliding issues (preserves local)\n- Prints warning to stderr\n- Suggests manual resolution command\n- Continues with non-colliding issues","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:05:02.175897-07:00","updated_at":"2025-10-16T19:08:30.20309-07:00","closed_at":"2025-10-16T19:08:30.20309-07:00"} +{"id":"bd-428","title":"Add integration tests for auto-import collision detection","description":"The auto-import collision detection fix (bd-376) needs comprehensive integration tests.\n\n## Test Scenarios Needed\n\n### 1. Basic Collision Detection\n```go\nTestAutoImportWithCollisions\n- Setup: Create issue in DB with status=closed\n- Simulate: Git pull with JSONL containing same issue with status=open\n- Verify: Local changes preserved, warning printed, issue still closed\n```\n\n### 2. Multiple Collisions\n```go\nTestAutoImportWithMultipleCollisions\n- Setup: 5 issues with local modifications\n- Simulate: JSONL with 3 colliding, 2 matching\n- Verify: 3 skipped, 2 updated, appropriate warnings\n```\n\n### 3. No Collisions (Happy Path)\n```go\nTestAutoImportWithoutCollisions\n- Setup: Clean database\n- Simulate: JSONL with new issues + exact matches\n- Verify: All imported successfully, no warnings\n```\n\n### 4. All Collisions\n```go\nTestAutoImportAllCollisions\n- Setup: Every issue has local modifications\n- Simulate: JSONL with conflicting versions\n- Verify: All skipped, warning lists all issues\n```\n\n### 5. Collision Detection Failure\n```go\nTestAutoImportCollisionDetectionError\n- Setup: Mock DetectCollisions() to return error\n- Verify: Import skipped entirely (safe failure mode)\n```\n\n### 6. Hash-Based Skip\n```go\nTestAutoImportHashUnchanged\n- Setup: JSONL hash matches last_import_hash\n- Verify: No collision detection runs, fast path\n```\n\n### 7. Fallback for Non-SQLite\n```go\nTestAutoImportWithoutCollisionDetection\n- Setup: Mock non-SQLite storage backend\n- Verify: Falls back to old behavior, no collision detection\n```\n\n## Test Infrastructure Needed\n\n1. **Helper functions:**\n - createTestDBWithIssues()\n - writeJSONLFile()\n - captureStderrWarnings()\n - simulateGitPull()\n\n2. **Fixtures:**\n - sample-collisions.jsonl\n - sample-exact-matches.jsonl\n - sample-mixed.jsonl\n\n3. **Assertions:**\n - assertIssueState(id, expectedStatus)\n - assertWarningContains(text)\n - assertCollisionCount(n)\n\n## Acceptance Criteria\n- All 7 test scenarios implemented\n- Tests pass consistently\n- Code coverage \u003e80% for autoImportIfNewer()\n- Tests run in \u003c5 seconds total\n- Clear test names and documentation","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-16T18:05:02.176549-07:00","updated_at":"2025-10-16T18:05:02.176549-07:00"} +{"id":"bd-429","title":"Consider batching API for bulk issue creation (recovered from bd-222)","description":"Current CreateIssue acquires a dedicated connection for each call. For bulk imports or agent workflows creating many issues, a batched API could improve performance:\n\nCreateIssues(ctx, issues []*Issue, actor string) error\n\nThis would:\n- Acquire one connection\n- Use one IMMEDIATE transaction\n- Insert all issues atomically\n- Reduce connection overhead\n\nNot urgent - current approach is correct and fast enough for typical use.\n\n**Recovered from:** bd-360 (lost in auto-import bug, see LOST_ISSUES_RECOVERY.md)","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:05:02.177375-07:00","updated_at":"2025-10-16T19:08:30.425481-07:00","closed_at":"2025-10-16T19:08:30.425481-07:00"} {"id":"bd-43","title":"Test auto-sync feature","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.629731-07:00","updated_at":"2025-10-16T18:12:45.742649-07:00","closed_at":"2025-10-16T17:49:54.629731-07:00"} +{"id":"bd-430","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":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T18:05:02.178935-07:00","updated_at":"2025-10-16T19:08:30.540494-07:00","closed_at":"2025-10-16T19:08:30.540494-07:00"} +{"id":"bd-431","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.","notes":"Awaiting user feedback - cannot reproduce locally, waiting for user to provide more details about environment and error message","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T18:05:02.180111-07:00","updated_at":"2025-10-16T19:08:31.651494-07:00","closed_at":"2025-10-16T19:08:31.651494-07:00","external_ref":"gh-3"} +{"id":"bd-432","title":"Add compacted_at_commit field to Issue type","description":"Add optional compacted_at_commit string field to store git commit hash when issue is compacted","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-16T18:05:02.18097-07:00","updated_at":"2025-10-16T18:05:02.18097-07:00"} +{"id":"bd-433","title":"Record git commit hash during compaction","description":"Update compact command to capture current git HEAD commit hash and store in compacted_at_commit field","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-16T18:05:02.182118-07:00","updated_at":"2025-10-16T18:05:02.182118-07:00"} +{"id":"bd-434","title":"Implement bd restore command","description":"Create new restore command that checks out git commit from compacted_at_commit, reads issue from JSONL, and displays full history","status":"open","priority":1,"issue_type":"feature","created_at":"2025-10-16T18:05:02.183027-07:00","updated_at":"2025-10-16T18:05:02.183027-07:00"} +{"id":"bd-435","title":"Add tests for git-based restoration","description":"Test compaction stores commit hash, restore command works, handles missing git repo gracefully","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T18:05:02.183952-07:00","updated_at":"2025-10-16T18:05:02.183952-07:00"} +{"id":"bd-436","title":"Document git-based restoration feature","description":"Update COMPACTION.md and README.md with restoration workflow and examples","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:05:02.185847-07:00","updated_at":"2025-10-16T19:08:30.870697-07:00","closed_at":"2025-10-16T19:08:30.870697-07:00"} +{"id":"bd-437","title":"Add performance benchmarks document","description":"Document actual performance metrics with hyperfine tests","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-16T18:05:02.186502-07:00","updated_at":"2025-10-16T19:08:29.72679-07:00","closed_at":"2025-10-16T19:08:29.72679-07:00"} +{"id":"bd-438","title":"parallel_test_2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:05:02.18713-07:00","updated_at":"2025-10-16T18:05:02.18713-07:00","closed_at":"2025-10-15T16:26:05.345118-07:00"} +{"id":"bd-439","title":"parallel_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:05:02.187725-07:00","updated_at":"2025-10-16T18:05:02.187725-07:00","closed_at":"2025-10-15T16:26:05.358813-07:00"} {"id":"bd-44","title":"Regular auto-ID issue","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.63028-07:00","updated_at":"2025-10-16T18:12:45.74309-07:00","closed_at":"2025-10-16T17:49:54.63028-07:00"} +{"id":"bd-440","title":"parallel_test_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:05:02.188753-07:00","updated_at":"2025-10-16T18:05:02.188753-07:00","closed_at":"2025-10-15T16:26:05.375985-07:00"} +{"id":"bd-441","title":"parallel_test_4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:05:02.189537-07:00","updated_at":"2025-10-16T18:05:02.189537-07:00","closed_at":"2025-10-15T16:26:05.404261-07:00"} +{"id":"bd-442","title":"parallel_test_1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:05:02.190287-07:00","updated_at":"2025-10-16T18:05:02.190287-07:00","closed_at":"2025-10-15T16:26:05.415413-07:00"} +{"id":"bd-443","title":"Add migration scripts for GitHub Issues","description":"Create scripts to import from GitHub Issues API or exported JSON","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:05:02.190949-07:00","updated_at":"2025-10-16T19:08:29.627316-07:00","closed_at":"2025-10-16T19:08:29.627316-07:00"} +{"id":"bd-444","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":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:05:02.191716-07:00","updated_at":"2025-10-16T18:05:02.191716-07:00","closed_at":"2025-10-16T14:37:09.712087-07:00","external_ref":"gh-11"} +{"id":"bd-445","title":"Use safer placeholder pattern in replaceIDReferences","description":"Currently uses bd-324 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":"closed","priority":3,"issue_type":"task","created_at":"2025-10-16T18:05:02.192424-07:00","updated_at":"2025-10-16T19:08:33.538124-07:00","closed_at":"2025-10-16T19:08:33.538124-07:00"} +{"id":"bd-447","title":"Add tests for git-based restoration","description":"Test compaction stores commit hash, restore command works, handles missing git repo gracefully","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.108386-07:00","updated_at":"2025-10-16T18:54:29.108386-07:00"} +{"id":"bd-448","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":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T18:54:29.114894-07:00","updated_at":"2025-10-16T19:08:29.968599-07:00","closed_at":"2025-10-16T19:08:29.968599-07:00"} +{"id":"bd-449","title":"parallel_test_8","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.116433-07:00","updated_at":"2025-10-16T19:08:46.559553-07:00","closed_at":"2025-10-16T19:08:46.559553-07:00"} {"id":"bd-45","title":"Test flush tracking","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.630656-07:00","updated_at":"2025-10-16T18:12:45.743488-07:00","closed_at":"2025-10-16T17:49:54.630656-07:00"} +{"id":"bd-450","title":"parallel_test_9","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.117232-07:00","updated_at":"2025-10-16T19:08:46.518038-07:00","closed_at":"2025-10-16T19:08:46.518038-07:00"} +{"id":"bd-451","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-16T18:54:29.118089-07:00","updated_at":"2025-10-16T18:54:29.118089-07:00"} +{"id":"bd-452","title":"race_test_4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.118929-07:00","updated_at":"2025-10-16T19:08:46.46566-07:00","closed_at":"2025-10-16T19:08:46.46566-07:00"} +{"id":"bd-453","title":"race_test_8","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.120396-07:00","updated_at":"2025-10-16T19:08:46.418144-07:00","closed_at":"2025-10-16T19:08:46.418144-07:00"} +{"id":"bd-454","title":"race_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.121523-07:00","updated_at":"2025-10-16T19:08:46.345986-07:00","closed_at":"2025-10-16T19:08:46.345986-07:00"} +{"id":"bd-455","title":"race_test_16","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.14489-07:00","updated_at":"2025-10-16T19:08:46.308174-07:00","closed_at":"2025-10-16T19:08:46.308174-07:00"} +{"id":"bd-456","title":"race_test_17","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.145877-07:00","updated_at":"2025-10-16T19:08:46.278652-07:00","closed_at":"2025-10-16T19:08:46.278652-07:00"} +{"id":"bd-457","title":"race_test_10","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.159194-07:00","updated_at":"2025-10-16T19:08:46.249105-07:00","closed_at":"2025-10-16T19:08:46.249105-07:00"} +{"id":"bd-458","title":"race_test_11","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.159866-07:00","updated_at":"2025-10-16T19:08:46.205391-07:00","closed_at":"2025-10-16T19:08:46.205391-07:00"} +{"id":"bd-459","title":"final_test_10","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.160672-07:00","updated_at":"2025-10-16T19:08:46.138687-07:00","closed_at":"2025-10-16T19:08:46.138687-07:00"} {"id":"bd-46","title":"Test export cancels timer","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.631027-07:00","updated_at":"2025-10-16T18:12:45.743912-07:00","closed_at":"2025-10-16T17:49:54.631027-07:00"} +{"id":"bd-460","title":"final_test_7","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.163056-07:00","updated_at":"2025-10-16T19:08:46.115153-07:00","closed_at":"2025-10-16T19:08:46.115153-07:00"} +{"id":"bd-461","title":"stress_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.163666-07:00","updated_at":"2025-10-16T19:08:46.094904-07:00","closed_at":"2025-10-16T19:08:46.094904-07:00"} +{"id":"bd-462","title":"stress_test_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.164402-07:00","updated_at":"2025-10-16T19:08:46.06358-07:00","closed_at":"2025-10-16T19:08:46.06358-07:00"} +{"id":"bd-463","title":"stress_test_1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.166004-07:00","updated_at":"2025-10-16T19:08:46.003748-07:00","closed_at":"2025-10-16T19:08:46.003748-07:00"} +{"id":"bd-464","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":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:54:29.167551-07:00","updated_at":"2025-10-16T19:08:29.549505-07:00","closed_at":"2025-10-16T19:08:29.549505-07:00"} +{"id":"bd-465","title":"race_test_4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.173666-07:00","updated_at":"2025-10-16T19:08:45.963556-07:00","closed_at":"2025-10-16T19:08:45.963556-07:00"} +{"id":"bd-466","title":"race_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.187434-07:00","updated_at":"2025-10-16T19:08:45.923654-07:00","closed_at":"2025-10-16T19:08:45.923654-07:00"} +{"id":"bd-467","title":"race_test_2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.189632-07:00","updated_at":"2025-10-16T19:08:45.87778-07:00","closed_at":"2025-10-16T19:08:45.87778-07:00"} +{"id":"bd-468","title":"race_test_7","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.192508-07:00","updated_at":"2025-10-16T19:08:45.841305-07:00","closed_at":"2025-10-16T19:08:45.841305-07:00"} +{"id":"bd-469","title":"race_test_14","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.193776-07:00","updated_at":"2025-10-16T19:08:45.796885-07:00","closed_at":"2025-10-16T19:08:45.796885-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-16T17:49:54.631383-07:00","updated_at":"2025-10-16T18:12:45.744358-07:00","closed_at":"2025-10-16T17:49:54.631383-07:00"} +{"id":"bd-470","title":"race_test_9","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.197319-07:00","updated_at":"2025-10-16T19:08:45.74767-07:00","closed_at":"2025-10-16T19:08:45.74767-07:00"} +{"id":"bd-471","title":"race_test_8","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.198992-07:00","updated_at":"2025-10-16T19:08:45.633664-07:00","closed_at":"2025-10-16T19:08:45.633664-07:00"} +{"id":"bd-472","title":"race_test_11","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.199752-07:00","updated_at":"2025-10-16T19:08:45.573533-07:00","closed_at":"2025-10-16T19:08:45.573533-07:00"} +{"id":"bd-473","title":"race_test_19","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.20066-07:00","updated_at":"2025-10-16T19:08:45.503905-07:00","closed_at":"2025-10-16T19:08:45.503905-07:00"} +{"id":"bd-474","title":"race_test_16","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.201518-07:00","updated_at":"2025-10-16T19:08:45.417553-07:00","closed_at":"2025-10-16T19:08:45.417553-07:00"} +{"id":"bd-475","title":"race_test_18","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.20249-07:00","updated_at":"2025-10-16T19:08:45.386189-07:00","closed_at":"2025-10-16T19:08:45.386189-07:00"} +{"id":"bd-476","title":"race_test_20","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.203114-07:00","updated_at":"2025-10-16T19:08:45.324007-07:00","closed_at":"2025-10-16T19:08:45.324007-07:00"} +{"id":"bd-477","title":"race_test_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.204178-07:00","updated_at":"2025-10-16T19:08:45.179029-07:00","closed_at":"2025-10-16T19:08:45.179029-07:00"} +{"id":"bd-478","title":"race_test_3","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.205082-07:00","updated_at":"2025-10-16T19:08:45.114477-07:00","closed_at":"2025-10-16T19:08:45.114477-07:00"} +{"id":"bd-479","title":"race_test_12","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.206087-07:00","updated_at":"2025-10-16T19:08:44.935945-07:00","closed_at":"2025-10-16T19:08:44.935945-07:00"} {"id":"bd-48","title":"Test incremental 2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.631988-07:00","updated_at":"2025-10-16T18:12:45.74484-07:00","closed_at":"2025-10-16T17:49:54.631988-07:00"} +{"id":"bd-480","title":"race_test_15","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.208689-07:00","updated_at":"2025-10-16T19:08:44.864116-07:00","closed_at":"2025-10-16T19:08:44.864116-07:00"} +{"id":"bd-481","title":"race_test_13","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.209342-07:00","updated_at":"2025-10-16T19:08:44.759492-07:00","closed_at":"2025-10-16T19:08:44.759492-07:00"} +{"id":"bd-482","title":"race_test_10","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.210508-07:00","updated_at":"2025-10-16T19:08:44.717309-07:00","closed_at":"2025-10-16T19:08:44.717309-07:00"} +{"id":"bd-483","title":"race_test_17","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.211541-07:00","updated_at":"2025-10-16T19:08:44.638739-07:00","closed_at":"2025-10-16T19:08:44.638739-07:00"} +{"id":"bd-484","title":"verification_","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.212136-07:00","updated_at":"2025-10-16T19:08:44.43951-07:00","closed_at":"2025-10-16T19:08:44.43951-07:00"} +{"id":"bd-485","title":"final_review_test_","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.214252-07:00","updated_at":"2025-10-16T19:08:44.327013-07:00","closed_at":"2025-10-16T19:08:44.327013-07:00"} +{"id":"bd-486","title":"P2: Consider batching API for bulk issue creation","description":"Current CreateIssue acquires a dedicated connection for each call. For bulk imports or agent workflows creating many issues, a batched API could improve performance:\n\nCreateIssues(ctx, issues []*Issue, actor string) error\n\nThis would:\n- Acquire one connection\n- Use one IMMEDIATE transaction\n- Insert all issues atomically\n- Reduce connection overhead\n\nNot urgent - current approach is correct and fast enough for typical use.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:54:29.215696-07:00","updated_at":"2025-10-16T19:08:32.867625-07:00","closed_at":"2025-10-16T19:08:32.867625-07:00"} +{"id":"bd-487","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":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T18:54:29.217094-07:00","updated_at":"2025-10-16T19:08:30.516471-07:00","closed_at":"2025-10-16T19:08:30.516471-07:00"} +{"id":"bd-488","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":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:54:29.219427-07:00","updated_at":"2025-10-16T19:08:31.091029-07:00","closed_at":"2025-10-16T19:08:31.091029-07:00"} +{"id":"bd-489","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":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:54:29.220414-07:00","updated_at":"2025-10-16T19:08:29.802389-07:00","closed_at":"2025-10-16T19:08:29.802389-07:00"} {"id":"bd-49","title":"Final test","description":"Testing with new binary","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T17:49:54.63243-07:00","updated_at":"2025-10-16T18:12:45.745253-07:00","closed_at":"2025-10-16T17:49:54.63243-07:00"} -{"id":"bd-5","title":"Test issue","description":"Testing prefix","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.632831-07:00","updated_at":"2025-10-16T18:12:45.745684-07:00","closed_at":"2025-10-16T17:49:54.632831-07:00","dependencies":[{"issue_id":"bd-5","depends_on_id":"bd-375","type":"parent-child","created_at":"2025-10-16T17:49:54.873276-07:00","created_by":"auto-import"},{"issue_id":"bd-5","depends_on_id":"bd-388","type":"parent-child","created_at":"2025-10-16T17:49:54.873836-07:00","created_by":"auto-import"}]} +{"id":"bd-490","title":"Code review: Auto-import collision detection fix (bd-228)","description":"Request thorough code review of the auto-import collision detection implementation.\n\n## Files Changed\n- cmd/bd/main.go: autoImportIfNewer() and new autoImportWithoutCollisionDetection()\n\n## Review Focus Areas\n\n### 1. Correctness\n- Does collision detection properly identify conflicts?\n- Are colliding issues correctly filtered from import?\n- Is the fallback function correct for non-SQLite backends?\n\n### 2. Edge Cases\n- What happens if DetectCollisions() fails?\n- What if all issues are collisions?\n- What if JSONL is malformed?\n- Race conditions with concurrent auto-imports?\n\n### 3. User Experience\n- Is the warning message clear and actionable?\n- Should we log to a file instead of/in addition to stderr?\n- Should there be a --auto-resolve flag?\n\n### 4. Performance\n- Does collision detection add significant latency?\n- Will this work with 1000+ issues?\n- Any unnecessary N+1 queries?\n\n### 5. Testing Gaps\n- Do we need integration tests for collision scenarios?\n- Should we test the warning output?\n- Test autoImportWithoutCollisionDetection() fallback?\n\n## Questions for Reviewer\n1. Should auto-import be more aggressive (auto-resolve) or more conservative (fail)?\n2. Should we add a counter for how many times collisions occurred?\n3. Should there be a config option to disable collision detection?\n4. Is the warning too verbose for typical workflows?\n\n## Current Behavior\n- Skips colliding issues (preserves local)\n- Prints warning to stderr\n- Suggests manual resolution command\n- Continues with non-colliding issues","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:54:29.222585-07:00","updated_at":"2025-10-16T19:08:30.135248-07:00","closed_at":"2025-10-16T19:08:30.135248-07:00"} +{"id":"bd-491","title":"Add integration tests for auto-import collision detection","description":"The auto-import collision detection fix (bd-376) needs comprehensive integration tests.\n\n## Test Scenarios Needed\n\n### 1. Basic Collision Detection\n```go\nTestAutoImportWithCollisions\n- Setup: Create issue in DB with status=closed\n- Simulate: Git pull with JSONL containing same issue with status=open\n- Verify: Local changes preserved, warning printed, issue still closed\n```\n\n### 2. Multiple Collisions\n```go\nTestAutoImportWithMultipleCollisions\n- Setup: 5 issues with local modifications\n- Simulate: JSONL with 3 colliding, 2 matching\n- Verify: 3 skipped, 2 updated, appropriate warnings\n```\n\n### 3. No Collisions (Happy Path)\n```go\nTestAutoImportWithoutCollisions\n- Setup: Clean database\n- Simulate: JSONL with new issues + exact matches\n- Verify: All imported successfully, no warnings\n```\n\n### 4. All Collisions\n```go\nTestAutoImportAllCollisions\n- Setup: Every issue has local modifications\n- Simulate: JSONL with conflicting versions\n- Verify: All skipped, warning lists all issues\n```\n\n### 5. Collision Detection Failure\n```go\nTestAutoImportCollisionDetectionError\n- Setup: Mock DetectCollisions() to return error\n- Verify: Import skipped entirely (safe failure mode)\n```\n\n### 6. Hash-Based Skip\n```go\nTestAutoImportHashUnchanged\n- Setup: JSONL hash matches last_import_hash\n- Verify: No collision detection runs, fast path\n```\n\n### 7. Fallback for Non-SQLite\n```go\nTestAutoImportWithoutCollisionDetection\n- Setup: Mock non-SQLite storage backend\n- Verify: Falls back to old behavior, no collision detection\n```\n\n## Test Infrastructure Needed\n\n1. **Helper functions:**\n - createTestDBWithIssues()\n - writeJSONLFile()\n - captureStderrWarnings()\n - simulateGitPull()\n\n2. **Fixtures:**\n - sample-collisions.jsonl\n - sample-exact-matches.jsonl\n - sample-mixed.jsonl\n\n3. **Assertions:**\n - assertIssueState(id, expectedStatus)\n - assertWarningContains(text)\n - assertCollisionCount(n)\n\n## Acceptance Criteria\n- All 7 test scenarios implemented\n- Tests pass consistently\n- Code coverage \u003e80% for autoImportIfNewer()\n- Tests run in \u003c5 seconds total\n- Clear test names and documentation","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-16T18:54:29.224122-07:00","updated_at":"2025-10-16T18:54:29.224122-07:00"} +{"id":"bd-492","title":"Consider batching API for bulk issue creation (recovered from bd-222)","description":"Current CreateIssue acquires a dedicated connection for each call. For bulk imports or agent workflows creating many issues, a batched API could improve performance:\n\nCreateIssues(ctx, issues []*Issue, actor string) error\n\nThis would:\n- Acquire one connection\n- Use one IMMEDIATE transaction\n- Insert all issues atomically\n- Reduce connection overhead\n\nNot urgent - current approach is correct and fast enough for typical use.\n\n**Recovered from:** bd-360 (lost in auto-import bug, see LOST_ISSUES_RECOVERY.md)","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:54:29.225697-07:00","updated_at":"2025-10-16T19:08:30.372173-07:00","closed_at":"2025-10-16T19:08:30.372173-07:00"} +{"id":"bd-493","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":"closed","priority":3,"issue_type":"bug","created_at":"2025-10-16T18:54:29.226626-07:00","updated_at":"2025-10-16T19:08:32.723891-07:00","closed_at":"2025-10-16T19:08:32.723891-07:00"} +{"id":"bd-494","title":"Use safer placeholder pattern in replaceIDReferences","description":"Currently uses bd-324 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":"closed","priority":3,"issue_type":"task","created_at":"2025-10-16T18:54:29.227598-07:00","updated_at":"2025-10-16T19:08:33.478999-07:00","closed_at":"2025-10-16T19:08:33.478999-07:00"} +{"id":"bd-495","title":"Git-based restoration for compacted issues","description":"Store git commit hash at compaction time to enable restoration of full issue history from version control. When issues are compacted, record the current git commit hash so users can restore the original uncompacted issue from git history.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:54:29.228422-07:00","updated_at":"2025-10-16T19:08:32.031676-07:00","closed_at":"2025-10-16T19:08:32.031676-07:00"} +{"id":"bd-496","title":"Add compacted_at_commit field to Issue type","description":"Add optional compacted_at_commit string field to store git commit hash when issue is compacted","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:54:29.229357-07:00","updated_at":"2025-10-16T19:08:29.459423-07:00","closed_at":"2025-10-16T19:08:29.459423-07:00"} +{"id":"bd-497","title":"Record git commit hash during compaction","description":"Update compact command to capture current git HEAD commit hash and store in compacted_at_commit field","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:54:29.231369-07:00","updated_at":"2025-10-16T19:08:33.338861-07:00","closed_at":"2025-10-16T19:08:33.338861-07:00"} +{"id":"bd-498","title":"Implement bd restore command","description":"Create new restore command that checks out git commit from compacted_at_commit, reads issue from JSONL, and displays full history","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T18:54:29.232439-07:00","updated_at":"2025-10-16T19:08:32.500355-07:00","closed_at":"2025-10-16T19:08:32.500355-07:00"} +{"id":"bd-499","title":"parallel_test_3","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.236426-07:00","updated_at":"2025-10-16T19:08:44.295669-07:00","closed_at":"2025-10-16T19:08:44.295669-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-16T14:33:21.385874-07:00","closed_at":"2025-10-15T03:01:29.581496-07:00","dependencies":[{"issue_id":"bd-5","depends_on_id":"bd-388","type":"parent-child","created_at":"2025-10-16T14:57:49.125077-07:00","created_by":"import-remap"},{"issue_id":"bd-5","depends_on_id":"bd-657","type":"parent-child","created_at":"2025-10-16T18:57:16.760805-07:00","created_by":"import-remap"},{"issue_id":"bd-5","depends_on_id":"bd-375","type":"parent-child","created_at":"2025-10-16T18:57:17.011865-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-16T17:49:54.633248-07:00","updated_at":"2025-10-16T18:12:45.746115-07:00","closed_at":"2025-10-16T17:49:54.633248-07:00"} +{"id":"bd-500","title":"parallel_test_10","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.237287-07:00","updated_at":"2025-10-16T19:08:44.249379-07:00","closed_at":"2025-10-16T19:08:44.249379-07:00"} +{"id":"bd-501","title":"parallel_test_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.238225-07:00","updated_at":"2025-10-16T18:54:29.238225-07:00","closed_at":"2025-10-16T17:49:54.468584-07:00"} +{"id":"bd-502","title":"parallel_test_2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.239523-07:00","updated_at":"2025-10-16T18:54:29.239523-07:00","closed_at":"2025-10-16T17:49:54.412382-07:00"} +{"id":"bd-503","title":"parallel_test_2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.241214-07:00","updated_at":"2025-10-16T19:08:44.208634-07:00","closed_at":"2025-10-16T19:08:44.208634-07:00"} +{"id":"bd-504","title":"parallel_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.242009-07:00","updated_at":"2025-10-16T19:08:44.171776-07:00","closed_at":"2025-10-16T19:08:44.171776-07:00"} +{"id":"bd-505","title":"parallel_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.242834-07:00","updated_at":"2025-10-16T18:54:29.242834-07:00","closed_at":"2025-10-16T17:49:54.467576-07:00"} +{"id":"bd-506","title":"Concurrent bd commands collide on shared .tmp filename","description":"When multiple bd commands run concurrently (e.g., different agents), they all write to .beads/issues.jsonl.tmp causing race conditions. One command's rename succeeds, consuming the .tmp file, then other commands fail with 'no such file or directory'. Solution: use unique temp filenames with PID or random suffix (e.g., issues.jsonl.tmp.12345).","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T18:54:29.244231-07:00","updated_at":"2025-10-16T18:54:29.244231-07:00","closed_at":"2025-10-16T17:49:54.323841-07:00"} +{"id":"bd-507","title":"parallel_test_4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.246065-07:00","updated_at":"2025-10-16T18:54:29.246065-07:00","closed_at":"2025-10-16T17:49:54.469639-07:00"} +{"id":"bd-508","title":"parallel_test_1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.246693-07:00","updated_at":"2025-10-16T18:54:29.246693-07:00","closed_at":"2025-10-16T17:49:54.471168-07:00"} +{"id":"bd-509","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":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:54:29.247674-07:00","updated_at":"2025-10-16T18:54:29.247674-07:00","closed_at":"2025-10-16T17:49:54.471547-07:00","external_ref":"gh-11"} {"id":"bd-51","title":"Test hash-based import","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.633709-07:00","updated_at":"2025-10-16T18:12:45.746536-07:00","closed_at":"2025-10-16T17:49:54.633709-07:00"} +{"id":"bd-510","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.","notes":"Awaiting user feedback - cannot reproduce locally, waiting for user to provide more details about environment and error message","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T18:54:29.254527-07:00","updated_at":"2025-10-16T19:08:31.607028-07:00","closed_at":"2025-10-16T19:08:31.607028-07:00","external_ref":"gh-3"} +{"id":"bd-511","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":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T18:54:29.258757-07:00","updated_at":"2025-10-16T18:54:29.258757-07:00","closed_at":"2025-10-16T17:49:54.472336-07:00"} +{"id":"bd-512","title":"parallel_test_3","description":"","design":"Review GH-11 requirements:\n- User wants to use beads across multiple dev machines\n- Docker hosting was proposed solution\n\nNew approach:\n- Phase 1: Pure git-based sync (no Docker needed)\n- Phase 2: Optional Docker gateway for convenience\n- Addresses use case without mandating server\n\nUpdate GH-11 with:\n- Link to DESIGN-GIT-SYNC.md\n- Explain git-based approach\n- Note optional Docker gateway\n- Ask for feedback\n\nClose issue when sync features implemented.","acceptance_criteria":"- GH-11 reviewed and understood\n- Comment added explaining sync approach\n- Link to design document\n- User feedback requested\n- Issue closed when Phase 1-2 complete\n- Documentation cross-referenced","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.25947-07:00","updated_at":"2025-10-16T19:08:44.103705-07:00","closed_at":"2025-10-16T19:08:44.103705-07:00"} +{"id":"bd-513","title":"parallel_test_5","description":"","acceptance_criteria":"Can add/remove/list labels via CLI, can filter issues by label, labels persist to JSONL","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.265467-07:00","updated_at":"2025-10-16T19:08:44.027323-07:00","closed_at":"2025-10-16T19:08:44.027323-07:00"} +{"id":"bd-514","title":"Add performance benchmarks document","description":"Document actual performance metrics with hyperfine tests","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-16T18:54:29.278305-07:00","updated_at":"2025-10-16T18:54:29.278305-07:00","closed_at":"2025-10-16T17:49:54.480313-07:00"} +{"id":"bd-515","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.","design":"Federation allows:\n- Multiple gateways sync with each other\n- Each gateway has authoritative set of issues\n- Peer-to-peer sync protocol\n- Conflict resolution across gateways\n\nArchitecture:\n- Gateway-to-gateway API\n- Peer discovery\n- Sync protocol between gateways\n- Distributed conflict resolution\n\nComplex feature - only if team usage emerges.","acceptance_criteria":"- Gateway federation protocol designed\n- Peer discovery mechanism\n- Gateway-to-gateway sync\n- Distributed conflict resolution\n- Tests for federation\n- Documentation in FEDERATION.md\n\n---","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-10-16T18:54:29.279242-07:00","updated_at":"2025-10-16T19:08:32.703267-07:00","closed_at":"2025-10-16T19:08:32.703267-07:00"} +{"id":"bd-516","title":"parallel_test_1","description":"","design":"Add new section: \"Multi-Device Sync\"\n\nContent:\n- Brief overview of git-based sync\n- Link to SYNC.md for details\n- Link to GATEWAY.md for gateway mode\n- Quick start examples\n- Configuration options\n\nKeep brief - detailed docs in separate files.","acceptance_criteria":"- README.md updated with sync section\n- Links to SYNC.md and GATEWAY.md\n- Quick start examples\n- Configuration overview\n- Maintains existing structure\n- All links working\n\n---","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.280457-07:00","updated_at":"2025-10-16T19:08:43.935627-07:00","closed_at":"2025-10-16T19:08:43.935627-07:00"} +{"id":"bd-517","title":"verification_","description":"","design":"Sections:\n1. Introduction\n2. Quick Start\n3. Manual Git Workflow\n4. bd sync Command\n5. bd daemon Background Sync\n6. Git Hooks\n7. Conflict Resolution\n8. Best Practices\n9. Troubleshooting\n10. FAQ\n\nInclude examples, code snippets, and diagrams.","acceptance_criteria":"- SYNC.md created with all sections\n- Quick start guide for new users\n- Detailed workflow examples\n- Conflict resolution guide\n- Best practices section\n- Troubleshooting with solutions\n- FAQ with common questions\n- Code examples working\n- Links from README.md\n\n---","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.281281-07:00","updated_at":"2025-10-16T19:08:43.819217-07:00","closed_at":"2025-10-16T19:08:43.819217-07:00"} +{"id":"bd-518","title":"parallel_test_4","description":"","design":"Sections:\n1. Introduction\n2. Authentication\n3. REST Endpoints\n4. WebSocket Protocol\n5. Error Handling\n6. Rate Limits\n7. Examples\n\nFor each endpoint:\n- URL and method\n- Request parameters\n- Request body schema\n- Response schema\n- Error responses\n- Code example","acceptance_criteria":"- API.md created with all sections\n- All endpoints documented\n- Request/response schemas\n- WebSocket protocol docs\n- Error codes and handling\n- Rate limit documentation\n- Examples in multiple languages\n- Links from README.md\n\n---","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.291492-07:00","updated_at":"2025-10-16T19:08:43.682991-07:00","closed_at":"2025-10-16T19:08:43.682991-07:00"} +{"id":"bd-519","title":"parallel_test_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.296165-07:00","updated_at":"2025-10-16T19:08:43.529542-07:00","closed_at":"2025-10-16T19:08:43.529542-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-16T17:49:54.634235-07:00","updated_at":"2025-10-16T18:12:45.746983-07:00","closed_at":"2025-10-16T17:49:54.634235-07:00"} +{"id":"bd-520","title":"parallel_test_7","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.29821-07:00","updated_at":"2025-10-16T19:08:43.491037-07:00","closed_at":"2025-10-16T19:08:43.491037-07:00"} +{"id":"bd-521","title":"parallel_test_4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.299627-07:00","updated_at":"2025-10-16T19:08:43.398243-07:00","closed_at":"2025-10-16T19:08:43.398243-07:00"} +{"id":"bd-522","title":"parallel_test_1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.311149-07:00","updated_at":"2025-10-16T19:08:43.332085-07:00","closed_at":"2025-10-16T19:08:43.332085-07:00"} +{"id":"bd-523","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":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:54:29.323831-07:00","updated_at":"2025-10-16T19:08:31.431304-07:00","closed_at":"2025-10-16T19:08:31.431304-07:00","external_ref":"gh-11"} +{"id":"bd-524","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":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T18:54:29.324466-07:00","updated_at":"2025-10-16T19:08:31.545562-07:00","closed_at":"2025-10-16T19:08:31.545562-07:00","external_ref":"gh-3"} +{"id":"bd-525","title":"Document git-based restoration feature","description":"Update COMPACTION.md and README.md with restoration workflow and examples","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.325521-07:00","updated_at":"2025-10-16T19:08:30.833215-07:00","closed_at":"2025-10-16T19:08:30.833215-07:00"} +{"id":"bd-526","title":"Reach 1.0 release milestone","description":"Stabilize API, finalize documentation, comprehensive testing","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:54:29.34597-07:00","updated_at":"2025-10-16T19:08:32.98196-07:00","closed_at":"2025-10-16T19:08:32.98196-07:00"} +{"id":"bd-527","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":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:54:29.363772-07:00","updated_at":"2025-10-16T19:08:30.013283-07:00","closed_at":"2025-10-16T19:08:30.013283-07:00"} +{"id":"bd-528","title":"Add performance benchmarks document","description":"Document actual performance metrics with hyperfine tests","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-16T18:54:29.365021-07:00","updated_at":"2025-10-16T19:08:29.708631-07:00","closed_at":"2025-10-16T19:08:29.708631-07:00"} +{"id":"bd-529","title":"Add migration scripts for GitHub Issues","description":"Create scripts to import from GitHub Issues API or exported JSON","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:54:29.365728-07:00","updated_at":"2025-10-16T19:08:29.605356-07:00","closed_at":"2025-10-16T19:08:29.605356-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-16T17:49:54.634631-07:00","updated_at":"2025-10-16T18:12:45.747565-07:00","closed_at":"2025-10-16T17:49:54.634631-07:00","dependencies":[{"issue_id":"bd-53","depends_on_id":"bd-52","type":"parent-child","created_at":"2025-10-16T17:49:54.874357-07:00","created_by":"auto-import"}]} +{"id":"bd-530","title":"Bug: Import creating duplicates instead of deduplicating","description":"Git log shows \"73 issues remapped\" during merge, suggesting --resolve-collisions is creating duplicate issues with new IDs instead of recognizing they're identical and deduplicating them.\n\nEvidence: bd-488, bd-367, bd-396 are all \"Epic: Fix status/closed_at inconsistency\" with identical content but different IDs and timestamps.\n\nRoot cause likely in DetectCollisions or --resolve-collisions logic - it's treating content-identical issues as collisions when they should be exact matches.","design":"**Root Cause Found:**\n\nDetectCollisions only checks if incoming issues exist in the DB. It doesn't deduplicate within the incoming JSONL batch itself.\n\nWhen JSONL contains multiple issues with:\n- Different IDs (bd-488, bd-367, bd-396)\n- Identical content\n- Different timestamps\n\nDetectCollisions treats them all as \"new issues\" because none exist in DB, then --resolve-collisions leaves them as-is.\n\n**Fix:**\nAdd deduplication step in DetectCollisions to detect content-identical issues within the incoming batch and consolidate them before processing.","notes":"**Fixed in commit [pending]**\n\nChanges made:\n1. Added `deduplicateIncomingIssues()` function in collision.go\n2. Modified `DetectCollisions()` to call deduplication before processing\n3. Deduplication consolidates content-identical issues, keeping smallest ID\n4. Added comprehensive test suite in collision_dedup_test.go\n\nResult: Importing JSONL with duplicates now correctly consolidates them instead of creating multiple copies.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T18:54:29.367086-07:00","updated_at":"2025-10-16T18:54:29.425365-07:00","closed_at":"2025-10-16T17:52:35.575954-07:00"} +{"id":"bd-531","title":"Implement bd restore command","description":"Create new restore command that checks out git commit from compacted_at_commit, reads issue from JSONL, and displays full history","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T18:54:29.370445-07:00","updated_at":"2025-10-16T19:08:32.446443-07:00","closed_at":"2025-10-16T19:08:32.446443-07:00"} +{"id":"bd-532","title":"Add compacted_at_commit field to Issue type","description":"Add optional compacted_at_commit string field to store git commit hash when issue is compacted","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:54:29.372914-07:00","updated_at":"2025-10-16T19:08:29.376257-07:00","closed_at":"2025-10-16T19:08:29.376257-07:00"} +{"id":"bd-533","title":"Record git commit hash during compaction","description":"Update compact command to capture current git HEAD commit hash and store in compacted_at_commit field","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:54:29.377847-07:00","updated_at":"2025-10-16T19:08:33.291602-07:00","closed_at":"2025-10-16T19:08:33.291602-07:00"} +{"id":"bd-534","title":"Low priority chore","description":"","status":"closed","priority":4,"issue_type":"chore","created_at":"2025-10-16T18:54:29.378627-07:00","updated_at":"2025-10-16T19:08:32.821878-07:00","closed_at":"2025-10-16T19:08:32.821878-07:00"} +{"id":"bd-535","title":"Add integration tests for auto-import collision detection","description":"The auto-import collision detection fix (bd-376) needs comprehensive integration tests.\n\n## Test Scenarios Needed\n\n### 1. Basic Collision Detection\n```go\nTestAutoImportWithCollisions\n- Setup: Create issue in DB with status=closed\n- Simulate: Git pull with JSONL containing same issue with status=open\n- Verify: Local changes preserved, warning printed, issue still closed\n```\n\n### 2. Multiple Collisions\n```go\nTestAutoImportWithMultipleCollisions\n- Setup: 5 issues with local modifications\n- Simulate: JSONL with 3 colliding, 2 matching\n- Verify: 3 skipped, 2 updated, appropriate warnings\n```\n\n### 3. No Collisions (Happy Path)\n```go\nTestAutoImportWithoutCollisions\n- Setup: Clean database\n- Simulate: JSONL with new issues + exact matches\n- Verify: All imported successfully, no warnings\n```\n\n### 4. All Collisions\n```go\nTestAutoImportAllCollisions\n- Setup: Every issue has local modifications\n- Simulate: JSONL with conflicting versions\n- Verify: All skipped, warning lists all issues\n```\n\n### 5. Collision Detection Failure\n```go\nTestAutoImportCollisionDetectionError\n- Setup: Mock DetectCollisions() to return error\n- Verify: Import skipped entirely (safe failure mode)\n```\n\n### 6. Hash-Based Skip\n```go\nTestAutoImportHashUnchanged\n- Setup: JSONL hash matches last_import_hash\n- Verify: No collision detection runs, fast path\n```\n\n### 7. Fallback for Non-SQLite\n```go\nTestAutoImportWithoutCollisionDetection\n- Setup: Mock non-SQLite storage backend\n- Verify: Falls back to old behavior, no collision detection\n```\n\n## Test Infrastructure Needed\n\n1. **Helper functions:**\n - createTestDBWithIssues()\n - writeJSONLFile()\n - captureStderrWarnings()\n - simulateGitPull()\n\n2. **Fixtures:**\n - sample-collisions.jsonl\n - sample-exact-matches.jsonl\n - sample-mixed.jsonl\n\n3. **Assertions:**\n - assertIssueState(id, expectedStatus)\n - assertWarningContains(text)\n - assertCollisionCount(n)\n\n## Acceptance Criteria\n- All 7 test scenarios implemented\n- Tests pass consistently\n- Code coverage \u003e80% for autoImportIfNewer()\n- Tests run in \u003c5 seconds total\n- Clear test names and documentation","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:54:29.379553-07:00","updated_at":"2025-10-16T18:54:29.379553-07:00","closed_at":"2025-10-16T17:49:54.608432-07:00"} +{"id":"bd-536","title":"Consider batching API for bulk issue creation (recovered from bd-222)","description":"Current CreateIssue acquires a dedicated connection for each call. For bulk imports or agent workflows creating many issues, a batched API could improve performance:\n\nCreateIssues(ctx, issues []*Issue, actor string) error\n\nThis would:\n- Acquire one connection\n- Use one IMMEDIATE transaction\n- Insert all issues atomically\n- Reduce connection overhead\n\nNot urgent - current approach is correct and fast enough for typical use.\n\n**Recovered from:** bd-390 (lost in auto-import bug, see LOST_ISSUES_RECOVERY.md)","notes":"Investigation complete. Successfully recovered 3 valuable issues (bd-536, bd-233) from 22 total lost. Historical context preserved in bd-89 notes. Auto-import collision detection (bd-552) now prevents future data loss.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:54:29.380494-07:00","updated_at":"2025-10-16T19:08:30.3355-07:00","closed_at":"2025-10-16T19:08:30.3355-07:00"} +{"id":"bd-537","title":"Ultrathink: Choose solution for status/closed_at inconsistency (bd-224)","description":"Deep analysis of solution options for bd-538 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-16T18:54:29.38148-07:00","updated_at":"2025-10-16T18:54:29.453069-07:00","closed_at":"2025-10-16T17:49:54.227815-07:00","dependencies":[{"issue_id":"bd-537","depends_on_id":"bd-391","type":"discovered-from","created_at":"2025-10-16T18:54:29.863977-07:00","created_by":"import-remap"}]} +{"id":"bd-538","title":"Concurrent bd commands collide on shared .tmp filename","description":"When multiple bd commands run concurrently (e.g., different agents), they all write to .beads/issues.jsonl.tmp causing race conditions. One command's rename succeeds, consuming the .tmp file, then other commands fail with 'no such file or directory'. Solution: use unique temp filenames with PID or random suffix (e.g., issues.jsonl.tmp.12345).","notes":"Label management fully implemented with comprehensive test coverage (10 test cases). Provides foundation for better data organization and filtering.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T18:54:29.382598-07:00","updated_at":"2025-10-16T18:54:29.382598-07:00","closed_at":"2025-10-16T17:49:54.496208-07:00"} +{"id":"bd-539","title":"Investigate data recovery for issues overwritten by auto-import bug","description":"Auto-import bug (bd-376) has been silently overwriting local changes since the feature was introduced. We need to investigate if any important data was lost and if it can be recovered.\n\n## Data Sources for Recovery\n\n1. **Git history of .beads/issues.jsonl** - May contain older versions with lost changes\n2. **Events table** - Has full audit trail with old_value/new_value\n3. **Commit messages** - May reference work that was done but later overwritten\n\n## Investigation Steps\n\n1. Check events table for patterns:\n - Look for auto-import events that changed status from closed → open\n - Look for manual updates followed by auto-import reverts\n - Identify issues with suspicious event sequences\n\n2. Git archaeology:\n - Check git log for .beads/issues.jsonl\n - Look for commits where status=closed was changed to status=open\n - Compare git history vs current database state\n\n3. Document lost work:\n - Create list of issues that were closed but reverted to open\n - Identify any critical work that was marked done but lost\n - Check if any issue references are now broken\n\n## Recovery Actions\n\nIf significant data loss is found:\n- Create script to reconstruct lost state from events table\n- Manually review and restore critical closed issues\n- Document lessons learned for preventing future data loss\n\n## Example Query\n\n```sql\n-- Find issues where status was manually changed then reverted by auto-import\nSELECT \n issue_id,\n GROUP_CONCAT(event_type || ':' || actor, ' -\u003e ') as event_chain\nFROM events \nWHERE issue_id IN (\n SELECT DISTINCT issue_id \n FROM events \n WHERE actor = 'auto-import' AND event_type = 'status_changed'\n)\nGROUP BY issue_id\nHAVING event_chain LIKE '%stevey%auto-import%';\n```","notes":"Investigation complete. Successfully recovered 3 valuable issues (bd-367, bd-233) from 22 total lost. Historical context preserved in bd-89 notes. Auto-import collision detection (bd-376) now prevents future data loss.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:54:29.383454-07:00","updated_at":"2025-10-16T18:54:29.383454-07:00","closed_at":"2025-10-16T17:49:54.230133-07:00","dependencies":[{"issue_id":"bd-539","depends_on_id":"bd-552","type":"discovered-from","created_at":"2025-10-16T18:54:29.852047-07:00","created_by":"import-remap"}]} {"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-16T17:49:54.635002-07:00","updated_at":"2025-10-16T18:12:45.74808-07:00","closed_at":"2025-10-16T17:49:54.635002-07:00","dependencies":[{"issue_id":"bd-54","depends_on_id":"bd-52","type":"parent-child","created_at":"2025-10-16T17:49:54.874995-07:00","created_by":"auto-import"}]} +{"id":"bd-540","title":"Reach 1.0 release milestone","description":"Stabilize API, finalize documentation, comprehensive testing","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:54:29.38494-07:00","updated_at":"2025-10-16T18:54:29.38494-07:00","closed_at":"2025-10-16T17:49:54.505862-07:00","dependencies":[{"issue_id":"bd-540","depends_on_id":"bd-270","type":"discovered-from","created_at":"2025-10-16T18:54:29.858198-07:00","created_by":"import-remap"}]} +{"id":"bd-541","title":"parallel_test_7","description":"","design":"Add validation in AddDependency that checks if dep.Type == DepParentChild and validates the direction is correct (parent depends on child, not child on parent). Reject with clear error message if direction is backwards.","acceptance_criteria":"- Child→parent dependencies are rejected with clear error\n- Parent→child dependencies work as expected\n- Error message explains correct direction\n- Tests cover both valid and invalid cases","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.38566-07:00","updated_at":"2025-10-16T18:54:29.38566-07:00","closed_at":"2025-10-16T17:49:54.340717-07:00","dependencies":[{"issue_id":"bd-541","depends_on_id":"bd-307","type":"parent-child","created_at":"2025-10-16T18:54:29.842315-07:00","created_by":"import-remap"}]} +{"id":"bd-542","title":"Low priority chore","description":"","status":"closed","priority":4,"issue_type":"chore","created_at":"2025-10-16T18:54:29.386684-07:00","updated_at":"2025-10-16T18:54:29.386684-07:00","closed_at":"2025-10-16T17:49:54.489847-07:00","dependencies":[{"issue_id":"bd-542","depends_on_id":"bd-382","type":"blocks","created_at":"2025-10-16T18:54:29.834761-07:00","created_by":"import-remap"}]} +{"id":"bd-543","title":"Add migration scripts for GitHub Issues","description":"Create scripts to import from GitHub Issues API or exported JSON","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:54:29.387481-07:00","updated_at":"2025-10-16T18:54:29.387481-07:00","closed_at":"2025-10-16T17:49:54.490276-07:00","dependencies":[{"issue_id":"bd-543","depends_on_id":"bd-367","type":"parent-child","created_at":"2025-10-16T18:54:29.929763-07:00","created_by":"import-remap"}]} +{"id":"bd-544","title":"parallel_test_9","description":"","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":2,"issue_type":"task","created_at":"2025-10-16T18:54:29.3881-07:00","updated_at":"2025-10-16T18:54:29.3881-07:00","closed_at":"2025-10-16T17:49:54.491748-07:00"} +{"id":"bd-545","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-551) while handling distributed creation gracefully.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T18:54:29.3909-07:00","updated_at":"2025-10-16T18:54:29.444156-07:00","closed_at":"2025-10-16T17:49:54.510752-07:00","dependencies":[{"issue_id":"bd-545","depends_on_id":"bd-552","type":"discovered-from","created_at":"2025-10-16T18:54:29.853074-07:00","created_by":"import-remap"}]} +{"id":"bd-546","title":"Add compacted_at_commit field to Issue type","description":"Add optional compacted_at_commit string field to store git commit hash when issue is compacted","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:54:29.391902-07:00","updated_at":"2025-10-16T19:08:29.310433-07:00","closed_at":"2025-10-16T19:08:29.310433-07:00","dependencies":[{"issue_id":"bd-546","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T18:54:29.934963-07:00","created_by":"import-remap"}]} +{"id":"bd-547","title":"Low priority chore","description":"","design":"Benchmarks for:\n1. JSONL import/export performance\n2. Collision detection performance\n3. Three-way merge performance\n4. Gateway API latency\n5. WebSocket throughput\n6. Concurrent client handling\n7. Large database operations (10k+ issues)\n\nUse Go benchmarking and profiling tools.\n\nTrack performance over time in CI.","acceptance_criteria":"- Benchmark suite implemented\n- All key operations benchmarked\n- CPU and memory profiling\n- Large database benchmarks\n- Concurrent operation benchmarks\n- CI integration for regression detection\n- Performance baseline documented\n- Documentation in PERFORMANCE.md\n\n---","status":"closed","priority":4,"issue_type":"chore","created_at":"2025-10-16T18:54:29.392669-07:00","updated_at":"2025-10-16T19:08:32.802673-07:00","closed_at":"2025-10-16T19:08:32.802673-07:00","dependencies":[{"issue_id":"bd-547","depends_on_id":"bd-388","type":"parent-child","created_at":"2025-10-16T18:54:29.915575-07:00","created_by":"import-remap"}]} +{"id":"bd-548","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","design":"Command should:\n1. Export pending changes to JSONL\n2. Commit changes to git\n3. Pull from remote (with conflict resolution)\n4. Push local commits to remote\n\nWraps the entire sync workflow in one command for better UX.","acceptance_criteria":"- bd sync command implemented\n- Exports dirty changes to JSONL automatically\n- Commits to git with descriptive message\n- Pulls and handles merge conflicts\n- Auto-imports updated JSONL\n- Pushes to remote\n- Error handling for git failures\n- Tests cover success and failure scenarios\n- Documentation in README.md\n\n---","notes":"All tasks completed: bd-64 (performance), bd-65 (migration), bd-66 (version sync), bd-67 (version script), bd-69 (CI coverage), bd-70 (test coverage). Code review follow-up complete.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:54:29.398351-07:00","updated_at":"2025-10-16T18:54:29.398351-07:00","closed_at":"2025-10-16T17:49:54.510305-07:00","dependencies":[{"issue_id":"bd-548","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T18:54:29.924-07:00","created_by":"import-remap"}]} +{"id":"bd-549","title":"Implement bd restore command","description":"Create new restore command that checks out git commit from compacted_at_commit, reads issue from JSONL, and displays full history","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T18:54:29.399249-07:00","updated_at":"2025-10-16T19:08:32.379228-07:00","closed_at":"2025-10-16T19:08:32.379228-07:00","dependencies":[{"issue_id":"bd-549","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T18:54:29.839621-07:00","created_by":"import-remap"}]} {"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-16T17:49:54.635418-07:00","updated_at":"2025-10-16T18:12:45.748667-07:00","closed_at":"2025-10-16T17:49:54.635418-07:00","dependencies":[{"issue_id":"bd-55","depends_on_id":"bd-52","type":"parent-child","created_at":"2025-10-16T17:49:54.875667-07:00","created_by":"auto-import"}]} +{"id":"bd-550","title":"Git-based restoration for compacted issues","description":"Store git commit hash at compaction time to enable restoration of full issue history from version control. When issues are compacted, record the current git commit hash so users can restore the original uncompacted issue from git history.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:54:29.405556-07:00","updated_at":"2025-10-16T19:08:31.96913-07:00","closed_at":"2025-10-16T19:08:31.96913-07:00","dependencies":[{"issue_id":"bd-550","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T18:54:29.891731-07:00","created_by":"import-remap"}]} +{"id":"bd-551","title":"Record git commit hash during compaction","description":"Update compact command to capture current git HEAD commit hash and store in compacted_at_commit field","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:54:29.406385-07:00","updated_at":"2025-10-16T19:08:33.231872-07:00","closed_at":"2025-10-16T19:08:33.231872-07:00","dependencies":[{"issue_id":"bd-551","depends_on_id":"bd-392","type":"blocks","created_at":"2025-10-16T18:54:29.843427-07:00","created_by":"import-remap"}]} +{"id":"bd-552","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-513, bd-199, bd-358-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":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T18:54:29.409532-07:00","updated_at":"2025-10-16T18:54:29.422563-07:00","closed_at":"2025-10-16T17:49:54.229303-07:00"} +{"id":"bd-553","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-374) while handling distributed creation gracefully.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T18:54:29.413281-07:00","updated_at":"2025-10-16T18:54:29.413281-07:00","closed_at":"2025-10-16T17:49:54.691542-07:00"} +{"id":"bd-554","title":"Add tests for git-based restoration","description":"Test compaction stores commit hash, restore command works, handles missing git repo gracefully","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.081362-07:00","updated_at":"2025-10-16T18:57:16.081362-07:00"} +{"id":"bd-555","title":"Add compacted_at_commit field to Issue type","description":"Add optional compacted_at_commit string field to store git commit hash when issue is compacted","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:57:16.084676-07:00","updated_at":"2025-10-16T19:08:29.250863-07:00","closed_at":"2025-10-16T19:08:29.250863-07:00"} +{"id":"bd-556","title":"parallel_test_8","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.085398-07:00","updated_at":"2025-10-16T19:08:43.143156-07:00","closed_at":"2025-10-16T19:08:43.143156-07:00"} +{"id":"bd-557","title":"parallel_test_9","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.086652-07:00","updated_at":"2025-10-16T19:08:43.066308-07:00","closed_at":"2025-10-16T19:08:43.066308-07:00"} +{"id":"bd-558","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-16T18:57:16.087909-07:00","updated_at":"2025-10-16T18:57:16.087909-07:00"} +{"id":"bd-559","title":"race_test_4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.088924-07:00","updated_at":"2025-10-16T19:08:43.030511-07:00","closed_at":"2025-10-16T19:08:43.030511-07:00"} {"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-16T17:49:54.636251-07:00","updated_at":"2025-10-16T18:12:45.749154-07:00","closed_at":"2025-10-16T17:49:54.636251-07:00","dependencies":[{"issue_id":"bd-56","depends_on_id":"bd-52","type":"parent-child","created_at":"2025-10-16T17:49:54.876657-07:00","created_by":"auto-import"}]} +{"id":"bd-560","title":"race_test_8","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.090257-07:00","updated_at":"2025-10-16T19:08:43.00531-07:00","closed_at":"2025-10-16T19:08:43.00531-07:00"} +{"id":"bd-561","title":"race_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.091191-07:00","updated_at":"2025-10-16T19:08:42.907157-07:00","closed_at":"2025-10-16T19:08:42.907157-07:00"} +{"id":"bd-562","title":"race_test_16","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.092273-07:00","updated_at":"2025-10-16T19:08:42.79021-07:00","closed_at":"2025-10-16T19:08:42.79021-07:00"} +{"id":"bd-563","title":"race_test_17","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.093146-07:00","updated_at":"2025-10-16T19:08:42.707179-07:00","closed_at":"2025-10-16T19:08:42.707179-07:00"} +{"id":"bd-564","title":"race_test_10","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.095128-07:00","updated_at":"2025-10-16T19:08:42.650192-07:00","closed_at":"2025-10-16T19:08:42.650192-07:00"} +{"id":"bd-565","title":"race_test_11","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.095923-07:00","updated_at":"2025-10-16T19:08:42.601606-07:00","closed_at":"2025-10-16T19:08:42.601606-07:00"} +{"id":"bd-566","title":"final_test_10","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.096912-07:00","updated_at":"2025-10-16T19:08:42.567194-07:00","closed_at":"2025-10-16T19:08:42.567194-07:00"} +{"id":"bd-567","title":"Concurrent bd commands collide on shared .tmp filename","description":"When multiple bd commands run concurrently (e.g., different agents), they all write to .beads/issues.jsonl.tmp causing race conditions. One command's rename succeeds, consuming the .tmp file, then other commands fail with 'no such file or directory'. Solution: use unique temp filenames with PID or random suffix (e.g., issues.jsonl.tmp.12345).","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T18:57:16.097942-07:00","updated_at":"2025-10-16T18:57:16.097942-07:00","closed_at":"2025-10-16T17:49:54.323841-07:00"} +{"id":"bd-568","title":"stress_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.098799-07:00","updated_at":"2025-10-16T19:08:42.530314-07:00","closed_at":"2025-10-16T19:08:42.530314-07:00"} +{"id":"bd-569","title":"stress_test_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.099688-07:00","updated_at":"2025-10-16T19:08:42.506307-07:00","closed_at":"2025-10-16T19:08:42.506307-07:00"} {"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-16T17:49:54.637027-07:00","updated_at":"2025-10-16T18:12:45.749648-07:00","closed_at":"2025-10-16T17:49:54.637027-07:00","dependencies":[{"issue_id":"bd-57","depends_on_id":"bd-52","type":"parent-child","created_at":"2025-10-16T17:49:54.877404-07:00","created_by":"auto-import"}]} +{"id":"bd-570","title":"stress_test_1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.100376-07:00","updated_at":"2025-10-16T19:08:42.464755-07:00","closed_at":"2025-10-16T19:08:42.464755-07:00"} +{"id":"bd-571","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":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:57:16.101107-07:00","updated_at":"2025-10-16T19:08:29.512981-07:00","closed_at":"2025-10-16T19:08:29.512981-07:00"} +{"id":"bd-572","title":"race_test_4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.102009-07:00","updated_at":"2025-10-16T19:08:42.444394-07:00","closed_at":"2025-10-16T19:08:42.444394-07:00"} +{"id":"bd-573","title":"race_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.102671-07:00","updated_at":"2025-10-16T19:08:42.415861-07:00","closed_at":"2025-10-16T19:08:42.415861-07:00"} +{"id":"bd-574","title":"race_test_2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.103608-07:00","updated_at":"2025-10-16T19:08:42.392281-07:00","closed_at":"2025-10-16T19:08:42.392281-07:00"} +{"id":"bd-575","title":"race_test_7","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.104398-07:00","updated_at":"2025-10-16T19:08:42.344102-07:00","closed_at":"2025-10-16T19:08:42.344102-07:00"} +{"id":"bd-576","title":"race_test_14","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.105357-07:00","updated_at":"2025-10-16T19:08:42.307463-07:00","closed_at":"2025-10-16T19:08:42.307463-07:00"} +{"id":"bd-577","title":"race_test_9","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.106035-07:00","updated_at":"2025-10-16T19:08:42.225511-07:00","closed_at":"2025-10-16T19:08:42.225511-07:00"} +{"id":"bd-578","title":"race_test_8","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.106883-07:00","updated_at":"2025-10-16T19:08:42.174665-07:00","closed_at":"2025-10-16T19:08:42.174665-07:00"} +{"id":"bd-579","title":"race_test_11","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.107574-07:00","updated_at":"2025-10-16T19:08:42.080099-07:00","closed_at":"2025-10-16T19:08:42.080099-07:00"} {"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-16T17:49:54.640612-07:00","updated_at":"2025-10-16T18:12:45.752285-07:00","closed_at":"2025-10-16T17:49:54.640612-07:00"} +{"id":"bd-580","title":"race_test_19","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.108424-07:00","updated_at":"2025-10-16T19:08:42.051149-07:00","closed_at":"2025-10-16T19:08:42.051149-07:00"} +{"id":"bd-581","title":"race_test_16","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.109095-07:00","updated_at":"2025-10-16T19:08:41.939009-07:00","closed_at":"2025-10-16T19:08:41.939009-07:00"} +{"id":"bd-582","title":"race_test_18","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.109904-07:00","updated_at":"2025-10-16T19:08:41.811343-07:00","closed_at":"2025-10-16T19:08:41.811343-07:00"} +{"id":"bd-583","title":"race_test_20","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.110877-07:00","updated_at":"2025-10-16T19:08:41.686884-07:00","closed_at":"2025-10-16T19:08:41.686884-07:00"} +{"id":"bd-584","title":"race_test_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.111868-07:00","updated_at":"2025-10-16T19:08:41.640492-07:00","closed_at":"2025-10-16T19:08:41.640492-07:00"} +{"id":"bd-585","title":"race_test_3","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.1129-07:00","updated_at":"2025-10-16T19:08:41.615273-07:00","closed_at":"2025-10-16T19:08:41.615273-07:00"} +{"id":"bd-586","title":"race_test_12","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.114034-07:00","updated_at":"2025-10-16T19:08:41.59009-07:00","closed_at":"2025-10-16T19:08:41.59009-07:00"} +{"id":"bd-587","title":"race_test_15","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.117429-07:00","updated_at":"2025-10-16T19:08:41.554294-07:00","closed_at":"2025-10-16T19:08:41.554294-07:00"} +{"id":"bd-588","title":"race_test_13","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.118444-07:00","updated_at":"2025-10-16T19:08:41.506476-07:00","closed_at":"2025-10-16T19:08:41.506476-07:00"} +{"id":"bd-589","title":"race_test_10","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.119487-07:00","updated_at":"2025-10-16T19:08:41.468519-07:00","closed_at":"2025-10-16T19:08:41.468519-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-16T17:49:54.641937-07:00","updated_at":"2025-10-16T18:12:45.754073-07:00","closed_at":"2025-10-16T17:49:54.641937-07:00"} +{"id":"bd-590","title":"race_test_17","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.120707-07:00","updated_at":"2025-10-16T19:08:41.40903-07:00","closed_at":"2025-10-16T19:08:41.40903-07:00"} +{"id":"bd-591","title":"verification_","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.121455-07:00","updated_at":"2025-10-16T19:08:41.326845-07:00","closed_at":"2025-10-16T19:08:41.326845-07:00"} +{"id":"bd-592","title":"final_review_test_","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.122201-07:00","updated_at":"2025-10-16T19:08:41.204502-07:00","closed_at":"2025-10-16T19:08:41.204502-07:00"} +{"id":"bd-593","title":"P2: Consider batching API for bulk issue creation","description":"Current CreateIssue acquires a dedicated connection for each call. For bulk imports or agent workflows creating many issues, a batched API could improve performance:\n\nCreateIssues(ctx, issues []*Issue, actor string) error\n\nThis would:\n- Acquire one connection\n- Use one IMMEDIATE transaction\n- Insert all issues atomically\n- Reduce connection overhead\n\nNot urgent - current approach is correct and fast enough for typical use.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:57:16.122852-07:00","updated_at":"2025-10-16T19:08:32.848213-07:00","closed_at":"2025-10-16T19:08:32.848213-07:00"} +{"id":"bd-594","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":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T18:57:16.124308-07:00","updated_at":"2025-10-16T19:08:30.495602-07:00","closed_at":"2025-10-16T19:08:30.495602-07:00"} +{"id":"bd-595","title":"Ultrathink: Choose solution for status/closed_at inconsistency (bd-224)","description":"Deep analysis of solution options for bd-654 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-16T18:57:16.125291-07:00","updated_at":"2025-10-16T18:57:16.42151-07:00","closed_at":"2025-10-16T17:49:54.227815-07:00"} +{"id":"bd-596","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":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:57:16.125905-07:00","updated_at":"2025-10-16T19:08:31.032978-07:00","closed_at":"2025-10-16T19:08:31.032978-07:00"} +{"id":"bd-597","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":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:57:16.126722-07:00","updated_at":"2025-10-16T19:08:29.775805-07:00","closed_at":"2025-10-16T19:08:29.775805-07:00"} +{"id":"bd-598","title":"Code review: Auto-import collision detection fix (bd-228)","description":"Request thorough code review of the auto-import collision detection implementation.\n\n## Files Changed\n- cmd/bd/main.go: autoImportIfNewer() and new autoImportWithoutCollisionDetection()\n\n## Review Focus Areas\n\n### 1. Correctness\n- Does collision detection properly identify conflicts?\n- Are colliding issues correctly filtered from import?\n- Is the fallback function correct for non-SQLite backends?\n\n### 2. Edge Cases\n- What happens if DetectCollisions() fails?\n- What if all issues are collisions?\n- What if JSONL is malformed?\n- Race conditions with concurrent auto-imports?\n\n### 3. User Experience\n- Is the warning message clear and actionable?\n- Should we log to a file instead of/in addition to stderr?\n- Should there be a --auto-resolve flag?\n\n### 4. Performance\n- Does collision detection add significant latency?\n- Will this work with 1000+ issues?\n- Any unnecessary N+1 queries?\n\n### 5. Testing Gaps\n- Do we need integration tests for collision scenarios?\n- Should we test the warning output?\n- Test autoImportWithoutCollisionDetection() fallback?\n\n## Questions for Reviewer\n1. Should auto-import be more aggressive (auto-resolve) or more conservative (fail)?\n2. Should we add a counter for how many times collisions occurred?\n3. Should there be a config option to disable collision detection?\n4. Is the warning too verbose for typical workflows?\n\n## Current Behavior\n- Skips colliding issues (preserves local)\n- Prints warning to stderr\n- Suggests manual resolution command\n- Continues with non-colliding issues","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:57:16.127529-07:00","updated_at":"2025-10-16T19:08:30.100123-07:00","closed_at":"2025-10-16T19:08:30.100123-07:00"} +{"id":"bd-599","title":"Add integration tests for auto-import collision detection","description":"The auto-import collision detection fix (bd-376) needs comprehensive integration tests.\n\n## Test Scenarios Needed\n\n### 1. Basic Collision Detection\n```go\nTestAutoImportWithCollisions\n- Setup: Create issue in DB with status=closed\n- Simulate: Git pull with JSONL containing same issue with status=open\n- Verify: Local changes preserved, warning printed, issue still closed\n```\n\n### 2. Multiple Collisions\n```go\nTestAutoImportWithMultipleCollisions\n- Setup: 5 issues with local modifications\n- Simulate: JSONL with 3 colliding, 2 matching\n- Verify: 3 skipped, 2 updated, appropriate warnings\n```\n\n### 3. No Collisions (Happy Path)\n```go\nTestAutoImportWithoutCollisions\n- Setup: Clean database\n- Simulate: JSONL with new issues + exact matches\n- Verify: All imported successfully, no warnings\n```\n\n### 4. All Collisions\n```go\nTestAutoImportAllCollisions\n- Setup: Every issue has local modifications\n- Simulate: JSONL with conflicting versions\n- Verify: All skipped, warning lists all issues\n```\n\n### 5. Collision Detection Failure\n```go\nTestAutoImportCollisionDetectionError\n- Setup: Mock DetectCollisions() to return error\n- Verify: Import skipped entirely (safe failure mode)\n```\n\n### 6. Hash-Based Skip\n```go\nTestAutoImportHashUnchanged\n- Setup: JSONL hash matches last_import_hash\n- Verify: No collision detection runs, fast path\n```\n\n### 7. Fallback for Non-SQLite\n```go\nTestAutoImportWithoutCollisionDetection\n- Setup: Mock non-SQLite storage backend\n- Verify: Falls back to old behavior, no collision detection\n```\n\n## Test Infrastructure Needed\n\n1. **Helper functions:**\n - createTestDBWithIssues()\n - writeJSONLFile()\n - captureStderrWarnings()\n - simulateGitPull()\n\n2. **Fixtures:**\n - sample-collisions.jsonl\n - sample-exact-matches.jsonl\n - sample-mixed.jsonl\n\n3. **Assertions:**\n - assertIssueState(id, expectedStatus)\n - assertWarningContains(text)\n - assertCollisionCount(n)\n\n## Acceptance Criteria\n- All 7 test scenarios implemented\n- Tests pass consistently\n- Code coverage \u003e80% for autoImportIfNewer()\n- Tests run in \u003c5 seconds total\n- Clear test names and documentation","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-16T18:57:16.128178-07:00","updated_at":"2025-10-16T18:57:16.128178-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-16T17:49:54.642434-07:00","updated_at":"2025-10-16T18:12:45.756821-07:00"} {"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-16T17:49:54.642875-07:00","updated_at":"2025-10-16T18:12:45.757349-07:00","closed_at":"2025-10-16T17:49:54.642875-07:00"} +{"id":"bd-600","title":"Consider batching API for bulk issue creation (recovered from bd-222)","description":"Current CreateIssue acquires a dedicated connection for each call. For bulk imports or agent workflows creating many issues, a batched API could improve performance:\n\nCreateIssues(ctx, issues []*Issue, actor string) error\n\nThis would:\n- Acquire one connection\n- Use one IMMEDIATE transaction\n- Insert all issues atomically\n- Reduce connection overhead\n\nNot urgent - current approach is correct and fast enough for typical use.\n\n**Recovered from:** bd-360 (lost in auto-import bug, see LOST_ISSUES_RECOVERY.md)","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:57:16.128761-07:00","updated_at":"2025-10-16T19:08:30.301991-07:00","closed_at":"2025-10-16T19:08:30.301991-07:00"} +{"id":"bd-601","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-660's collision resolution.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T18:57:16.12934-07:00","updated_at":"2025-10-16T18:57:16.413015-07:00","closed_at":"2025-10-16T17:49:54.240484-07:00"} +{"id":"bd-602","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":"closed","priority":3,"issue_type":"bug","created_at":"2025-10-16T18:57:16.130007-07:00","updated_at":"2025-10-16T19:08:32.648858-07:00","closed_at":"2025-10-16T19:08:32.648858-07:00"} +{"id":"bd-603","title":"Use safer placeholder pattern in replaceIDReferences","description":"Currently uses bd-324 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":"closed","priority":3,"issue_type":"task","created_at":"2025-10-16T18:57:16.130694-07:00","updated_at":"2025-10-16T19:08:33.431939-07:00","closed_at":"2025-10-16T19:08:33.431939-07:00"} +{"id":"bd-604","title":"Git-based restoration for compacted issues","description":"Store git commit hash at compaction time to enable restoration of full issue history from version control. When issues are compacted, record the current git commit hash so users can restore the original uncompacted issue from git history.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:57:16.131361-07:00","updated_at":"2025-10-16T19:08:31.933404-07:00","closed_at":"2025-10-16T19:08:31.933404-07:00"} +{"id":"bd-605","title":"Add compacted_at_commit field to Issue type","description":"Add optional compacted_at_commit string field to store git commit hash when issue is compacted","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:57:16.13228-07:00","updated_at":"2025-10-16T19:08:29.197838-07:00","closed_at":"2025-10-16T19:08:29.197838-07:00"} +{"id":"bd-606","title":"Record git commit hash during compaction","description":"Update compact command to capture current git HEAD commit hash and store in compacted_at_commit field","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:57:16.139786-07:00","updated_at":"2025-10-16T19:08:33.203181-07:00","closed_at":"2025-10-16T19:08:33.203181-07:00"} +{"id":"bd-607","title":"Implement bd restore command","description":"Create new restore command that checks out git commit from compacted_at_commit, reads issue from JSONL, and displays full history","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T18:57:16.147008-07:00","updated_at":"2025-10-16T19:08:32.325158-07:00","closed_at":"2025-10-16T19:08:32.325158-07:00"} +{"id":"bd-608","title":"parallel_test_3","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.161617-07:00","updated_at":"2025-10-16T19:08:41.15906-07:00","closed_at":"2025-10-16T19:08:41.15906-07:00"} +{"id":"bd-609","title":"parallel_test_10","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.194118-07:00","updated_at":"2025-10-16T19:08:41.097831-07:00","closed_at":"2025-10-16T19:08:41.097831-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-16T17:49:54.644205-07:00","updated_at":"2025-10-16T18:12:45.757862-07:00","closed_at":"2025-10-16T17:49:54.644205-07:00"} +{"id":"bd-610","title":"final_test_7","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.220553-07:00","updated_at":"2025-10-16T19:08:41.054516-07:00","closed_at":"2025-10-16T19:08:41.054516-07:00"} +{"id":"bd-611","title":"parallel_test_7","description":"","design":"Add validation in AddDependency that checks if dep.Type == DepParentChild and validates the direction is correct (parent depends on child, not child on parent). Reject with clear error message if direction is backwards.","acceptance_criteria":"- Child→parent dependencies are rejected with clear error\n- Parent→child dependencies work as expected\n- Error message explains correct direction\n- Tests cover both valid and invalid cases","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.227227-07:00","updated_at":"2025-10-16T18:57:16.227227-07:00","closed_at":"2025-10-16T17:49:54.340717-07:00"} +{"id":"bd-612","title":"parallel_test_2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.232795-07:00","updated_at":"2025-10-16T18:57:16.232795-07:00","closed_at":"2025-10-16T17:49:54.412382-07:00"} +{"id":"bd-613","title":"parallel_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.235664-07:00","updated_at":"2025-10-16T18:57:16.235664-07:00","closed_at":"2025-10-16T17:49:54.467576-07:00"} +{"id":"bd-614","title":"parallel_test_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.236286-07:00","updated_at":"2025-10-16T18:57:16.236286-07:00","closed_at":"2025-10-16T17:49:54.468584-07:00"} +{"id":"bd-615","title":"parallel_test_4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.238895-07:00","updated_at":"2025-10-16T18:57:16.238895-07:00","closed_at":"2025-10-16T17:49:54.469639-07:00"} +{"id":"bd-616","title":"parallel_test_1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.239759-07:00","updated_at":"2025-10-16T18:57:16.239759-07:00","closed_at":"2025-10-16T17:49:54.471168-07:00"} +{"id":"bd-617","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":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:57:16.246023-07:00","updated_at":"2025-10-16T18:57:16.246023-07:00","closed_at":"2025-10-16T17:49:54.471547-07:00","external_ref":"gh-11"} +{"id":"bd-618","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.","notes":"Awaiting user feedback - cannot reproduce locally, waiting for user to provide more details about environment and error message","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T18:57:16.249493-07:00","updated_at":"2025-10-16T19:08:31.495197-07:00","closed_at":"2025-10-16T19:08:31.495197-07:00","external_ref":"gh-3"} +{"id":"bd-619","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":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T18:57:16.251812-07:00","updated_at":"2025-10-16T18:57:16.251812-07:00","closed_at":"2025-10-16T17:49:54.472336-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-16T17:49:54.64468-07:00","updated_at":"2025-10-16T18:12:45.758332-07:00","closed_at":"2025-10-16T17:49:54.64468-07:00"} +{"id":"bd-620","title":"parallel_test_3","description":"","design":"Review GH-11 requirements:\n- User wants to use beads across multiple dev machines\n- Docker hosting was proposed solution\n\nNew approach:\n- Phase 1: Pure git-based sync (no Docker needed)\n- Phase 2: Optional Docker gateway for convenience\n- Addresses use case without mandating server\n\nUpdate GH-11 with:\n- Link to DESIGN-GIT-SYNC.md\n- Explain git-based approach\n- Note optional Docker gateway\n- Ask for feedback\n\nClose issue when sync features implemented.","acceptance_criteria":"- GH-11 reviewed and understood\n- Comment added explaining sync approach\n- Link to design document\n- User feedback requested\n- Issue closed when Phase 1-2 complete\n- Documentation cross-referenced","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.252728-07:00","updated_at":"2025-10-16T19:08:41.01831-07:00","closed_at":"2025-10-16T19:08:41.01831-07:00"} +{"id":"bd-621","title":"parallel_test_5","description":"","acceptance_criteria":"Can add/remove/list labels via CLI, can filter issues by label, labels persist to JSONL","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.253519-07:00","updated_at":"2025-10-16T19:08:40.972251-07:00","closed_at":"2025-10-16T19:08:40.972251-07:00"} +{"id":"bd-622","title":"Implement bd restore command","description":"Create new restore command that checks out git commit from compacted_at_commit, reads issue from JSONL, and displays full history","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T18:57:16.255193-07:00","updated_at":"2025-10-16T19:08:32.275605-07:00","closed_at":"2025-10-16T19:08:32.275605-07:00"} +{"id":"bd-623","title":"parallel_test_2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.258011-07:00","updated_at":"2025-10-16T19:08:40.932027-07:00","closed_at":"2025-10-16T19:08:40.932027-07:00"} +{"id":"bd-624","title":"parallel_test_5","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.259921-07:00","updated_at":"2025-10-16T19:08:40.802442-07:00","closed_at":"2025-10-16T19:08:40.802442-07:00"} +{"id":"bd-625","title":"parallel_test_6","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.260541-07:00","updated_at":"2025-10-16T19:08:40.768813-07:00","closed_at":"2025-10-16T19:08:40.768813-07:00"} +{"id":"bd-626","title":"parallel_test_7","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.262607-07:00","updated_at":"2025-10-16T19:08:40.718816-07:00","closed_at":"2025-10-16T19:08:40.718816-07:00"} +{"id":"bd-627","title":"parallel_test_4","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.263891-07:00","updated_at":"2025-10-16T19:08:40.662107-07:00","closed_at":"2025-10-16T19:08:40.662107-07:00"} +{"id":"bd-628","title":"parallel_test_1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.265633-07:00","updated_at":"2025-10-16T19:08:40.615463-07:00","closed_at":"2025-10-16T19:08:40.615463-07:00"} +{"id":"bd-629","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":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:57:16.266652-07:00","updated_at":"2025-10-16T19:08:31.346599-07:00","closed_at":"2025-10-16T19:08:31.346599-07:00","external_ref":"gh-11"} {"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-16T17:49:54.645331-07:00","updated_at":"2025-10-16T18:12:45.758896-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-16T17:49:54.645795-07:00","updated_at":"2025-10-16T18:12:45.75941-07:00","closed_at":"2025-10-16T17:49:54.645795-07:00","dependencies":[{"issue_id":"bd-64","depends_on_id":"bd-378","type":"parent-child","created_at":"2025-10-16T17:49:54.878048-07:00","created_by":"auto-import"},{"issue_id":"bd-64","depends_on_id":"bd-389","type":"parent-child","created_at":"2025-10-16T17:49:54.878482-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-16T17:49:54.646345-07:00","updated_at":"2025-10-16T18:12:45.759898-07:00","closed_at":"2025-10-16T17:49:54.646345-07:00","dependencies":[{"issue_id":"bd-65","depends_on_id":"bd-378","type":"parent-child","created_at":"2025-10-16T17:49:54.879476-07:00","created_by":"auto-import"},{"issue_id":"bd-65","depends_on_id":"bd-389","type":"parent-child","created_at":"2025-10-16T17:49:54.880758-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-16T17:49:54.646888-07:00","updated_at":"2025-10-16T18:12:45.760548-07:00","closed_at":"2025-10-16T17:49:54.646888-07:00","dependencies":[{"issue_id":"bd-66","depends_on_id":"bd-378","type":"parent-child","created_at":"2025-10-16T17:49:54.881433-07:00","created_by":"auto-import"},{"issue_id":"bd-66","depends_on_id":"bd-389","type":"parent-child","created_at":"2025-10-16T17:49:54.882205-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-16T17:49:54.647395-07:00","updated_at":"2025-10-16T18:12:45.761226-07:00","closed_at":"2025-10-16T17:49:54.647395-07:00","dependencies":[{"issue_id":"bd-67","depends_on_id":"bd-378","type":"parent-child","created_at":"2025-10-16T17:49:54.883078-07:00","created_by":"auto-import"},{"issue_id":"bd-67","depends_on_id":"bd-389","type":"parent-child","created_at":"2025-10-16T17:49:54.883588-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-16T17:49:54.653556-07:00","updated_at":"2025-10-16T18:12:45.761765-07:00","dependencies":[{"issue_id":"bd-68","depends_on_id":"bd-378","type":"parent-child","created_at":"2025-10-16T17:49:54.884071-07:00","created_by":"auto-import"},{"issue_id":"bd-68","depends_on_id":"bd-389","type":"parent-child","created_at":"2025-10-16T17:49:54.889431-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-16T17:49:54.65406-07:00","updated_at":"2025-10-16T18:12:45.762231-07:00","closed_at":"2025-10-16T17:49:54.65406-07:00","dependencies":[{"issue_id":"bd-69","depends_on_id":"bd-378","type":"parent-child","created_at":"2025-10-16T17:49:54.8996-07:00","created_by":"auto-import"},{"issue_id":"bd-69","depends_on_id":"bd-389","type":"parent-child","created_at":"2025-10-16T17:49:54.900147-07:00","created_by":"auto-import"}]} +{"id":"bd-630","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":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T18:57:16.267697-07:00","updated_at":"2025-10-16T18:57:16.267697-07:00","closed_at":"2025-10-16T18:18:03.79501-07:00","external_ref":"gh-3"} +{"id":"bd-631","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":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T18:57:16.268525-07:00","updated_at":"2025-10-16T19:08:29.91983-07:00","closed_at":"2025-10-16T19:08:29.91983-07:00"} +{"id":"bd-632","title":"Reach 1.0 release milestone","description":"Stabilize API, finalize documentation, comprehensive testing","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:57:16.281913-07:00","updated_at":"2025-10-16T19:08:32.939651-07:00","closed_at":"2025-10-16T19:08:32.939651-07:00"} +{"id":"bd-633","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":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:57:16.28274-07:00","updated_at":"2025-10-16T19:08:29.989379-07:00","closed_at":"2025-10-16T19:08:29.989379-07:00"} +{"id":"bd-634","title":"Add performance benchmarks document","description":"Document actual performance metrics with hyperfine tests","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-16T18:57:16.290463-07:00","updated_at":"2025-10-16T19:08:29.670618-07:00","closed_at":"2025-10-16T19:08:29.670618-07:00"} +{"id":"bd-635","title":"Add migration scripts for GitHub Issues","description":"Create scripts to import from GitHub Issues API or exported JSON","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:57:16.292565-07:00","updated_at":"2025-10-16T19:08:29.575692-07:00","closed_at":"2025-10-16T19:08:29.575692-07:00"} +{"id":"bd-636","title":"Bug: Import creating duplicates instead of deduplicating","description":"Git log shows \"73 issues remapped\" during merge, suggesting --resolve-collisions is creating duplicate issues with new IDs instead of recognizing they're identical and deduplicating them.\n\nEvidence: bd-596, bd-367, bd-396 are all \"Epic: Fix status/closed_at inconsistency\" with identical content but different IDs and timestamps.\n\nRoot cause likely in DetectCollisions or --resolve-collisions logic - it's treating content-identical issues as collisions when they should be exact matches.","design":"**Root Cause Found:**\n\nDetectCollisions only checks if incoming issues exist in the DB. It doesn't deduplicate within the incoming JSONL batch itself.\n\nWhen JSONL contains multiple issues with:\n- Different IDs (bd-596, bd-367, bd-396)\n- Identical content\n- Different timestamps\n\nDetectCollisions treats them all as \"new issues\" because none exist in DB, then --resolve-collisions leaves them as-is.\n\n**Fix:**\nAdd deduplication step in DetectCollisions to detect content-identical issues within the incoming batch and consolidate them before processing.","notes":"**Fixed in commit [pending]**\n\nChanges made:\n1. Added `deduplicateIncomingIssues()` function in collision.go\n2. Modified `DetectCollisions()` to call deduplication before processing\n3. Deduplication consolidates content-identical issues, keeping smallest ID\n4. Added comprehensive test suite in collision_dedup_test.go\n\nResult: Importing JSONL with duplicates now correctly consolidates them instead of creating multiple copies.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T18:57:16.29361-07:00","updated_at":"2025-10-16T18:57:16.342249-07:00","closed_at":"2025-10-16T17:52:35.575954-07:00"} +{"id":"bd-637","title":"Implement bd restore command","description":"Create new restore command that checks out git commit from compacted_at_commit, reads issue from JSONL, and displays full history","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T18:57:16.294864-07:00","updated_at":"2025-10-16T19:08:32.191623-07:00","closed_at":"2025-10-16T19:08:32.191623-07:00"} +{"id":"bd-638","title":"Document git-based restoration feature","description":"Update COMPACTION.md and README.md with restoration workflow and examples","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.295983-07:00","updated_at":"2025-10-16T19:08:30.697727-07:00","closed_at":"2025-10-16T19:08:30.697727-07:00"} +{"id":"bd-639","title":"Add compacted_at_commit field to Issue type","description":"Add optional compacted_at_commit string field to store git commit hash when issue is compacted","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:57:16.296664-07:00","updated_at":"2025-10-16T19:08:29.039887-07:00","closed_at":"2025-10-16T19:08:29.039887-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-16T14:33:21.479094-07:00","closed_at":"2025-10-15T03:01:29.587994-07:00","dependencies":[{"issue_id":"bd-64","depends_on_id":"bd-389","type":"parent-child","created_at":"2025-10-16T14:57:49.207586-07:00","created_by":"import-remap"},{"issue_id":"bd-64","depends_on_id":"bd-661","type":"parent-child","created_at":"2025-10-16T18:57:16.835843-07:00","created_by":"import-remap"},{"issue_id":"bd-64","depends_on_id":"bd-378","type":"parent-child","created_at":"2025-10-16T18:57:17.064476-07:00","created_by":"auto-import"}]} +{"id":"bd-640","title":"Add integration tests for auto-import collision detection","description":"The auto-import collision detection fix (bd-376) needs comprehensive integration tests.\n\n## Test Scenarios Needed\n\n### 1. Basic Collision Detection\n```go\nTestAutoImportWithCollisions\n- Setup: Create issue in DB with status=closed\n- Simulate: Git pull with JSONL containing same issue with status=open\n- Verify: Local changes preserved, warning printed, issue still closed\n```\n\n### 2. Multiple Collisions\n```go\nTestAutoImportWithMultipleCollisions\n- Setup: 5 issues with local modifications\n- Simulate: JSONL with 3 colliding, 2 matching\n- Verify: 3 skipped, 2 updated, appropriate warnings\n```\n\n### 3. No Collisions (Happy Path)\n```go\nTestAutoImportWithoutCollisions\n- Setup: Clean database\n- Simulate: JSONL with new issues + exact matches\n- Verify: All imported successfully, no warnings\n```\n\n### 4. All Collisions\n```go\nTestAutoImportAllCollisions\n- Setup: Every issue has local modifications\n- Simulate: JSONL with conflicting versions\n- Verify: All skipped, warning lists all issues\n```\n\n### 5. Collision Detection Failure\n```go\nTestAutoImportCollisionDetectionError\n- Setup: Mock DetectCollisions() to return error\n- Verify: Import skipped entirely (safe failure mode)\n```\n\n### 6. Hash-Based Skip\n```go\nTestAutoImportHashUnchanged\n- Setup: JSONL hash matches last_import_hash\n- Verify: No collision detection runs, fast path\n```\n\n### 7. Fallback for Non-SQLite\n```go\nTestAutoImportWithoutCollisionDetection\n- Setup: Mock non-SQLite storage backend\n- Verify: Falls back to old behavior, no collision detection\n```\n\n## Test Infrastructure Needed\n\n1. **Helper functions:**\n - createTestDBWithIssues()\n - writeJSONLFile()\n - captureStderrWarnings()\n - simulateGitPull()\n\n2. **Fixtures:**\n - sample-collisions.jsonl\n - sample-exact-matches.jsonl\n - sample-mixed.jsonl\n\n3. **Assertions:**\n - assertIssueState(id, expectedStatus)\n - assertWarningContains(text)\n - assertCollisionCount(n)\n\n## Acceptance Criteria\n- All 7 test scenarios implemented\n- Tests pass consistently\n- Code coverage \u003e80% for autoImportIfNewer()\n- Tests run in \u003c5 seconds total\n- Clear test names and documentation","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:57:16.298009-07:00","updated_at":"2025-10-16T18:57:16.298009-07:00","closed_at":"2025-10-16T17:49:54.608432-07:00"} +{"id":"bd-641","title":"Record git commit hash during compaction","description":"Update compact command to capture current git HEAD commit hash and store in compacted_at_commit field","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:57:16.303615-07:00","updated_at":"2025-10-16T19:08:33.16375-07:00","closed_at":"2025-10-16T19:08:33.16375-07:00"} +{"id":"bd-642","title":"Record git commit hash during compaction","description":"Update compact command to capture current git HEAD commit hash and store in compacted_at_commit field","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:57:16.306079-07:00","updated_at":"2025-10-16T19:08:33.105616-07:00","closed_at":"2025-10-16T19:08:33.105616-07:00"} +{"id":"bd-643","title":"Low priority chore","description":"","status":"closed","priority":4,"issue_type":"chore","created_at":"2025-10-16T18:57:16.307575-07:00","updated_at":"2025-10-16T19:08:32.781184-07:00","closed_at":"2025-10-16T19:08:32.781184-07:00"} +{"id":"bd-644","title":"parallel_test_4","description":"","design":"Sections:\n1. Introduction\n2. Authentication\n3. REST Endpoints\n4. WebSocket Protocol\n5. Error Handling\n6. Rate Limits\n7. Examples\n\nFor each endpoint:\n- URL and method\n- Request parameters\n- Request body schema\n- Response schema\n- Error responses\n- Code example","acceptance_criteria":"- API.md created with all sections\n- All endpoints documented\n- Request/response schemas\n- WebSocket protocol docs\n- Error codes and handling\n- Rate limit documentation\n- Examples in multiple languages\n- Links from README.md\n\n---","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.30893-07:00","updated_at":"2025-10-16T19:08:40.478065-07:00","closed_at":"2025-10-16T19:08:40.478065-07:00","dependencies":[{"issue_id":"bd-644","depends_on_id":"bd-659","type":"parent-child","created_at":"2025-10-16T18:57:16.814136-07:00","created_by":"import-remap"}]} +{"id":"bd-645","title":"Add migration scripts for GitHub Issues","description":"Create scripts to import from GitHub Issues API or exported JSON","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:57:16.310349-07:00","updated_at":"2025-10-16T18:57:16.310349-07:00","closed_at":"2025-10-16T17:49:54.490276-07:00","dependencies":[{"issue_id":"bd-645","depends_on_id":"bd-657","type":"parent-child","created_at":"2025-10-16T18:57:16.858357-07:00","created_by":"import-remap"}]} +{"id":"bd-646","title":"Investigate data recovery for issues overwritten by auto-import bug","description":"Auto-import bug (bd-376) has been silently overwriting local changes since the feature was introduced. We need to investigate if any important data was lost and if it can be recovered.\n\n## Data Sources for Recovery\n\n1. **Git history of .beads/issues.jsonl** - May contain older versions with lost changes\n2. **Events table** - Has full audit trail with old_value/new_value\n3. **Commit messages** - May reference work that was done but later overwritten\n\n## Investigation Steps\n\n1. Check events table for patterns:\n - Look for auto-import events that changed status from closed → open\n - Look for manual updates followed by auto-import reverts\n - Identify issues with suspicious event sequences\n\n2. Git archaeology:\n - Check git log for .beads/issues.jsonl\n - Look for commits where status=closed was changed to status=open\n - Compare git history vs current database state\n\n3. Document lost work:\n - Create list of issues that were closed but reverted to open\n - Identify any critical work that was marked done but lost\n - Check if any issue references are now broken\n\n## Recovery Actions\n\nIf significant data loss is found:\n- Create script to reconstruct lost state from events table\n- Manually review and restore critical closed issues\n- Document lessons learned for preventing future data loss\n\n## Example Query\n\n```sql\n-- Find issues where status was manually changed then reverted by auto-import\nSELECT \n issue_id,\n GROUP_CONCAT(event_type || ':' || actor, ' -\u003e ') as event_chain\nFROM events \nWHERE issue_id IN (\n SELECT DISTINCT issue_id \n FROM events \n WHERE actor = 'auto-import' AND event_type = 'status_changed'\n)\nGROUP BY issue_id\nHAVING event_chain LIKE '%stevey%auto-import%';\n```","notes":"Investigation complete. Successfully recovered 3 valuable issues (bd-367, bd-233) from 22 total lost. Historical context preserved in bd-89 notes. Auto-import collision detection (bd-376) now prevents future data loss.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T18:57:16.312989-07:00","updated_at":"2025-10-16T18:57:16.312989-07:00","closed_at":"2025-10-16T17:49:54.230133-07:00","dependencies":[{"issue_id":"bd-646","depends_on_id":"bd-656","type":"discovered-from","created_at":"2025-10-16T18:57:16.809064-07:00","created_by":"import-remap"}]} +{"id":"bd-647","title":"Low priority chore","description":"","status":"closed","priority":4,"issue_type":"chore","created_at":"2025-10-16T18:57:16.313802-07:00","updated_at":"2025-10-16T18:57:16.313802-07:00","closed_at":"2025-10-16T17:49:54.489847-07:00","dependencies":[{"issue_id":"bd-647","depends_on_id":"bd-657","type":"parent-child","created_at":"2025-10-16T18:57:16.795661-07:00","created_by":"import-remap"}]} +{"id":"bd-648","title":"Add performance benchmarks document","description":"Document actual performance metrics with hyperfine tests","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-16T18:57:16.314508-07:00","updated_at":"2025-10-16T18:57:16.314508-07:00","closed_at":"2025-10-16T17:49:54.480313-07:00","dependencies":[{"issue_id":"bd-648","depends_on_id":"bd-657","type":"parent-child","created_at":"2025-10-16T18:57:16.789725-07:00","created_by":"import-remap"}]} +{"id":"bd-649","title":"Git-based restoration for compacted issues","description":"Store git commit hash at compaction time to enable restoration of full issue history from version control. When issues are compacted, record the current git commit hash so users can restore the original uncompacted issue from git history.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:57:16.31515-07:00","updated_at":"2025-10-16T19:08:31.901554-07:00","closed_at":"2025-10-16T19:08:31.901554-07:00"} +{"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-16T14:33:21.493802-07:00","closed_at":"2025-10-15T03:01:29.588393-07:00","dependencies":[{"issue_id":"bd-65","depends_on_id":"bd-389","type":"parent-child","created_at":"2025-10-16T14:57:49.216297-07:00","created_by":"import-remap"},{"issue_id":"bd-65","depends_on_id":"bd-661","type":"parent-child","created_at":"2025-10-16T18:57:16.804863-07:00","created_by":"import-remap"},{"issue_id":"bd-65","depends_on_id":"bd-378","type":"parent-child","created_at":"2025-10-16T18:57:17.069375-07:00","created_by":"auto-import"}]} +{"id":"bd-650","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.","design":"Federation allows:\n- Multiple gateways sync with each other\n- Each gateway has authoritative set of issues\n- Peer-to-peer sync protocol\n- Conflict resolution across gateways\n\nArchitecture:\n- Gateway-to-gateway API\n- Peer discovery\n- Sync protocol between gateways\n- Distributed conflict resolution\n\nComplex feature - only if team usage emerges.","acceptance_criteria":"- Gateway federation protocol designed\n- Peer discovery mechanism\n- Gateway-to-gateway sync\n- Distributed conflict resolution\n- Tests for federation\n- Documentation in FEDERATION.md\n\n---","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-10-16T18:57:16.315828-07:00","updated_at":"2025-10-16T19:08:32.59666-07:00","closed_at":"2025-10-16T19:08:32.59666-07:00","dependencies":[{"issue_id":"bd-650","depends_on_id":"bd-659","type":"parent-child","created_at":"2025-10-16T18:57:16.810601-07:00","created_by":"import-remap"}]} +{"id":"bd-651","title":"Consider batching API for bulk issue creation (recovered from bd-222)","description":"Current CreateIssue acquires a dedicated connection for each call. For bulk imports or agent workflows creating many issues, a batched API could improve performance:\n\nCreateIssues(ctx, issues []*Issue, actor string) error\n\nThis would:\n- Acquire one connection\n- Use one IMMEDIATE transaction\n- Insert all issues atomically\n- Reduce connection overhead\n\nNot urgent - current approach is correct and fast enough for typical use.\n\n**Recovered from:** bd-390 (lost in auto-import bug, see LOST_ISSUES_RECOVERY.md)","notes":"Investigation complete. Successfully recovered 3 valuable issues (bd-651, bd-233) from 22 total lost. Historical context preserved in bd-89 notes. Auto-import collision detection (bd-656) now prevents future data loss.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-16T18:57:16.316474-07:00","updated_at":"2025-10-16T19:08:30.228351-07:00","closed_at":"2025-10-16T19:08:30.228351-07:00","dependencies":[{"issue_id":"bd-651","depends_on_id":"bd-376","type":"discovered-from","created_at":"2025-10-16T18:57:16.756874-07:00","created_by":"import-remap"}]} +{"id":"bd-652","title":"parallel_test_1","description":"","design":"Add new section: \"Multi-Device Sync\"\n\nContent:\n- Brief overview of git-based sync\n- Link to SYNC.md for details\n- Link to GATEWAY.md for gateway mode\n- Quick start examples\n- Configuration options\n\nKeep brief - detailed docs in separate files.","acceptance_criteria":"- README.md updated with sync section\n- Links to SYNC.md and GATEWAY.md\n- Quick start examples\n- Configuration overview\n- Maintains existing structure\n- All links working\n\n---","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.31729-07:00","updated_at":"2025-10-16T19:08:40.427109-07:00","closed_at":"2025-10-16T19:08:40.427109-07:00","dependencies":[{"issue_id":"bd-652","depends_on_id":"bd-659","type":"parent-child","created_at":"2025-10-16T18:57:16.855409-07:00","created_by":"import-remap"}]} +{"id":"bd-653","title":"verification_","description":"","design":"Sections:\n1. Introduction\n2. Quick Start\n3. Manual Git Workflow\n4. bd sync Command\n5. bd daemon Background Sync\n6. Git Hooks\n7. Conflict Resolution\n8. Best Practices\n9. Troubleshooting\n10. FAQ\n\nInclude examples, code snippets, and diagrams.","acceptance_criteria":"- SYNC.md created with all sections\n- Quick start guide for new users\n- Detailed workflow examples\n- Conflict resolution guide\n- Best practices section\n- Troubleshooting with solutions\n- FAQ with common questions\n- Code examples working\n- Links from README.md\n\n---","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.317983-07:00","updated_at":"2025-10-16T19:08:40.312566-07:00","closed_at":"2025-10-16T19:08:40.312566-07:00","dependencies":[{"issue_id":"bd-653","depends_on_id":"bd-659","type":"parent-child","created_at":"2025-10-16T18:57:16.856915-07:00","created_by":"import-remap"}]} +{"id":"bd-654","title":"Concurrent bd commands collide on shared .tmp filename","description":"When multiple bd commands run concurrently (e.g., different agents), they all write to .beads/issues.jsonl.tmp causing race conditions. One command's rename succeeds, consuming the .tmp file, then other commands fail with 'no such file or directory'. Solution: use unique temp filenames with PID or random suffix (e.g., issues.jsonl.tmp.12345).","notes":"Label management fully implemented with comprehensive test coverage (10 test cases). Provides foundation for better data organization and filtering.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T18:57:16.319205-07:00","updated_at":"2025-10-16T18:57:16.319205-07:00","closed_at":"2025-10-16T17:49:54.496208-07:00"} +{"id":"bd-655","title":"parallel_test_9","description":"","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":2,"issue_type":"task","created_at":"2025-10-16T18:57:16.320156-07:00","updated_at":"2025-10-16T18:57:16.320156-07:00","closed_at":"2025-10-16T17:49:54.491748-07:00","dependencies":[{"issue_id":"bd-655","depends_on_id":"bd-654","type":"discovered-from","created_at":"2025-10-16T18:57:16.854016-07:00","created_by":"import-remap"}]} +{"id":"bd-656","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-621, bd-199, bd-358-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":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T18:57:16.321969-07:00","updated_at":"2025-10-16T18:57:16.338676-07:00","closed_at":"2025-10-16T17:49:54.229303-07:00"} +{"id":"bd-657","title":"Reach 1.0 release milestone","description":"Stabilize API, finalize documentation, comprehensive testing","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:57:16.323024-07:00","updated_at":"2025-10-16T18:57:16.323024-07:00","closed_at":"2025-10-16T17:49:54.505862-07:00"} +{"id":"bd-658","title":"Add integration tests for auto-import collision detection","description":"The auto-import collision detection fix (bd-656) needs comprehensive integration tests.\n\n## Test Scenarios Needed\n\n### 1. Basic Collision Detection\n```go\nTestAutoImportWithCollisions\n- Setup: Create issue in DB with status=closed\n- Simulate: Git pull with JSONL containing same issue with status=open\n- Verify: Local changes preserved, warning printed, issue still closed\n```\n\n### 2. Multiple Collisions\n```go\nTestAutoImportWithMultipleCollisions\n- Setup: 5 issues with local modifications\n- Simulate: JSONL with 3 colliding, 2 matching\n- Verify: 3 skipped, 2 updated, appropriate warnings\n```\n\n### 3. No Collisions (Happy Path)\n```go\nTestAutoImportWithoutCollisions\n- Setup: Clean database\n- Simulate: JSONL with new issues + exact matches\n- Verify: All imported successfully, no warnings\n```\n\n### 4. All Collisions\n```go\nTestAutoImportAllCollisions\n- Setup: Every issue has local modifications\n- Simulate: JSONL with conflicting versions\n- Verify: All skipped, warning lists all issues\n```\n\n### 5. Collision Detection Failure\n```go\nTestAutoImportCollisionDetectionError\n- Setup: Mock DetectCollisions() to return error\n- Verify: Import skipped entirely (safe failure mode)\n```\n\n### 6. Hash-Based Skip\n```go\nTestAutoImportHashUnchanged\n- Setup: JSONL hash matches last_import_hash\n- Verify: No collision detection runs, fast path\n```\n\n### 7. Fallback for Non-SQLite\n```go\nTestAutoImportWithoutCollisionDetection\n- Setup: Mock non-SQLite storage backend\n- Verify: Falls back to old behavior, no collision detection\n```\n\n## Test Infrastructure Needed\n\n1. **Helper functions:**\n - createTestDBWithIssues()\n - writeJSONLFile()\n - captureStderrWarnings()\n - simulateGitPull()\n\n2. **Fixtures:**\n - sample-collisions.jsonl\n - sample-exact-matches.jsonl\n - sample-mixed.jsonl\n\n3. **Assertions:**\n - assertIssueState(id, expectedStatus)\n - assertWarningContains(text)\n - assertCollisionCount(n)\n\n## Acceptance Criteria\n- All 7 test scenarios implemented\n- Tests pass consistently\n- Code coverage \u003e80% for autoImportIfNewer()\n- Tests run in \u003c5 seconds total\n- Clear test names and documentation","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-16T18:57:16.323669-07:00","updated_at":"2025-10-16T18:57:16.388111-07:00","dependencies":[{"issue_id":"bd-658","depends_on_id":"bd-545","type":"blocks","created_at":"2025-10-16T18:57:16.791127-07:00","created_by":"import-remap"},{"issue_id":"bd-658","depends_on_id":"bd-376","type":"discovered-from","created_at":"2025-10-16T18:57:16.792704-07:00","created_by":"import-remap"},{"issue_id":"bd-658","depends_on_id":"bd-662","type":"blocks","created_at":"2025-10-16T18:57:16.793791-07:00","created_by":"import-remap"}]} +{"id":"bd-659","title":"Low priority chore","description":"","design":"Benchmarks for:\n1. JSONL import/export performance\n2. Collision detection performance\n3. Three-way merge performance\n4. Gateway API latency\n5. WebSocket throughput\n6. Concurrent client handling\n7. Large database operations (10k+ issues)\n\nUse Go benchmarking and profiling tools.\n\nTrack performance over time in CI.","acceptance_criteria":"- Benchmark suite implemented\n- All key operations benchmarked\n- CPU and memory profiling\n- Large database benchmarks\n- Concurrent operation benchmarks\n- CI integration for regression detection\n- Performance baseline documented\n- Documentation in PERFORMANCE.md\n\n---","status":"closed","priority":4,"issue_type":"chore","created_at":"2025-10-16T18:57:16.325571-07:00","updated_at":"2025-10-16T19:08:32.76036-07:00","closed_at":"2025-10-16T19:08:32.76036-07:00"} +{"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-16T14:33:21.495108-07:00","closed_at":"2025-10-15T03:01:29.58909-07:00","dependencies":[{"issue_id":"bd-66","depends_on_id":"bd-389","type":"parent-child","created_at":"2025-10-16T14:57:49.178216-07:00","created_by":"import-remap"},{"issue_id":"bd-66","depends_on_id":"bd-661","type":"parent-child","created_at":"2025-10-16T18:57:16.862849-07:00","created_by":"import-remap"},{"issue_id":"bd-66","depends_on_id":"bd-378","type":"parent-child","created_at":"2025-10-16T18:57:17.071998-07:00","created_by":"auto-import"}]} +{"id":"bd-660","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-374) while handling distributed creation gracefully.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T18:57:16.326296-07:00","updated_at":"2025-10-16T18:57:16.326296-07:00","closed_at":"2025-10-16T17:49:54.691542-07:00"} +{"id":"bd-661","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","design":"Command should:\n1. Export pending changes to JSONL\n2. Commit changes to git\n3. Pull from remote (with conflict resolution)\n4. Push local commits to remote\n\nWraps the entire sync workflow in one command for better UX.","acceptance_criteria":"- bd sync command implemented\n- Exports dirty changes to JSONL automatically\n- Commits to git with descriptive message\n- Pulls and handles merge conflicts\n- Auto-imports updated JSONL\n- Pushes to remote\n- Error handling for git failures\n- Tests cover success and failure scenarios\n- Documentation in README.md\n\n---","notes":"All tasks completed: bd-64 (performance), bd-65 (migration), bd-66 (version sync), bd-67 (version script), bd-69 (CI coverage), bd-70 (test coverage). Code review follow-up complete.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-16T18:57:16.327043-07:00","updated_at":"2025-10-16T18:57:16.327043-07:00","closed_at":"2025-10-16T17:49:54.510305-07:00"} +{"id":"bd-662","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-641) while handling distributed creation gracefully.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T18:57:16.330979-07:00","updated_at":"2025-10-16T18:57:16.382685-07:00","closed_at":"2025-10-16T17:49:54.510752-07:00","dependencies":[{"issue_id":"bd-662","depends_on_id":"bd-656","type":"discovered-from","created_at":"2025-10-16T18:57:16.79771-07:00","created_by":"import-remap"}]} +{"id":"bd-663","title":"Fix metadata error handling in auto-import","description":"GetMetadata() failure causes auto-import to stop forever. Should treat missing/corrupt metadata as first import (lastHash='') instead of skipping.","status":"open","priority":0,"issue_type":"bug","created_at":"2025-10-16T19:04:18.00281-07:00","updated_at":"2025-10-16T19:04:18.00281-07:00","dependencies":[{"issue_id":"bd-663","depends_on_id":"bd-379","type":"discovered-from","created_at":"2025-10-16T19:04:18.011842-07:00","created_by":"stevey"}]} +{"id":"bd-664","title":"Ensure last_import_hash update is error-checked","description":"If hash update fails after successful import, auto-import will retry same import forever. Must error-check SetMetadata() and warn user.","status":"open","priority":0,"issue_type":"bug","created_at":"2025-10-16T19:04:18.015002-07:00","updated_at":"2025-10-16T19:04:18.015002-07:00","dependencies":[{"issue_id":"bd-664","depends_on_id":"bd-379","type":"discovered-from","created_at":"2025-10-16T19:04:18.018601-07:00","created_by":"stevey"}]} +{"id":"bd-666","title":"Fix N+1 query pattern in auto-import","description":"Line 347 calls GetIssue() for every imported issue. With 1000+ issues this is slow. Batch fetch all existing issues upfront.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T19:04:18.082894-07:00","updated_at":"2025-10-16T19:13:22.93101-07:00","closed_at":"2025-10-16T19:13:22.93101-07:00","dependencies":[{"issue_id":"bd-666","depends_on_id":"bd-379","type":"discovered-from","created_at":"2025-10-16T19:04:18.085777-07:00","created_by":"stevey"}]} +{"id":"bd-667","title":"Implement bd renumber command to compact issue ID space","description":"After closing many duplicates, we have high issue numbers (bd-666) but only 114 open issues. Add command to renumber all issues sequentially to fill gaps.\n\nBehavior:\n- Renumber all issues starting from 1 (or next available after last closed)\n- Update all references: dependencies, parent-child, discovered-from links\n- Update text references in descriptions, notes, acceptance criteria\n- Preserve chronological order by created_at\n- Show mapping report (old ID -\u003e new ID)\n- Require confirmation or --force flag\n- Export clean JSONL after renumber\n\nBenefits:\n- Cleaner ID space after collision remapping creates gaps\n- More human-friendly issue numbers\n- Easier to track project scope\n\nRisks:\n- Breaking external references (GitHub issues, docs, commits)\n- Complexity of updating all references\n- Git history confusion\n\nConsider: Maybe only renumber open issues, leave closed ones untouched?","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-16T19:11:16.097068-07:00","updated_at":"2025-10-16T19:11:16.097068-07:00"} +{"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-16T14:33:21.515891-07:00","closed_at":"2025-10-15T03:01:29.58971-07:00","dependencies":[{"issue_id":"bd-67","depends_on_id":"bd-389","type":"parent-child","created_at":"2025-10-16T14:57:49.217301-07:00","created_by":"import-remap"},{"issue_id":"bd-67","depends_on_id":"bd-661","type":"parent-child","created_at":"2025-10-16T18:57:16.818769-07:00","created_by":"import-remap"},{"issue_id":"bd-67","depends_on_id":"bd-378","type":"parent-child","created_at":"2025-10-16T18:57:17.072564-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-16T14:33:21.51703-07:00","dependencies":[{"issue_id":"bd-68","depends_on_id":"bd-389","type":"parent-child","created_at":"2025-10-16T14:57:49.18494-07:00","created_by":"import-remap"},{"issue_id":"bd-68","depends_on_id":"bd-661","type":"parent-child","created_at":"2025-10-16T18:57:16.806369-07:00","created_by":"import-remap"},{"issue_id":"bd-68","depends_on_id":"bd-378","type":"parent-child","created_at":"2025-10-16T18:57:17.073648-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-16T14:33:21.520766-07:00","closed_at":"2025-10-15T03:01:29.590601-07:00","dependencies":[{"issue_id":"bd-69","depends_on_id":"bd-389","type":"parent-child","created_at":"2025-10-16T14:57:49.127458-07:00","created_by":"import-remap"},{"issue_id":"bd-69","depends_on_id":"bd-661","type":"parent-child","created_at":"2025-10-16T18:57:16.817404-07:00","created_by":"import-remap"},{"issue_id":"bd-69","depends_on_id":"bd-378","type":"parent-child","created_at":"2025-10-16T18:57:17.079606-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-16T17:49:54.654662-07:00","updated_at":"2025-10-16T18:12:45.762722-07:00"} -{"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-16T17:49:54.665945-07:00","updated_at":"2025-10-16T18:12:45.763241-07:00","closed_at":"2025-10-16T17:49:54.665945-07:00","dependencies":[{"issue_id":"bd-70","depends_on_id":"bd-378","type":"parent-child","created_at":"2025-10-16T17:49:54.9007-07:00","created_by":"auto-import"},{"issue_id":"bd-70","depends_on_id":"bd-389","type":"parent-child","created_at":"2025-10-16T17:49:54.907891-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-16T14:33:21.523662-07:00","closed_at":"2025-10-15T03:01:29.591338-07:00","dependencies":[{"issue_id":"bd-70","depends_on_id":"bd-389","type":"parent-child","created_at":"2025-10-16T14:57:49.244676-07:00","created_by":"import-remap"},{"issue_id":"bd-70","depends_on_id":"bd-661","type":"parent-child","created_at":"2025-10-16T18:57:16.838428-07:00","created_by":"import-remap"},{"issue_id":"bd-70","depends_on_id":"bd-378","type":"parent-child","created_at":"2025-10-16T18:57:17.080473-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-16T17:49:54.669468-07:00","updated_at":"2025-10-16T18:12:45.763712-07:00"} {"id":"bd-72","title":"Test performance - issue 1","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-16T17:49:54.67225-07:00","updated_at":"2025-10-16T18:12:45.764167-07:00"} {"id":"bd-73","title":"Performance test 1","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-16T17:49:54.677424-07:00","updated_at":"2025-10-16T18:12:45.764817-07:00"} @@ -406,7 +650,7 @@ {"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":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T17:49:54.6885-07:00","updated_at":"2025-10-16T18:18:03.79501-07:00","closed_at":"2025-10-16T18:18:03.79501-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-16T17:49:54.690081-07:00","updated_at":"2025-10-16T18:12:45.788919-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","notes":"**Historical context (recovered from lost issue bd-221):**\n\nFirst attempt at fixing this race condition had a critical flaw: used 'ROLLBACK; BEGIN IMMEDIATE' which executed as two separate statements. After ROLLBACK, the Go tx object was invalid but continued to be used, causing undefined behavior.\n\nRoot cause of failed fix: database/sql connection pooling. Without acquiring a dedicated connection, subsequent queries could use different connections from the pool, breaking the transaction.\n\nCorrect fix (the one that was merged): Use conn := s.db.Conn(ctx) to acquire a dedicated connection, then execute BEGIN IMMEDIATE, all operations, and COMMIT on that single connection.\n\nThis bug was caught during code review and fixed before merging.\n\nSee LOST_ISSUES_RECOVERY.md for details on bd-221.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T17:49:54.691116-07:00","updated_at":"2025-10-16T18:12:45.789534-07:00","closed_at":"2025-10-16T17:49:54.691116-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-374) while handling distributed creation gracefully.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-16T17:49:54.691542-07:00","updated_at":"2025-10-16T18:12:45.790027-07:00","closed_at":"2025-10-16T17:49:54.691542-07:00"} +{"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-551) 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-16T18:54:29.630811-07:00","closed_at":"2025-10-15T03:01:29.600517-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-16T17:49:54.694595-07:00","updated_at":"2025-10-16T18:12:45.790519-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-16T17:49:54.696688-07:00","updated_at":"2025-10-16T18:12:45.790977-07:00","closed_at":"2025-10-16T17:49:54.696688-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-16T17:49:54.697639-07:00","updated_at":"2025-10-16T18:12:45.791408-07:00","external_ref":"gh-11"} diff --git a/DUPLICATES_REPORT.md b/DUPLICATES_REPORT.md new file mode 100644 index 00000000..83fc8bbc --- /dev/null +++ b/DUPLICATES_REPORT.md @@ -0,0 +1,656 @@ +# Duplicate Issues Report + +Generated: Thu Oct 16 19:06:37 PDT 2025 + +## Add OAuth2 support +Count: 3 +- bd-177 (closed) created 2025-10-14T14:43:06.904366-07:00 +- bd-174 (closed) created 2025-10-14T14:43:06.90268-07:00 +- bd-170 (closed) created 2025-10-14T14:43:06.900641-07:00 + +## Add compacted_at_commit field to Issue type +Count: 9 +- bd-639 (open) created 2025-10-16T18:57:16.296664-07:00 +- bd-605 (open) created 2025-10-16T18:57:16.13228-07:00 +- bd-555 (open) created 2025-10-16T18:57:16.084676-07:00 +- bd-546 (open) created 2025-10-16T18:54:29.391902-07:00 +- bd-532 (open) created 2025-10-16T18:54:29.372914-07:00 +- bd-496 (open) created 2025-10-16T18:54:29.229357-07:00 +- bd-432 (open) created 2025-10-16T18:05:02.18097-07:00 +- bd-405 (closed) created 2025-10-16T16:03:31.57487-07:00 +- bd-384 (closed) created 2025-10-16T14:57:48.834903-07:00 + +## Add integration tests for auto-import collision detection +Count: 9 +- bd-658 (open) created 2025-10-16T18:57:16.323669-07:00 +- bd-640 (closed) created 2025-10-16T18:57:16.298009-07:00 +- bd-599 (open) created 2025-10-16T18:57:16.128178-07:00 +- bd-535 (closed) created 2025-10-16T18:54:29.379553-07:00 +- bd-491 (open) created 2025-10-16T18:54:29.224122-07:00 +- bd-428 (open) created 2025-10-16T18:05:02.176549-07:00 +- bd-401 (open) created 2025-10-16T16:03:31.546156-07:00 +- bd-372 (open) created 2025-10-16T14:57:48.78612-07:00 +- bd-231 (closed) created 2025-10-15T02:12:49.315295-07:00 + +## Add label management commands to CLI +Count: 4 +- bd-571 (open) created 2025-10-16T18:57:16.101107-07:00 +- bd-464 (open) created 2025-10-16T18:54:29.167551-07:00 +- bd-364 (open) created 2025-10-16T14:57:48.773386-07:00 +- bd-198 (closed) created 2025-10-15T01:10:48.43357-07:00 + +## Add migration scripts for GitHub Issues +Count: 8 +- bd-645 (closed) created 2025-10-16T18:57:16.310349-07:00 +- bd-635 (open) created 2025-10-16T18:57:16.292565-07:00 +- bd-543 (closed) created 2025-10-16T18:54:29.387481-07:00 +- bd-529 (open) created 2025-10-16T18:54:29.365728-07:00 +- bd-443 (open) created 2025-10-16T18:05:02.190949-07:00 +- bd-416 (open) created 2025-10-16T16:03:31.596085-07:00 +- bd-370 (open) created 2025-10-16T14:57:48.783124-07:00 +- bd-6 (closed) created 2025-10-14T14:43:06.929582-07:00 + +## Add performance benchmarks document +Count: 8 +- bd-648 (closed) created 2025-10-16T18:57:16.314508-07:00 +- bd-634 (open) created 2025-10-16T18:57:16.290463-07:00 +- bd-528 (open) created 2025-10-16T18:54:29.365021-07:00 +- bd-514 (closed) created 2025-10-16T18:54:29.278305-07:00 +- bd-437 (open) created 2025-10-16T18:05:02.186502-07:00 +- bd-410 (open) created 2025-10-16T16:03:31.585083-07:00 +- bd-376 (open) created 2025-10-16T14:57:48.794452-07:00 +- bd-7 (closed) created 2025-10-14T14:43:06.934101-07:00 + +## Add rate limiting to auth endpoints +Count: 3 +- bd-178 (closed) created 2025-10-14T14:43:06.904917-07:00 +- bd-175 (closed) created 2025-10-14T14:43:06.903236-07:00 +- bd-171 (closed) created 2025-10-14T14:43:06.900983-07:00 + +## Add tests for git-based restoration +Count: 5 +- bd-554 (open) created 2025-10-16T18:57:16.081362-07:00 +- bd-447 (open) created 2025-10-16T18:54:29.108386-07:00 +- bd-435 (open) created 2025-10-16T18:05:02.183952-07:00 +- bd-408 (open) created 2025-10-16T16:03:31.582488-07:00 +- bd-381 (open) created 2025-10-16T14:57:48.821462-07:00 + +## Audit and document all inconsistent issues in database +Count: 6 +- bd-597 (open) created 2025-10-16T18:57:16.126722-07:00 +- bd-489 (open) created 2025-10-16T18:54:29.220414-07:00 +- bd-424 (open) created 2025-10-16T18:05:02.172587-07:00 +- bd-397 (open) created 2025-10-16T16:03:31.520913-07:00 +- bd-366 (open) created 2025-10-16T14:57:48.776118-07:00 +- bd-227 (closed) created 2025-10-15T01:58:50.908363-07:00 + +## Auto-import fails in git workflows due to mtime issues +Count: 7 +- bd-631 (in_progress) created 2025-10-16T18:57:16.268525-07:00 +- bd-619 (closed) created 2025-10-16T18:57:16.251812-07:00 +- bd-511 (closed) created 2025-10-16T18:54:29.258757-07:00 +- bd-448 (in_progress) created 2025-10-16T18:54:29.114894-07:00 +- bd-421 (closed) created 2025-10-16T18:05:02.16198-07:00 +- bd-334 (in_progress) created 2025-10-16T14:57:48.682806-07:00 +- bd-84 (closed) created 2025-10-14T14:43:06.941275-07:00 + +## Benchmark cycle detection performance on large dependency graphs +Count: 2 +- bd-374 (open) created 2025-10-16T14:57:48.792813-07:00 +- bd-311 (closed) created 2025-10-16T10:28:24.231469-07:00 + +## Bug: Import creating duplicates instead of deduplicating +Count: 2 +- bd-636 (closed) created 2025-10-16T18:57:16.29361-07:00 +- bd-530 (closed) created 2025-10-16T18:54:29.367086-07:00 + +## Build collision resolution tooling for distributed branch workflows +Count: 5 +- bd-662 (closed) created 2025-10-16T18:57:16.330979-07:00 +- bd-660 (closed) created 2025-10-16T18:57:16.326296-07:00 +- bd-553 (closed) created 2025-10-16T18:54:29.413281-07:00 +- bd-545 (closed) created 2025-10-16T18:54:29.3909-07:00 +- bd-9 (closed) created 2025-10-14T14:43:06.943629-07:00 + +## Code review follow-up: Post-PR #8 merge improvements +Count: 8 +- bd-661 (closed) created 2025-10-16T18:57:16.327043-07:00 +- bd-633 (open) created 2025-10-16T18:57:16.28274-07:00 +- bd-548 (closed) created 2025-10-16T18:54:29.398351-07:00 +- bd-527 (open) created 2025-10-16T18:54:29.363772-07:00 +- bd-426 (open) created 2025-10-16T18:05:02.175188-07:00 +- bd-399 (open) created 2025-10-16T16:03:31.525208-07:00 +- bd-389 (open) created 2025-10-16T14:57:48.843762-07:00 +- bd-71 (closed) created 2025-10-14T14:43:06.934829-07:00 + +## Code review: Auto-import collision detection fix (bd-228) +Count: 6 +- bd-598 (open) created 2025-10-16T18:57:16.127529-07:00 +- bd-490 (open) created 2025-10-16T18:54:29.222585-07:00 +- bd-427 (open) created 2025-10-16T18:05:02.175897-07:00 +- bd-400 (open) created 2025-10-16T16:03:31.536355-07:00 +- bd-379 (closed) created 2025-10-16T14:57:48.812015-07:00 +- bd-230 (closed) created 2025-10-15T02:12:48.210337-07:00 + +## Concurrent bd commands collide on shared .tmp filename +Count: 5 +- bd-654 (closed) created 2025-10-16T18:57:16.319205-07:00 +- bd-567 (closed) created 2025-10-16T18:57:16.097942-07:00 +- bd-538 (closed) created 2025-10-16T18:54:29.382598-07:00 +- bd-506 (closed) created 2025-10-16T18:54:29.244231-07:00 +- bd-373 (closed) created 2025-10-16T14:57:48.790027-07:00 + +## Consider batching API for bulk issue creation (recovered from bd-222) +Count: 8 +- bd-651 (open) created 2025-10-16T18:57:16.316474-07:00 +- bd-600 (open) created 2025-10-16T18:57:16.128761-07:00 +- bd-536 (open) created 2025-10-16T18:54:29.380494-07:00 +- bd-492 (open) created 2025-10-16T18:54:29.225697-07:00 +- bd-429 (open) created 2025-10-16T18:05:02.177375-07:00 +- bd-402 (open) created 2025-10-16T16:03:31.547562-07:00 +- bd-371 (open) created 2025-10-16T14:57:48.784477-07:00 +- bd-232 (closed) created 2025-10-15T02:21:43.085279-07:00 + +## Critical: Auto-import silently overwrites local changes without collision detection +Count: 3 +- bd-656 (closed) created 2025-10-16T18:57:16.321969-07:00 +- bd-552 (closed) created 2025-10-16T18:54:29.409532-07:00 +- bd-228 (closed) created 2025-10-15T02:06:30.671918-07:00 + +## Data model allows inconsistent status/closed_at states +Count: 6 +- bd-594 (in_progress) created 2025-10-16T18:57:16.124308-07:00 +- bd-487 (in_progress) created 2025-10-16T18:54:29.217094-07:00 +- bd-430 (in_progress) created 2025-10-16T18:05:02.178935-07:00 +- bd-417 (in_progress) created 2025-10-16T16:03:31.596875-07:00 +- bd-391 (in_progress) created 2025-10-16T14:57:48.845572-07:00 +- bd-224 (closed) created 2025-10-15T01:36:21.971783-07:00 + +## Document git-based restoration feature +Count: 5 +- bd-638 (open) created 2025-10-16T18:57:16.295983-07:00 +- bd-525 (open) created 2025-10-16T18:54:29.325521-07:00 +- bd-436 (open) created 2025-10-16T18:05:02.185847-07:00 +- bd-409 (open) created 2025-10-16T16:03:31.584232-07:00 +- bd-380 (open) created 2025-10-16T14:57:48.816028-07:00 + +## Epic: Add intelligent database compaction with Claude Haiku +Count: 2 +- bd-392 (open) created 2025-10-16T14:57:48.846232-07:00 +- bd-251 (open) created 2025-10-15T21:51:23.210339-07:00 + +## Epic: Fix status/closed_at inconsistency (bd-224 solution) +Count: 6 +- bd-596 (open) created 2025-10-16T18:57:16.125905-07:00 +- bd-488 (open) created 2025-10-16T18:54:29.219427-07:00 +- bd-423 (open) created 2025-10-16T18:05:02.164815-07:00 +- bd-396 (open) created 2025-10-16T16:03:31.504655-07:00 +- bd-367 (open) created 2025-10-16T14:57:48.77756-07:00 +- bd-226 (closed) created 2025-10-15T01:58:41.041574-07:00 + +## Fix: bd init --prefix test -q flag not recognized +Count: 4 +- bd-558 (open) created 2025-10-16T18:57:16.087909-07:00 +- bd-451 (open) created 2025-10-16T18:54:29.118089-07:00 +- bd-321 (open) created 2025-10-16T14:57:48.632494-07:00 +- bd-169 (closed) created 2025-10-14T14:43:06.899974-07:00 + +## GH-11: Add Docker support for hosted/shared instance +Count: 8 +- bd-629 (open) created 2025-10-16T18:57:16.266652-07:00 +- bd-617 (closed) created 2025-10-16T18:57:16.246023-07:00 +- bd-523 (open) created 2025-10-16T18:54:29.323831-07:00 +- bd-509 (closed) created 2025-10-16T18:54:29.247674-07:00 +- bd-444 (closed) created 2025-10-16T18:05:02.191716-07:00 +- bd-394 (closed) created 2025-10-16T16:03:31.498107-07:00 +- bd-358 (open) created 2025-10-16T14:57:48.754885-07:00 +- bd-92 (closed) created 2025-10-14T14:43:06.945147-07:00 + +## GH-3: Debug zsh killed error on bd init +Count: 8 +- bd-630 (closed) created 2025-10-16T18:57:16.267697-07:00 +- bd-618 (blocked) created 2025-10-16T18:57:16.249493-07:00 +- bd-524 (open) created 2025-10-16T18:54:29.324466-07:00 +- bd-510 (blocked) created 2025-10-16T18:54:29.254527-07:00 +- bd-431 (blocked) created 2025-10-16T18:05:02.180111-07:00 +- bd-406 (blocked) created 2025-10-16T16:03:31.580261-07:00 +- bd-348 (open) created 2025-10-16T14:57:48.746521-07:00 +- bd-87 (blocked) created 2025-10-14T14:43:06.942576-07:00 + +## Git-based restoration for compacted issues +Count: 7 +- bd-649 (open) created 2025-10-16T18:57:16.31515-07:00 +- bd-604 (open) created 2025-10-16T18:57:16.131361-07:00 +- bd-550 (open) created 2025-10-16T18:54:29.405556-07:00 +- bd-495 (open) created 2025-10-16T18:54:29.228422-07:00 +- bd-422 (open) created 2025-10-16T18:05:02.163999-07:00 +- bd-404 (open) created 2025-10-16T16:03:31.564412-07:00 +- bd-385 (closed) created 2025-10-16T14:57:48.836877-07:00 + +## Implement bd restore command +Count: 9 +- bd-637 (open) created 2025-10-16T18:57:16.294864-07:00 +- bd-622 (open) created 2025-10-16T18:57:16.255193-07:00 +- bd-607 (open) created 2025-10-16T18:57:16.147008-07:00 +- bd-549 (open) created 2025-10-16T18:54:29.399249-07:00 +- bd-531 (open) created 2025-10-16T18:54:29.370445-07:00 +- bd-498 (open) created 2025-10-16T18:54:29.232439-07:00 +- bd-434 (open) created 2025-10-16T18:05:02.183027-07:00 +- bd-407 (closed) created 2025-10-16T16:03:31.581845-07:00 +- bd-383 (closed) created 2025-10-16T14:57:48.831757-07:00 + +## Improve error handling in dependency removal during remapping +Count: 6 +- bd-650 (open) created 2025-10-16T18:57:16.315828-07:00 +- bd-602 (open) created 2025-10-16T18:57:16.130007-07:00 +- bd-515 (open) created 2025-10-16T18:54:29.279242-07:00 +- bd-493 (open) created 2025-10-16T18:54:29.226626-07:00 +- bd-359 (open) created 2025-10-16T14:57:48.756031-07:00 +- bd-28 (closed) created 2025-10-14T14:43:06.912228-07:00 + +## Improve session management +Count: 3 +- bd-179 (closed) created 2025-10-14T14:43:06.905375-07:00 +- bd-176 (closed) created 2025-10-14T14:43:06.903785-07:00 +- bd-172 (closed) created 2025-10-14T14:43:06.901432-07:00 + +## Investigate data recovery for issues overwritten by auto-import bug +Count: 3 +- bd-646 (closed) created 2025-10-16T18:57:16.312989-07:00 +- bd-539 (closed) created 2025-10-16T18:54:29.383454-07:00 +- bd-229 (closed) created 2025-10-15T02:10:40.724826-07:00 + +## Low priority chore +Count: 8 +- bd-659 (open) created 2025-10-16T18:57:16.325571-07:00 +- bd-647 (closed) created 2025-10-16T18:57:16.313802-07:00 +- bd-643 (open) created 2025-10-16T18:57:16.307575-07:00 +- bd-547 (open) created 2025-10-16T18:54:29.392669-07:00 +- bd-542 (closed) created 2025-10-16T18:54:29.386684-07:00 +- bd-534 (open) created 2025-10-16T18:54:29.378627-07:00 +- bd-377 (open) created 2025-10-16T14:57:48.796499-07:00 +- bd-4 (closed) created 2025-10-14T14:43:06.917877-07:00 + +## P2: Consider batching API for bulk issue creation +Count: 4 +- bd-593 (open) created 2025-10-16T18:57:16.122852-07:00 +- bd-486 (open) created 2025-10-16T18:54:29.215696-07:00 +- bd-390 (open) created 2025-10-16T14:57:48.844729-07:00 +- bd-222 (closed) created 2025-10-15T01:18:46.4512-07:00 + +## Phase 1: Implement bd daemon command +Count: 2 +- bd-386 (closed) created 2025-10-16T14:57:48.840609-07:00 +- bd-273 (closed) created 2025-10-16T01:40:04.263802-07:00 + +## Phase 1: Implement bd sync command +Count: 2 +- bd-378 (closed) created 2025-10-16T14:57:48.811221-07:00 +- bd-272 (closed) created 2025-10-16T01:40:04.246855-07:00 + +## Reach 1.0 release milestone +Count: 8 +- bd-657 (closed) created 2025-10-16T18:57:16.323024-07:00 +- bd-632 (open) created 2025-10-16T18:57:16.281913-07:00 +- bd-540 (closed) created 2025-10-16T18:54:29.38494-07:00 +- bd-526 (open) created 2025-10-16T18:54:29.34597-07:00 +- bd-425 (open) created 2025-10-16T18:05:02.174097-07:00 +- bd-398 (open) created 2025-10-16T16:03:31.523258-07:00 +- bd-388 (open) created 2025-10-16T14:57:48.842642-07:00 +- bd-8 (closed) created 2025-10-14T14:43:06.938911-07:00 + +## Record git commit hash during compaction +Count: 9 +- bd-642 (open) created 2025-10-16T18:57:16.306079-07:00 +- bd-641 (open) created 2025-10-16T18:57:16.303615-07:00 +- bd-606 (open) created 2025-10-16T18:57:16.139786-07:00 +- bd-551 (open) created 2025-10-16T18:54:29.406385-07:00 +- bd-533 (open) created 2025-10-16T18:54:29.377847-07:00 +- bd-497 (open) created 2025-10-16T18:54:29.231369-07:00 +- bd-433 (open) created 2025-10-16T18:05:02.182118-07:00 +- bd-395 (closed) created 2025-10-16T16:03:31.501666-07:00 +- bd-387 (closed) created 2025-10-16T14:57:48.841348-07:00 + +## Support ID space partitioning for parallel worker agents +Count: 2 +- bd-601 (closed) created 2025-10-16T18:57:16.12934-07:00 +- bd-24 (closed) created 2025-10-14T14:43:06.910467-07:00 + +## Test reopen command +Count: 2 +- bd-249 (closed) created 2025-10-15T16:28:49.924381-07:00 +- bd-248 (closed) created 2025-10-15T16:28:44.246154-07:00 + +## Ultrathink: Choose solution for status/closed_at inconsistency (bd-224) +Count: 3 +- bd-595 (closed) created 2025-10-16T18:57:16.125291-07:00 +- bd-537 (closed) created 2025-10-16T18:54:29.38148-07:00 +- bd-225 (closed) created 2025-10-15T01:47:25.564925-07:00 + +## Use safer placeholder pattern in replaceIDReferences +Count: 5 +- bd-603 (open) created 2025-10-16T18:57:16.130694-07:00 +- bd-494 (open) created 2025-10-16T18:54:29.227598-07:00 +- bd-445 (open) created 2025-10-16T18:05:02.192424-07:00 +- bd-403 (open) created 2025-10-16T16:03:31.550675-07:00 +- bd-29 (open) created 2025-10-14T14:43:06.912567-07:00 + +## final_review_test_ +Count: 4 +- bd-592 (open) created 2025-10-16T18:57:16.122201-07:00 +- bd-485 (open) created 2025-10-16T18:54:29.214252-07:00 +- bd-317 (open) created 2025-10-16T14:57:48.617035-07:00 +- bd-220 (closed) created 2025-10-15T01:17:55.669949-07:00 + +## final_test_10 +Count: 5 +- bd-566 (open) created 2025-10-16T18:57:16.096912-07:00 +- bd-459 (open) created 2025-10-16T18:54:29.160672-07:00 +- bd-365 (closed) created 2025-10-16T14:57:48.77507-07:00 +- bd-353 (open) created 2025-10-16T14:57:48.750486-07:00 +- bd-191 (closed) created 2025-10-15T01:07:02.010151-07:00 + +## final_test_7 +Count: 4 +- bd-610 (open) created 2025-10-16T18:57:16.220553-07:00 +- bd-460 (open) created 2025-10-16T18:54:29.163056-07:00 +- bd-330 (open) created 2025-10-16T14:57:48.665684-07:00 +- bd-192 (closed) created 2025-10-15T01:07:02.010504-07:00 + +## parallel_test_1 +Count: 10 +- bd-652 (open) created 2025-10-16T18:57:16.31729-07:00 +- bd-628 (open) created 2025-10-16T18:57:16.265633-07:00 +- bd-616 (closed) created 2025-10-16T18:57:16.239759-07:00 +- bd-522 (open) created 2025-10-16T18:54:29.311149-07:00 +- bd-516 (open) created 2025-10-16T18:54:29.280457-07:00 +- bd-508 (closed) created 2025-10-16T18:54:29.246693-07:00 +- bd-442 (closed) created 2025-10-16T18:05:02.190287-07:00 +- bd-415 (closed) created 2025-10-16T16:03:31.592055-07:00 +- bd-361 (open) created 2025-10-16T14:57:48.761649-07:00 +- bd-94 (closed) created 2025-10-14T14:43:06.946176-07:00 + +## parallel_test_10 +Count: 4 +- bd-609 (open) created 2025-10-16T18:57:16.194118-07:00 +- bd-500 (open) created 2025-10-16T18:54:29.237287-07:00 +- bd-335 (open) created 2025-10-16T14:57:48.689034-07:00 +- bd-100 (closed) created 2025-10-14T14:43:06.865466-07:00 + +## parallel_test_2 +Count: 8 +- bd-623 (open) created 2025-10-16T18:57:16.258011-07:00 +- bd-612 (closed) created 2025-10-16T18:57:16.232795-07:00 +- bd-503 (open) created 2025-10-16T18:54:29.241214-07:00 +- bd-502 (closed) created 2025-10-16T18:54:29.239523-07:00 +- bd-438 (closed) created 2025-10-16T18:05:02.18713-07:00 +- bd-411 (closed) created 2025-10-16T16:03:31.585784-07:00 +- bd-355 (open) created 2025-10-16T14:57:48.752315-07:00 +- bd-99 (closed) created 2025-10-14T14:43:06.948343-07:00 + +## parallel_test_3 +Count: 6 +- bd-620 (open) created 2025-10-16T18:57:16.252728-07:00 +- bd-608 (open) created 2025-10-16T18:57:16.161617-07:00 +- bd-512 (open) created 2025-10-16T18:54:29.25947-07:00 +- bd-499 (open) created 2025-10-16T18:54:29.236426-07:00 +- bd-354 (open) created 2025-10-16T14:57:48.751322-07:00 +- bd-101 (closed) created 2025-10-14T14:43:06.865941-07:00 + +## parallel_test_4 +Count: 11 +- bd-644 (open) created 2025-10-16T18:57:16.30893-07:00 +- bd-627 (open) created 2025-10-16T18:57:16.263891-07:00 +- bd-615 (closed) created 2025-10-16T18:57:16.238895-07:00 +- bd-521 (open) created 2025-10-16T18:54:29.299627-07:00 +- bd-518 (open) created 2025-10-16T18:54:29.291492-07:00 +- bd-507 (closed) created 2025-10-16T18:54:29.246065-07:00 +- bd-441 (closed) created 2025-10-16T18:05:02.189537-07:00 +- bd-418 (open) created 2025-10-16T16:03:31.597564-07:00 +- bd-414 (closed) created 2025-10-16T16:03:31.589071-07:00 +- bd-363 (open) created 2025-10-16T14:57:48.770023-07:00 +- bd-95 (closed) created 2025-10-14T14:43:06.946509-07:00 + +## parallel_test_5 +Count: 10 +- bd-624 (open) created 2025-10-16T18:57:16.259921-07:00 +- bd-621 (open) created 2025-10-16T18:57:16.253519-07:00 +- bd-613 (closed) created 2025-10-16T18:57:16.235664-07:00 +- bd-513 (open) created 2025-10-16T18:54:29.265467-07:00 +- bd-505 (closed) created 2025-10-16T18:54:29.242834-07:00 +- bd-504 (open) created 2025-10-16T18:54:29.242009-07:00 +- bd-439 (closed) created 2025-10-16T18:05:02.187725-07:00 +- bd-412 (closed) created 2025-10-16T16:03:31.586415-07:00 +- bd-356 (open) created 2025-10-16T14:57:48.753003-07:00 +- bd-98 (closed) created 2025-10-14T14:43:06.947803-07:00 + +## parallel_test_6 +Count: 8 +- bd-625 (open) created 2025-10-16T18:57:16.260541-07:00 +- bd-614 (closed) created 2025-10-16T18:57:16.236286-07:00 +- bd-519 (open) created 2025-10-16T18:54:29.296165-07:00 +- bd-501 (closed) created 2025-10-16T18:54:29.238225-07:00 +- bd-440 (closed) created 2025-10-16T18:05:02.188753-07:00 +- bd-413 (closed) created 2025-10-16T16:03:31.588315-07:00 +- bd-357 (open) created 2025-10-16T14:57:48.754125-07:00 +- bd-97 (closed) created 2025-10-14T14:43:06.947256-07:00 + +## parallel_test_7 +Count: 6 +- bd-626 (open) created 2025-10-16T18:57:16.262607-07:00 +- bd-611 (closed) created 2025-10-16T18:57:16.227227-07:00 +- bd-541 (closed) created 2025-10-16T18:54:29.38566-07:00 +- bd-520 (open) created 2025-10-16T18:54:29.29821-07:00 +- bd-360 (open) created 2025-10-16T14:57:48.75773-07:00 +- bd-96 (closed) created 2025-10-14T14:43:06.946887-07:00 + +## parallel_test_8 +Count: 5 +- bd-556 (open) created 2025-10-16T18:57:16.085398-07:00 +- bd-449 (open) created 2025-10-16T18:54:29.116433-07:00 +- bd-382 (closed) created 2025-10-16T14:57:48.825863-07:00 +- bd-319 (open) created 2025-10-16T14:57:48.630725-07:00 +- bd-102 (closed) created 2025-10-14T14:43:06.866351-07:00 + +## parallel_test_9 +Count: 7 +- bd-655 (closed) created 2025-10-16T18:57:16.320156-07:00 +- bd-557 (open) created 2025-10-16T18:57:16.086652-07:00 +- bd-544 (closed) created 2025-10-16T18:54:29.3881-07:00 +- bd-450 (open) created 2025-10-16T18:54:29.117232-07:00 +- bd-368 (closed) created 2025-10-16T14:57:48.780354-07:00 +- bd-320 (open) created 2025-10-16T14:57:48.631628-07:00 +- bd-103 (closed) created 2025-10-14T14:43:06.866766-07:00 + +## race_test_10 +Count: 8 +- bd-589 (open) created 2025-10-16T18:57:16.119487-07:00 +- bd-564 (open) created 2025-10-16T18:57:16.095128-07:00 +- bd-482 (open) created 2025-10-16T18:54:29.210508-07:00 +- bd-457 (open) created 2025-10-16T18:54:29.159194-07:00 +- bd-352 (open) created 2025-10-16T14:57:48.749464-07:00 +- bd-327 (open) created 2025-10-16T14:57:48.660524-07:00 +- bd-217 (closed) created 2025-10-15T01:11:09.805774-07:00 +- bd-189 (closed) created 2025-10-15T01:07:02.008903-07:00 + +## race_test_11 +Count: 8 +- bd-579 (open) created 2025-10-16T18:57:16.107574-07:00 +- bd-565 (open) created 2025-10-16T18:57:16.095923-07:00 +- bd-472 (open) created 2025-10-16T18:54:29.199752-07:00 +- bd-458 (open) created 2025-10-16T18:54:29.159866-07:00 +- bd-342 (open) created 2025-10-16T14:57:48.720418-07:00 +- bd-328 (open) created 2025-10-16T14:57:48.662708-07:00 +- bd-207 (closed) created 2025-10-15T01:11:09.049061-07:00 +- bd-190 (closed) created 2025-10-15T01:07:02.009797-07:00 + +## race_test_12 +Count: 4 +- bd-586 (open) created 2025-10-16T18:57:16.114034-07:00 +- bd-479 (open) created 2025-10-16T18:54:29.206087-07:00 +- bd-349 (open) created 2025-10-16T14:57:48.747288-07:00 +- bd-214 (closed) created 2025-10-15T01:11:09.061603-07:00 + +## race_test_13 +Count: 4 +- bd-588 (open) created 2025-10-16T18:57:16.118444-07:00 +- bd-481 (open) created 2025-10-16T18:54:29.209342-07:00 +- bd-351 (open) created 2025-10-16T14:57:48.748767-07:00 +- bd-216 (closed) created 2025-10-15T01:11:09.74037-07:00 + +## race_test_14 +Count: 4 +- bd-576 (open) created 2025-10-16T18:57:16.105357-07:00 +- bd-469 (open) created 2025-10-16T18:54:29.193776-07:00 +- bd-339 (open) created 2025-10-16T14:57:48.715948-07:00 +- bd-204 (closed) created 2025-10-15T01:11:09.028356-07:00 + +## race_test_15 +Count: 4 +- bd-587 (open) created 2025-10-16T18:57:16.117429-07:00 +- bd-480 (open) created 2025-10-16T18:54:29.208689-07:00 +- bd-350 (open) created 2025-10-16T14:57:48.748148-07:00 +- bd-215 (closed) created 2025-10-15T01:11:09.651271-07:00 + +## race_test_16 +Count: 8 +- bd-581 (open) created 2025-10-16T18:57:16.109095-07:00 +- bd-562 (open) created 2025-10-16T18:57:16.092273-07:00 +- bd-474 (open) created 2025-10-16T18:54:29.201518-07:00 +- bd-455 (open) created 2025-10-16T18:54:29.14489-07:00 +- bd-344 (open) created 2025-10-16T14:57:48.732302-07:00 +- bd-325 (open) created 2025-10-16T14:57:48.643077-07:00 +- bd-209 (closed) created 2025-10-15T01:11:09.146015-07:00 +- bd-187 (closed) created 2025-10-15T01:07:02.008177-07:00 + +## race_test_17 +Count: 8 +- bd-590 (open) created 2025-10-16T18:57:16.120707-07:00 +- bd-563 (open) created 2025-10-16T18:57:16.093146-07:00 +- bd-483 (open) created 2025-10-16T18:54:29.211541-07:00 +- bd-456 (open) created 2025-10-16T18:54:29.145877-07:00 +- bd-329 (open) created 2025-10-16T14:57:48.663415-07:00 +- bd-326 (open) created 2025-10-16T14:57:48.645291-07:00 +- bd-218 (closed) created 2025-10-15T01:11:09.838009-07:00 +- bd-188 (closed) created 2025-10-15T01:07:02.008525-07:00 + +## race_test_18 +Count: 4 +- bd-582 (open) created 2025-10-16T18:57:16.109904-07:00 +- bd-475 (open) created 2025-10-16T18:54:29.20249-07:00 +- bd-345 (open) created 2025-10-16T14:57:48.742594-07:00 +- bd-210 (closed) created 2025-10-15T01:11:09.146262-07:00 + +## race_test_19 +Count: 4 +- bd-580 (open) created 2025-10-16T18:57:16.108424-07:00 +- bd-473 (open) created 2025-10-16T18:54:29.20066-07:00 +- bd-343 (open) created 2025-10-16T14:57:48.727492-07:00 +- bd-208 (closed) created 2025-10-15T01:11:09.061296-07:00 + +## race_test_2 +Count: 4 +- bd-574 (open) created 2025-10-16T18:57:16.103608-07:00 +- bd-467 (open) created 2025-10-16T18:54:29.189632-07:00 +- bd-337 (open) created 2025-10-16T14:57:48.700706-07:00 +- bd-202 (closed) created 2025-10-15T01:11:09.022114-07:00 + +## race_test_20 +Count: 4 +- bd-583 (open) created 2025-10-16T18:57:16.110877-07:00 +- bd-476 (open) created 2025-10-16T18:54:29.203114-07:00 +- bd-346 (open) created 2025-10-16T14:57:48.744437-07:00 +- bd-211 (closed) created 2025-10-15T01:11:09.151945-07:00 + +## race_test_3 +Count: 4 +- bd-585 (open) created 2025-10-16T18:57:16.1129-07:00 +- bd-478 (open) created 2025-10-16T18:54:29.205082-07:00 +- bd-318 (open) created 2025-10-16T14:57:48.62383-07:00 +- bd-213 (closed) created 2025-10-15T01:11:09.244796-07:00 + +## race_test_4 +Count: 8 +- bd-572 (open) created 2025-10-16T18:57:16.102009-07:00 +- bd-559 (open) created 2025-10-16T18:57:16.088924-07:00 +- bd-465 (open) created 2025-10-16T18:54:29.173666-07:00 +- bd-452 (open) created 2025-10-16T18:54:29.118929-07:00 +- bd-369 (open) created 2025-10-16T14:57:48.781563-07:00 +- bd-322 (open) created 2025-10-16T14:57:48.635357-07:00 +- bd-200 (closed) created 2025-10-15T01:11:09.001476-07:00 +- bd-184 (closed) created 2025-10-15T01:07:02.006879-07:00 + +## race_test_5 +Count: 8 +- bd-573 (open) created 2025-10-16T18:57:16.102671-07:00 +- bd-561 (open) created 2025-10-16T18:57:16.091191-07:00 +- bd-466 (open) created 2025-10-16T18:54:29.187434-07:00 +- bd-454 (open) created 2025-10-16T18:54:29.121523-07:00 +- bd-336 (open) created 2025-10-16T14:57:48.697455-07:00 +- bd-324 (open) created 2025-10-16T14:57:48.637257-07:00 +- bd-201 (closed) created 2025-10-15T01:11:09.007015-07:00 +- bd-186 (closed) created 2025-10-15T01:07:02.007814-07:00 + +## race_test_6 +Count: 4 +- bd-584 (open) created 2025-10-16T18:57:16.111868-07:00 +- bd-477 (open) created 2025-10-16T18:54:29.204178-07:00 +- bd-347 (open) created 2025-10-16T14:57:48.745496-07:00 +- bd-212 (closed) created 2025-10-15T01:11:09.18421-07:00 + +## race_test_7 +Count: 4 +- bd-575 (open) created 2025-10-16T18:57:16.104398-07:00 +- bd-468 (open) created 2025-10-16T18:54:29.192508-07:00 +- bd-338 (open) created 2025-10-16T14:57:48.7088-07:00 +- bd-203 (closed) created 2025-10-15T01:11:09.021971-07:00 + +## race_test_8 +Count: 8 +- bd-578 (open) created 2025-10-16T18:57:16.106883-07:00 +- bd-560 (open) created 2025-10-16T18:57:16.090257-07:00 +- bd-471 (open) created 2025-10-16T18:54:29.198992-07:00 +- bd-453 (open) created 2025-10-16T18:54:29.120396-07:00 +- bd-341 (open) created 2025-10-16T14:57:48.719466-07:00 +- bd-323 (open) created 2025-10-16T14:57:48.636432-07:00 +- bd-206 (closed) created 2025-10-15T01:11:09.040766-07:00 +- bd-185 (closed) created 2025-10-15T01:07:02.007447-07:00 + +## race_test_9 +Count: 4 +- bd-577 (open) created 2025-10-16T18:57:16.106035-07:00 +- bd-470 (open) created 2025-10-16T18:54:29.197319-07:00 +- bd-340 (open) created 2025-10-16T14:57:48.716781-07:00 +- bd-205 (closed) created 2025-10-15T01:11:09.032373-07:00 + +## stress_test_1 +Count: 4 +- bd-570 (open) created 2025-10-16T18:57:16.100376-07:00 +- bd-463 (open) created 2025-10-16T18:54:29.166004-07:00 +- bd-333 (open) created 2025-10-16T14:57:48.682146-07:00 +- bd-195 (closed) created 2025-10-15T01:07:02.011549-07:00 + +## stress_test_5 +Count: 4 +- bd-568 (open) created 2025-10-16T18:57:16.098799-07:00 +- bd-461 (open) created 2025-10-16T18:54:29.163666-07:00 +- bd-331 (open) created 2025-10-16T14:57:48.668149-07:00 +- bd-193 (closed) created 2025-10-15T01:07:02.010847-07:00 + +## stress_test_6 +Count: 5 +- bd-569 (open) created 2025-10-16T18:57:16.099688-07:00 +- bd-462 (open) created 2025-10-16T18:54:29.164402-07:00 +- bd-375 (closed) created 2025-10-16T14:57:48.793624-07:00 +- bd-332 (open) created 2025-10-16T14:57:48.680992-07:00 +- bd-194 (closed) created 2025-10-15T01:07:02.011186-07:00 + +## verification_ +Count: 6 +- bd-653 (open) created 2025-10-16T18:57:16.317983-07:00 +- bd-591 (open) created 2025-10-16T18:57:16.121455-07:00 +- bd-517 (open) created 2025-10-16T18:54:29.281281-07:00 +- bd-484 (open) created 2025-10-16T18:54:29.212136-07:00 +- bd-362 (open) created 2025-10-16T14:57:48.765482-07:00 +- bd-219 (closed) created 2025-10-15T01:12:54.151096-07:00 + diff --git a/REVIEW_BD379.md b/REVIEW_BD379.md new file mode 100644 index 00000000..22c50dd6 --- /dev/null +++ b/REVIEW_BD379.md @@ -0,0 +1,177 @@ +# Code Review: Auto-Import Collision Detection (bd-379) + +## Executive Summary + +The auto-import collision detection implementation is **functionally working but has several correctness and robustness issues** that should be addressed. Rating: **3.5/5** - Works in happy path but vulnerable to edge cases. + +## Critical Issues (P0-P1) + +### 1. **Metadata Error Handling is Too Conservative** (P0) +**Current behavior:** If `GetMetadata()` fails, auto-import is skipped entirely. + +**Problem:** This means if metadata is corrupted or missing, auto-import stops forever until manually fixed. + +**Fix:** +```go +lastHash, err := store.GetMetadata(ctx, "last_import_hash") +if err != nil { + if os.Getenv("BD_DEBUG") != "" { + fmt.Fprintf(os.Stderr, "Debug: metadata read failed (%v), assuming first import\n", err) + } + lastHash = "" // Treat as first import +} +``` + +### 2. **Hash Not Updated on Partial Success** (P0) +**Problem:** If import succeeds but we fail to update `last_import_hash`, auto-import will retry the same import forever. + +**Current behavior:** Hash update happens at end (line ~404) but not error-checked. + +**Fix:** Track import success/failure state and only update hash on full success: +```go +// After all imports complete successfully +if err := store.SetMetadata(ctx, "last_import_hash", currentHash); err != nil { + fmt.Fprintf(os.Stderr, "Warning: failed to update import hash: %v\n", err) + fmt.Fprintf(os.Stderr, "Next auto-import may re-import these issues.\n") +} +``` + +### 3. **No Transaction for Multi-Issue Import** (P1) +**Problem:** If import fails midway, database is left in inconsistent state. + +**Current behavior:** Each issue is imported separately (lines 346-401). + +**Fix:** Wrap entire import in a transaction or use batch operations. + +### 4. **N+1 Query Pattern** (P1) +**Problem:** Line 347: `store.GetIssue(ctx, issue.ID)` is called for every issue = O(n) queries. + +**Impact:** With 1000+ issues, this is slow and hammers the database. + +**Fix:** Batch fetch all existing IDs upfront: +```go +existingIDs := make(map[string]*types.Issue) +allExisting, err := store.SearchIssues(ctx, "", types.IssueFilter{}) +for _, issue := range allExisting { + existingIDs[issue.ID] = issue +} +``` + +## Medium Issues (P2) + +### 5. **Scanner Uses String Conversion** (P2) +**Line 233:** `strings.NewReader(string(jsonlData))` + +**Problem:** Unnecessarily converts bytes to string, wastes memory. + +**Fix:** `bytes.NewReader(jsonlData)` + +### 6. **Verbose Output on Every Auto-Import** (P2) +**Current:** Prints remapping summary to stderr on every collision (lines 309-329). + +**Problem:** For frequent auto-imports with collisions, this gets noisy. + +**Fix:** Gate detailed output behind `BD_DEBUG`, show 1-line summary by default: +```go +if os.Getenv("BD_DEBUG") != "" { + // Detailed output +} else { + fmt.Fprintf(os.Stderr, "Auto-import: %d parsed, %d remapped due to collisions\n", len(allIssues), numRemapped) +} +``` + +### 7. **No Collision Metrics/Telemetry** (P2) +**Problem:** No way to track how often collisions occur or if they're increasing. + +**Fix:** Add metadata counters: +- `collision_count_total` +- `last_collision_timestamp` +- `auto_import_runs_total` + +### 8. **"All Collisions" Case Not Optimized** (P2) +**Problem:** If every issue collides (e.g., pulling unchanged state), we still process everything. + +**Fix:** If `len(filteredIssues) == 0` and `len(collisionResult.NewIssues) == 0`, it's a no-op - just update hash and return. + +## Low Priority Issues (P3) + +### 9. **No Configurable Collision Mode** (P3) +Some users may prefer auto-import to **fail** on collisions rather than auto-resolve. + +**Suggestion:** Add `BD_AUTO_IMPORT_MODE=remap|fail` environment variable. + +### 10. **No Collision Threshold** (P3) +If 90% of issues collide, something is probably wrong (bad merge). + +**Suggestion:** Add `BD_AUTO_IMPORT_COLLISION_THRESHOLD` - if exceeded, fail with clear error. + +## Testing Gaps + +Missing test coverage for: +1. ✅ Metadata read failure → should treat as first import +2. ✅ Hash update failure → should warn but not crash +3. ✅ All issues collide → should be no-op +4. ✅ Scanner buffer overflow (>2MB line) → should error gracefully +5. ✅ Concurrent auto-imports (race condition testing) +6. ✅ Transaction rollback on mid-import failure +7. ✅ 1000+ issue performance test + +## Answers to Review Questions + +### Q1: Should auto-import be more aggressive (auto-resolve) or conservative (fail)? + +**Recommendation:** Keep auto-resolve as default but add: +- Collision threshold that switches to fail mode if exceeded +- Config option for users who prefer fail-fast behavior +- Clear messaging about what was remapped + +### Q2: Should we add a counter for collision occurrences? + +**Yes.** Add metadata: +- `collision_count_total` (cumulative) +- `last_collision_count` (last run) +- `last_collision_timestamp` + +### Q3: Should there be a config option to disable collision detection? + +**No.** Collision detection is a safety feature. Instead provide: +- `BD_AUTO_IMPORT_MODE=remap|fail` to control behavior +- `--no-auto-import` flag already exists to disable entirely + +### Q4: Is the warning too verbose for typical workflows? + +**Yes.** The 10-line summary on every auto-import is noisy. Gate behind `BD_DEBUG`. + +## Recommended Fixes Priority + +**P0 (Critical - Fix ASAP):** +- [ ] bd-TBD: Fix metadata error handling (treat as first import) +- [ ] bd-TBD: Ensure hash update happens and is error-checked +- [ ] bd-TBD: Fix N+1 query pattern with batch fetch + +**P1 (High - Fix Before 1.0):** +- [ ] bd-TBD: Wrap import in transaction for atomicity +- [ ] bd-TBD: Add test coverage for edge cases +- [ ] bd-TBD: Optimize "all collisions" case + +**P2 (Medium - Nice to Have):** +- [ ] bd-TBD: Reduce output verbosity (gate behind BD_DEBUG) +- [ ] bd-TBD: Use bytes.NewReader instead of string conversion +- [ ] bd-TBD: Add collision metrics/telemetry + +**P3 (Low - Future Enhancement):** +- [ ] bd-TBD: Add BD_AUTO_IMPORT_MODE config +- [ ] bd-TBD: Add collision threshold safety rail + +## Conclusion + +The implementation **works for the happy path** but has **robustness issues** around error handling, performance, and edge cases. The auto-resolve approach is good, but needs better error handling and performance optimization. + +**Estimated effort to fix P0-P1 issues:** 2-3 days +**Risk level if not fixed:** Medium-High (data loss possible on edge cases, poor performance at scale) + +--- + +**Review completed:** 2025-10-16 +**Reviewer:** Oracle (via Amp) +**Issue:** bd-379 diff --git a/analyze_duplicates.sh b/analyze_duplicates.sh new file mode 100755 index 00000000..8c8d94a4 --- /dev/null +++ b/analyze_duplicates.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# Analyze duplicate issues + +echo "# Duplicate Issues Report" +echo "" +echo "Generated: $(date)" +echo "" + +./bd list --json | jq -r 'group_by(.title) | .[] | select(length > 1) | { + title: .[0].title, + count: length, + issues: [.[] | {id, status, created_at}] +} | "## \(.title)\nCount: \(.count)\n" + (.issues | map("- \(.id) (\(.status)) created \(.created_at)") | join("\n")) + "\n"' diff --git a/close_duplicates.sh b/close_duplicates.sh new file mode 100755 index 00000000..d4463fb3 --- /dev/null +++ b/close_duplicates.sh @@ -0,0 +1,149 @@ +#!/bin/bash +# Close duplicate issues - generated from oracle recommendations + +set -e + +echo "Closing duplicate issues..." +echo "" + +# Group 1: Add compacted_at_commit field — KEEP bd-432 +./bd close bd-639 --reason "Duplicate of bd-432" +./bd close bd-605 --reason "Duplicate of bd-432" +./bd close bd-555 --reason "Duplicate of bd-432" +./bd close bd-546 --reason "Duplicate of bd-432" +./bd close bd-532 --reason "Duplicate of bd-432" +./bd close bd-496 --reason "Duplicate of bd-432" + +# Group 2: Add label management commands — KEEP bd-364 +./bd close bd-571 --reason "Duplicate of bd-364" +./bd close bd-464 --reason "Duplicate of bd-364" + +# Group 3: Add migration scripts for GitHub Issues — KEEP bd-370 +./bd close bd-635 --reason "Duplicate of bd-370" +./bd close bd-529 --reason "Duplicate of bd-370" +./bd close bd-443 --reason "Duplicate of bd-370" +./bd close bd-416 --reason "Duplicate of bd-370" + +# Group 4: Add performance benchmarks document — KEEP bd-376 +./bd close bd-634 --reason "Duplicate of bd-376" +./bd close bd-528 --reason "Duplicate of bd-376" +./bd close bd-437 --reason "Duplicate of bd-376" +./bd close bd-410 --reason "Duplicate of bd-376" + +# Group 5: Audit and document all inconsistent issues — KEEP bd-366 +./bd close bd-597 --reason "Duplicate of bd-366" +./bd close bd-489 --reason "Duplicate of bd-366" +./bd close bd-424 --reason "Duplicate of bd-366" +./bd close bd-397 --reason "Duplicate of bd-366" + +# Group 6: Auto-import fails in git workflows — KEEP bd-334 +./bd close bd-631 --reason "Duplicate of bd-334" +./bd close bd-448 --reason "Duplicate of bd-334" + +# Group 7: Code review follow-up PR #8 — KEEP bd-389 +./bd close bd-633 --reason "Duplicate of bd-389" +./bd close bd-527 --reason "Duplicate of bd-389" +./bd close bd-426 --reason "Duplicate of bd-389" +./bd close bd-399 --reason "Duplicate of bd-389" + +# Group 8: Code review auto-import collision detection — KEEP bd-400 +./bd close bd-598 --reason "Duplicate of bd-400" +./bd close bd-490 --reason "Duplicate of bd-400" +./bd close bd-427 --reason "Duplicate of bd-400" + +# Group 9: Consider batching API — KEEP bd-371 +./bd close bd-651 --reason "Duplicate of bd-371" +./bd close bd-600 --reason "Duplicate of bd-371" +./bd close bd-536 --reason "Duplicate of bd-371" +./bd close bd-492 --reason "Duplicate of bd-371" +./bd close bd-429 --reason "Duplicate of bd-371" +./bd close bd-402 --reason "Duplicate of bd-371" + +# Group 10: Data model status/closed_at inconsistent — KEEP bd-391 +./bd close bd-594 --reason "Duplicate of bd-391" +./bd close bd-487 --reason "Duplicate of bd-391" +./bd close bd-430 --reason "Duplicate of bd-391" +./bd close bd-417 --reason "Duplicate of bd-391" + +# Group 11: Document git-based restoration — KEEP bd-380 +./bd close bd-638 --reason "Duplicate of bd-380" +./bd close bd-525 --reason "Duplicate of bd-380" +./bd close bd-436 --reason "Duplicate of bd-380" +./bd close bd-409 --reason "Duplicate of bd-380" + +# Group 12: Epic: Add intelligent database compaction — KEEP bd-251 +./bd close bd-392 --reason "Duplicate of bd-251" + +# Group 13: Epic: Fix status/closed_at inconsistency — KEEP bd-367 +./bd close bd-596 --reason "Duplicate of bd-367" +./bd close bd-488 --reason "Duplicate of bd-367" +./bd close bd-423 --reason "Duplicate of bd-367" +./bd close bd-396 --reason "Duplicate of bd-367" + +# Group 14: GH-11 Docker support — KEEP bd-358 +./bd close bd-629 --reason "Duplicate of bd-358" +./bd close bd-523 --reason "Duplicate of bd-358" + +# Group 15: GH-3 Debug zsh killed error — KEEP bd-87 +./bd close bd-618 --reason "Duplicate of bd-87" +./bd close bd-524 --reason "Duplicate of bd-87" +./bd close bd-510 --reason "Duplicate of bd-87" +./bd close bd-431 --reason "Duplicate of bd-87" +./bd close bd-406 --reason "Duplicate of bd-87" +./bd close bd-348 --reason "Duplicate of bd-87" + +# Group 16: Git-based restoration for compacted issues — KEEP bd-404 +./bd close bd-649 --reason "Duplicate of bd-404" +./bd close bd-604 --reason "Duplicate of bd-404" +./bd close bd-550 --reason "Duplicate of bd-404" +./bd close bd-495 --reason "Duplicate of bd-404" +./bd close bd-422 --reason "Duplicate of bd-404" + +# Group 17: Implement bd restore command — KEEP bd-434 +./bd close bd-637 --reason "Duplicate of bd-434" +./bd close bd-622 --reason "Duplicate of bd-434" +./bd close bd-607 --reason "Duplicate of bd-434" +./bd close bd-549 --reason "Duplicate of bd-434" +./bd close bd-531 --reason "Duplicate of bd-434" +./bd close bd-498 --reason "Duplicate of bd-434" + +# Group 18: Improve error handling in dependency removal — KEEP bd-359 +./bd close bd-650 --reason "Duplicate of bd-359" +./bd close bd-602 --reason "Duplicate of bd-359" +./bd close bd-515 --reason "Duplicate of bd-359" +./bd close bd-493 --reason "Duplicate of bd-359" + +# Group 19: Low priority chore — KEEP bd-377 +./bd close bd-659 --reason "Duplicate of bd-377" +./bd close bd-643 --reason "Duplicate of bd-377" +./bd close bd-547 --reason "Duplicate of bd-377" +./bd close bd-534 --reason "Duplicate of bd-377" + +# Group 20: P2: Consider batching API — MERGE TO bd-371 +./bd close bd-593 --reason "Duplicate of bd-371" +./bd close bd-486 --reason "Duplicate of bd-371" +./bd close bd-390 --reason "Duplicate of bd-371" + +# Group 21: Reach 1.0 release milestone — KEEP bd-388 +./bd close bd-632 --reason "Duplicate of bd-388" +./bd close bd-526 --reason "Duplicate of bd-388" +./bd close bd-425 --reason "Duplicate of bd-388" +./bd close bd-398 --reason "Duplicate of bd-388" + +# Group 22: Record git commit hash during compaction — KEEP bd-433 +./bd close bd-642 --reason "Duplicate of bd-433" +./bd close bd-641 --reason "Duplicate of bd-433" +./bd close bd-606 --reason "Duplicate of bd-433" +./bd close bd-551 --reason "Duplicate of bd-433" +./bd close bd-533 --reason "Duplicate of bd-433" +./bd close bd-497 --reason "Duplicate of bd-433" + +# Group 23: Use safer placeholder pattern — KEEP bd-29 +./bd close bd-603 --reason "Duplicate of bd-29" +./bd close bd-494 --reason "Duplicate of bd-29" +./bd close bd-445 --reason "Duplicate of bd-29" +./bd close bd-403 --reason "Duplicate of bd-29" + +echo "" +echo "Done! Closed duplicates, kept the oldest open issue in each group." +./bd stats diff --git a/cmd/bd/main.go b/cmd/bd/main.go index bb078300..8d6d73dc 100644 --- a/cmd/bd/main.go +++ b/cmd/bd/main.go @@ -342,12 +342,22 @@ func autoImportIfNewer() { allIssues = filteredIssues } + // Batch fetch all existing issues to avoid N+1 query pattern (bd-666) + allExistingIssues, err := store.SearchIssues(ctx, "", types.IssueFilter{}) + if err != nil { + fmt.Fprintf(os.Stderr, "Auto-import failed: error fetching existing issues: %v\n", err) + return + } + + // Build map for O(1) lookup + existingByID := make(map[string]*types.Issue) + for _, issue := range allExistingIssues { + existingByID[issue.ID] = issue + } + // Import non-colliding issues (exact matches + new issues) for _, issue := range allIssues { - existing, err := store.GetIssue(ctx, issue.ID) - if err != nil { - continue - } + existing := existingByID[issue.ID] if existing != nil { // Update existing issue