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>
The previous instructions mentioned sync carefully but didn't emphasize that
git push is absolutely required for the plane to actually land. Multiple agents
have failed to push, leaving work uncommitted on the runway.
Changes:
- Added explicit 'git push' step with CRITICAL emphasis
- Added verification step to check 'up to date with origin/main'
- Updated example workflow to show push as mandatory step
- Added clear statement: 'The plane has NOT landed until git push completes'
The metaphor is obvious - if you don't push, the plane is still on the ground!
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Changed 'bd clean' to 'bd cleanup' (correct command name)
- Added cleanup step to remove backup files and temporary artifacts
- Ensures clean repository state at end of agent sessions
Extracted repeated priority and ID validation patterns from CLI commands
into reusable functions in internal/validation/bead.go.
Changes:
- Added ValidatePriority(): Combines parsing and error handling
- Added ValidateIDFormat(): Validates ID format and extracts prefix
- Added ValidatePrefix(): Validates prefix matching with database config
- Updated create.go and show.go to use new validation functions
- Simplified force flag logic to always call ValidatePrefix()
- Added comprehensive tests for all validation functions
- Added TODO comment for daemon mode validation enhancement
Results:
- Reduced code duplication by ~20 lines
- Centralized validation logic for easier maintenance
- Consistent error messages across all commands
- All tests passing
Fixes bd-g5p7
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previously, bd sync would fail with "Pre-export validation failed:
refusing to export: JSONL is newer than database" when JSONL was
modified (e.g., after git pull).
Now bd sync intelligently handles this by:
- Detecting when JSONL is newer than the database
- Automatically importing before exporting
- Continuing with the normal sync flow
This makes the workflow much smoother - users can just run 'bd sync'
and it figures out what needs to be done.
Changes:
- Added isJSONLNewer() helper to check file timestamps
- Modified sync command to auto-import when JSONL is newer
- Extracted timestamp check logic for reusability
Resolves: bd-ca0b
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Ran bd cleanup --force to remove all closed issues, keeping only 48 open issues.
This significantly reduces the database size and makes it easier to work with.
Deleted:
- 490 closed issues
- 221 dependency links
- 54 labels
- 755 events
Orphaned issues (will need parent repair):
- bd-tne, bd-tru, bd-ktng, bd-c362, bd-98c4e1fa.1, bd-7e7ddffa.1, bd-o78
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problem:
In direct mode, bd list was making a separate GetLabels() call for
each issue when displaying labels. With 538 issues, this resulted in
538 separate database queries.
While investigating the reported 5+ second slowness, discovered this
N+1 query issue that would impact performance with many issues.
Solution:
1. Added GetLabelsForIssues(issueIDs []string) to Storage interface
2. Implemented bulk fetch in SQLite (already existed, now exposed)
3. Implemented bulk fetch in MemoryStorage
4. Updated list.go to fetch all labels in single query
Changes:
- internal/storage/storage.go: Add GetLabelsForIssues to interface
- internal/storage/memory/memory.go: Implement GetLabelsForIssues
- cmd/bd/list.go: Use bulk fetching in all output modes
Impact:
Eliminates N queries for labels, replacing with 1 bulk query.
This optimization applies to direct mode only (daemon mode already
uses bulk operations via RPC).
Note: The reported 5s slowness was actually caused by daemon auto-start
timeout. Use --no-daemon flag or run 'bd migrate --update-repo-id' to
resolve the legacy database issue causing daemon startup failures.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed all closed beads (490 total, 497 including cascade deletions):
- Completed feature implementations
- Fixed bugs and resolved issues
- Test issues from development
- Deprecated/removed features
- Refactoring tasks
Database reduced from 538 to 48 beads (46 open, 2 other states)
All deleted beads preserved in git history for reference.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>