Epics now require a "Working Model" section in their description,
in addition to "Success Criteria". This provides clear guidance on
HOW the epic will be executed:
- Owner role: Coordinator vs Implementer
- Delegation target: Polecats, crew, external
- Review process: Approval gates
Closes gt-0lp
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The doltTransaction.CreateIssue method was missing ID generation logic
that exists in the SQLite transaction implementation. When issues were
created within a transaction with empty IDs (like during wisp creation),
they would all get empty string "" as the primary key, causing
"duplicate primary key given: []" errors.
This fix adds the same ID generation logic from SQLite transaction:
- Get config prefix from database
- Apply IDPrefix/PrefixOverride to determine effective prefix
- Generate hash-based ID using generateIssueID
Fixes wisp creation failures across all rigs running Dolt server mode.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add GetDependencyRecordsForIssues method to storage interface that
fetches dependencies only for specified issue IDs instead of all
dependencies in the database.
This optimizes bd list --json which previously called
GetAllDependencyRecords() even when displaying only a few issues
(e.g., bd list --limit 10).
- Add GetDependencyRecordsForIssues to Storage interface
- Implement in SQLite, Dolt, and Memory backends
- Update list.go JSON output to use targeted method
- Update mock storage in tests
Origin: Mayor's review of PR #1296
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(import): support custom issue types during import
Fixes regression from 7cf67153 where custom issue types (agent, molecule,
convoy, etc.) were rejected during import with "invalid issue type" error.
- Add validateFieldUpdateWithCustom() for both custom statuses and types
- Add validateIssueTypeWithCustom() for custom type validation
- Update queries.go UpdateIssue() to fetch and validate custom types
- Update transaction.go UpdateIssue() to fetch and validate custom types
- Add 15 test cases covering custom type validation scenarios
This aligns UpdateIssue() validation with the federation trust model used
by ValidateForImport().
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix(test): add metadata.json and chdir to temp dir in direct mode tests
Fixes three test failures caused by commit e82f5136 which changed
ensureStoreActive() to use factory.NewFromConfig() instead of respecting
the global dbPath variable.
Root cause:
- Tests create issues in test.db and set dbPath = testDBPath
- ensureStoreActive() calls factory.NewFromConfig() which reads metadata.json
- Without metadata.json, it defaults to beads.db
- Opens empty beads.db instead of test.db with the seeded issues
- Additionally, FindBeadsDir() was finding the real .beads dir, not the test one
Fixes applied:
1. TestFallbackToDirectModeEnablesFlush: Add metadata.json pointing to test.db and chdir to temp dir
2. TestImportFromJSONLInlineAfterDaemonDisconnect: Same fix
3. TestIsBeadsPluginInstalledProjectLevel: Set temp HOME to avoid detecting plugin from real ~/.claude/settings.json
All three tests now pass.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
The Dolt stats subdatabase at .dolt/stats/.dolt/noms/LOCK was causing
"cannot update manifest: database is read only" errors after crashes.
Changes:
- cleanupStaleDoltLock now also cleans stats and oldgen subdatabase LOCKs
- Add dolt_stats_stop() call to fully stop stats background worker
- Set dolt_stats_auto_refresh_interval=0 to prevent stats restart
Fixes bd-dolt.1
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: mayor
Role: mayor
Add stale_closed_issues_days config option to metadata.json:
- 0 (default): Check disabled - repos keep unlimited beads
- >0: Enable check with specified day threshold
Design philosophy: Time-based cleanup is a crude proxy for the real
concern (database size). Disabled by default since a repo with 100
closed issues from 5 years ago doesn't need cleanup.
Also adds a warning when check is disabled but database has >10,000
closed issues, recommending users enable the threshold.
Co-Authored-By: SageOx <ox@sageox.ai>
Executed-By: beads/crew/emma
Rig: beads
Role: crew
Port the adaptive ID length algorithm from SQLite to Dolt backend.
The ID length now scales from 3-8 characters based on database size
using birthday paradox collision probability calculations.
- Add adaptive_length.go with length computation based on issue count
- Update generateIssueID to use adaptive length with nonce fallback
- Add collision detection and retry logic matching SQLite behavior
Fixes bd-c40999
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: mayor
Role: mayor
Add complete documentation for Dolt backend covering:
- Migration from SQLite to Dolt
- Contributor onboarding (bootstrap on clone)
- Troubleshooting common issues
- Recovery procedures
- Server mode setup and management
- Git hooks integration
- Configuration reference
Also improve server mode error handling to suggest gt dolt start
when connection is refused.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When the Dolt database connection is temporarily unavailable (e.g.,
stale connection, server restart), GetCustomTypes() and GetCustomStatuses()
now fall back to reading from config.yaml instead of failing.
This matches the SQLite storage behavior and fixes the stop hook
failure where `gt costs record` would fail with "invalid issue type: event"
when the Dolt connection was broken.
The fallback is checked in two cases:
1. When database query returns an error
2. When database has no custom types/statuses configured
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Daemon now refuses to start when dolt backend is configured
(dolt uses sql-server mode, not the SQLite daemon)
- Add same-directory check in GetRoutedStorageWithOpener to avoid
opening duplicate connections when routing resolves to current dir
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add extensive test coverage for the Dolt storage implementation:
- dependencies_extended_test.go: Extended dependency operation tests
- dolt_benchmark_test.go: Performance benchmarks for Dolt operations
- history_test.go: Version history query tests
- labels_test.go: Label operation tests
These tests validate Dolt backend correctness and provide performance
baselines for comparison with SQLite.
Co-authored-by: upstream_syncer <matthew.baker@pihealth.ai>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Refactors UpdateIssue, CloseIssue, CreateTombstone, and DeleteIssues
to use the withTx helper with BEGIN IMMEDIATE instead of BeginTx.
This completes the GH#1272 fix by ensuring all write transactions
acquire write locks early, preventing deadlocks.
Changes:
- UpdateIssue: now uses withTx and markDirty helper
- CloseIssue: now uses withTx and markDirty helper
- CreateTombstone: now uses withTx and markDirty helper
- DeleteIssues: now uses withTx with dbExecutor interface
- Helper functions (resolveDeleteSet, expandWithDependents,
validateNoDependents, etc.) changed from *sql.Tx to dbExecutor
This is a P3 follow-up to the P1 sqlite lock fix (PR #1274).
Closes: bd-fgzp
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
The daemon server's handleList was returning dependency counts but not
the actual dependency records. This complements PR #1296 which fixed
the direct CLI path.
Code paths now fixed:
- Direct (--no-daemon): cmd/bd/list.go (PR #1296)
- Daemon (default): internal/rpc/server_issues_epics.go (this PR)
Fixes bd-d240
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(gate): use GateWait RPC for add-waiter command
bd gate add-waiter was calling Update RPC which rejects waiters
field (not in allowedUpdateFields). Changed to use existing GateWait
RPC that handles waiters correctly.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(storage): allow waiters field in UpdateIssue
Add waiters to allowedUpdateFields whitelist and handle JSON
serialization for the array field. This enables bd gate add-waiter
to work in direct mode (--no-daemon).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(storage/dolt): allow waiters field in UpdateIssue
Mirror the SQLite fix: add waiters to allowed fields and handle JSON
serialization for the array field.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Child issues created with --parent were missing from export_hashes table,
which affects integrity tracking and future incremental export features.
This fix ensures SetExportHash() is called for all exported issues:
- Updated ExportResult to include IssueContentHashes map
- Updated finalizeExport() to call SetExportHash() for each exported issue
- Updated exportToJSONLDeferred() to collect content hashes during export
- Updated performIncrementalExport() to collect content hashes for dirty issues
- Updated exportToJSONLWithStore() to call SetExportHash() after export
- Updated daemon's handleExport() to call SetExportHash() after export
Added test TestExportPopulatesExportHashes to verify the fix works for
both regular and hierarchical (child) issue IDs.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
The handleRename function was being called with the raw storage.Storage
interface inside upsertIssuesTx, which runs within a transaction. When
handleRename called store.DeleteIssue() or store.CreateIssue(), these
methods attempted to start new transactions via withTx/BEGIN IMMEDIATE,
causing a deadlock since SQLite cannot nest BEGIN IMMEDIATE transactions.
This fix:
- Adds handleRenameTx that accepts storage.Transaction and uses tx methods
- Updates the call site in upsertIssuesTx to use handleRenameTx(ctx, tx, ...)
The non-transactional upsertIssues continues to use handleRename for
backends that don't support transactions.
Fixes nested transaction deadlock during bd sync when issue renames occur.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
- FindDatabasePath now handles Dolt server mode (no local dir required)
- main.go uses NewFromConfigWithOptions for Dolt to read server settings
- Routing uses factory via callback to respect backend configuration
- Handle Dolt "database exists" error (error 1007) gracefully
Previously, Dolt server mode failed because:
1. FindDatabasePath required a local directory to exist
2. main.go bypassed server mode config when creating Dolt storage
3. Routing always opened SQLite regardless of backend config
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add dolt_mode, dolt_server_host, dolt_server_port fields to configfile.Config
- Add IsDoltServerMode(), GetDoltServerHost(), GetDoltServerPort() helpers
- Update factory to read server mode config and set Options accordingly
- Skip bootstrap in server mode (database lives on server)
- Pass Database name to dolt.Config for USE statement after connecting
- Disable dolt stats collection to avoid lock issues in embedded mode
This enables bd to connect to a running dolt sql-server (started via
'gt dolt start') instead of using embedded mode, allowing multi-client
access without file locking conflicts.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Skip Bootstrap when ServerMode is true (bootstrap is for embedded cold-start)
- Fix doltExists() to follow symlinks using os.Stat
- Pass database name from metadata.json to DoltStore config
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Code review fix: In server mode, Dolt connects to an external sql-server
and should NOT be single-process-only. The whole point of server mode is
to enable multi-writer access.
Changes:
- Add Config.GetCapabilities() method that considers server mode
- Update daemon_guard, daemon_autostart, daemons, main to use GetCapabilities()
- Add TestGetCapabilities test
- Update init command help text to document server mode flags
The existing CapabilitiesForBackend(string) is kept for backward compatibility
but now includes a note to use Config.GetCapabilities() when the full config
is available.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Dolt server mode configuration to metadata.json for multi-writer access:
- Add DoltMode, DoltServerHost, DoltServerPort, DoltServerUser fields to Config
- Add helper methods with sensible defaults (127.0.0.1:3306, root user)
- Update factory to read server mode config and pass to dolt.Config
- Add --server, --server-host, --server-port, --server-user flags to bd init
- Validate that --server requires --backend dolt
- Add comprehensive tests for server mode configuration
Example metadata.json for server mode:
{
"backend": "dolt",
"database": "dolt",
"dolt_mode": "server",
"dolt_server_host": "192.168.1.100",
"dolt_server_port": 3306,
"dolt_server_user": "beads"
}
Password should be set via BEADS_DOLT_PASSWORD env var for security.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds Dolt auto-commit functionality for write commands and sets explicit commit authors.
Includes fix for race condition in commandDidWrite (converted to atomic.Bool).
Original PR: #1267 by @coffeegoddd
Co-authored-by: Dustin Brown <dustin@dolthub.com>
The original PR added retry logic on top of BEGIN IMMEDIATE, but this caused
multi-minute hangs because:
1. Connection has busy_timeout=30s set via pragma
2. Each BEGIN IMMEDIATE waits up to 30s before returning SQLITE_BUSY
3. With 5 retries, worst case was 5 × 30s = 150+ seconds
The fix removes the retry loop since SQLite's busy_timeout already handles
retries internally. BEGIN IMMEDIATE still acquires the write lock early,
preventing deadlocks - we just let busy_timeout handle contention.
Root cause analysis in bd-9ldm.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update withTx to use BEGIN IMMEDIATE with exponential backoff retry
on SQLITE_BUSY errors. This prevents "database is locked" failures
during concurrent operations (daemon + CLI, multi-agent workflows).
Changes:
- withTx now uses beginImmediateWithRetry (same pattern as RunInTransaction)
- Add dbExecutor interface for helper functions that work with both
*sql.Tx and *sql.Conn
- Update all withTx callers to use *sql.Conn
- Refactor DeleteIssue to use withTx (fixes the specific error in auto-import)
- Update markIssuesDirtyTx to accept dbExecutor interface
Affected paths:
- MarkIssuesDirty, ClearDirtyIssuesByID (dirty.go)
- AddDependency, RemoveDependency (dependencies.go)
- executeLabelOperation (labels.go)
- AddComment (events.go)
- ApplyCompaction (compact.go)
- DeleteIssue (queries.go)
Note: Some direct BeginTx calls in queries.go (CloseIssue, UpdateIssue,
ReopenIssue, DeleteIssues) still use the old pattern and could be
refactored in a follow-up.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds operational improvements to the Dolt storage backend for increased
reliability in production environments with concurrent clients:
1. Lock retry with exponential backoff:
- Add LockRetries and LockRetryDelay config options
- Automatic retry on lock contention (default: 30 retries, ~6s window)
- Exponential backoff starting at 100ms
- Handles transient format version errors during manifest updates
2. Stale lock file cleanup:
- Detect and clean orphaned .dolt/noms/LOCK files on startup
- Prevents "database is read only" errors after crashes
- Only removes empty locks older than 5 seconds
3. Transient error detection:
- isTransientDoltError() detects retryable conditions
- isLockError() identifies lock contention scenarios
- cleanupStaleDoltLock() safely removes orphaned locks
These improvements address common issues in multi-process environments
where the Dolt embedded driver creates exclusive locks that persist
after unexpected termination.
Co-authored-by: upstream_syncer <matthew.baker@pihealth.ai>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
When creating issues with explicit IDs via PrefixOverride (for cross-rig
creation), the storage layer was still validating against the local
config prefix, causing errors like:
issue ID 'da-DataArchive-witness' does not match configured prefix 'hq'
The queries.go layer already handled PrefixOverride correctly, but
transaction.go did not. This fix adds the same PrefixOverride handling
to transaction.go:
1. Check if PrefixOverride is set
2. If set, use it as the prefix and skip validation (caller knows best)
3. Otherwise, fall back to existing IDPrefix/configPrefix logic
This allows gt doctor --fix to create agent beads for non-local rigs.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
fix(daemon): prevent zombie state after database file replacement
Adds checkFreshness() to health check paths (GetMetadata, GetConfig, GetAllConfig) and refactors reconnect() to validate new connection before closing old.
PR-URL: https://github.com/steveyegge/beads/pull/1213
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix(autoimport): auto-correct deleted status to tombstone for JSONL compatibility (GH#1223)
This fix addresses the 'Stuck in sync diversion loop' issue where v0.48.0
encountered validation errors during JSONL import. The issue occurs when
JSONL files from older versions have issues with status='deleted' but the
current code expects status='tombstone' for deleted issues.
Changes:
- Add migration logic in parseJSONL to auto-correct 'deleted' status to 'tombstone'
- Ensure tombstones always have deleted_at timestamp set
- Add debug logging for both migration operations
- Prevents users from being stuck in sync divergence when upgrading
Fixes GH#1223: Stuck in sync diversion loop
* fix(autoimport): comprehensively fix corrupted deleted_at on non-tombstone issues (GH#1223)
The initial fix for GH#1223 only caught issues with status='deleted', but the real
data in the wild had issues with status='closed' (or other statuses) but also
had deleted_at set, which violates the validation rule.
Changes:
- Add broader migration logic: any non-tombstone issue with deleted_at should become tombstone
- Apply fix in all three JSONL parsing locations:
- internal/autoimport/autoimport.go (parseJSONL for auto-import)
- cmd/bd/import.go (import command)
- cmd/bd/daemon_sync.go (daemon sync helper)
- Add comprehensive test case for corrupted closed issues with deleted_at
- Fixes the 'non-tombstone issues cannot have deleted_at timestamp' validation error
during fresh bd init or import
Fixes GH#1223: Stuck in sync diversion loop
* Add merge driver comment to .gitattributes
* fix: properly clean up .gitattributes during bd admin reset
Fixes GH#1223 - Stuck in sync diversion loop
The removeGitattributesEntry() function was not properly cleaning up
beads-related entries from .gitattributes. It only removed lines
containing "merge=beads" but left behind:
- The comment line "# Use bd merge for beads JSONL files"
- Empty lines following removed entries
This caused .gitattributes to remain in a modified state after
bd admin reset --force, triggering sync divergence warning loop.
The fix now:
- Skips lines containing "merge=beads" (existing behavior)
- Skips beads-related comment lines
- Skips empty lines that follow removed beads entries
- Properly cleans up file so it's either empty (and gets deleted)
or contains only non-beads content
---------
Co-authored-by: Amp <amp@example.com>
The Dolt storage was scanning created_at and updated_at directly into
time.Time fields, but SQLite stores these as TEXT strings. The Go SQLite
driver cannot automatically convert TEXT to time.Time.
Added parseTimeString() helper and fixed all scan functions:
- issues.go: scanIssue()
- dependencies.go: scanIssueRow()
- history.go: GetIssueHistory(), GetIssueAsOf()
- transaction.go: scanIssueTx()
Fixes bd-4dqmy
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move LocalProvider from cmd/bd/doctor/git.go to internal/storage/local_provider.go
where it belongs alongside StorageProvider. Both implement IssueProvider for
orphan detection - LocalProvider for direct SQLite access (--db flag),
StorageProvider for the global Storage interface.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(orphans): honor --db flag for cross-repo orphan detection
Problem:
- `bd orphans --db /path` ignored the --db flag entirely
- FindOrphanedIssues() hardcoded local .beads/ directory
Solution:
- Introduce IssueProvider interface for abstract issue lookup
- Add StorageProvider adapter wrapping Storage instances
- Update FindOrphanedIssues to accept provider instead of path
- Wire orphans command to create provider from --db flag
Closes: steveyegge/beads#1196
* test(orphans): add cross-repo and provider tests for --db flag fix
- Add TestFindOrphanedIssues_WithMockProvider (table-driven, UT-01 through UT-09)
- Add TestFindOrphanedIssues_CrossRepo (validates --db flag honored)
- Add TestFindOrphanedIssues_LocalProvider (backward compat RT-01)
- Add TestFindOrphanedIssues_ProviderError (error handling UT-07)
- Add TestFindOrphanedIssues_IntegrationCrossRepo (IT-02 full)
- Add TestLocalProvider_* unit tests
Coverage for IssueProvider interface and cross-repo orphan detection.
* docs: add bd orphans command to CLI reference
Document the orphan detection command including the cross-repo
workflow enabled by the --db flag fix in this PR.
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>
* fix(ready): exclude molecule steps from bd ready by default (GH#1239)
Add ID prefix constants (IDPrefixMol, IDPrefixWisp) to types.go as single
source of truth. Update pour.go and wisp.go to use these constants.
GetReadyWork now excludes issues with -mol- in their ID when no explicit
type filter is specified. Users can still see mol steps with --type=task.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(ready): config-driven ID pattern exclusion (GH#1239)
Add ready.exclude_id_patterns config for excluding IDs from bd ready.
Default patterns: -mol-, -wisp- (molecule steps and wisps).
Changes:
- Add IncludeMolSteps to WorkFilter for internal callers
- Update findGateReadyMolecules and getMoleculeCurrentStep to use it
- Make exclusion patterns config-driven via ready.exclude_id_patterns
- Remove hardcoded MolStepIDPattern() in favor of config
- Add test for custom patterns (e.g., gastown's -role-)
Usage: bd config set ready.exclude_id_patterns "-mol-,-wisp-,-role-"
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: remove -role- example from ready.go comments
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: remove GH#1239 references from code comments
Issue references belong in commit messages, not code.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Add integration tests for the Gas Town hub+spokes topology where:
- Hub (mayor rig) runs dolt sql-server with remotesapi
- Spokes (crew clones) configure hub as their only peer
- Data flows through hub in star topology
Tests included:
- TestHubSpokes_MultiCloneSync: Basic two-spoke convergence
- TestHubSpokes_WorkDispatch: Hub dispatches work, spokes complete it
- TestHubSpokes_ThreeSpokesConverge: Three-spoke convergence test
Note: These tests follow the same pattern as peer_sync_integration_test.go
and document current behavior including the no common ancestor limitation
that affects cross-database sync.
Closes bd-phwci
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes stack overflow and database initialization failures when running bd on WSL2 with Docker Desktop bind mounts.
## Problem
The bd CLI crashed with stack overflow when running on WSL2 with repositories on Docker Desktop bind mounts (/mnt/wsl/docker-desktop-bind-mounts/...). SQLite WAL mode fails with 'locking protocol' error on these network filesystems.
## Solution
- Expand WAL mode detection to identify Docker bind mounts at /mnt/wsl/* (in addition to Windows paths at /mnt/[a-zA-Z]/)
- Fall back to DELETE journal mode on these problematic paths
- Add comprehensive unit tests for path detection
Fixes GH #1224, relates to GH #920
Co-authored-by: maphew <matt.wilkie@gmail.com>
Remove Gas Town-specific type constants (TypeMolecule, TypeGate, TypeConvoy,
TypeMergeRequest, TypeSlot, TypeAgent, TypeRole, TypeRig, TypeEvent, TypeMessage)
from internal/types/types.go.
Beads now only has core work types built-in:
- bug, feature, task, epic, chore
All Gas Town types are now purely custom types with no special handling in beads.
Use string literals like "gate" or "molecule" when needed, and configure
types.custom in config.yaml for validation.
Changes:
- Remove Gas Town type constants from types.go
- Remove mr/mol aliases from Normalize()
- Update bd types command to only show core types
- Replace all constant usages with string literals throughout codebase
- Update tests to use string literals
This decouples beads from Gas Town, making it a generic issue tracker.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Improve the federation status command to show more comprehensive
information similar to `git remote -v` with health info:
- Show peer URLs alongside peer names
- Display pending local changes count (uncommitted)
- Test connectivity to each peer (via fetch)
- Track and display last sync time in metadata table
- Show reachability status with error messages on failure
Changes:
- cmd/bd/federation.go: Enhanced status output with URLs, connectivity
checks, pending changes, and last sync time
- internal/storage/dolt/federation.go: Added getLastSyncTime/setLastSyncTime
methods using metadata table, record sync time on successful sync
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>
Merge SQL user authentication with Emma federation sync implementation:
- Add federation_peers table for encrypted credential storage
- Add credentials.go with AES-256-GCM encryption, SHA-256 key derivation
- Extend FederatedStorage interface with credential methods
- Add --user, --password, --sovereignty flags to bd federation add-peer
- Integrate credentials into PushTo/PullFrom/Fetch via withPeerCredentials
- DOLT_REMOTE_USER/PASSWORD env vars protected by mutex for concurrency
Credentials automatically used when syncing with peers that have stored auth.
Continues: bd-wkumz.10, Closes: bd-4p67y
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add --federation-port and --remotesapi-port flags (default 3306/8080)
- Fix log file leak in server.go - track and close on Stop()
- Add BEADS_DOLT_PASSWORD env var for server mode authentication
- Update DSN to include password when set
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>