Closes three tickets related to GitHub #334 and #278:
- bd-dvd: Parent resurrection fix (GetNextChildID now resurrects parents)
- bd-ymj: Export metadata fix (prevents false JSONL changed errors)
- bd-ar2: Code review epic with 12 subtasks (all completed)
All fixes implemented in commit 4c5f99c and follow-up improvements.
Updated GH #334 with fix details and marked as triaged.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated all test files to pass context.Background() as the first parameter
to sqlite.New() calls to match the updated function signature.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Multiple test files were still using the old sqlite.New(path) signature
instead of the new sqlite.New(ctx, path) signature. This was causing
compilation failures in the test suite.
Fixed files:
- internal/importer/importer_test.go
- internal/importer/external_ref_test.go
- internal/importer/timestamp_test.go
- internal/rpc/limits_test.go
- internal/rpc/list_filters_test.go
- internal/rpc/rpc_test.go
- internal/rpc/status_test.go
- internal/syncbranch/syncbranch_test.go
Identified and tagged obviously-slow integration tests with
`//go:build integration` to exclude them from default test runs.
This is step 1 of fixing test performance. The real fix is in
bd-1rh: refactoring tests to use shared DB setup instead of
creating 279 separate databases.
Tagged files:
- cmd/bd: 8 files (CLI tests, git ops, performance benchmarks)
- internal: 8 files (integration tests, E2E tests)
Issues:
- bd-1rh: Main issue tracking test performance
- bd-c49: Audit all tests and create grouping plan (next step)
- bd-y6d: POC refactor of create_test.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit addresses critical code review findings from bd-dvd and bd-ymj fixes:
## Completed Tasks
### bd-ar2.1: Extract duplicated metadata update code
- Created `updateExportMetadata()` helper function
- Eliminated 22-line duplication between createExportFunc and createSyncFunc
- Single source of truth for metadata updates
### bd-ar2.2: Add multi-repo support to export metadata updates
- Added per-repo metadata key tracking with keySuffix parameter
- Both export and sync functions now update metadata for all repos
### bd-ar2.3: Fix tests to use actual daemon functions
- TestExportUpdatesMetadata now calls updateExportMetadata() directly
- Added TestUpdateExportMetadataMultiRepo() for multi-repo testing
- Fixed export_mtime_test.go tests to call updateExportMetadata()
### bd-ar2.9: Fix variable shadowing in GetNextChildID
- Changed `err` to `resurrectErr` to avoid shadowing
- Improves code clarity and passes linter checks
### bd-ar2.10: Fix hasJSONLChanged to support per-repo keys
- Updated hasJSONLChanged() to accept keySuffix parameter
- Reads metadata with correct per-repo keys
- All callers updated (validatePreExport, daemon import, sync command)
### bd-ar2.11: Use stable repo identifiers instead of paths
- Added getRepoKeyForPath() helper function
- Uses stable identifiers like ".", "../frontend" instead of absolute paths
- Metadata keys now portable across machines and clones
- Prevents orphaned metadata when repos are moved
## Files Changed
- cmd/bd/daemon_sync.go: Helper functions, metadata updates
- cmd/bd/integrity.go: hasJSONLChanged() with keySuffix support
- cmd/bd/sync.go: Updated to use getRepoKeyForPath()
- cmd/bd/*_test.go: Tests updated for new signatures
- internal/storage/sqlite/hash_ids.go: Fixed variable shadowing
## Testing
All export, sync, and integrity tests pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Bug 1 (bd-dvd): GetNextChildID now attempts parent resurrection from JSONL
before failing. Added TryResurrectParent call to match CreateIssue behavior.
Bug 2 (bd-ymj): Export now updates last_import_hash metadata to prevent
'JSONL content has changed' errors on subsequent exports.
Files changed:
- internal/storage/sqlite/hash_ids.go: Add resurrection attempt
- cmd/bd/daemon_sync.go: Add metadata updates after export
- Tests added for both fixes
- Fixed pre-existing bug in integrity_content_test.go
Follow-up work tracked in epic bd-ar2 (9 issues for improvements).
Fixes GH #334
Adds a new `bd search` command optimized for quick text searches,
addressing the issue where Claude using MCP bd list consumes 30k tokens.
Features:
- Searches across title, description, and ID with OR logic
- Default limit of 50 results (vs unlimited for bd list)
- Supports key filters: --status, --assignee, --type, --label
- Works in both daemon and direct modes
- Provides --json and --long output formats
Examples:
bd search "performance" --status open
bd search "database" --label backend --limit 10
bd search "bd-5q" # Search by partial ID
This provides a more efficient alternative to bd list when users
just want to find issues quickly without loading all results.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The function was declared twice:
- Line 80: New version (simpler, no error wrapping)
- Line 390: Old version (with error wrapping)
This caused compilation failure in CI. Removed the old declaration at line 390.
Also fixed integrity_content_test.go to pass context.Context to sqlite.New()
as required by the updated API.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes#340
Created AGENT_INSTRUCTIONS.md to house detailed operational instructions,
reducing AGENTS.md from 963 to 626 lines (~35% reduction).
Changes:
- New AGENT_INSTRUCTIONS.md with development, testing, and release procedures
- AGENTS.md now serves as quick overview with references to detailed docs
- Updated README.md link to "Landing the Plane" section
- Fixed broken team-workflow README links
Benefits:
- Prevents context pollution when multiple tools add instructions
- Better separation: quick reference vs detailed operations
- Enables tool-specific instruction files
- Maintains all content, just reorganized
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Cleaned up scripts/ directory by removing:
- Investigation/one-off tools (collision-calculator, latency benchmarks)
- Test cleanup utilities (cleanup-test-pollution)
- Nix packaging support (update-nix-hash)
- Agent Mail server management scripts (4 scripts, will be replaced)
Retains only actively-used scripts:
- release.sh, bump-version.sh, update-homebrew.sh
- install.sh, install-hooks.sh, hooks/
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The critical bug where git operations could resurrect deleted issues
has been resolved with content-based staleness detection.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace mtime-based staleness detection with content-based (SHA256 hash) to prevent
git operations from resurrecting deleted issues.
**Problem:**
Auto-import used file modification time to detect if JSONL was "newer" than database.
Git operations (checkout, merge, pull) restore old files with recent mtimes, causing
auto-import to load stale data over current database state, resurrecting deleted issues.
**Solution:**
- Added computeJSONLHash() to compute SHA256 of JSONL content
- Added hasJSONLChanged() with two-tier check:
1. Fast-path: Check mtime first (99% of checks are instant)
2. Slow-path: Compute hash only if mtime changed (catches git operations)
- Store metadata: last_import_hash, last_import_mtime, last_import_time
- Updated auto-import in daemon_sync.go to use content-based check
- Updated validatePreExport to use content-based check (bd-xwo)
- Graceful degradation: metadata failures are non-fatal warnings
**Changes:**
- cmd/bd/integrity.go: Add computeJSONLHash(), hasJSONLChanged()
- cmd/bd/integrity_test.go: Add comprehensive tests for new functions
- cmd/bd/import.go: Update metadata after import
- cmd/bd/sync.go: Use hasJSONLChanged() instead of isJSONLNewer()
- cmd/bd/daemon_sync.go: Use hasJSONLChanged() in auto-import
**Testing:**
- Unit tests pass (TestHasJSONLChanged with 7 scenarios)
- Integration test passes (test_bd_khnb_fix.sh)
- Verified git resurrection scenario prevented
Fixes: bd-khnb
Related: bd-3bg, bd-xwo, bd-39o, bd-56p, bd-m8t, bd-rfj, bd-t5o
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Complete implementation of signal-aware context propagation for graceful
cancellation across all commands and storage operations.
Key changes:
1. Signal-aware contexts (bd-rtp):
- Added rootCtx/rootCancel in main.go using signal.NotifyContext()
- Set up in PersistentPreRun, cancelled in PersistentPostRun
- Daemon uses same pattern in runDaemonLoop()
- Handles SIGINT/SIGTERM for graceful shutdown
2. Context propagation (bd-yb8):
- All commands now use rootCtx instead of context.Background()
- sqlite.New() receives context for cancellable operations
- Database operations respect context cancellation
- Storage layer propagates context through all queries
3. Cancellation tests (bd-2o2):
- Added import_cancellation_test.go with comprehensive tests
- Added export cancellation test in export_test.go
- Tests verify database integrity after cancellation
- All cancellation tests passing
Fixes applied during review:
- Fixed rootCtx lifecycle (removed premature defer from PersistentPreRun)
- Fixed test context contamination (reset rootCtx in test cleanup)
- Fixed export tests missing context setup
Impact:
- Pressing Ctrl+C during import/export now cancels gracefully
- No database corruption or hanging transactions
- Clean shutdown of all operations
Tested:
- go build ./cmd/bd ✓
- go test ./cmd/bd -run TestImportCancellation ✓
- go test ./cmd/bd -run TestExportCommand ✓
- Manual Ctrl+C testing verified
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Critical fixes to context propagation implementation (bd-rtp, bd-yb8, bd-2o2):
1. Fix rootCtx lifecycle in main.go:
- Removed premature defer rootCancel() from PersistentPreRun (line 132)
- Added proper cleanup in PersistentPostRun (lines 544-547)
- Context now properly spans from setup through command execution to cleanup
2. Fix test context contamination in cli_fast_test.go:
- Reset rootCtx and rootCancel to nil in test cleanup (lines 139-140)
- Prevents cancelled contexts from affecting subsequent tests
3. Fix export tests missing context in export_test.go:
- Added rootCtx initialization in 5 export test subtests
- Tests now properly set up context before calling exportCmd.Run()
These fixes ensure:
- Signal-aware contexts work correctly for graceful cancellation
- Ctrl+C properly cancels import/export operations
- Database integrity is maintained after cancellation
- All cancellation tests pass (TestImportCancellation, TestExportCommand)
Tested:
- go build ./cmd/bd ✓
- go test ./cmd/bd -run TestImportCancellation ✓
- go test ./cmd/bd -run TestExportCommand ✓
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes#312
Users were confused about which files should be committed after running
'bd init --branch beads-metadata'. The PROTECTED_BRANCHES.md doc now
clearly explains:
1. Files to commit to protected branch (main):
- .beads/.gitignore - Tells git what to ignore
- .gitattributes - Merge driver configuration
2. Files automatically gitignored (do NOT commit):
- .beads/beads.db - SQLite database (local only)
- .beads/daemon.* - Runtime files
- .beads/*.left/right.jsonl - Temporary merge artifacts
3. Files in sync branch (beads-metadata):
- .beads/beads.jsonl - Issue data (committed by daemon)
- .beads/metadata.json - Repository metadata
- .beads/config.yaml - Configuration template
Added step-by-step instructions in Quick Start section and a "What lives
in each branch" section to How It Works.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add .pytest_cache/ to ignored test artifacts
- Reorganize sections for clarity
- Move .coverage to testing artifacts section
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes#299
Added comprehensive documentation to help new users understand what files
should be committed vs ignored after running bd init:
1. README.md:
- New "Files Created by bd init" section
- Clear lists of files to commit vs ignore
- Explains purpose of .gitattributes for team collaboration
2. docs/GIT_INTEGRATION.md:
- Enhanced .gitattributes section with IMPORTANT notice
- Explains why it must be committed (merge driver config)
- Lists benefits of intelligent JSONL merging
Key clarification: .gitattributes should be COMMITTED (not ignored) as it
configures git merge behavior for the entire team.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Critical fixes to code review findings:
1. Remove global state access from flushToJSONLWithState
- FlushManager now has true single ownership of flush state
- No more race conditions from concurrent global state access
- flushToJSONLWithState trusts only the flushState parameter
- Legacy wrapper handles success detection via failure count
2. Fix shutdown timeout data loss risk
- Increased timeout from 5s → 30s to prevent data loss
- Added detailed comments explaining the timeout rationale
- Better error message indicates potential data loss scenario
Implementation details:
- New FlushManager uses event-driven single-owner pattern
- Channels eliminate shared mutable state (markDirtyCh, flushNowCh, etc.)
- Comprehensive race detector tests verify concurrency safety
- Backward compatible with existing tests via legacy code path
- ARCHITECTURE.md documents design principles and guarantees
Test results:
- All race detector tests pass (TestFlushManager*)
- Legacy API compatibility verified (TestMarkDirtyAndScheduleFlush*)
- No race conditions detected under concurrent load
Future improvements tracked as beads:
- bd-gdn: Add functional tests for flush correctness verification
- bd-5xt: Log errors from timer-triggered flushes
- bd-i00: Convert magic numbers to named constants
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This change fixes the issue where 'bd sync' would fail with a false-positive
"JSONL is newer than database" error after the daemon auto-exports.
Root Cause:
- Daemon exports local changes to JSONL, updating its timestamp
- bd sync sees JSONL.mtime > DB.mtime and incorrectly assumes external changes
- This blocks export even though content is identical
Solution:
- Modified isJSONLNewer() to use SHA256 content hash comparison
- Only triggers auto-import when JSONL is newer AND content differs
- Prevents false positives from daemon auto-export timestamp updates
- Maintains conservative fallback if hashes can't be computed
Changes:
- Added computeJSONLHash() and computeDBHash() helper functions
- Created isJSONLNewerWithStore() to support testing with explicit store
- Added comprehensive tests for content-based comparison logic
- All existing tests pass, including export_mtime tests
Fixes: bd-lm2q
Added Known Issues section to beads-mcp README documenting:
- FastMCP schema generation bug blocking MCP tools in Claude Code
- Workaround using slash commands (/beads:ready, /beads:show, etc.)
- Links to issue #346 and upstream FastMCP issue #2455
- Resolution path once upstream fix is released
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- bd-1h8: Add --no-daemon hint to compact error messages
- bd-8ql: Replace non-existent merge command with actionable guidance
- bd-ayw: Add 'When to use daemon mode' decision tree to daemon.md
- bd-keb: Add database maintenance section to QUICKSTART.md
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added prominent warning at the top of the Agent Mail section in AGENTS.md
to prevent AI agents from attempting to use mcp-agent-mail tools when the
server is not set up.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed all closed beads that were resurrected by the auto-import bug
documented in bd-khnb. Database now at 46 beads (all open/active).
The resurrection happened when:
- Earlier git operation restored old JSONL with 538 issues
- bd migrate --update-repo-id triggered daemon startup
- Auto-import saw "newer" JSONL (recent mtime from git)
- Imported old data over cleaned database
- 490 previously deleted issues resurrected
This cleanup removes those resurrected closed issues.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Filed bug report for critical data loss issue where bd migrate --update-repo-id
(and other operations) can trigger auto-import that resurrects deleted issues.
Root cause: Auto-import uses mtime-based staleness detection, which fails when
git operations restore old JSONL files with recent mtimes.
Impact: User deletions can be silently undone after git checkout/merge/pull.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Resolved conflict in AGENTS.md by keeping our version which emphasizes
that git push is CRITICAL for landing the plane.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>