Commit Graph

14 Commits

Author SHA1 Message Date
Steve Yegge
bb33007036 Fix revive style issues (bd-56)
- Fix 14 unused-parameter warnings (rename to _)
- Fix 2 redefines-builtin-id (max→maxCount, min→minInt)
- Fix 3 indent-error-flow issues with gofmt
- Merged duplicate bd-126 into bd-116
2025-10-25 18:13:49 -07:00
Steve Yegge
e3ff12448f Fix: RemapCollisions deletes existing issue dependencies (GH #120, bd-56)
Bug: updateDependencyReferences() was incorrectly updating ALL dependencies
in the database during collision resolution with --resolve-collisions,
including dependencies belonging to existing issues.

Root cause: The function checked if dep.IssueID was in idMapping keys
(old imported IDs like 'bd-1'), but those are also the IDs of existing
database issues. This caused existing dependencies to be incorrectly
modified or deleted.

Fix: Changed logic to only update dependencies where IssueID is in
idMapping VALUES (new remapped IDs like 'bd-295'). This ensures only
dependencies from remapped issues are updated, not existing ones.

During normal import flow, this is effectively a no-op since imported
dependencies haven't been added to the database yet when RemapCollisions
runs (they're added later in Phase 5 of import_shared.go).

Changes:
- Updated updateDependencyReferences() in collision.go to build a set
  of new remapped IDs and only update dependencies with those IDs
- Added comprehensive documentation explaining the correct semantics
- Added regression tests: TestRemapCollisionsRemapsImportedNotExisting
  and TestRemapCollisionsDoesNotUpdateNonexistentDependencies
- Skipped 3 tests that expected the old buggy behavior with clear
  notes about why they need to be rewritten

Real-world impact: In one case, 125 dependencies were incorrectly
deleted from 157 existing issues during collision resolution.

Fixes https://github.com/steveyegge/beads/issues/120
Fixes bd-56
2025-10-23 10:25:13 -07:00
Steve Yegge
e97c122feb Cleanup and fixes: godoc comments, removed dead code, fixed renumber FK constraint bug
- Added comprehensive godoc comments for auto-flush functions (bd-4)
- Removed unused issueMap in scoreCollisions (bd-6)
- Fixed renumber command FK constraint failure (bd-143)
  - Changed UpdateIssueID to use explicit connection with FK disabled
  - Resolves 'constraint failed: FOREIGN KEY constraint failed' error
- Deleted 22 test/placeholder issues
- Renumbered issues from bd-1 to bd-143 (eliminated gaps)

Amp-Thread-ID: https://ampcode.com/threads/T-65f78f08-4856-4af0-9d6c-af33e88b5f63
Co-authored-by: Amp <amp@ampcode.com>
2025-10-19 19:37:58 -07:00
Steve Yegge
6811d1cf42 Fix multiple issues and renumber database
- bd-170: Implement hybrid sorting for ready work (recent 48h first, then oldest)
- bd-87: Use safer null-byte placeholders in ID remapping
- bd-92: Make auto-flush debounce configurable via BEADS_FLUSH_DEBOUNCE
- bd-171: Fix nil pointer dereference in renumber command
- Delete spurious test issues (bd-7, bd-130-134)
- Renumber database from 171 down to 144 issues
2025-10-18 09:58:35 -07:00
Steve Yegge
fc29beae6d Fix bd-421: Add deduplication to prevent importing duplicate issues
- Added deduplicateIncomingIssues() to consolidate content-identical issues
- DetectCollisions now deduplicates within incoming batch before processing
- Keeps issue with smallest ID when duplicates found
- Added comprehensive test suite in collision_dedup_test.go
- Export clean JSONL with bd-421 fix applied

Amp-Thread-ID: https://ampcode.com/threads/T-c17dd8bf-c298-4a80-baa5-55fa7c7bb9a3
Co-authored-by: Amp <amp@ampcode.com>
2025-10-16 18:08:58 -07:00
Steve Yegge
c3e3326bba Fix critical bugs: bd-169, bd-28, bd-393
- bd-169: Add -q/--quiet flag to bd init command
- bd-28: Improve error handling in RemoveDependency
  - Now checks RowsAffected and returns error if dependency doesn't exist
  - New removeDependencyIfExists() helper for collision remapping
- bd-393: CRITICAL - Fix auto-import skipping collisions
  - Auto-import was LOSING work from other workers
  - Now automatically remaps collisions to new IDs
  - Calls RemapCollisions() instead of skipping

All tests pass.

Amp-Thread-ID: https://ampcode.com/threads/T-cba86837-28db-47ce-94eb-67fade82376a
Co-authored-by: Amp <amp@ampcode.com>
2025-10-16 15:00:54 -07:00
Steve Yegge
4fe648d140 Fix bd-437: Use addDependencyUnchecked during collision resolution
When remapping dependencies during collision resolution, skip semantic
validation (like parent-child direction checks) since we're just updating
IDs on existing dependencies that were already validated.

Fixes parent-child validation error during import --resolve-collisions.
2025-10-16 13:42:47 -07:00
Steve Yegge
331a435418 Fix collision resolver: sync ID counters before remapping
The collision resolver was failing when remapping issues to new IDs because
the issue_counters table was out of sync with actual database IDs. Test issues
(bd-200 through bd-312) were created without updating the counter, causing
UNIQUE constraint violations when --resolve-collisions tried to use those IDs.

Added SyncAllCounters() call before remapping to ensure counters reflect all
existing issues in the database. This prevents ID collisions during import.

Fixes the core functionality needed for multi-device git-based sync (bd-271).

Amp-Thread-ID: https://ampcode.com/threads/T-a2a94e1b-b220-41b0-bf7d-f2640a44292b
Co-authored-by: Amp <amp@ampcode.com>
2025-10-16 11:59:34 -07:00
Steve Yegge
f0266339c5 Complete bd-227: Audit status/closed_at inconsistencies
Findings:
- 86/93 closed issues (92%) are missing closed_at timestamps
- All inconsistencies are historical (old issues bd-1 through bd-93)
- No cases of non-closed issues with timestamps

Recommendation: Set closed_at = updated_at for affected issues
Next: Apply cleanup SQL and add constraint
2025-10-15 13:08:48 -07:00
v4rgas
20e3235435 fix: replace in-memory ID counter with atomic database counter
Replace the in-memory nextID counter with an atomic database-backed
counter using the issue_counters table. This fixes race conditions
when multiple processes create issues concurrently.

Changes:
- Add issue_counters table with atomic INSERT...ON CONFLICT pattern
- Remove in-memory nextID field and sync.Mutex from SQLiteStorage
- Implement getNextIDForPrefix() for atomic ID generation
- Update CreateIssue() to use database counter instead of memory
- Update RemapCollisions() to use database counter for collision resolution
- Clean up old planning and bug documentation files

Fixes the multi-process ID generation race condition tested in
cmd/bd/race_test.go.
2025-10-14 01:18:50 -07:00
Steve Yegge
25644d9717 Cache compiled regexes in ID replacement for 1.9x performance boost
Implements bd-27: Cache compiled regexes in replaceIDReferences for performance

Problem:
replaceIDReferences() was compiling regex patterns on every call. With 100
issues and 10 ID mappings, that resulted in 4,000 regex compilations (100
issues × 4 text fields × 10 ID mappings).

Solution:
- Added buildReplacementCache() to pre-compile all regexes once
- Added replaceIDReferencesWithCache() to reuse compiled regexes
- Updated updateReferences() to build cache once and reuse for all issues
- Kept replaceIDReferences() for backward compatibility (calls cached version)

Performance Results (from benchmarks):
Single text:
- 1.33x faster (26,162 ns → 19,641 ns)
- 68% less memory (25,769 B → 8,241 B)
- 80% fewer allocations (278 → 55)

Real-world (400 texts, 10 mappings):
- 1.89x faster (5.1ms → 2.7ms)
- 90% less memory (7.7 MB → 0.8 MB)
- 86% fewer allocations (104,112 → 14,801)

Tests:
- All existing tests pass
- Added 3 benchmark tests demonstrating improvements

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-13 23:50:48 -07:00
Steve Yegge
183ded4096 Add collision resolution with automatic ID remapping
Implements --resolve-collisions flag for import command to safely handle ID
collisions during branch merges. When enabled, colliding issues are remapped
to new IDs and all text references and dependencies are automatically updated.

Also adds comprehensive tests, branch-merge example, and documentation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-12 17:13:09 -07:00
Steve Yegge
42e3bb315d Implement reference scoring algorithm (bd-13)
Add reference scoring to prioritize which colliding issues should be
renumbered during collision resolution. Issues with fewer references
are renumbered first to minimize total update work.

Changes to collision.go:
- Add ReferenceScore field to CollisionDetail
- scoreCollisions() calculates scores and sorts collisions ascending
- countReferences() counts text mentions + dependency references
- Uses word-boundary regex (\b) to match exact IDs (bd-10 not bd-100)

New tests in collision_test.go:
- TestCountReferences: validates reference counting logic
- TestScoreCollisions: verifies scoring and sorting behavior
- TestCountReferencesWordBoundary: ensures exact ID matching

Reference score = text mentions (desc/design/notes/criteria) + deps
Sort order: fewest references first (minimizes renumbering impact)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-12 16:27:05 -07:00
Steve Yegge
b065b32a51 Implement collision detection for import (bd-12)
Add collision detection infrastructure to identify conflicts during
JSONL import when branches diverge and create issues with the same ID.

New files:
- internal/storage/sqlite/collision.go: Core collision detection logic
  - detectCollisions() categorizes issues as exact matches, collisions, or new
  - compareIssues() identifies which fields differ between issues
  - CollisionDetail provides detailed collision reporting

- internal/storage/sqlite/collision_test.go: Comprehensive test suite
  - Tests exact matches, new issues, and various collision scenarios
  - Tests multi-field conflicts and edge cases
  - All tests passing

This lays the foundation for bd-13 through bd-17 (reference scoring,
ID remapping, CLI flags, and documentation).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-12 16:22:44 -07:00