Implements configurable per-field merge strategies (hq-ew1mbr.11):
- Add FieldStrategy type with strategies: newest, max, union, manual
- Add conflict.fields config section for per-field overrides
- compaction_level defaults to "max" (highest value wins)
- estimated_minutes defaults to "manual" (flags for user resolution)
- labels defaults to "union" (set merge)
Manual conflicts are displayed during sync with resolution options:
bd sync --ours / --theirs, or bd resolve <id> <field> <value>
Config example:
conflict:
strategy: newest
fields:
compaction_level: max
estimated_minutes: manual
labels: union
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
During bd init, auto-import fails with "invalid issue type" errors even
when types.custom is defined in config.yaml. This happens because custom
types are read from the database, but the database is being created
during init and doesn't have the config set yet.
Changes:
- Add GetCustomTypesFromYAML() to internal/config/config.go to read
types.custom from config.yaml via viper
- Modify GetCustomTypes() in sqlite/config.go to fallback to config.yaml
when the database doesn't have types.custom configured
- Add tests for GetCustomTypesFromYAML()
This allows fresh clones with custom types defined in config.yaml (e.g.,
Gas Town types like molecule, gate, convoy, agent, event) to successfully
auto-import their JSONL during bd init.
Fixes GH#1225
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Change routing.mode default from "auto" to "" (empty/disabled).
This fixes GH#1165 where fresh `bd init --prefix X` followed by
`bd create` would unexpectedly route to ~/.beads-planning and fail
with "database not initialized: issue_prefix config is missing".
Auto-routing now requires explicit opt-in via:
- `bd init --contributor` flag, OR
- `bd config set routing.mode auto`
Includes test verifying the default and doc updates clarifying
the opt-in requirement.
Code review improvements to internal/config/sync.go:
1. Warning suppression toggle
- Add ConfigWarnings bool to enable/disable warnings
- Add ConfigWarningWriter io.Writer for testable output
2. Consolidate sync mode constants
- cmd/bd/sync_mode.go now imports from internal/config
- Single source of truth for mode values
- Uses shared IsValidSyncMode() for validation
3. Fix empty sovereignty semantics
- Empty now returns SovereigntyNone (no restriction)
- Only non-empty invalid values fall back to T1 with warning
4. Export validation helpers
- IsValidSyncMode(), IsValidConflictStrategy(), IsValidSovereignty()
- ValidSyncModes(), ValidConflictStrategies(), ValidSovereigntyTiers()
- String() methods on all typed values
5. Logger interface
- ConfigWarningWriter allows custom logging destinations
- Tests can capture warnings without os.Stderr manipulation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(config): remove duplicate declarations between config.go and sync.go
Commit e82e15a8 created sync.go with typed constants (SyncMode,
ConflictStrategy, Sovereignty) but didn't remove the original untyped
constants from config.go that were added in 16f8c3d3. This caused
redeclaration errors preventing the project from building.
Changes:
- Remove duplicate SyncMode, ConflictStrategy, Sovereignty constants
from config.go (keep typed versions in sync.go)
- Remove duplicate GetSyncMode, GetConflictStrategy, GetSovereignty
functions from config.go (keep sync.go versions with warnings)
- Update SyncConfig, ConflictConfig, FederationConfig structs to use
typed fields instead of string
- Add IsSyncModeValid, IsConflictStrategyValid, IsSovereigntyValid
wrapper functions that use sync.go's validation maps
- Update cmd/bd/sync.go to use typed ConflictStrategy parameter
- Update tests to work with typed constants
* fix(dolt): handle Merge return values in concurrent test
* fix(test): add --repo flag to show_test.go to bypass auto-routing
The tests were failing because the create command was routing issues
to ~/.beads-planning instead of the test's temp directory. Adding
--repo . overrides auto-routing and creates issues in the test dir.
Centralizes repository context resolution via RepoContext API, fixing bugs where git commands run in the wrong repo when BEADS_DIR points elsewhere or in worktree scenarios.
Add .beads/config.yaml support for template validation settings:
- validation.on-create: warn|error|none (default: none)
- validation.on-sync: warn|error|none (default: none)
When set to "warn", issues missing required sections (based on type) show
warnings but operations proceed. When set to "error", operations fail.
Implementation:
- Add validation keys to YamlOnlyKeys in yaml_config.go
- Add defaults in config.go
- Wire up bd create to check validation.on-create config
- Wire up bd sync to run validation before export
- Add tests for config loading
- Update CONFIG.md documentation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tests were failing when BD_ACTOR or other BD_/BEADS_ environment
variables were set. Added envSnapshot helper to save, clear, and
restore environment variables for proper test isolation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Config (bd-66w1):
- Add external_projects config for mapping project names to paths
- Add GetExternalProjects() and ResolveExternalProjectPath() functions
- Add config documentation and tests
External deps (bd-om4a):
- bd dep add accepts external:project:capability syntax
- External refs stored as-is in dependencies table
- GetBlockedIssues includes external deps in blocked_by list
- blocked_issues_cache includes external dependencies
- Add validation and parsing helpers for external refs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add `bd mail send/inbox/read/ack` commands for inter-agent messaging
- Implement GetIdentity() with priority chain: flag > BEADS_IDENTITY env > config.yaml > git user.name > hostname
- Messages are stored as issues with type=message for git-native communication
- Support both daemon and direct mode for all mail operations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replaces manual working directory save/restore patterns
with Go's built-in `t.Chdir()` helper across 23 test files.
The manual pattern involved calling `os.Getwd()` to save
the original directory, using `defer os.Chdir(origWd)` for
restoration, and manually handling errors during directory
changes. This boilerplate has been replaced with single
`t.Chdir(path)` calls that handle cleanup automatically.
The `t.Chdir()` method automatically restores the working
directory when the test completes, eliminating the need for
manual defer statements and error handling.
Total:
~75 instances replaced (assuming Claude's math is right)
Co-authored-by: Claude <noreply@anthropic.com>
- config: Add tests for GetStringSlice, GetMultiRepoConfig, and nil viper
behavior. Coverage improved from 65.3% to 84.0%.
- git: Add tests for error paths in RemoveBeadsWorktree, SyncJSONLToWorktree,
CheckWorktreeHealth, and sparse checkout functions. Coverage improved
from 72.9% to 82.7%.
Closes: bd-t3b, bd-4h3, bd-ge7
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Changed file permissions from 0644 → 0600 for JSONL exports and config files
- Changed directory permissions from 0755 → 0750 in all test code
- Updated .golangci.yml with proper exclusions for false positives
- Reduced gosec warnings from 102 to 22 (all remaining are acceptable)
Closes bd-57
Amp-Thread-ID: https://ampcode.com/threads/T-f754d957-9e42-4e74-861e-57235c7e6436
Co-authored-by: Amp <amp@ampcode.com>