Commit Graph

105 Commits

Author SHA1 Message Date
Steve Yegge
a737223b3c fix: doctor checks follow redirect for Gas Town support (bd-tvus)
Extended bd-tvus fix to all doctor check functions that access .beads/
directory. In Gas Town multi-clone setups, crew/polecat clones use
.beads/redirect files to point to the shared mayor/rig beads directory.

Doctor checks now use resolveBeadsDir() to follow these redirects:
- daemon.go: CheckDaemonStatus
- git.go: CheckSyncBranchConfig, FindOrphanedIssues, CheckOrphanedIssues
- installation.go: CheckMultipleDatabases, CheckPermissions
- integrity.go: CheckIDFormat, CheckDependencyCycles, CheckTombstones,
  CheckDeletionsManifest, CheckRepoFingerprint
- jsonl_integrity.go: CheckJSONLIntegrity
- legacy.go: CheckFreshClone
- maintenance.go: CheckStaleClosedIssues, CheckExpiredTombstones,
  CheckCompactionCandidates
- perf.go: RunPerformanceDiagnostics, CollectPlatformInfo
- validation.go: CheckMergeArtifacts, CheckOrphanedDependencies,
  CheckDuplicateIssues, CheckTestPollution, CheckChildParentDependencies,
  CheckGitConflicts
- version.go: CheckMetadataVersionTracking

Intentionally NOT changed (check local files):
- CheckInstallation: checks local .beads/ exists
- CheckUntrackedBeadsFiles: checks git tracking of local files

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 20:41:57 -08:00
Steve Yegge
f9bbe8e8e0 fix(doctor): follow redirect when checking database (bd-tvus)
The bug was that doctor's database checks used the local .beads/beads.db
file directly, while import followed the redirect to the actual database.
This caused confusing output showing 0 issues when the actual database
had hundreds. Fixed by using resolveBeadsDir() in all database checks.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 20:20:06 -08:00
matt wilkie
d3fe6b0f32 fix: lint errors and update Nix vendorHash
- Add nolint:unparam for readOnly param in sqlite_open.go
- Handle cmd.Help() error in wisp.go
- Handle rows.Close() error in migration 028
- Handle targetStore.Close() error in create.go
- Update Nix vendorHash for current dependencies

Cherry-picked from PR #769
2025-12-27 17:29:36 -08:00
matt wilkie
99f5e50a32 feat: Add 'bd orphans' command with DRY refactoring of orphan detection
Implements the 'bd orphans' command to identify issues referenced in commits
but still open in the database, and refactors to eliminate code duplication.

- Creates cmd/bd/orphans.go with Cobra command structure
- Identifies orphaned issues (referenced in git commits but still open/in_progress)
- Supports multiple output formats (human, JSON, detailed)
- Auto-close with --fix flag

DRY refactoring:
- Extracted FindOrphanedIssues() to cmd/bd/doctor/git.go as shared core logic
- Moved OrphanIssue type to cmd/bd/doctor/types.go
- Refactored CheckOrphanedIssues() to use FindOrphanedIssues()

Cherry-picked from PR #767

Co-authored-by: Amp <amp@ampcode.com>
2025-12-27 17:23:45 -08:00
Steve Yegge
2c82acd10b feat: integrate detect-pollution into bd doctor --check=pollution (bd-kff0)
- Add --check flag to doctor for specific check modes
- Add --check=pollution to run detailed pollution detection
- Add --clean flag to delete detected test issues
- Mark detect-pollution command as hidden (deprecated)
- Update fix messages to point to new doctor --check=pollution

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 16:20:12 -08:00
Steve Yegge
1611f16751 refactor: remove unused bd pin/unpin/hook commands (bd-x0zl)
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>
2025-12-27 16:02:15 -08:00
Steve Yegge
c8b912cbe6 bd sync: 2025-12-27 15:56:42 2025-12-27 15:56:42 -08:00
Steve Yegge
05304e3ab1 Merge origin/main, fix test git init for modern git 2025-12-27 00:17:36 -08:00
Ryan Snodgrass
350a78f1ba fix: resolve all golangci-lint errors
Fixes 15 pre-existing lint issues:

