Commit Graph

5355 Commits

Author SHA1 Message Date
Daniel Sauer
4fffdb7fae fix(sqlite): add missing agent fields to scanIssues and related queries (#1176)
The scanIssues() function and multiple SQL queries were not selecting or
scanning agent-related fields (hook_bead, role_bead, agent_state, last_activity,
role_type, rig, mol_type) and time-based scheduling fields (due_at, defer_until).

This caused bd list --json to return null for last_activity even when the
database contained valid timestamps, preventing proper agent health monitoring.

Updated files:
- dependencies.go: scanIssues() variable declarations, scan calls, assignments
- queries.go: SearchIssues query
- labels.go: GetIssuesByLabel query
- ready.go: GetReadyWork and GetNewlyUnblockedByClose queries
- transaction.go: GetIssue query, SearchIssues query, scanIssueRow()

Fixes steveyegge/beads#1175
2026-01-19 10:11:03 -08:00
aleiby
f4ee7ee73b fix(routing): default to Maintainer when no git remote exists (#1185)
When no git remote is configured, DetectUserRole() now defaults to
Maintainer instead of Contributor. This fixes issue routing for:

1. New personal projects (no remote configured yet)
2. Intentionally local-only repositories

Previously, issues would silently route to ~/.beads-planning instead
of the local .beads/ directory.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 10:11:00 -08:00
Peter Chanthamynavong
460d2bf113 fix(doctor): improve diagnostic fix message output (#1187)
Problem:
- Diagnostic fix messages were restricted to single lines
- Inconsistent file path formatting in database sync issues
- Outdated cleanup command suggested in maintenance fixes

Solution:
- Implement multiline support for doctor fix messages
- Standardize issue file paths across database diagnostics
- Update maintenance fix instructions to use 'bd admin cleanup'

Impact:
- Clearer and more accurate recovery instructions for users
- Better readability of complex diagnostic output

Fixes: GH#1170, GH#1171, GH#1172
2026-01-19 10:10:57 -08:00
Steven Syrek
73d4d5ecb2 fix(create): validate explicit IDs against allowed_prefixes using starts-with matching (#1137)
When creating issues with explicit IDs like `bd create --id hq-cv-test`,
the prefix validation was failing even when `hq-cv` was in `allowed_prefixes`.

Root cause: `ExtractIssuePrefix("hq-cv-test")` returns `"hq"` (not `"hq-cv"`)
because "test" looks like an English word, causing the algorithm to fall back
to the first hyphen. The validation then checked if `"hq"` was in the allowed
list containing `"hq-cv"` - which failed.

The fix adds `ValidateIDPrefixAllowed()` which validates the full ID using
"starts with" matching (the same approach the importer uses successfully).
This correctly handles multi-hyphen prefixes like `hq-cv-` regardless of
what the suffix looks like.

Fixes #1135

Co-authored-by: Steven Syrek <steven.syrek@deepl.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 10:08:56 -08:00
Steven Syrek
8e40018701 fix(daemon): Fix double-unlock risk in debouncer on action panic (#1140)
The debouncer's timer callback used a pattern that could cause a
double-unlock panic if the action function panicked:

  d.mu.Lock()
  defer d.mu.Unlock()
  if d.seq == currentSeq {
      d.mu.Unlock()  // Manual unlock
      d.action()     // If this panics...
      d.mu.Lock()    // ...this never runs
  }                  // ...but defer still tries to unlock

Fix: Remove the defer and manually manage lock state. Now if the
action panics, the lock is already released, preventing a
double-unlock panic that would mask the original panic.

Co-authored-by: Steven Syrek <steven.syrek@deepl.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 10:08:53 -08:00
Steven Syrek
ba832c4f37 fix(daemon): Eliminate race condition in sync state load-modify-save (#1139)
The RecordSyncFailure and ResetBackoffOnDaemonStart functions had a
TOCTOU (time-of-check-time-of-use) race condition. They called
LoadSyncState (which locks, reads, unlocks) then modified the state,
then called SaveSyncState (which locks, writes, unlocks).

Between LoadSyncState returning and SaveSyncState being called, another
goroutine could load the old state, modify it, and save it - then this
goroutine's save would overwrite those changes.

Fix: Create internal unlocked helper functions (loadSyncStateUnlocked,
saveSyncStateUnlocked) and have RecordSyncFailure and
ResetBackoffOnDaemonStart hold the lock for the entire load-modify-save
operation.

Co-authored-by: Steven Syrek <steven.syrek@deepl.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 10:08:41 -08:00
beads/crew/emma
4bc0b698a8 fix(staleness): skip auto-import when store is read-only (GH#1089)
Track whether the store was actually opened read-only (vs just requested)
since the fallback logic may change opts.ReadOnly. Use this to skip
auto-import in staleness checks - importing would fail anyway if the
store is read-only.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 18:25:50 -08:00
beads/crew/emma
c8ffcce621 fix(validation): accept prefix when it's a prefix of allowed entry (GH#1135)
When ExtractIssuePrefix returns "hq" from an ID like "hq-cv-test"
(because "test" is word-like), but "hq-cv" is in allowedPrefixes,
we should accept "hq" since it's clearly intended to be part of "hq-cv".

This handles cases where the prefix extraction algorithm yields a
shorter prefix than the user intended, but the full intended prefix
is in the allowed list.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 18:25:33 -08:00
beads/crew/emma
356ab92b78 feat(sync): wire up sync.mode config to change sync behavior
Implements hq-ew1mbr.27: The sync.mode config now actually changes how
bd sync operates:

- git-portable (default): JSONL exported on push, imported on pull
- realtime: JSONL exported on every change (placeholder for daemon hook)
- dolt-native: Uses Dolt Push/Pull, skips JSONL workflow entirely
- belt-and-suspenders: Both Dolt remotes AND JSONL for redundancy

Changes:
- Add sync_mode.go with mode constants, Get/Set functions, and helpers
- Update bd sync --status to show actual mode from config
- Add --set-mode flag to bd sync for configuring the mode
- Modify doExportSync to respect mode (Dolt push for dolt-native)
- Modify doPullFirstSync to use Dolt pull for dolt-native mode
- Add RemoteStorage interface for Push/Pull operations
- Add comprehensive tests for sync mode functionality

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 10:36:20 -08:00
jane
c99bd00ca7 feat(sync): implement interactive conflict resolution for manual strategy
Adds interactive manual conflict resolution for `bd sync --resolve --manual`:
- Shows field-by-field diff between local and remote versions
- Prompts user to choose: local (l), remote (r), merge (m), skip (s)
- Supports viewing full JSON diff with 'd' option
- Skipped conflicts remain in conflict state for later resolution
- Integrates with existing 3-way merge infrastructure

New files:
- cmd/bd/sync_manual.go: Interactive conflict resolution logic
- cmd/bd/sync_manual_test.go: Unit tests for helper functions

Closes hq-ew1mbr.28

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 14:02:47 -08:00
lizzy
9ddd7a2620 feat(config): add validate command for sync config
Add `bd config validate` command to validate sync-related configuration:

- sync.mode: validates values (local, git-branch, external)
- conflict.strategy: validates values (lww, manual, ours, theirs)
- federation.sovereignty: validates values (none, isolated, federated)
- federation.remote: ensures set when sync.mode is 'external'
- Remote URL format: validates dolthub://, gs://, s3://, file://, etc.

Also validates existing config via doctor.CheckConfigValues (sync.branch,
routing.mode, etc.)

Closes: hq-ew1mbr.29

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 14:02:28 -08:00
collins
e82e15a8c2 feat(config): add GetSyncMode, GetConflictStrategy, GetSovereignty with warnings
Add config accessor functions for sync mode, conflict strategy, and
federation sovereignty tier settings. These functions:

- Read from config.yaml via viper
- Validate against known valid values
- Return sensible defaults when not set
- Log warnings to stderr when invalid values are configured (instead
  of silently falling back to defaults)

Closes: hq-ew1mbr.26

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 13:58:00 -08:00
darcy
16f8c3d3ae feat(sync): add sync mode configuration (hq-ew1mbr.3)
Add configurable sync modes for Dolt storage integration:

Sync modes:
- git-portable (default): Export JSONL on push, import on pull
- realtime: Export JSONL on every database change
- dolt-native: Use Dolt remotes directly (no JSONL)
- belt-and-suspenders: Both Dolt remote AND JSONL backup

Configuration options in .beads/config.yaml:
- sync.mode: Select sync mode
- sync.export_on: push (default) or change
- sync.import_on: pull (default) or change
- conflict.strategy: newest (default), ours, theirs, manual
- federation.remote: Dolt remote URL for dolt-native mode
- federation.sovereignty: T1-T4 data sovereignty tier

The sync command now displays configuration in `bd sync --status`
and uses configured conflict strategy for resolution.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 10:52:29 -08:00
lydia
ba0e754dc8 feat(hook): implement per-worktree export state tracking (Design Part 21)
Updates ExportState to track Dolt commits (not git commits) for accurate
change detection. This prevents polecats sharing a Dolt DB from exporting
each others uncommitted work.

Changes:
- ExportState now tracks Dolt commit hash via VersionedStorage.GetCurrentCommit()
- Added WorktreeHash and Actor fields for debugging and future filtering
- hookPreCommitDolt uses Diff() to detect changes since last export
- Added hookPreCommitDoltFallback for graceful degradation
- Added exportIncrementalDolt and exportFullDolt helper functions
- Removed unused exportToJSONLFromStore function

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 10:46:44 -08:00
dennis
1f59119144 fix(sync): use town-level routes for prefix validation
Follow-up to 828fc11b addressing code review feedback:

1. Added LoadTownRoutes() - exported function that walks up to find
   town-level routes.jsonl (e.g., ~/gt/.beads/routes.jsonl)

2. Updated buildAllowedPrefixSet to use LoadTownRoutes instead of
   LoadRoutes, so it finds routes even when importing from a rig's
   local beads directory

3. Added unit tests for buildAllowedPrefixSet covering:
   - Primary prefix inclusion
   - allowed_prefixes config parsing
   - Routes from routes.jsonl
   - Missing routes.jsonl handling
   - Empty beadsDir handling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 09:51:46 -08:00
beads/crew/emma
4f0f5744a6 feat(types): remove Gas Town types from core built-in types
Core beads built-in types now only include work types:
- bug, feature, task, epic, chore

Gas Town types (molecule, gate, convoy, merge-request, slot, agent,
role, rig, event, message) are now "well-known custom types":
- Constants still exist for code convenience
- Require types.custom configuration for validation
- bd types command shows core types and configured custom types

Changes:
- types.go: Separate core work types from well-known custom types
- IsValid(): Only accepts core work types
- bd types: Updated to show core types and custom types from config
- memory.go: Use ValidateWithCustom for custom type support
- multirepo.go: Only check core types as built-in
- Updated all tests to configure custom types

This allows Gas Town (and other projects) to define their own types
via config while keeping beads core focused on work tracking.

Closes: bd-find4

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 05:07:11 -08:00
emma
88a6438c80 chore(release): bump version to 0.48.0
Release highlights:
- VersionedStorage interface for pluggable backends
- bd types command and enhancement type alias
- bd close -m flag (git commit convention)
- RepoContext API for centralized git operations
- Dolt backend improvements (WIP)
- Many bug fixes for doctor, sync, hooks, worktrees

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 04:36:41 -08:00
mayor
6af5cae1d1 chore: ignore metadata.json in .beads 2026-01-17 04:22:35 -08:00
emma
10bdc94294 feat(close): add -m as alias for --reason
Adds -m/--message as a hidden alias for --reason, following the git
commit convention where -m specifies a message. This makes the command
more intuitive for users familiar with git workflows.

Usage: bd close <id> -m "reason for closing"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 03:48:51 -08:00
dennis
828fc11b57 fix(sync): allow routed prefixes in import validation
When importing issues in a multi-rig setup (Gas Town), the prefix
validation was failing for issues with prefixes from other rigs
(e.g., hq-* prefixes from town-level beads).

This fix extends buildAllowedPrefixSet to also load prefixes from
routes.jsonl, allowing issues from any routed rig to pass validation.

Fixes: gt-2maz79

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 03:45:02 -08:00
lydia
feed888b57 fix(duplicates): use combined weight (dependents + dependencies) for merge target selection (GH#1022)
When choosing which duplicate to keep, the merge target now considers
both dependentCount (children/blocked-by) AND dependsOnCount (dependencies).
This ensures issues with ANY structural connections are preferred over
empty shells, rather than only considering children.

- Updated chooseMergeTarget to calculate weight = dependentCount + dependsOnCount
- Updated display output to show weight instead of just dependents
- Updated JSON output to include dependencies and weight fields
- Added tests for dependsOnCount inclusion and combined weight calculation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 03:44:13 -08:00
jane
251ded73be fix(merge-slot): use daemon RPC to get issue_prefix in daemon mode
When running in daemon mode, getMergeSlotID() was not using the daemon
RPC to retrieve the configured issue_prefix, causing it to fall back
to the hardcoded "bd" default. This fix adds the missing daemon path
that uses daemonClient.GetConfig() to properly retrieve the prefix,
matching the pattern used in create.go.

Fixes #1096

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 03:44:02 -08:00
emma
a21a29c283 fix(doctor): remove destructive sync branch health check (GH#1062)
The "Sync Branch Health" check incorrectly warned when the sync branch
differed from main on source files. Since the sync branch only tracks
.beads/ data, source file differences are expected behavior.

The associated --fix action (reset sync branch to main and force push)
was destructive and destroyed legitimate sync branch history.

Removed Check 2 entirely - only Check 1 (detecting divergence from remote
after force-push) remains, which is a legitimate issue.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 03:42:35 -08:00
wickham
9f44884f9d docs(skill): sync CLI reference with v0.47.1 commands
Update SKILL.md prerequisite version from 0.43.0 to 0.47.0.

Add documentation for new commands in CLI_REFERENCE.md:
- Health & Status section: doctor, status, prime
- Quick capture (q) for scripting
- Comments management
- Full search command with sorting and filtering
- Visualization section with graph command
- Blocked issues filter

Fixes #1042

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 03:41:19 -08:00
elinor
f06e742273 fix(daemon): apply git.author config to sync branch commits
The daemon's gitCommitInWorktree function was building git commit
commands directly without checking the git.author and git.no-gpg-sign
config options. This caused daemon sync commits to use the local git
user config instead of the configured beads-specific author.

Now gitCommitInWorktree applies the same config-based author and
signing options that buildCommitArgs uses for regular commits.

Fixes #1051
2026-01-17 03:40:28 -08:00
emma
e60e8f1823 chore: remove placeholder comment in test
Remove `// See: https://github.com/steveyegge/beads/issues/XXX`
placeholder that was left in the regression test from PR #1131.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 02:51:06 -08:00
dave
c220542926 fix(init): use --git-common-dir for worktree exclude paths (GH#1053)
When running bd init --stealth in a worktree, excludes were being
written to .git/worktrees/<name>/info/exclude which has no effect.
Changed setupGitExclude and setupForkExclude to use --git-common-dir
instead of --git-dir so excludes go to the main repo .git/info/exclude.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 02:29:01 -08:00
quartz
94581ab233 feat(storage): add VersionedStorage interface with history/diff/branch operations
Extends Storage interface with Dolt-specific version control capabilities:

- New VersionedStorage interface in storage/versioned.go with:
  - History queries: History(), AsOf(), Diff()
  - Branch operations: Branch(), Merge(), CurrentBranch(), ListBranches()
  - Commit operations: Commit(), GetCurrentCommit()
  - Conflict resolution: GetConflicts(), ResolveConflicts()
  - Helper types: HistoryEntry, DiffEntry, Conflict

- DoltStore implements VersionedStorage interface

- New CLI commands:
  - bd history <id> - Show issue version history
  - bd diff <from> <to> - Show changes between commits/branches
  - bd branch [name] - List or create branches
  - bd vc merge <branch> - Merge branch to current
  - bd vc commit -m <msg> - Create a commit
  - bd vc status - Show current branch/commit

- Added --as-of flag to bd show for time-travel queries

- IsVersioned() helper for graceful SQLite backend detection

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 01:55:16 -08:00
onyx
a7cd9136d8 feat(sync): implement bd sync command specification
Changes the default bd sync behavior to export-only per the spec:
- bd sync: Export to JSONL (no staging/committing)
- bd sync --import: Import from JSONL (shorthand for --import-only)
- bd sync --status: Show sync state (mode, last export, pending changes, conflicts)
- bd sync --resolve: Resolve conflicts with strategies (newest/ours/theirs)
- bd sync --force: Force full export/import (skip incremental)
- bd sync --full: Full sync (legacy pull→merge→export→commit→push behavior)

The new --status output format shows:
- Sync mode: git-portable
- Last export: timestamp (commit hash)
- Pending changes: N issues modified since last export
- Import branch: name or none
- Conflicts: count or none

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 01:55:06 -08:00
opal
ca24c17af8 feat(compact): add --dolt flag for Dolt garbage collection
Add `bd compact --dolt` command to run Dolt garbage collection on
.beads/dolt directory. This helps reclaim disk space when using the
Dolt backend, where auto-commit per mutation causes commit history
to grow over time.

Features:
- Runs `dolt gc` in the .beads/dolt directory
- Shows disk space before/after with bytes freed
- Supports --dry-run to preview without running GC
- Supports --json for machine-readable output
- Helpful error messages for missing dolt directory or command

Closes: hq-ew1mbr.14

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 01:54:50 -08:00
jasper
ab5f507c66 test(dolt): add concurrent writer tests for embedded Dolt
Validates Gas Town multi-polecat concurrent access scenarios:
- Concurrent issue creation (10 goroutines)
- Same-issue update race conditions
- Read-write mix (5 readers, 5 writers, 100 iterations)
- Long transaction blocking
- Branch-per-agent merge race
- Worktree export isolation
- Concurrent dependency operations
- High contention stress test (20 workers, 1000 ops)

Also fixes Status() to scan string status from dolt_status table.

All tests pass with 100% success rate under contention.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 01:54:46 -08:00
obsidian
2cbffca4f3 feat(dolt): implement automatic bootstrap from JSONL on first access
Add automatic Dolt database bootstrapping when JSONL files exist but no
Dolt database is present (cold-start scenario after git clone).

Key features:
- Lock/wait pattern prevents concurrent bootstrap races
- Graceful degradation skips malformed JSONL lines with warnings
- Multi-table ordering: issues → labels → dependencies
- Prefix auto-detection from JSONL content

New files:
- internal/storage/dolt/bootstrap.go - Bootstrap logic
- internal/storage/dolt/bootstrap_test.go - Comprehensive tests

Modified:
- internal/storage/factory/factory_dolt.go - Integration point

Closes: hq-ew1mbr.10

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 01:54:31 -08:00
gastown/crew/max
87f84c5fa6 fix(create): use agent-aware prefix extraction for agent beads
The generic ValidateIDFormat() used isLikelyHash() which treated
3-character suffixes like "nux" as valid hashes, causing agent IDs
like "nx-nexus-polecat-nux" to extract prefix as "nx-nexus-polecat"
instead of the correct "nx".

Fix: For --type=agent, validate agent ID format first and use
ExtractAgentPrefix() which correctly extracts prefix from the
first hyphen for agent IDs.

Fixes #591

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 00:42:06 -08:00
tom
2c00d6d203 Merge branch 'main' of github.com:steveyegge/beads into mayor-rig 2026-01-17 00:37:17 -08:00
tom
ec90643d3d chore: sync beads (2) 2026-01-17 00:37:15 -08:00
tom
e477264e6e chore: sync beads 2026-01-17 00:37:03 -08:00
tom
ba77a1095f fix: ignore entire .claude/ directory, not just settings
The .claude/skills/ directories are created by Claude Code when agents
add skills (ghi-list, pr-list, handoff). These should not be tracked.

Fixes: gt-q0jy15.2
2026-01-17 00:36:38 -08:00
Steve Yegge
aae234bba7 Merge pull request #1138 from steveyegge/fix/agents-md-claude-md-reference-1049
docs: fix AGENTS.md references to nonexistent CLAUDE.md
2026-01-17 00:24:55 -08:00
beads/crew/giles
97adc19cf5 fix(main): move noDbCommands check before expensive git operations
Fixes #1093: `bd version` was spawning 5-7 git subprocesses before
checking if it even needed database access.

Moved the noDbCommands early-return check to run BEFORE:
- ensureForkProtection() (spawns ~5 git commands)
- signalOrchestratorActivity() (spawns git config)

This eliminates unnecessary process churn for simple commands like
`bd version`, `bd help`, `bd completion`, etc.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 00:24:36 -08:00
beads/crew/fang
634b01a609 docs(prime): warn agents about bd edit opening interactive editor
Add warning to bd prime output that bd edit opens $EDITOR which blocks
autonomous agents. Recommends bd update with --title/--description/etc
flags instead. Fixes #1061.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 00:24:34 -08:00
wickham
5fab5f58e6 fix(cli): suppress no-git-repo note with --quiet flag
The "Note: No git repository initialized" message now respects the
--quiet flag, preventing non-essential output in quiet mode.

Fixes #1080

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 00:16:05 -08:00
beads/crew/grip
7a61e6b1e5 docs: fix AGENTS.md references to nonexistent CLAUDE.md
Fixes #1049 - AGENTS.md referenced CLAUDE.md which doesn't exist on main.

Changes:
- "Key Sections in CLAUDE.md" -> "Key Sections"
- "See CLAUDE.md..." -> "See AGENT_INSTRUCTIONS.md..."

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 00:15:24 -08:00
Steve Yegge
b6155c69f2 Merge pull request #1130 from aleiby/fix/delete-marks-dependents-dirty
fix: Mark dependent issues dirty when deleting to prevent orphan deps in JSONL
2026-01-17 00:05:41 -08:00
John Zila
6aa8ebd26f fix(sync): write to worktree JSONL only when sync-branch configured (#1133)
Fixes #1103: bd sync --merge fails when sync-branch configured due to
skip-worktree/daemon write conflict.

Root cause: When sync-branch is configured, daemon/bd writes to main's
.beads/issues.jsonl which has skip-worktree set. This hides changes from
`git status` but `git merge` still detects them, causing merge failures.

Solution: When sync-branch is configured, redirect all JSONL writes to
the worktree's JSONL only. Main's JSONL is now read-only and only updated
via merges from the sync branch.

Changes:
- autoflush.go: findJSONLPath() now returns worktree JSONL path when
  sync-branch configured, with safeguards for test isolation
- sync_branch.go: Remove incomplete skip-worktree manipulation code
  that is no longer needed with this architectural fix

Data flow with sync-branch:
1. bd create -> SQLite
2. bd sync --flush-only -> worktree/.beads/issues.jsonl
3. bd sync --merge -> clean merge (main's JSONL unchanged)
4. auto-import -> SQLite updated from merged JSONL
2026-01-17 00:04:09 -08:00
Steve Yegge
24bff73c54 Merge pull request #1136 from sjsyrek/fix/hook-chaining-preserves-original-1120
fix(hooks): prevent bd hooks install --chain from destroying user's original hook
2026-01-17 00:03:46 -08:00
Nicolas Suzor
c8187137f5 fix(utils): prevent nil pointer panic in ResolvePartialID (#1132)
Add nil check at start of ResolvePartialID to return a proper error
instead of panicking when storage interface is nil.

Root cause: When bd refile (or other commands) is called with a nil
storage, calling store.SearchIssues() panics with SIGSEGV. This can
happen when routing fails to initialize storage properly.

Now returns: "cannot resolve issue ID <id>: storage is nil"

Fixes: bd-7ypor

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 00:00:56 -08:00
Steven Syrek
a5140075f1 fix(hooks): prevent bd hooks install --chain from destroying user's original hook
When bd init installs hooks with chaining, it renames the user's original
hook to .old and creates a new bd hook that chains to it. If bd doctor
later runs bd hooks install --chain, it would:

1. Not recognize the inline bd hook (from bd init) as a bd hook
2. Rename it to .old, overwriting the user's original hook
3. Install a new shim hook

This fix addresses two root causes:

1. Detection mismatch: areBdShimsInstalled() and getHookVersion() now
   recognize inline bd hooks (which have "# bd (beads)" marker) in
   addition to shim hooks (which have "# bd-shim" marker)

2. No .old protection: bd hooks install --chain now checks if .old
   already exists before renaming, preserving the user's original hook

Fixes #1120

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 08:44:30 +01:00
gastown/crew/george
aee86dfae2 fix(types): consolidate enhancement alias and fix update command
- Add "enhancement" to util.issueTypeAliases for consistency
- Make types.IssueType.Normalize() case-insensitive and include all aliases
- Fix update.go to normalize type before validation
- Remove duplicate type validation block in update.go

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 16:02:51 -08:00
beads/crew/fang
62dd5f8585 feat(hooks): add DeleteBranch for import branch cleanup
- Add DeleteBranch method to DoltStore for removing branches
- Update hookPostMergeDolt to clean up import branches after merge
- Completes hq-ew1mbr.9 git hook infrastructure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 16:00:06 -08:00
beads/crew/wolf
13af11768f feat(bd): add 'bd types' command to list valid issue types
Lists all valid issue types with descriptions, organized by category:
- Work types (task, bug, feature, chore, epic)
- System types (molecule, gate, convoy, merge-request, slot)
- Agent types (agent, role, rig, event, message)

Supports --json output for scripting.

Closes: bd-9ilm5

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 15:57:18 -08:00