From 473650f3edf0fdf8fe012dd00821b05fad1d6070 Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Tue, 21 Oct 2025 21:59:38 -0700 Subject: [PATCH] Update issues.jsonl - close bd-49 --- .beads/issues.jsonl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index ca441dda..da7739ca 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -6,8 +6,8 @@ {"id":"bd-1054","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:47:03.829881-07:00","updated_at":"2025-10-21T21:50:35.197826-07:00"} {"id":"bd-1055","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:47:03.954118-07:00","updated_at":"2025-10-21T21:50:35.198023-07:00"} {"id":"bd-1056","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:47:04.077037-07:00","updated_at":"2025-10-21T21:50:35.198221-07:00"} -{"id":"bd-1057","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:47:36.452611-07:00","updated_at":"2025-10-21T21:50:35.198444-07:00"} -{"id":"bd-1062","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:48:05.749608-07:00","updated_at":"2025-10-21T21:50:35.200118-07:00"} +{"id":"bd-1057","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:47:36.452611-07:00","updated_at":"2025-10-21T21:50:35.198444-07:00","comments":[{"id":2,"issue_id":"bd-1057","author":"tester","text":"first comment","created_at":"2025-10-22T04:47:36Z"}]} +{"id":"bd-1062","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:48:05.749608-07:00","updated_at":"2025-10-21T21:50:35.200118-07:00","comments":[{"id":3,"issue_id":"bd-1062","author":"tester","text":"first comment","created_at":"2025-10-22T04:48:05Z"}]} {"id":"bd-11","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-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:50:35.208756-07:00","closed_at":"2025-10-18T09:41:18.209717-07:00"} {"id":"bd-12","title":"Implement text reference scanning and replacement","description":"Scan all issues for text references to merged IDs (bd-X patterns) and update to target ID. Reuse logic from import collision resolution.","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:50:35.232687-07:00"} {"id":"bd-13","title":"Add CLI merge command and flags","description":"Implement bd merge command with: multiple sources, --into target, --dry-run, --json flags. Add interactive confirmation.","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:50:35.255412-07:00"} @@ -23,7 +23,7 @@ {"id":"bd-2066","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:48:10.705237-07:00","updated_at":"2025-10-21T21:50:35.438246-07:00"} {"id":"bd-2067","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:48:10.820999-07:00","updated_at":"2025-10-21T21:50:35.438444-07:00"} {"id":"bd-2068","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:48:10.935996-07:00","updated_at":"2025-10-21T21:50:35.43864-07:00"} -{"id":"bd-2069","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:48:51.51376-07:00","updated_at":"2025-10-21T21:50:35.438893-07:00"} +{"id":"bd-2069","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:48:51.51376-07:00","updated_at":"2025-10-21T21:50:35.438893-07:00","comments":[{"id":4,"issue_id":"bd-2069","author":"tester","text":"first comment","created_at":"2025-10-22T04:48:51Z"}]} {"id":"bd-21","title":"Make merge command idempotent for safe retry after partial failures","description":"The merge command currently performs 3 operations without an outer transaction:\n1. Migrate dependencies from source → target\n2. Update text references across all issues\n3. Close source issues\n\nIf merge fails mid-operation (network issue, daemon crash, etc.), a retry will fail or produce incorrect results because some operations already succeeded.\n\n**Goal:** Make merge idempotent so retrying after partial failure is safe and completes the remaining work.\n\n**Idempotency checks needed:**\n- Skip dependency migration if target already has the dependency\n- Skip text reference updates if already updated\n- Skip closing source issues if already closed\n- Report which operations were skipped vs performed\n\n**Example output:**\n```\n✓ Merged 2 issue(s) into bd-128\n - Dependencies: 3 migrated, 2 already existed\n - Text references: 5 updated, 0 already correct\n - Source issues: 1 closed, 1 already closed\n```\n\n**Related:** bd-18 originally requested transaction support, but idempotency is a better solution for this use case since individual operations are already atomic.","design":"Current merge code already has some idempotency:\n- Dependency migration checks `alreadyExists` before adding (line ~145-151 in merge.go)\n- Text reference updates are naturally idempotent (replacing bd-X with bd-Y twice has same result)\n\nMissing idempotency:\n- CloseIssue fails if source already closed\n- Error messages don't distinguish \"already done\" from \"real failure\"\n\nImplementation:\n1. Check source issue status before closing - skip if already closed\n2. Track which operations succeeded/skipped\n3. Return detailed results for user visibility\n4. Consider adding --dry-run output showing what would be done vs skipped","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:50:35.445956-07:00"} {"id":"bd-22","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-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:50:35.469171-07:00","closed_at":"2025-10-14T02:51:52.19905-07:00"} {"id":"bd-23","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":"closed","priority":4,"issue_type":"feature","created_at":"2025-10-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:50:35.492416-07:00","closed_at":"2025-10-19T08:59:59.596748-07:00"} @@ -40,7 +40,7 @@ {"id":"bd-3073","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:48:56.827052-07:00","updated_at":"2025-10-21T21:50:35.672885-07:00"} {"id":"bd-3074","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:48:56.941307-07:00","updated_at":"2025-10-21T21:50:35.673084-07:00"} {"id":"bd-3075","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:48:57.05586-07:00","updated_at":"2025-10-21T21:50:35.673282-07:00"} -{"id":"bd-3076","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:48:57.530536-07:00","updated_at":"2025-10-21T21:50:35.673478-07:00"} +{"id":"bd-3076","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:48:57.530536-07:00","updated_at":"2025-10-21T21:50:35.673478-07:00","comments":[{"id":5,"issue_id":"bd-3076","author":"tester","text":"first comment","created_at":"2025-10-22T04:48:57Z"}]} {"id":"bd-31","title":"Document label best practices and use cases","description":"Create documentation covering:\n- When to use labels vs structured fields\n- Common label sets (coding agents, open source, product dev, SRE)\n- Naming conventions (kebab-case, specificity, present tense)\n- Anti-patterns (too many labels, overlapping, personal labels)\n- Label lifecycle management\n\nContent from LABELS.md analysis document.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:50:35.679586-07:00","closed_at":"2025-10-19T23:11:46.125417-07:00"} {"id":"bd-32","title":"Add rule-based compaction (e.g., compact children of closed epics)","description":"Support semantic compaction rules beyond just time-based, such as:\n- Compact all children of closed epics\n- Compact by priority level (e.g., all P3/P4 closed issues)\n- Compact by label (e.g., all issues labeled 'archive')\n- Compact by type (e.g., all closed chores)\n\nThis would allow smarter database size management based on semantic meaning rather than just age.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-10-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:50:35.702605-07:00"} {"id":"bd-33","title":"Add compact --dry-run that shows size savings estimates","description":"When running 'bd compact --dry-run', show estimated database size reduction in KB/MB and percentage, similar to what 'du -h' would show.\n\nExample output:\n Tier 1 candidates: 15 issues\n Current size: 2.4 MB\n After compaction: ~1.7 MB (70% reduction, 0.7 MB saved)\n \nThis helps users understand impact before compacting.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-10-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:50:35.726207-07:00"} @@ -58,7 +58,7 @@ {"id":"bd-4080","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:04.208243-07:00","updated_at":"2025-10-21T21:50:35.910066-07:00"} {"id":"bd-4081","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:04.32731-07:00","updated_at":"2025-10-21T21:50:35.910276-07:00"} {"id":"bd-4082","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:04.448745-07:00","updated_at":"2025-10-21T21:50:35.910488-07:00"} -{"id":"bd-4083","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:04.940641-07:00","updated_at":"2025-10-21T21:50:35.910692-07:00"} +{"id":"bd-4083","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:04.940641-07:00","updated_at":"2025-10-21T21:50:35.910692-07:00","comments":[{"id":6,"issue_id":"bd-4083","author":"tester","text":"first comment","created_at":"2025-10-22T04:49:04Z"}]} {"id":"bd-41","title":"Add validation/warning for malformed issue IDs","description":"getNextID silently ignores non-numeric ID suffixes (e.g., bd-foo). CAST returns NULL for invalid strings. Consider detecting and warning about malformed IDs in database. Location: internal/storage/sqlite/sqlite.go:79-82","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:50:35.914657-07:00","closed_at":"2025-10-14T02:51:52.198988-07:00"} {"id":"bd-42","title":"Add cross-repo issue references (future enhancement)","description":"Support referencing issues across different beads repositories. Useful for tracking dependencies between separate projects.\n\nProposed syntax:\n- Local reference: bd-128 (current behavior)\n- Cross-repo by path: ~/src/other-project#bd-456\n- Cross-repo by workspace name: @project2:bd-789\n\nUse cases:\n1. Frontend project depends on backend API issue\n2. Shared library changes blocking multiple projects\n3. System administrator tracking work across machines\n4. Monorepo with separate beads databases per component\n\nImplementation challenges:\n- Storage layer needs to query external databases\n- Dependency resolution across repos\n- What if external repo not available?\n- How to handle in JSONL export/import?\n- Security: should repos be able to read others?\n\nDesign questions to resolve first:\n1. Read-only references vs full cross-repo dependencies?\n2. How to handle repo renames/moves?\n3. Absolute paths vs workspace names vs git remotes?\n4. Should bd-183 auto-discover related repos?\n\nRecommendation: \n- Gather user feedback first\n- Start with read-only references\n- Implement as plugin/extension?\n\nContext: This is mentioned in bd-183 as approach #2. Much more complex than daemon multi-repo approach. Only implement if there's strong user demand.\n\nPriority: Backlog (4) - wait for user feedback before designing","status":"closed","priority":4,"issue_type":"feature","created_at":"2025-10-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:50:35.938651-07:00","closed_at":"2025-10-20T22:00:31.966891-07:00"} {"id":"bd-43","title":"Test auto-export timing","description":"","status":"closed","priority":4,"issue_type":"task","created_at":"2025-10-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:50:35.961872-07:00","closed_at":"2025-10-20T22:00:31.964329-07:00"} @@ -69,14 +69,14 @@ {"id":"bd-48","title":"Stress tests pollute production database with test issues","description":"TestStressNoUniqueConstraintViolations and other stress tests in internal/rpc/stress_test.go create issues in production database instead of test database. Confirmed: 1,000 test issues (Agent X Issue Y) created at 20:46:01 during test run. Root cause: test goroutines connect to production daemon at .beads/bd.sock instead of isolated test daemon in temp directory.","status":"open","priority":0,"issue_type":"bug","created_at":"2025-10-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:50:36.080238-07:00"} {"id":"bd-49","title":"Daemon storage cache doesn't detect external database modifications","description":"When bd commands bypass the daemon and directly modify the database (e.g., `bd import` with direct file access, or deleting/recreating bd.db), the daemon's cached storage connection becomes stale and serves outdated data.\n\n**Reproduction**:\n1. Start daemon: `bd daemon`\n2. Run bd stats → shows N issues\n3. Delete database: `rm .beads/bd.db` \n4. Reinit and import: `bd init \u0026\u0026 bd import -i .beads/issues.jsonl`\n5. Run bd stats → shows 0 issues (wrong!)\n6. Direct query: `sqlite3 .beads/bd.db 'SELECT COUNT(*) FROM issues'` → shows correct count\n7. Restart daemon: `bd daemon --stop` then retry stats → now shows correct count\n\n**Root cause**: \n- server.go:1410-1414 retrieves cached storage without checking if DB file changed\n- Cache only evicts based on TTL (30min) or LRU, never on external modifications\n- Direct file operations bypass daemon, leaving cache stale\n\n**Impact**:\n- Users see incorrect/stale data after external DB operations\n- Confusing behavior with no clear indication cache is stale\n- Requires daemon restart to fix\n\n**Proposed fixes**:\n1. Check mtime on cache hit, invalidate if file changed\n2. Add cache eviction API (bd cache --clear)\n3. Use file locking to prevent external modifications while daemon running\n4. SQLite WAL mode change notifications","design":"**Better approach: Check DB file mtime on cache lookup**\n\nToo many commands bypass the daemon (import, init, renumber, compact, delete, dep tree, export, stale). Notifying from each would be error-prone and easy to forget when adding new commands.\n\n**Implementation:**\n\n1. Add `dbMtime time.Time` field to `StorageCacheEntry`\n2. In `getStorageForRequest()` on cache hit:\n - Stat the DB file to get current mtime\n - If mtime changed since cached, evict entry and reopen\n - Otherwise return cached connection\n3. Store mtime when initially caching\n\n**Code location:**\n- `internal/rpc/server.go:1410-1414` (cache hit path)\n- `internal/rpc/server.go:49-52` (StorageCacheEntry struct)\n\n**Benefits:**\n- Simple, centralized check\n- Works for all commands that bypass daemon\n- Works for external tools modifying DB\n- No need to update every command\n- Minimal performance overhead (one stat() call on cache hit)\n\n**Trade-offs:**\n- Small overhead on every cache hit (negligible - stat is fast)\n- mtime granularity may miss rapid changes (unlikely in practice)","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-21T21:14:42.82974-07:00","updated_at":"2025-10-21T21:51:22.331957-07:00","closed_at":"2025-10-21T21:51:22.331957-07:00"} {"id":"bd-5","title":"Write tests for merge functionality","description":"Unit tests: validation, merge logic, data integrity. Integration tests: end-to-end workflow, export/import. Edge case tests: chains, circular refs, epics.","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:50:36.127646-07:00"} -{"id":"bd-50","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:46:58.899686-07:00","updated_at":"2025-10-21T21:50:36.127858-07:00"} +{"id":"bd-50","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:46:58.899686-07:00","updated_at":"2025-10-21T21:50:36.127858-07:00","comments":[{"id":1,"issue_id":"bd-50","author":"tester","text":"first comment","created_at":"2025-10-22T04:46:58Z"}]} {"id":"bd-5084","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:10.286147-07:00","updated_at":"2025-10-21T21:50:36.148776-07:00"} {"id":"bd-5085","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:10.40747-07:00","updated_at":"2025-10-21T21:50:36.149019-07:00"} {"id":"bd-5086","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:10.883536-07:00","updated_at":"2025-10-21T21:50:36.149257-07:00"} {"id":"bd-5087","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:11.00153-07:00","updated_at":"2025-10-21T21:50:36.149474-07:00"} {"id":"bd-5088","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:11.11929-07:00","updated_at":"2025-10-21T21:50:36.149687-07:00"} {"id":"bd-5089","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:11.238811-07:00","updated_at":"2025-10-21T21:50:36.149913-07:00"} -{"id":"bd-5090","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:11.733216-07:00","updated_at":"2025-10-21T21:50:36.150337-07:00"} +{"id":"bd-5090","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:11.733216-07:00","updated_at":"2025-10-21T21:50:36.150337-07:00","comments":[{"id":7,"issue_id":"bd-5090","author":"tester","text":"first comment","created_at":"2025-10-22T04:49:11Z"}]} {"id":"bd-6","title":"Document merge command and AI integration","description":"Update README, AGENTS.md with merge command examples. Document AI agent duplicate detection workflow.","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:11:07.548812-07:00"} {"id":"bd-6091","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:17.4932-07:00","updated_at":"2025-10-21T21:49:17.4932-07:00"} {"id":"bd-6092","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:17.612343-07:00","updated_at":"2025-10-21T21:49:17.612343-07:00"} @@ -84,6 +84,6 @@ {"id":"bd-6094","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:18.209478-07:00","updated_at":"2025-10-21T21:49:18.209478-07:00"} {"id":"bd-6095","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:18.329719-07:00","updated_at":"2025-10-21T21:49:18.329719-07:00"} {"id":"bd-6096","title":"Version test issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:18.463865-07:00","updated_at":"2025-10-21T21:49:18.463865-07:00"} -{"id":"bd-6097","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:18.972423-07:00","updated_at":"2025-10-21T21:49:18.972423-07:00"} +{"id":"bd-6097","title":"Comment test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-21T21:49:18.972423-07:00","updated_at":"2025-10-21T21:49:18.972423-07:00","comments":[{"id":8,"issue_id":"bd-6097","author":"tester","text":"first comment","created_at":"2025-10-22T04:49:18Z"}]} {"id":"bd-7","title":"Add merged_into field to database schema","description":"Add merged_into field to Issue struct and update database schema to support merge tracking","notes":"Simplified: no schema field needed. Close merged issues with reason 'Merged into bd-X'. See bd-79 design.","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:11:07.548812-07:00"} {"id":"bd-8","title":"Update export/import for merge fields","description":"Include merged_into in JSONL export format. Handle merge relationships on import.","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-21T21:11:07.548812-07:00","updated_at":"2025-10-21T21:11:07.548812-07:00"}