After 2 weeks of collision/stale-data fixes, reviewed all changes to identify
spurious code that is no longer needed after content-hash resolution was implemented.
**Removed:**
1. countReferences() function from collision.go (lines 274-328)
- Was used for reference-count based collision scoring
- Completely unused after switching to content-hash based resolution (commit 2e87329)
- Still exists in duplicates.go for deduplication (different use case)
2. ReferenceScore field from CollisionDetail struct
- Marked as DEPRECATED but never removed
- No longer used by ScoreCollisions() which now uses content hashing
3. TestCountReferences and TestCountReferencesWordBoundary tests
- Tested the now-deleted countReferences() function
- No longer relevant
**Fixed:**
- Updated CheckpointWAL comments to remove misleading "staleness detection" claim
- Staleness detection uses metadata (last_import_time), NOT file mtime
- CheckpointWAL is still valuable for data persistence and WAL size reduction
- Comments now accurately reflect actual benefits
**Verified:**
- All tests pass (internal/storage/sqlite)
- Content-hash collision resolution still works correctly
- No behavioral changes, just cleanup
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Detect fsnotify.NewWatcher() errors and auto-fallback to polling mode
- Add BEADS_WATCHER_FALLBACK env var to control behavior (default: enabled)
- Poll every 5 seconds with comprehensive change detection:
- Track file existence, size, and mtime to catch all changes
- Handle file disappearance/reappearance correctly
- Trigger on file recreation even with older timestamps
- Fix goroutine leak: Close() now stops background goroutines via cancel context
- Tighten git refs filtering to only trigger for events under .git/refs/heads
- Trigger after successful JSONL rewatch on rename/remove events
- Improve logging to show actual poll interval in warnings
All tests passing.
Amp-Thread-ID: https://ampcode.com/threads/T-8f5edc23-4b78-4b80-b8f3-66050f45eb61
Co-authored-by: Amp <amp@ampcode.com>
- Add RenameDetail type to track content matches with different IDs
- Remove deletion logic from DetectCollisions (now read-only)
- Create ApplyCollisionResolution to handle all modifications
- Update importer.go to use two-phase approach (detect then apply)
- Fix dependency preservation in RemapCollisions
- Collect all dependencies before CASCADE DELETE
- Recreate with updated IDs after remapping
- Add tests: TestDetectCollisionsReadOnly, TestApplyCollisionResolution
- Update collision tests for content-hash scoring behavior
- Create bd-100 to track fixing autoimport tests
The test was comparing full JSON output including timestamps, causing
false negative failures. The 2-clone collision resolution actually works
correctly - both clones converge to identical semantic content.
Changes:
- Added compareIssuesIgnoringTimestamps helper to compare issue content
- Compares ID, title, description, status, priority, type (not timestamps)
- Added filterTrackedChanges to ignore untracked files in git status
- Test now passes, proving collision resolution works for 2-clone case
Closes bd-91
Amp-Thread-ID: https://ampcode.com/threads/T-a58284d2-f39f-482a-9db0-bec31c19e9e5
Co-authored-by: Amp <amp@ampcode.com>
- Replace timestamp-based collision scoring with deterministic content hashing
- Add hashIssueContent() using SHA-256 of all substantive fields
- Modify ScoreCollisions to compare hashes and set RemapIncoming flag
- Update RemapCollisions to handle both directions (remap incoming OR existing)
- Add CollisionDetail.RemapIncoming field to control which version gets remapped
- Add unit tests for hash function and deterministic collision resolution
Status: Hash-based resolution works correctly, but TestTwoCloneCollision still
fails due to missing rename detection. After Clone B resolves collision,
Clone A needs to recognize its issue was remapped to a different ID.
Next: Add content-based rename detection during import to prevent
re-resolving already-resolved collisions.
Progress on bd-86.
Amp-Thread-ID: https://ampcode.com/threads/T-b19b49e8-b52a-463d-b052-8a526a500260
Co-authored-by: Amp <amp@ampcode.com>
- Move RELEASING.md and LINTING.md to docs/ (maintainer-only content)
- Delete WORKFLOW.md (agent workflow content belongs in AGENTS.md)
- Delete TEXT_FORMATS.md (technical details belong in ADVANCED.md)
- Update all cross-references to point to new locations
- Keep CLAUDE.md (required by Claude Code)
Reduces root-level docs from 20 to 16 files with clearer organization.
Amp-Thread-ID: https://ampcode.com/threads/T-fe1db4f3-16c6-4a79-8887-c7f4c1f11c43
Co-authored-by: Amp <amp@ampcode.com>
- Removed renameImportedIssuePrefixes and supporting functions
- Removed unused imports (fmt, sort, strings, utils)
- Saved ~130 LOC of dead code
- All tests pass
- Replace fixed 2s sleeps with smart polling (50-100ms intervals)
- Reduce daemon wait timeout from 5s to 1s with early exit
- Add timeout to daemon cleanup to prevent hanging
- Test now runs in ~18s instead of timing out at 60s
Amp-Thread-ID: https://ampcode.com/threads/T-51945255-d5fd-4b42-9816-c44ff4d3bdd1
Co-authored-by: Amp <amp@ampcode.com>
- Creates TestTwoCloneCollision integration test
- Sets up 2 independent clones with git hooks and daemons
- Both file issues with same ID (test-1)
- Demonstrates databases don't converge after collision resolution
- Clone A: test-1='Issue from clone A', test-2='Issue from clone B'
- Clone B: test-1='Issue from clone B', test-2='Issue from clone A'
- Git status shows dirty state in both clones
- Test proves beads fails at basic multi-agent workflow
Also adds --json flag to create, ready, and list commands for
better test integration.
Amp-Thread-ID: https://ampcode.com/threads/T-8fa0ab6c-2226-4f9b-8e11-14e1156537fc
Co-authored-by: Amp <amp@ampcode.com>