errcheck (6 issues):
- mol_distill.go: Add _ = for f.Close() and os.Remove()
- routed.go: Add _ = for routedStorage.Close() (4 locations)

gosec (8 issues):
- maintenance.go, routes.go: Add nolint for G304 (file paths from known dirs)
- mol_distill.go: Add nolint for G304 (file creation in known search paths)
- formula.go: Change WriteFile permissions from 0644 to 0600 (G306)
- gate.go: Add nolint for G204 (exec.Command with trusted AwaitID fields)

misspell (1 issue):
- gate.go: Fix "cancelled" -> "canceled" in comment

unparam (2 issues):
- cook.go, controlflow.go: Add nolint for functions returning always-nil error

Also:
- Update pre-commit-hooks to v6.0.0
- Add lint step to "Landing the Plane" session-end protocol
2025-12-26 19:20:03 -05:00
Ryan Snodgrass
9c9f2f2ad8 fix(tests): use --initial-branch=main for modern git compatibility
Modern git (2.28+) uses 'main' as default branch, not 'master'.
Tests were failing because they assumed 'master' branch exists.

Changes:
- Use 'git init --initial-branch=main' instead of bare 'git init'
- Change 'git checkout master' to 'git checkout main'
- Add git.ResetCaches() after os.Chdir() to clear cached git state
- Ensures test isolation when changing directories
2025-12-26 19:09:41 -05:00
Ryan Snodgrass
252de1cdba feat(daemon): add sync backoff and consolidate hints into tips
Daemon sync improvements:
- Adds exponential backoff on sync failures (30s → 1m → 2m → 5m → 10m → 30m cap)
- Tracks sync state in .beads/sync-state.json (NeedsManualSync, FailureCount, BackoffUntil)
- Resets backoff on daemon start and manual bd sync
- Adds sync-state.json to default .gitignore

Tips consolidation (following ox-cli pattern):
- Moves sync conflict hint from hints.go into tips.go
- Proactive health checks trump educational tips
- Uses InjectTip() with high priority (200) and 100% probability for urgent warnings
- Removes deprecated hints.go
2025-12-26 19:09:31 -05:00
Ryan Snodgrass
721ae70ccb feat(doctor): add database corruption recovery to --fix
Adds automatic database recovery when bd doctor --fix detects corruption:
- Detects SQLite corruption (malformed database, SQLITE_CORRUPT errors)
- Backs up corrupted database before recovery attempt
- Rebuilds from JSONL if available (issues.jsonl, deletions.jsonl)
- Falls back to fresh database if JSONL unavailable
- Reports recovery results (issues imported, success/failure)

