Commit Graph

482 Commits

Author SHA1 Message Date
Eduardo Koloma Jr
8fab565f35 fix(gate): ensure add-waiter command functions (#1265)
* 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>
2026-01-24 17:10:12 -08:00
beads/crew/emma
e82f5136c1 fix(dolt): proper server mode support for routing and storage
- 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>
2026-01-24 00:26:58 -08:00
mayor
13c362e67e feat(dolt): add server mode support for multi-client access
- 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>
2026-01-23 22:35:34 -08:00
beads/crew/emma
db0c6fbd3f fix(dolt): enable server mode for Gas Town integration (bd-nnjik)
- 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>
2026-01-23 22:24:55 -08:00
emma
484cd9d5fd feat(dolt): add server mode config to metadata.json schema (bd-dolt.2.2)
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>
2026-01-23 20:01:46 -08:00
Steve Yegge
cec1356995 Merge pull request #1274 from aleiby/fix/1272-sqlite-retry-logic
fix(sqlite): add retry logic to transaction entry points
2026-01-22 21:05:37 -08:00
Steve Yegge
ab61b0956b feat(dolt): auto-commit write commands and set explicit commit authors (#1270)
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>
2026-01-22 20:52:20 -08:00
ruby
35bd93b443 fix(sqlite): use BEGIN IMMEDIATE without retry loop (GH#1272)
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>
2026-01-22 20:27:54 -08:00
ruby
718fc49776 fix(sqlite): add retry logic to transaction entry points (GH#1272)
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>
2026-01-22 18:30:48 -08:00
groblegark
d037158624 fix(dolt): add lock retry and stale lock cleanup for operational reliability (#1260)
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>
2026-01-22 13:04:56 -08:00
justSteve
244b32b624 Fix PrefixOverride not respected in transaction storage layer (#1257)
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>
2026-01-22 13:04:52 -08:00
Roland Tritsch
5264d7aa60 fix(daemon): prevent zombie state after database file replacement (#1213)
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>
2026-01-21 22:46:59 -08:00
beads/crew/lydia
2cc96197c0 fix(dolt): parse timestamps from TEXT columns instead of direct time.Time scan
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>
2026-01-21 20:48:47 -08:00
beads/crew/jane
2a56aab92c refactor(storage): move LocalProvider to internal/storage package
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>
2026-01-21 20:41:53 -08:00
Peter Chanthamynavong
c11fa799be fix(orphans): honor --db flag for cross-repo orphan detection (#1200)
* 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.
2026-01-21 19:52:31 -08:00
aleiby
0b6df198a5 fix(ready): exclude molecule steps from bd ready by default (#1246)
* 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>
2026-01-21 19:30:15 -08:00
beads/crew/emma
de73002c03 test(dolt): add hub+spokes multi-clone integration tests
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>
2026-01-21 19:21:38 -08:00
matt wilkie
ef162a954a fix(GH#1224): detect Docker Desktop bind mounts in WSL2 and disable WAL mode
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>
2026-01-21 16:53:49 -08:00
Steve Yegge
caf4c368c4 Merge pull request #1240 from coffeegoddd/db/import-export
Enable full-fidelity JSONL import/export for Dolt backend
2026-01-21 16:40:03 -08:00
Test
7670112341 /internal/storage/dolt: fix windows build issue 2026-01-21 13:59:47 -08:00
Test
b849f598d7 /{cmd,docs,internal}: support import export for dolt backends 2026-01-21 13:13:24 -08:00
collins
7cf67153de refactor(types): remove Gas Town type constants from beads core (bd-w2zz4)
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>
2026-01-21 10:36:59 -08:00
emma
cff58c4639 feat(dolt): add peer-to-peer federation integration tests (bd-wkumz.9)
Add MergeAllowUnrelated for initial federation sync between
independently initialized towns.

Integration tests cover:
- Two-server push/pull operations
- Conflict resolution strategies
- Work handoff between towns
- Reputation tracking

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 23:14:58 -08:00
beads/crew/collins
c3f68caf7a feat(federation): enhance bd federation status command (bd-wkumz.5)
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>
2026-01-20 23:12:33 -08:00
Steve Brown
b7242a67d1 fix: load types.custom from config.yaml during init auto-import (GH#1225) (#1226)
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>
2026-01-20 22:34:22 -08:00
beads/crew/jane
d3d2326a8b feat(federation): add SQL user authentication for peer sync
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>
2026-01-20 21:15:11 -08:00
beads/crew/darcy
ea51c4b0bd fix(federation): add configurable ports, password support, fix log leak
- 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>
2026-01-20 20:55:27 -08:00
beads/crew/darcy
da4584ae57 feat(federation): add dolt sql-server mode for daemon (bd-wkumz.2)
Add --federation flag to bd daemon start that runs dolt sql-server
instead of the embedded driver. Enables multi-writer support and
exposes remotesapi on port 8080 for peer-to-peer push/pull.

Changes:
- Add --federation flag to daemon start command
- Create dolt server manager (internal/storage/dolt/server.go)
- Update DoltStore to support server mode via MySQL protocol
- Integrate server lifecycle into daemon (auto-start/stop)
- Add tests for server management and server mode connections

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 20:48:24 -08:00
beads/crew/collins
458fb7197a fix(sqlite): handle text timestamps in scan for cross-driver compatibility
The ncruces/go-sqlite3 driver does not always auto-convert TEXT columns
to time.Time. This caused scan errors on updated_at/created_at fields,
blocking witness startup.

Fix: Scan timestamps into sql.NullString and parse with parseTimeString()
helper that handles RFC3339Nano, RFC3339, and SQLite native formats.

Fixes: bd-4dqmy

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 20:48:08 -08:00
beads/crew/wickham
90344b9939 feat(dolt): bootstrap routes.jsonl and interactions.jsonl (bd-lbdy7)
Add support for importing routes.jsonl and interactions.jsonl during
Dolt bootstrap. Previously only issues.jsonl was imported.

Changes:
- Add routes and interactions tables to Dolt schema
- Import routes before issues (no dependencies)
- Import interactions after issues (may reference issue_id)
- Reuse audit.Entry type instead of duplicating
- Add tests for multi-file bootstrap

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 20:47:59 -08:00
beads/crew/lizzy
938a17cda5 feat(dolt): add GetChangesSinceExport and CommitExists methods (bd-ejv83)
Add versioned storage methods for incremental export support:
- GetChangesSinceExport: returns changes since a commit hash, with
  NeedsFullExport flag for invalid/GC'd commits
- CommitExists: checks if a commit hash exists, supports short prefixes

Also fixes dolt_diff syntax for embedded driver (from_ref, to_ref, table).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 20:47:48 -08:00
beads/crew/emma
6190dd9362 feat(federation): implement bd federation sync command
Add peer-to-peer synchronization for Dolt-backed beads databases:

- New FederatedStorage interface with PushTo, PullFrom, Fetch, ListRemotes,
  RemoveRemote, and SyncStatus methods
- DoltStore implementation using DOLT_PUSH, DOLT_PULL, DOLT_FETCH
- Full bd federation command with subcommands:
  - sync: bidirectional sync with conflict resolution (--strategy ours|theirs)
  - status: show ahead/behind counts and conflict state
  - add-peer/remove-peer/list-peers: manage federation remotes
- Comprehensive tests for all federation APIs

Closes: bd-wkumz.4

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 20:47:18 -08:00
beads/crew/emma
4f3c3febd5 feat(dolt): add federation prototype tests
Add integration tests validating Dolt APIs needed for peer-to-peer
federation between Gas Towns:

- TestFederationDatabaseIsolation: verify separate towns have isolated DBs
- TestFederationVersionControlAPIs: branch, checkout, merge, commit
- TestFederationRemoteConfiguration: AddRemote accepts dolthub:// URLs
- TestFederationHistoryQueries: commit history, dolt_log, AS OF

Key finding: Production federation uses dolt sql-server remotesapi
(port 8080) for direct peer-to-peer push/pull - no DoltHub required.

Also fixes concurrent_test.go Merge() return value handling.

Refs: bd-wkumz (Federation epic), hq-ew1mbr.7 (prototype task)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 18:40:54 -08:00
Dustin Brown
d3ccd5cfba Fix Dolt backend init/daemon/doctor; prevent accidental SQLite artifacts; add integration tests; clean up lint (#1218)
* /{cmd,internal}: get dolt backend init working and allow issue creation

* /{website,internal,docs,cmd}: integration tests and more split backend fixes

* /{cmd,internal}: fix lint issues

* /cmd/bd/doctor/integrity.go: fix unable to query issues bug with dolt backend

* /cmd/bd/daemon.go: remove debug logging
2026-01-20 17:34:00 -08:00
Steven Syrek
82426423fe fix(sqlite): Add missing rows.Err() checks after row iteration (#1141)
The scanIssues and scanIssuesWithDependencyType helper functions were
not checking rows.Err() after iterating through query results. This
could cause errors during iteration (connection drops, context
cancellation, etc.) to be silently ignored.

Per Go database/sql best practices, rows.Err() should always be checked
after a rows.Next() loop completes to catch any errors that occurred
during iteration.

Co-authored-by: Steven Syrek <steven.syrek@deepl.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 10:12:26 -08:00
Subhrajit Makur
065ca3d6af fix(config): remove duplicate declarations and fix test failures (#1160)
* 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.
2026-01-19 10:11:14 -08:00
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
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
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
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
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
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
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
gastown/crew/george
9ecdc00664 feat(types): add "enhancement" as alias for "feature" type
Support --type enhancement as an alias for --type feature when creating
issues. The normalization happens before validation to ensure consistency
across all code paths.

Closes gt-hzanoe

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 15:44:33 -08:00
quartz
99d6592207 fix(dolt): Optimize N+1 queries and add proper test timeouts
- Add batch query optimization to avoid N+1 queries in scanIssueIDs
- Create GetIssuesByIDs helper to fetch multiple issues in single query
- Add scanIssueRow helper to scan issue data from rows iterator
- Add proper timeout contexts to all Dolt tests using testContext helper

The embedded Dolt driver is slow for repeated queries. Replacing N+1
GetIssue calls with a single IN clause query fixes the 30s+ timeouts
in TestDoltStoreDependencies, TestDoltStoreSearch, and
TestDoltStoreGetReadyWork.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:50:28 -08:00
obsidian
d05f7cee8f fix(dolt): improve test reliability with timeouts and PATH detection
- Use exec.LookPath instead of hardcoded path for Dolt detection
- Add test context with timeout to prevent tests from hanging
- Document known issues with embedded Dolt driver async operations

The embedded Dolt driver can hang on complex JOIN queries. This change
ensures tests fail gracefully with timeout rather than hanging.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 12:30:26 -08:00
mayor
0c64edfc09 fix: Mark dependent issues dirty when deleting to prevent orphan deps in JSONL
When an issue is deleted, issues that depend on it were not being marked
dirty. This caused stale dependency references to persist in JSONL after
the target issue was deleted, because the dependent issues were never
re-exported.

This manifests as FK validation failures during multi-repo hydration:
"foreign key violation: issue X depends on non-existent issue Y"

The fix queries for dependent issues before deleting and marks them dirty
so they get re-exported without the stale dependency reference.

Adds test: TestDeleteIssueMarksDependentsDirty

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 12:27:36 -08:00
Bobby Johnson
55e733cf62 fix: enable building on Windows without CGO (#1117)
The dolt storage backend requires CGO due to its gozstd dependency.
This change makes the dolt backend optional using build tags, allowing
`go install` to work on Windows where CGO is disabled by default.

Changes:
- Add BackendFactory registration pattern to factory package
- Create factory_dolt.go with `//go:build cgo` constraint that
  registers the dolt backend only when CGO is available
- Update init.go to use factory instead of direct dolt import
- When dolt backend is requested without CGO, provide helpful error
  message directing users to pre-built binaries

The sqlite backend (default) works without CGO and covers the majority
of use cases. Users who need dolt can either:
1. Use pre-built binaries from GitHub releases
2. Enable CGO by installing a C compiler

Fixes #1116
2026-01-15 19:23:02 -08:00
LoomDeBWiles
c40affd601 fix(storage): normalize timestamps to UTC to prevent validation failures (#1123)
All time.Now() calls in the dolt storage layer now use time.Now().UTC()
to ensure consistent timezone handling. Previously, timestamps could be
stored with mixed timezone formats (UTC 'Z' vs local '+01:00'), causing
bv validation to fail when updated_at appeared earlier than created_at
in absolute time.

Files modified:
- transaction.go: CreateIssue, UpdateIssue, CloseIssue
- issues.go: CreateIssue, CreateIssues, UpdateIssue, CloseIssue, markDirty, manageClosedAt
- rename.go: UpdateIssueID (2 locations)
- events.go: AddIssueComment (2 locations)
- dirty.go: SetExportHash
- queries.go: Overdue filter, GetStaleIssues

Fixes: bd-84gw9

Co-authored-by: LoomDeBWiles <loomenwiles@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 19:22:50 -08:00