Commit Graph

984 Commits

Author SHA1 Message Date
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
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
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
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
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
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
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
Zain Rizvi
e723417168 Fix git hooks not working in worktrees (#1126)
Git hooks are shared across all worktrees and live in the common git
directory (e.g., /repo/.git/hooks), not the worktree-specific directory
(e.g., /repo/.git/worktrees/feature/hooks).

The core issue was in GetGitHooksDir() which used GetGitDir() instead
of GetGitCommonDir(). This caused hooks to be installed to/read from
the wrong location when running in a worktree.

Additionally, several places in the codebase manually constructed
hooks paths using gitDir + "hooks" instead of calling GetGitHooksDir().
These have been updated to use the proper worktree-aware path.

Affected areas:
- GetGitHooksDir() now uses GetGitCommonDir()
- CheckGitHooks() uses GetGitHooksDir()
- installHooks/uninstallHooks use GetGitHooksDir()
- runChainedHook() uses GetGitHooksDir()
- Doctor checks use git-common-dir for hooks paths
- Reset command uses GetGitCommonDir() for hooks and beads-worktrees

Symptoms that this fixes:
- Chained hooks (pre-commit.old) not running in worktrees
- bd hooks install not finding/installing hooks correctly in worktrees
- bd hooks list showing incorrect status in worktrees
- bd doctor reporting incorrect hooks status in worktrees

Co-authored-by: Zain Rizvi <4468967+ZainRizvi@users.noreply.github.com>
2026-01-16 12:01:43 -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
aleiby
490e9f695f fix: exclude role and rig types from bd ready (#1105)
Role and rig beads are reference metadata that should never be closed
or appear as actionable work. They are similar to agent beads which
are already excluded.

- Add 'role' and 'rig' to the issue type exclusion list in GetReadyWork
- Update comments to document the excluded types

Fixes confusion where role/rig beads appeared in bd ready output,
leading agents to try to close them as regular work items.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 19:20:58 -08:00
Bo
6b5bebfa12 fix(routing): handle symlinked .beads directories correctly (#1112)
When .beads is a symlink (e.g., ~/gt/.beads -> ~/gt/olympus/.beads),
findTownRoutes() incorrectly used filepath.Dir() on the resolved
symlink path to determine the town root.

This caused route resolution to fail because the town root would be
~/gt/olympus instead of ~/gt, making routes point to non-existent
directories.

The fix adds findTownRootFromCWD() which walks up from the current
working directory instead of the beads directory path. This finds
the correct town root regardless of symlink resolution.

Changes:
- Add findTownRootFromCWD() function
- Update findTownRoutes() to use CWD-based town root detection
- Add fallback to filepath.Dir() for non-Gas Town repos
- Add debug logging (BD_DEBUG_ROUTING=1)
- Add comprehensive test case

Test: go test ./internal/routing/...
2026-01-15 19:20:42 -08:00
beads/crew/dave
28a7f10955 fix(lint): add nolint comments for gosec G201/G104 in dolt storage
The SQL formatting warnings (G201) are safe because:
- Placeholders only contain "?" markers for parameterized queries
- WHERE/SET clauses use validated column names with ? placeholders
- Refs are validated by validateRef() before use in AS OF queries
- LIMIT values are safe integers from filter.Limit

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 11:42:05 -08:00
beads/crew/dave
fe67e9e232 fix(test): fix TestInitNoDbMode for no-db mode config persistence
Changes:
- Save issue-prefix in config.yaml when using --no-db mode
  (previously only saved in database which doesn't exist in no-db mode)
- Add config.ResetForTesting() to allow reloading config in tests
- Simplify test to verify config values rather than execute subsequent
  commands (cobra's flag caching makes multi-Execute() testing complex)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 11:37:57 -08:00
Peter Chanthamynavong
0a48519561 feat(context): centralize RepoContext API for git operations (#1102)
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.
2026-01-15 07:55:08 -08:00
beads/crew/fang
d1722d9204 docs: update daemon CLI syntax from flags to subcommands
Update all documentation to use the new subcommand syntax:
- `bd daemon --start` → `bd daemon start`
- `bd daemon --stop` → `bd daemon stop`
- `bd daemon --status` → `bd daemon status`
- `bd daemon --health` → `bd daemon status --all`
- `--global=false` → `--local`

The old flag syntax is deprecated but still works with warnings.

Closes: bd-734vd

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 21:47:15 -08:00
mayor
669ea40684 feat(storage): add --backend flag for Dolt backend selection
Phase 2 of Dolt integration - enables runtime backend selection:

- Add --backend flag to bd init (sqlite|dolt)
- Create storage factory for backend instantiation
- Update daemon and main.go to use factory with config detection
- Update database discovery to find Dolt backends via metadata.json
- Fix Dolt schema init to split statements for MySQL compatibility
- Add ReadOnly mode to skip schema init for read-only commands

Usage: bd init --backend dolt --prefix myproject

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 21:42:31 -08:00
mayor
1dc36098a3 feat(storage): add Dolt backend for version-controlled issue storage
Implements a complete Dolt storage backend that mirrors the SQLite implementation
with MySQL-compatible syntax and adds version control capabilities.

Key features:
- Full Storage interface implementation (~50 methods)
- Version control operations: commit, push, pull, branch, merge, checkout
- History queries via AS OF and dolt_history_* tables
- Cell-level merge instead of line-level JSONL merge
- SQL injection protection with input validation

Bug fixes applied during implementation:
- Added missing quality_score, work_type, source_system to scanIssue
- Fixed Status() to properly parse boolean staged column
- Added validation to CreateIssues (was missing in batch create)
- Made RenameDependencyPrefix transactional
- Expanded GetIssueHistory to return more complete data

Test coverage: 17 tests covering CRUD, dependencies, labels, search,
comments, events, statistics, and SQL injection protection.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 21:06:10 -08:00
Peter Chanthamynavong
31239495f1 fix(routing): complete bd init --contributor routing (bd-6x6g) (#1088)
Implements the missing contributor routing logic so bd init --contributor actually works. Contributors' issues automatically route to ~/.beads-planning/ while maintainers' issues stay local.
2026-01-14 20:50:56 -08:00
Michael
b9d2799d29 fix(docs): update command syntax from '--' to single argument format for start, stop and status. (#1086) 2026-01-14 20:43:07 -08:00
beads/crew/dave
9e639da5ba fix(create): allow creating issues with explicit ID that matches tombstone (bd-0gm4r)
When using `bd create --id=<id>` where the ID matches an existing
tombstone (from `bd delete --hard --force`), the creation now succeeds
by first deleting the tombstone and all related records.

This enables use cases like polecat respawn where a worker needs to
recreate an issue with the same ID.

Changes:
- queries.go: Check for tombstone before insert, delete it if found
  (cleans up events, labels, dependencies, comments, dirty_issues)
- tombstone_test.go: Add regression test

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Executed-By: beads/crew/dave
Rig: beads
Role: crew
2026-01-14 20:36:47 -08:00
beads/crew/dave
3298c45e4b fix(sync): handle redirect + sync-branch incompatibility (bd-wayc3)
When a crew worker's .beads/ is redirected to another repo, bd sync
now detects this and skips all git operations (sync-branch worktree
manipulation). Instead, it just exports to JSONL and lets the target
repo's owner handle the git sync.

Changes:
- sync.go: Detect redirect early, skip git operations when active
- beads.go: Update GetRedirectInfo() to check git repo even when
  BEADS_DIR is pre-set (findLocalBdsDirInRepo helper)
- validation.go: Add doctor check for redirect + sync-branch conflict
- doctor.go: Register new check, remove undefined CheckMisclassifiedWisps

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Executed-By: beads/crew/dave
Rig: beads
Role: crew
2026-01-14 20:36:30 -08:00
beads/crew/emma
c51022a3d6 chore: add role templates and gitignore bd_test
- Add witness, deacon, refinery role templates
- Ignore bd_test binary (bd-test was already ignored)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 18:03:43 -08:00
Steve Yegge
d544f278a5 Merge pull request #1073 from niklas-wortmann/junie
feat: add Junie agent integration
2026-01-13 13:06:18 -08:00
Steve Yegge
b5fbbb3a09 Merge pull request #1067 from Atmosphere-Aviation/fix/gate-list-closed-section
Fix bd gate list: Separate closed gates into own section
2026-01-13 13:06:15 -08:00
Jan-Niklas W
d475e424c2 feat: add Junie agent integration
Add support for JetBrains Junie AI agent:
- Create .junie/guidelines.md with workflow instructions
- Create .junie/mcp/mcp.json for MCP server configuration
- Add 'junie' to BuiltinRecipes in recipes.go
- Add runJunieRecipe() handler in setup.go
- Add website documentation
- Add integrations/junie/README.md

Usage: bd setup junie
2026-01-13 08:41:25 -06:00
Mike
66007ac3ea fix: resolve short IDs in comments add/list daemon mode (#1070)
Add daemonClient.ResolveID() calls before AddComment and ListComments
operations in daemon mode, following the pattern from update.go.

Previously, short IDs (e.g., "5wbm") worked with most bd commands but
failed with `comments add` and `comments list` when using the daemon.
The short ID was passed directly to the RPC server which expected full
IDs (e.g., "prefix-5wbm").

Changes:
- cmd/bd/comments.go: Add ID resolution before daemon RPC calls
- internal/rpc/comments_test.go: Update tests to reflect client-side
  resolution pattern (RPC server expects full IDs, CLI resolves first)

Fixes: https://github.com/steveyegge/beads/issues/1070
2026-01-13 13:28:30 +00:00
Mike
1f84f7cce3 test: add failing tests for short ID support in comments (#1070)
Add tests demonstrating that `bd comments add` and `bd comments list`
don't accept short IDs in daemon mode, while other commands do.

Tests added:
- TestCLI_CommentsAddShortID (cli_fast_test.go)
  - Tests short ID, partial ID, and comment alias in direct mode (passes)

- TestCommentAddWithShortID (internal/rpc/comments_test.go)
  - Tests RPC layer with short ID (FAILS - demonstrates bug)

- TestCommentListWithShortID (internal/rpc/comments_test.go)
  - Tests listing comments with short ID (FAILS - demonstrates bug)

The fix should add daemonClient.ResolveID() before AddComment/ListComments,
following the pattern in update.go and label.go.

Refs: https://github.com/steveyegge/beads/issues/1070
2026-01-13 13:22:19 +00:00
nux
d69bf4faa8 Fix bd gate list: Separate closed gates into own section
Previously, displayGates() always showed 'Open Gates' header even when
closed gates were included via --all flag. Also, closed gates would
appear mixed with open gates under the misleading 'Open Gates' header.

Changes:
- Modified displayGates() to accept showAll parameter
- Separates gates into 'Open Gates' and 'Closed Gates' sections
- Closed gates only shown when --all flag is used
- Fixed handleGateList RPC handler to use ExcludeStatus instead of
  Status filter for consistency with CLI behavior

Fixes gas-town issue go-47m
2026-01-13 00:46:50 -08:00
dennis
f703237c3d fix(ready): prevent wisps from appearing in bd ready
Add multiple layers of defense against misclassified wisps:
- Importer auto-detects -wisp- pattern and sets ephemeral flag
- GetReadyWork excludes -wisp- IDs via SQL LIKE clause
- Doctor check 26d detects misclassified wisps in JSONL

This addresses recurring issue where wisps with missing ephemeral
flag would pollute bd ready output after JSONL import.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 00:14:12 -08:00
garnet
e8a4474788 fix(storage): use strict INSERT for batch issue creation (GH#956)
Add insertIssuesStrict function that uses plain INSERT instead of
INSERT OR IGNORE. Update bulkInsertIssues and transactional CreateIssues
to use the strict variant.

This fixes a race condition where INSERT OR IGNORE could silently skip
duplicate insertions, but the code would still attempt to record events
for those "inserted" issues, causing FOREIGN KEY constraint failures.

The strict INSERT will now fail explicitly if a duplicate is encountered,
which should never happen since checkForExistingIDs runs first within
the same transaction.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 19:42:04 -08:00
beads/crew/dave
ec1a32b9a8 fix(storage): add reconnectMu RLock protection to prevent race condition (#1054)
Add missing reconnectMu.RLock() protection to storage methods that were
vulnerable to the same race condition fixed in GH#607. The FreshnessChecker
can trigger reconnect() which closes s.db while queries are in flight,
causing "database is closed" errors during daemon export operations.

Protected methods:
- labels.go: GetLabelsForIssues (GetLabels intentionally unprotected - called from GetIssue which holds lock)
- comments.go: GetIssueComments, GetCommentsForIssues
- dependencies.go: GetDependencyCounts, GetDependencyRecords, GetAllDependencyRecords, GetDependencyTree, loadDependencyGraph
- config.go: SetConfig, GetConfig, GetAllConfig, DeleteConfig, SetMetadata, GetMetadata
- dirty.go: MarkIssueDirty, GetDirtyIssues, GetDirtyIssueHash, GetDirtyIssueCount
- events.go: GetEvents, GetStatistics, GetMoleculeProgress
- hash.go: All hash methods
- hash_ids.go: GetNextChildID, ensureChildCounterUpdated (getNextChildNumber unprotected - called internally)

Internal helpers called from already-locked contexts intentionally omit
RLock to avoid deadlock (Go's RWMutex doesn't support recursive locking).

Fixes: bd-vx7fp

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Executed-By: beads/crew/dave
Rig: beads
Role: crew
2026-01-12 18:29:42 -08:00
Nicolas Suzor
7fe824781a fix: use route prefix when creating issues in rigs (#1028)
* fix(create): Use prefix from routes.jsonl when creating issues with --rig

When using `bd create --rig <name>`, the prefix from routes.jsonl was
being discarded. This caused issues to be created with the target
database's default prefix instead of the route's prefix.

This is particularly problematic when using the redirect mechanism to
share a single database across multiple rigs - the redirect correctly
routes to the shared database, but the prefix was not being applied.

The fix:
1. Capture the prefix from routing.ResolveBeadsDirForRig()
2. Temporarily override the target database's issue_prefix config
3. Restore the original prefix after issue creation

Example scenario that now works:
- routes.jsonl: {"prefix": "aops-", "path": "src/academicOps"}
- src/academicOps/.beads/redirect points to ~/writing/.beads
- `bd create --rig aops "Test"` now creates aops-xxx instead of ns-xxx

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(create): pass prefix via struct field instead of mutating config

The previous approach temporarily mutated the database's issue_prefix
config during cross-rig issue creation, then restored it afterward.
This was fragile in multi-user scenarios where concurrent operations
could see the wrong prefix.

New approach:
- Add PrefixOverride field to types.Issue
- CreateIssue checks PrefixOverride first, uses it if set
- createInRig sets issue.PrefixOverride instead of mutating config

This passes state as a parameter rather than mutating shared state,
making it safe for concurrent multi-user access.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-12 01:20:32 -08:00
beads/crew/giles
0248895298 fix(sqlite): rebuild blocked_issues_cache after rename-prefix (GH#1016)
RenameDependencyPrefix updates issue IDs in the dependencies table but
was not rebuilding the blocked_issues_cache, leaving stale IDs in the
cache that no longer exist in the issues table.

Add invalidateBlockedCache() call at the end of RenameDependencyPrefix
to rebuild the cache with the new issue IDs.

Fixes: GH#1016

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 20:45:09 -08:00
beads/crew/wolf
764f3747ba fix(merge): add QualityScore field to merge Issue struct
Add QualityScore *float32 field to internal/merge/merge.go to match
internal/types/types.go. Also add last-touched to .beads/.gitignore.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 18:46:12 -08:00
Eugene Sukhodolin
d04bffb9b6 fix(validation): support hyphenated prefixes in ValidateIDFormat (#1013)
* test(validation): add failing tests for hyphenated prefix parsing

Reproduces bug where `bd create --parent` fails for projects with
hyphenated prefixes like "bead-me-up" or "web-app".

Root cause: ValidateIDFormat splits on first hyphen, so:
  "bead-me-up-3e9.1" → prefix "bead" (wrong, should be "bead-me-up")

The bug flow in create.go:
1. User runs: bd create "Child" --parent bead-me-up-3e9
2. GetNextChildID generates: bead-me-up-3e9.1
3. ValidateIDFormat extracts: "bead" (splits at first hyphen)
4. ValidatePrefix compares: "bead" vs "bead-me-up" → MISMATCH

Tests added:
- TestValidateIDFormat: 6 cases for hyphenated prefix IDs
- TestValidateIDFormat_ParentChildFlow: simulates exact --parent flow,
  showing simple prefixes pass while hyphenated prefixes fail

Workaround: use --force flag to bypass prefix validation.

* fix(validation): support hyphenated prefixes in ValidateIDFormat

Use utils.ExtractIssuePrefix instead of naive first-hyphen splitting.
This fixes bd create --parent failing for projects with hyphenated
prefixes like "bead-me-up" or "web-app".

Before: "bead-me-up-3e9" → prefix "bead" (wrong)
After:  "bead-me-up-3e9" → prefix "bead-me-up" (correct)

ExtractIssuePrefix uses smart heuristics: split on last hyphen,
check if suffix is hash-like (3-8 chars, alphanumeric, digits for 4+).

* Update internal/validation/bead_test.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-11 18:16:48 -08:00
beads/crew/fang
0de6b10ac0 fix: add missing crystallizes column to SELECT queries and remove duplicate
- Remove duplicate crystallizes column from schema.go
- Add crystallizes to SELECT in transaction.go SearchIssues
- Add crystallizes to SELECT in ready.go GetReadyWork and GetNewlyUnblockedByClose
- Add crystallizes to SELECT in labels.go GetIssuesByLabel
- Add missing placeholder in issues.go INSERT VALUES
- Update migrations_test.go schema to include crystallizes column

Fixes test failures caused by schema/query column count mismatches.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:55:16 -08:00
beads/crew/fang
1d42732ad1 fix: add TypeRig constant and IsBuiltIn method (GH#1002)
- Add TypeRig IssueType constant for rig identity beads
- Add TypeRig to IsValid() switch statement
- Add IsBuiltIn() method for multi-repo hydration trust checks
- Add Crystallizes field to Issue struct and ComputeContentHash

Fixes validation rejecting documented issue types like 'rig' and 'agent'.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:46:44 -08:00
beads/crew/fang
f5cd36752d feat: add crystallizes column to sqlite storage
Adds crystallizes column for work economics (compounds vs evaporates)
per Decision 006. Includes migration 036 and updates to all INSERT/SELECT
queries in issues.go, queries.go, dependencies.go, and transaction.go.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:46:44 -08:00
Steve Yegge
0ed349b3ed fix(linear): use project_id when creating issues via sync --push (GH#973) (#1012)
The linear.project_id config was being read and used for filtering
when pulling issues from Linear, but was not being passed when
creating new issues via --push. Now CreateIssue includes projectId
in the mutation input when configured.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:46:00 -08:00
beads/crew/dave
40ae598751 fix(lint): resolve unparam warnings in doctor and rpc packages
- multirepo.go: discoverChildTypes now returns []string instead of
  ([]string, error) since error was always nil
- socket_path.go: tmpDir changed from function to const since it
  always returned "/tmp" regardless of platform

Fixes CI lint failures caused by unparam linter detecting unused
error returns and constant function results.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Executed-By: beads/crew/dave
Rig: beads
Role: crew
2026-01-10 23:17:37 -08:00
beads/crew/dave
ac24a63187 fix: make tests resilient to project .beads/redirect
Tests were failing because beads.FindDatabasePath() follows the
project's .beads/redirect file, causing tests to find unexpected
databases. Fixed by:

- Setting BEADS_DIR in tests that need isolation from git repo detection
- Clearing BEADS_DIR in TestMain to prevent global contamination
- Updating migration test schema to include owner column

This ensures tests work correctly in crew directories that have
redirect files pointing to shared .beads directories.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Executed-By: beads/crew/dave
Rig: beads
Role: crew
2026-01-10 22:38:04 -08:00
beads/crew/dave
f79e636000 feat: consolidate schema changes from crew directories
Merges schema additions from crew/fang, crew/giles, crew/grip, and crew/wolf:

- crystallizes: bool field for work economics (compounds vs evaporates)
- work_type: WorkType field for assignment model (mutex vs open_competition)
- source_system: string field for federation adapter tracking
- quality_score: *float32 for aggregate quality (0.0-1.0)
- delegated-from: new dependency type for work delegation chains

Migrations properly sequenced as 037-040 (after existing 036 owner_column).

Also fixes test compilation errors for removed TypeRig and IsBuiltIn references.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Executed-By: beads/crew/dave
Rig: beads
Role: crew
2026-01-10 22:38:04 -08:00
ruby
5605e590a3 fix(sqlite): prevent FK constraint failure on batch create (GH#956)
Add checkForExistingIDs check to transaction-based batch creation
(sqliteTxStorage.CreateIssues) before calling insertIssues. This
prevents INSERT OR IGNORE from silently skipping duplicate IDs,
which would cause FK constraint failures when recording events
for issues that weren't actually inserted.

Also fixes unrelated test bug: renamed parseCommaSeparated to
parseCommaSeparatedList in validators_test.go.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 22:02:03 -08:00