Recovery is triggered automatically by --fix when corruption is detected.
No manual intervention required.
2025-12-26 18:55:07 -05:00
Jordan Hubbard
28f2c76589 Merge branch 'steveyegge:main' into main 2025-12-26 17:22:14 -04:00
Steve Yegge
d3e90225a0 fix(doctor): Preserve parent-child dependencies in child→parent check (GH#750)
The CheckChildParentDependencies detection and ChildParentDependencies fix
were flagging ALL child→parent dependencies, including legitimate
'parent-child' type structural hierarchy relationships.

Now only blocking types (blocks, conditional-blocks, waits-for) are
detected as anti-patterns. The 'parent-child' type is a legitimate
hierarchy marker used for:
- Tracking parent-child relationships
- Transitive block propagation (if parent blocked, children blocked)
- Hierarchy visualization in external tools

Changes:
- Add type filter to SELECT queries (only blocking types)
- Add type filter to DELETE statement (preserve parent-child)
- Add regression test TestChildParentDependencies_PreservesParentChildType

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 12:49:40 -08:00
Jordan Hubbard
7af3106610 doctor: add fs fault injection and lock contention coverage
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2025-12-26 09:22:45 -04:00
Jordan Hubbard
8166207eb4 doctor: add JSONL integrity check/fix and harden repairs
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2025-12-26 08:18:25 -04:00
Jordan Hubbard
1a4f06ef8c doctor: harden corruption repair and JSONL config
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2025-12-26 04:29:29 -04:00
Jordan Hubbard
b089aaa0d6 tests: add chaos doctor repair coverage and stabilize git init
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2025-12-25 21:50:13 -04:00
Jordan Hubbard
1184bd1e59 doctor: add git hygiene checks and DB integrity auto-fix
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2025-12-25 21:35:44 -04:00
Steve Yegge
3034fc392e fix(doctor): handle installed_plugins.json v2 format (GH#741)
Claude Code's installed_plugins.json changed from v1 (plugins as structs)
to v2 (plugins as arrays). Update GetClaudePluginVersion() to handle both.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 16:20:02 -08:00
Steve Yegge
d2b1656c5d fix: Make child→parent dep fix opt-in with --fix-child-parent (bd-cuek)
GH#740: bd doctor --fix was auto-removing child→parent dependencies,
calling them an 'anti-pattern'. While these often indicate modeling
mistakes (deadlock), they may be intentional in some workflows.

Changes:
- Add --fix-child-parent flag (required to remove child→parent deps)
- Remove ChildParentDependencies from default --fix set
- Update warning message to reference new flag
- Update comments to reflect more nuanced understanding

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 14:05:55 -08:00
Steve Yegge
29501c7aeb feat: Add stale molecules check to bd doctor (bd-6a5z)
Extends bd doctor to detect complete-but-unclosed molecules (epics where
all children are closed but root is still open).

- Added CheckStaleMolecules() to doctor/maintenance.go
- Added resolveBeadsDir() helper to follow Gas Town redirect files
- Check appears in Maintenance category with warning severity
- Shows example IDs and suggests 'bd mol stale' for review

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 12:42:55 -08:00
Dirceu Pereira Tiegs
939ade731f fix: doctor check skips interactions.jsonl and molecules.jsonl (GH#709) (#739)
The fix for GH#709 updated FindJSONLInDir to skip interactions.jsonl,
but the doctor check in CheckLegacyJSONLFilename was not updated.
This caused `bd doctor` to warn about multiple JSONL files when
both issues.jsonl and interactions.jsonl exist (which is normal
after `bd init`).

Also skip molecules.jsonl which is another system file that shouldn't
be counted as a duplicate issue database.
2025-12-25 11:52:43 -08:00
Steve Yegge
ce2b05356a feat(deps): detect/prevent child→parent dependency anti-pattern (bd-nim5)
This prevents a common mistake where users add dependencies from child
issues to their parent epics. This creates a deadlock:
- Child can't start (blocked by open parent)
- Parent can't close (children not done)

Changes:
- dep.go: Reject child→parent deps at creation time with clear error
- server_labels_deps_comments.go: Same check for daemon RPC
- doctor/validation.go: New check detects existing bad deps
- doctor/fix/validation.go: Auto-fix removes bad deps
- doctor.go: Wire up check and fix handler

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 13:03:27 -08:00
matt wilkie
0f93bef240 fix(bd-68e4): export must specify -o to write to file, not stdout
When 'bd doctor --fix' detects DB has more issues than JSONL, it runs
'bd export' to sync them. However, 'bd export' without -o flag outputs
to stdout instead of writing to .beads/issues.jsonl, making the fix a
no-op.

Add -o .beads/issues.jsonl --force to the export command to ensure the
JSONL file is actually updated.
2025-12-24 12:37:24 -08:00
Steve Yegge
e67f27c092 bd sync: 2025-12-23 23:38:57 2025-12-24 00:06:41 -08:00
Steve Yegge
2de1695615 bd sync: 2025-12-23 22:33:32 2025-12-23 22:33:33 -08:00
Steve Yegge
cf9e5a597b bd sync: 2025-12-23 20:50:50 2025-12-23 20:50:50 -08:00
Steve Yegge
9c8761abc9 bd sync: 2025-12-23 20:45:19 2025-12-23 20:45:19 -08:00
Steve Yegge
7b671662aa bd sync: 2025-12-23 13:49:07 2025-12-23 14:39:07 -08:00
Ryan
297c696336 feat(doctor): add count-based database size check (#724)
feat(doctor): add count-based database size check

Adds CheckDatabaseSize (Check 29) that warns when closed issues exceed a configurable threshold (default: 5000). The check is informational only - no auto-fix since pruning is destructive.

Also improves fix guidance for sync-branch hook compatibility and legacy JSONL filename checks.

PR #724 by @rsnodgrass
2025-12-23 13:29:35 -08:00
Steve Yegge
8b49d8f079 fix: resolve golangci-lint errors
- Add _ = prefix for ignored Close/Remove return values
- Fix unused cmd parameter in runMoleculeReady
- Add nolint:misspell for intentional British "cancelled" spelling
- Update comments to use US spelling where not intentional

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 05:10:38 -08:00
Ryan
e8d0860571 fix(doctor): use --fix instead of manual commands (#715)
UX improvement: doctor advice now recommends bd doctor --fix instead of manual commands
2025-12-23 02:30:33 -08:00
Steve Yegge
aa1ce63156 feat: consolidate maintenance commands into bd doctor --fix (bd-bqcc)
Add new Maintenance category to bd doctor with checks for:
- Stale closed issues (older than 30 days)
- Expired tombstones (older than TTL)
- Compaction candidates (info only)

Add fix handlers for cleanup and tombstone pruning via bd doctor --fix.
Add deprecation hints to cleanup, compact, and detect-pollution commands
suggesting users try bd doctor instead.

This consolidation reduces cognitive load - users just need to remember
'bd doctor' for health checks and 'bd doctor --fix' for maintenance.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 01:31:18 -08:00
Steve Yegge
e2ab727a2c fix(doctor): use context.Background() instead of nil in CheckDuplicateIssues
The nil context caused a panic during store.Close() in tests.
Passing context.Background() fixes the test timeout issue.
2025-12-22 20:21:30 -08:00
Ryan Snodgrass
cafc0b9dfb refactor(doctor): consolidate maintenance commands + improve daemon startup
Consolidate clean, repair-deps, validate into bd doctor:
- Add validation checks to doctor (merge artifacts, orphaned deps, duplicates, test pollution, git conflicts)
- Add auto-fix for merge artifacts and orphaned dependencies
- Delete obsolete command files: clean.go, repair_deps.go, validate.go
- Delete orphaned test files: clean_security_test.go, validate_test.go

Improve daemon startup performance:
- Add fast-fail detection when daemon crashed (check lock before retrying)
- Reduce graceful shutdown timeout from 5s to 1s
- Skip daemon connection for root command (just shows help)
- Extract shutdown timeout as constants (daemonShutdownTimeout, daemonShutdownPollInterval)

Other changes:
- Move rename-prefix command to Maintenance group in help
- Fix Makefile to inject git commit hash via ldflags

New files:
- cmd/bd/doctor/validation.go (5 check functions)
- cmd/bd/doctor/fix/validation.go (2 fix functions)
2025-12-22 20:21:30 -08:00
Steve Yegge
90ce008047 Merge pull request #705 from crcatala/fix/add-interactions-jsonl-to-gitignore-allowlist
Reviewed by dave (beads crew worker)
2025-12-22 20:17:51 -08:00
Charles P. Cross
737e65afbd fix(daemon): add periodic remote sync to event-driven mode (#698)
* fix(daemon): add periodic remote sync to event-driven mode

The event-driven daemon mode only triggered imports when the local JSONL
file changed (via file watcher) or when the fallback ticker fired (only
if watcher failed). This meant the daemon wouldn't see updates pushed
by other clones until something triggered a local file change.

Bug scenario:
1. Clone A creates an issue and daemon pushes to sync branch
2. Clone B's daemon only watched local file changes
3. Clone B would not see the new issue until something triggered local change
4. With this fix: Clone B's daemon periodically calls doAutoImport

This fix adds a 30-second periodic remote sync ticker that calls
doAutoImport(), which includes syncBranchPull() to fetch and import
updates from the remote sync branch.

This is essential for multi-clone workflows where:
- Clone A creates an issue and daemon pushes to sync branch
- Clone B's daemon needs to periodically pull to see the new issue
- Without periodic sync, Clone B would only see updates if its local
  JSONL file happened to change

The 30-second interval balances responsiveness with network overhead.

Adds integration test TestEventDrivenLoop_PeriodicRemoteSync that
verifies the event-driven loop starts with periodic sync support.

* feat(daemon): add configurable interval for periodic remote sync

- Add BEADS_REMOTE_SYNC_INTERVAL environment variable to configure
  the interval for periodic remote sync (default: 30s)
- Add getRemoteSyncInterval() function to parse the env var
- Minimum interval is 5s to prevent excessive load
- Setting to 0 disables periodic sync (not recommended)
- Add comprehensive integration tests for the configuration

Valid duration formats:
- "30s" (30 seconds)
- "1m" (1 minute)
- "5m" (5 minutes)

Tests added:
- TestEventDrivenLoop_HasRemoteSyncTicker
- TestGetRemoteSyncInterval_Default
- TestGetRemoteSyncInterval_CustomValue
- TestGetRemoteSyncInterval_MinimumEnforced
- TestGetRemoteSyncInterval_InvalidValue
- TestGetRemoteSyncInterval_Zero
- TestSyncBranchPull_FetchesRemoteUpdates

* fix: resolve all golangci-lint errors (cherry-pick from fix/linting-errors)

Cherry-picked linting fixes to ensure CI passes.

* feat(daemon): add config.yaml support for remote-sync-interval

- Add remote-sync-interval to .beads/config.yaml as alternative to
  BEADS_REMOTE_SYNC_INTERVAL environment variable
- Environment variable takes precedence over config.yaml (follows
  existing pattern for flush-debounce)
- Add config binding in internal/config/config.go
- Update getRemoteSyncInterval() to use config.GetDuration()
- Add doctor validation for remote-sync-interval in config.yaml

Configuration sources (in order of precedence):
1. BEADS_REMOTE_SYNC_INTERVAL environment variable
2. remote-sync-interval in .beads/config.yaml
3. DefaultRemoteSyncInterval (30s)

Example config.yaml:
  remote-sync-interval: "1m"

---------

Co-authored-by: Charles P. Cross <cpdata@users.noreply.github.com>
2025-12-22 14:15:33 -08:00
cc-vps
7ad9fb537b fix: add interactions.jsonl to .gitignore allowlist
The interactions.jsonl file is an append-only audit log that should be
tracked in git (synced with bd sync), but it was missing from the
negation patterns in .beads/.gitignore.

This adds !interactions.jsonl alongside !issues.jsonl and !metadata.json
for consistency and clarity that this file should be committed.

Co-authored-by: Christian Catalan <crcatala@gmail.com>
2025-12-22 13:48:06 -08:00
Ryan
a11b20960a fix(doctor): UX improvements for diagnostics and daemon (#687)
* fix(doctor): UX improvements for diagnostics and daemon

- Add Repo Fingerprint check to detect when database belongs to a
  different repository (copied .beads dir or git remote URL change)
- Add interactive fix for repo fingerprint with options: update repo ID,
  reinitialize database, or skip
- Add visible warning when daemon takes >5s to start, recommending
  'bd doctor' for diagnosis
- Detect install method (Homebrew vs script) and show only relevant
  upgrade command
- Improve WARNINGS section:
  - Add icons (⚠ or ✖) next to each item
  - Color numbers by severity (yellow for warnings, red for errors)
  - Render entire error lines in red
  - Sort by severity (errors first)
  - Fix alignment with checkmarks above
- Use heavier fail icon (✖) for better visibility
- Add integration and validation tests for doctor fixes

* fix(lint): address errcheck and gosec warnings

- mol_bond.go: explicitly ignore ephStore.Close() error
- beads.go: add nosec for .gitignore file permissions (0644 is standard)
2025-12-22 01:25:23 -08:00
Steve Yegge
240a4e2dbc feat: add bd doctor check for orphaned issues (bd-5hrq)
- Add CheckOrphanedIssues to detect issues referenced in commits but still open
- Pattern matches (prefix-xxx) in git log against open issues in database
- Reports warning with issue IDs and commit hashes
- Add 8 comprehensive tests for the new check

Also:
- Add tests for mol spawn --attach functionality (bd-f7p1)
- Document commit message convention in AGENT_INSTRUCTIONS.md
- Fix CheckpointWAL to use wrapDBError for consistency

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 22:05:14 -08:00
matt wilkie
9db8efaa5c docs: update docs.md for bidirectional DBJSONLSync fix (bd-68e4) 2025-12-21 11:25:57 -07:00
matt wilkie
2de4d0facd fix(bd-68e4): make DBJSONLSync bidirectional - export DB when it has more issues
- Modified fix.DBJSONLSync() to detect which direction to sync:
  - If DB > JSONL: run 'bd export' to sync JSONL (DB has newer data)
  - If JSONL > DB: run 'bd sync --import-only' to import (JSONL is source of truth)
  - If equal but different timestamps: use file mtime to decide direction

- Updated CheckDatabaseJSONLSync() error messages to recommend correct fix direction:
  - Shows different guidance based on whether DB or JSONL has more issues

- Added helper functions:
  - countDatabaseIssues() to count issues in SQLite
  - countJSONLIssues() to count issues in JSONL (local, avoids circular import)

- Added tests for countJSONLIssues() with edge cases

Fixes issue where 'bd doctor --fix' would recommend 'bd sync --import-only'
when DB > JSONL, which would be a no-op since JSONL hasn't changed.
2025-12-21 11:22:37 -07:00
Steve Yegge
5b2a516aca fix(doctor): check .local_version instead of deprecated LastBdVersion (fixes #662)
The doctor's version tracking check was looking at metadata.json:LastBdVersion,
but version tracking was moved to .local_version file (gitignored). This caused
the "LastBdVersion field is empty" warning to persist even after running bd
commands, because those commands update .local_version but not metadata.json.

- Update CheckMetadataVersionTracking to read from .local_version
- Rename check from "Metadata Version Tracking" to "Version Tracking"
- Update tests to use .local_version instead of metadata.json
- Remove unused configfile import

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 14:41:13 -08:00
Steve Yegge
c988b171e8 feat(config): add git.author and git.no-gpg-sign options (fixes #600)
Adds configuration options for beads git commits:
- git.author: Override commit author (e.g., "beads-bot <beads@example.com>")
- git.no-gpg-sign: Disable GPG signing for beads commits

This is useful for users with Touch ID commit signing (like Secretive)
who get prompted for every beads auto-commit.

Config example:
```yaml
git:
  author: "beads-bot <beads@example.com>"
  no-gpg-sign: true
```

Environment variables: BD_GIT_AUTHOR, BD_GIT_NO_GPG_SIGN

Closes #600

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 03:36:41 -08:00
Ryan
3c08e5eb9d DOCTOR IMPROVEMENTS: visual improvements/grouping + add comprehensive tests + fix gosec warnings (#656)
* test(doctor): add comprehensive tests for fix and check functions

Add edge case tests, e2e tests, and improve test coverage for:
- database_test.go: database integrity and sync checks
- git_test.go: git hooks, merge driver, sync branch tests
- gitignore_test.go: gitignore validation
- prefix_test.go: ID prefix handling
- fix/fix_test.go: fix operations
- fix/e2e_test.go: end-to-end fix scenarios
- fix/fix_edge_cases_test.go: edge case handling

* docs: add testing philosophy and anti-patterns guide

- Create TESTING_PHILOSOPHY.md covering test pyramid, priority matrix,
  what NOT to test, and 5 anti-patterns with code examples
- Add cross-reference from README_TESTING.md
- Document beads-specific guidance (well-covered areas vs gaps)
- Include target metrics (test-to-code ratio, execution time targets)

* chore: revert .beads/ to upstream/main state

* refactor(doctor): add category grouping and Ayu theme colors

- Add Category field to DoctorCheck for organizing checks by type
- Define category constants: Core, Git, Runtime, Data, Integration, Metadata
- Update thanks command to use shared Ayu color palette from internal/ui
- Simplify test fixtures by removing redundant test cases

* fix(doctor): prevent test fork bomb and fix test failures

- Add ErrTestBinary guard in getBdBinary() to prevent tests from
  recursively executing the test binary when calling bd subcommands
- Update claude_test.go to use new check names (CLI Availability,
  Prime Documentation)
- Fix syncbranch test path comparison by resolving symlinks
  (/var vs /private/var on macOS)
- Fix permissions check to use exact comparison instead of bitmask
- Fix UntrackedJSONL to use git commit --only to preserve staged changes
- Fix MergeDriver edge case test by making both .git dir and config
  read-only
- Add skipIfTestBinary helper for E2E tests that need real bd binary

* test(doctor): skip read-only config test in CI environments

GitHub Actions containers may have CAP_DAC_OVERRIDE or similar
capabilities that allow writing to read-only files, causing
the test to fail. Skip the test when CI=true or GITHUB_ACTIONS=true.
2025-12-20 03:10:06 -08:00
Steve Yegge
8e8301a016 fix(doctor): update broken Claude plugin link (GH#623)
The bd doctor command was pointing to a non-existent README anchor
(#claude-code-plugin). Updated to point to docs/PLUGIN.md which
contains the actual plugin installation instructions.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 02:38:56 -08:00
Steve Yegge
567dd0a0c6 fix(schema): add pinned column to schema compatibility checks
The schema_probe.go and doctor/database.go had different column lists
for validating database schemas. Neither included the pinned column
added in migration 023, causing:
- Doctor to report "All required tables and columns present" on
  databases missing the pinned column
- Potential failures when using `gt mail send` on databases without
  the pinned column

Changes:
- Add pinned, sender, ephemeral to doctor's criticalChecks
- Add metadata, thread_id to dependencies check
- Add all missing columns to schema_probe.go's expectedSchema:
  source_repo, close_reason, deleted_at, deleted_by, delete_reason,
  original_type, sender, ephemeral, pinned

Fixes: beads-9yc

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 19:57:14 -08:00
Steve Yegge
13a471fe45 test(doctor): add tests to restore coverage above 45%
Add tests for doctor package functions after refactor PR #653:
- version_test.go: CompareVersions, IsValidSemver, ParseVersionParts
- types_test.go: status constants and DoctorCheck struct
- installation_test.go: CheckInstallation, CheckMultipleDatabases, CheckPermissions
- integrity_test.go: CheckIDFormat, CheckDependencyCycles, CheckTombstones, CheckDeletionsManifest
- database_test.go: CheckDatabaseVersion, CheckSchemaCompatibility, CheckDatabaseIntegrity
- daemon_test.go: CheckDaemonStatus
- git_test.go: CheckGitHooks, CheckMergeDriver, CheckSyncBranchConfig

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 17:43:18 -08:00
Ryan
e9be35e374 refactor(doctor): split doctor.go into modular package files (#653)
* refactor(doctor): split doctor.go into modular package files

Split the 3,171-line doctor.go into logical sub-files within the
cmd/bd/doctor/ package, reducing the main file to 834 lines (74% reduction).

New package structure:
- types.go: DoctorCheck struct and status constants
- installation.go: CheckInstallation, CheckMultipleDatabases, CheckPermissions
- git.go: CheckGitHooks, CheckMergeDriver, CheckSyncBranch* checks
- database.go: CheckDatabaseVersion, CheckSchemaCompatibility, CheckDatabaseJSONLSync
- version.go: CheckCLIVersion, CheckMetadataVersionTracking, CompareVersions
- integrity.go: CheckIDFormat, CheckDependencyCycles, CheckTombstones
- daemon.go: CheckDaemonStatus, CheckVersionMismatch
- quick.go: Quick checks for sync-branch and hooks

Updated tests to use exported doctor.CheckXxx() functions and
doctor.StatusXxx constants.

* fix(doctor): suppress gosec G204 false positives

Add #nosec G204 comments to exec.Command calls in CheckSyncBranchHealth
where variables come from trusted sources (config files or hardcoded
values like "main"/"master"/"origin"), not untrusted user input.
2025-12-19 17:29:36 -08:00