feat: Add 'bd stale' command to show and release orphaned executor claims
- Implements bd stale command to show issues with execution_state where executor is dead/stopped - Adds --release flag to automatically release orphaned issues - Adds --threshold flag to customize heartbeat staleness threshold (default: 300s/5min) - Handles missing executor instances (LEFT JOIN) for cases where executor was deleted - Adds QueryContext and BeginTx helper methods to SQLiteStorage for advanced queries - Fixes ExternalRef comparison bug in import_shared.go (pointer vs string) - Removes unused imports in import.go Resolves vc-124
This commit is contained in:
@@ -1,96 +0,0 @@
|
||||
# BUG FOUND: getNextID() uses alphabetical MAX instead of numerical
|
||||
|
||||
## Location
|
||||
`internal/storage/sqlite/sqlite.go:60-84`, function `getNextID()`
|
||||
|
||||
## The Bug
|
||||
```go
|
||||
err := db.QueryRow("SELECT MAX(id) FROM issues").Scan(&maxID)
|
||||
```
|
||||
|
||||
This uses alphabetical MAX on the text `id` column, not numerical MAX.
|
||||
|
||||
## Impact
|
||||
When you have bd-1 through bd-10:
|
||||
- Alphabetical sort: bd-1, bd-10, bd-2, bd-3, ... bd-9
|
||||
- MAX(id) returns "bd-9" (alphabetically last)
|
||||
- nextID is calculated as 10
|
||||
- Creating a new issue tries to use bd-10, which already exists
|
||||
- Result: UNIQUE constraint failed
|
||||
|
||||
## Reproduction
|
||||
```bash
|
||||
# After creating bd-1 through bd-10
|
||||
./bd create "Test issue" -t task -p 1
|
||||
# Error: failed to insert issue: UNIQUE constraint failed: issues.id
|
||||
```
|
||||
|
||||
## The Fix
|
||||
|
||||
Option 1: Cast to integer in SQL (BEST)
|
||||
```sql
|
||||
SELECT MAX(CAST(SUBSTR(id, INSTR(id, '-') + 1) AS INTEGER)) FROM issues WHERE id LIKE 'bd-%'
|
||||
```
|
||||
|
||||
Option 2: Pad IDs with zeros
|
||||
- Change ID format from "bd-10" to "bd-0010"
|
||||
- Alphabetical and numerical order match
|
||||
- Breaks existing IDs
|
||||
|
||||
Option 3: Query all IDs and find max in Go
|
||||
- Less efficient but more flexible
|
||||
- Works with any ID format
|
||||
|
||||
## Recommended Solution
|
||||
|
||||
Option 1 with proper prefix handling:
|
||||
|
||||
```go
|
||||
func getNextID(db *sql.DB) int {
|
||||
// Get prefix from config (default "bd")
|
||||
var prefix string
|
||||
err := db.QueryRow("SELECT value FROM config WHERE key = 'issue_prefix'").Scan(&prefix)
|
||||
if err != nil || prefix == "" {
|
||||
prefix = "bd"
|
||||
}
|
||||
|
||||
// Find max numeric ID for this prefix
|
||||
var maxNum sql.NullInt64
|
||||
query := `
|
||||
SELECT MAX(CAST(SUBSTR(id, LENGTH(?) + 2) AS INTEGER))
|
||||
FROM issues
|
||||
WHERE id LIKE ? || '-%'
|
||||
`
|
||||
err = db.QueryRow(query, prefix, prefix).Scan(&maxNum)
|
||||
if err != nil || !maxNum.Valid {
|
||||
return 1
|
||||
}
|
||||
|
||||
return int(maxNum.Int64) + 1
|
||||
}
|
||||
```
|
||||
|
||||
## Workaround for Now
|
||||
|
||||
Manually specify IDs when creating issues:
|
||||
```bash
|
||||
# This won't work because auto-ID fails:
|
||||
./bd create "Title" -t task -p 1
|
||||
|
||||
# Workaround - manually calculate next ID:
|
||||
./bd list | grep -oE 'bd-[0-9]+' | sed 's/bd-//' | sort -n | tail -1
|
||||
# Then add 1 and create with explicit ID in code
|
||||
```
|
||||
|
||||
Or fix the bug first before continuing!
|
||||
|
||||
## Related to bd-9
|
||||
|
||||
This bug is EXACTLY the kind of distributed ID collision problem that bd-9 is designed to solve! But we should also fix the root cause.
|
||||
|
||||
## Created Issue
|
||||
|
||||
Should create: "Fix getNextID() to use numerical MAX instead of alphabetical"
|
||||
- Type: bug
|
||||
- Priority: 0 (critical - blocks all new issue creation)
|
||||
- Blocks: bd-9 (can't create child issues)
|
||||
@@ -1,86 +0,0 @@
|
||||
# Child Issues for BD-9: Collision Resolution
|
||||
|
||||
## Issues to Create
|
||||
|
||||
These issues break down bd-9 into implementable chunks. Link them all to bd-9 as parent-child dependencies.
|
||||
|
||||
### Issue 1: Extend export to include dependencies
|
||||
**Title**: Extend export to include dependencies in JSONL
|
||||
**Type**: task
|
||||
**Priority**: 1
|
||||
**Description**: Modify export.go to include dependencies array in each issue's JSONL output. This makes JSONL self-contained and enables proper collision resolution. Format: {"id":"bd-10","dependencies":[{"depends_on_id":"bd-5","type":"blocks"}]}
|
||||
**Command**: `bd create "Extend export to include dependencies in JSONL" -t task -p 1 -d "Modify export.go to include dependencies array in each issue's JSONL output. This makes JSONL self-contained and enables proper collision resolution. Format: {\"id\":\"bd-10\",\"dependencies\":[{\"depends_on_id\":\"bd-5\",\"type\":\"blocks\"}]}"`
|
||||
|
||||
### Issue 2: Implement collision detection
|
||||
**Title**: Implement collision detection in import
|
||||
**Type**: task
|
||||
**Priority**: 1
|
||||
**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.
|
||||
**Command**: `bd create "Implement collision detection in import" -t task -p 1 -d "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."`
|
||||
|
||||
### Issue 3: Implement reference scoring
|
||||
**Title**: Implement reference scoring algorithm
|
||||
**Type**: task
|
||||
**Priority**: 1
|
||||
**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.
|
||||
**Command**: `bd create "Implement reference scoring algorithm" -t task -p 1 -d "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."`
|
||||
|
||||
### Issue 4: Implement ID remapping
|
||||
**Title**: Implement ID remapping with reference updates
|
||||
**Type**: task
|
||||
**Priority**: 1
|
||||
**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.
|
||||
**Command**: `bd create "Implement ID remapping with reference updates" -t task -p 1 -d "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."`
|
||||
|
||||
### Issue 5: Add CLI flags
|
||||
**Title**: Add --resolve-collisions flag and user reporting
|
||||
**Type**: task
|
||||
**Priority**: 1
|
||||
**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).
|
||||
**Command**: `bd create "Add --resolve-collisions flag and user reporting" -t task -p 1 -d "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)."`
|
||||
|
||||
### Issue 6: Write tests
|
||||
**Title**: Write comprehensive collision resolution tests
|
||||
**Type**: task
|
||||
**Priority**: 1
|
||||
**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.
|
||||
**Command**: `bd create "Write comprehensive collision resolution tests" -t task -p 1 -d "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."`
|
||||
|
||||
### Issue 7: Update docs
|
||||
**Title**: Update documentation for collision resolution
|
||||
**Type**: task
|
||||
**Priority**: 1
|
||||
**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.
|
||||
**Command**: `bd create "Update documentation for collision resolution" -t task -p 1 -d "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."`
|
||||
|
||||
## Additional Feature Issue
|
||||
|
||||
### Issue: Add design field support to update command
|
||||
**Title**: Add design/notes/acceptance_criteria fields to update command
|
||||
**Type**: feature
|
||||
**Priority**: 2
|
||||
**Description**: Currently bd update only supports status, priority, title, assignee. Add support for --design, --notes, --acceptance-criteria flags. This makes it easier to add detailed designs to issues after creation.
|
||||
**Command**: `bd create "Add design/notes/acceptance_criteria fields to update command" -t feature -p 2 -d "Currently bd update only supports status, priority, title, assignee. Add support for --design, --notes, --acceptance-criteria flags. This makes it easier to add detailed designs to issues after creation."`
|
||||
|
||||
## Dependency Linking
|
||||
|
||||
After creating all child issues, link them to bd-9:
|
||||
```bash
|
||||
# Assuming the issues are bd-10 through bd-16 (or whatever IDs were assigned)
|
||||
bd dep add <child-id> bd-9 --type parent-child
|
||||
```
|
||||
|
||||
Example:
|
||||
```bash
|
||||
bd dep add bd-10 bd-9 --type parent-child
|
||||
bd dep add bd-11 bd-9 --type parent-child
|
||||
bd dep add bd-12 bd-9 --type parent-child
|
||||
# etc.
|
||||
```
|
||||
|
||||
## Current State
|
||||
|
||||
- bd-10 was created successfully ("Extend export to include dependencies")
|
||||
- bd-11+ attempts failed with UNIQUE constraint errors
|
||||
- This suggests those IDs already exist in the DB but may not be in the JSONL file
|
||||
- Need to investigate DB/JSONL sync issue before creating more issues
|
||||
Reference in New Issue
Block a user