Previously `make install` used `go install` which put the binary in ~/go/bin
without codesigning, while PATH used ~/.local/bin - causing chronic stale
binary issues. Now install depends on build (which codesigns on macOS) and
copies to the correct location.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: mayor
Role: mayor
Analysis found these commands are dead code:
- gt never calls `bd pin` - uses `bd update --status=pinned` instead
- Beads.Pin() wrapper exists but is never called
- bd hook functionality duplicated by gt mol status
- Code comment says "pinned field is cosmetic for bd hook visibility"
Removed:
- cmd/bd/pin.go
- cmd/bd/unpin.go
- cmd/bd/hook.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update Makefile install target to extract and pass git commit/branch via ldflags
- Add -X main.Commit and -X main.Branch to all build configurations in .goreleaser.yml
- Create scripts/install.sh helper for explicit version control during installation
- Add comprehensive tests for commit/branch resolution and output formatting
Fixes github #503: 'bd version' now reports as-built commit hash and branch
information regardless of installation method (make install, go install, or
released binaries from goreleaser).
Overview: Added comprehensive test infrastructure to handle the large
test suite (41K LOC, 313 tests in cmd/bd alone) with automatic skipping
of known broken tests.
Changes:
- .test-skip: List of broken tests to skip (with GH issue references)
- scripts/test.sh: Smart test runner that auto-skips broken tests
- docs/TESTING.md: Comprehensive testing guide
- .claude/test-strategy.md: Quick reference for AI agents
- Updated Makefile to use new test script
Known Issues Filed:
- GH #355: TestFallbackToDirectModeEnablesFlush (database deadlock)
- GH #356: TestFindJSONLPathDefault (wrong JSONL filename)
Performance: 3min total (180s compilation, 3.8s execution)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: add performance testing framework foundation
Implements foundation for comprehensive performance testing and user
diagnostics for beads databases at 10K-20K scale.
Components added:
- Fixture generator (internal/testutil/fixtures/) for realistic test data
* LargeSQLite/XLargeSQLite: 10K/20K issues with epic hierarchies
* LargeFromJSONL/XLargeFromJSONL: test JSONL import path
* Realistic cross-linked dependencies, labels, assignees
* Reproducible with seeded RNG
- User diagnostics (bd doctor --perf) for field performance data
* Collects platform info (OS, arch, Go/SQLite versions)
* Measures key operation timings (ready, list, show, search)
* Generates CPU profiles for bug reports
* Clean separation in cmd/bd/doctor/perf.go
Test data characteristics:
- 10% epics, 30% features, 60% tasks
- 4-level hierarchies (Epic → Feature → Task → Subtask)
- 20% cross-epic blocking dependencies
- Realistic status/priority/label distributions
Supports bd-l954 (Performance Testing Framework epic)
Closes bd-6ed8, bd-q59i
* perf: optimize GetReadyWork with compound index (20x speedup)
Add compound index on dependencies(depends_on_id, type, issue_id) to
eliminate performance bottleneck in GetReadyWork recursive CTE query.
Performance improvements (10K issue database):
- GetReadyWork: 752ms → 36.6ms (20.5x faster)
- Target: <50ms ✓ ACHIEVED
- 20K database: ~1500ms → 79.4ms (19x faster)
Benchmark infrastructure enhancements:
- Add dataset caching in /tmp/beads-bench-cache/ to avoid regenerating
10K-20K issues on every benchmark run (first run: ~2min, subsequent: <5s)
- Add progress logging during fixture generation (shows 10%, 20%... completion)
- Add database size logging (17.5 MB for 10K, 35.1 MB for 20K)
- Document rationale for only benchmarking large datasets (>10K issues)
- Add CPU/trace profiling with --profile flag for performance debugging
Schema changes:
- internal/storage/sqlite/schema.go: Add idx_dependencies_depends_on_type_issue
New files:
- internal/storage/sqlite/bench_helpers_test.go: Reusable benchmark setup with caching
- internal/storage/sqlite/sqlite_bench_test.go: Comprehensive benchmarks for critical operations
- Makefile: Convenient benchmark execution (make bench-quick, make bench)
Related:
- Resolves bd-5qim (optimize GetReadyWork performance)
- Builds on bd-6ed8 (fixture generator), bd-q59i (bd doctor --perf)
* perf: add WASM compilation cache to eliminate cold-start overhead
Configure wazero compilation cache for ncruces/go-sqlite3 to avoid
~220ms JIT compilation on every process start.
Cache configuration:
- Location: ~/.cache/beads/wasm/ (platform-specific via os.UserCacheDir)
- Automatic version management: wazero keys entries by its version
- Fallback: in-memory cache if directory creation fails
- No cleanup needed: old versions are harmless (~5-10MB each)
Performance impact:
- First run: ~220ms (populate cache)
- Subsequent runs: ~20ms (load from cache)
- Savings: ~200ms per cold start
Cache invalidation:
- Automatic when wazero version changes (upgrades use new cache dir)
- Manual cleanup: rm -rf ~/.cache/beads/wasm/ (safe to delete anytime)
This complements daemon mode:
- Daemon mode: eliminates startup cost by keeping process alive
- WASM cache: reduces startup cost for one-off commands or daemon restarts
Changes:
- internal/storage/sqlite/sqlite.go: Add init() with cache setup
* refactor: improve maintainability of performance testing code
Extract common patterns and eliminate duplication across benchmarks, fixture generation, and performance diagnostics. Replace magic numbers with explicit configuration to improve readability and make it easier to tune test parameters.
* docs: clarify profiling behavior and add missing documentation
Add explanatory comments for profiling setup to clarify why --profile
forces direct mode (captures actual database operations instead of RPC
overhead) and document the stopCPUProfile function's role in flushing
profile data to disk. Also fix gosec G104 linter warning by explicitly
ignoring Close() error during cleanup.
* fix: prevent bench-quick from running indefinitely
Added //go:build bench tags and skipped timeout-prone benchmarks to
prevent make bench-quick from running for hours.
Changes:
- Add //go:build bench tag to cycle_bench_test.go and compact_bench_test.go
- Skip Dense graph benchmarks (documented to timeout >120s)
- Fix compact benchmark prefix: bd- → bd (validation expects prefix without trailing dash)
Before: make bench-quick ran for 3.5+ hours (12,699s) before manual interrupt
After: make bench-quick completes in ~25 seconds
The Dense graph benchmarks are known to timeout and represent rare edge
cases that don't need optimization for typical workflows.