The ProtoID field in BondRef was misleading as it could hold both proto
IDs (from proto+proto bonds) and molecule IDs (from mol+mol bonds).
Rename to SourceID with updated JSON tag to better reflect its purpose.
Changes:
- Rename BondRef.ProtoID to SourceID in types.go
- Update JSON tag from proto_id to source_id
- Update all usages in mol_bond.go and tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Step.Expand and Step.ExpandVars are implemented in ApplyInlineExpansions
(expand.go), but had stale TODO comments claiming they were not
- Updated doc comments to reference the implementation
- Updated bd-7zka to reflect which features are still not implemented
(Step.Condition and Step.Gate remain as future work)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added GetDependenciesWithMetadata and GetDependentsWithMetadata to mockStorage
to match the Storage interface definition.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add TypeConvoy to issue types for cross-project tracking
- Implement reactive completion: when all tracked issues close,
convoy auto-closes with reason "All tracked issues completed"
- Uses 'tracks' dependency type (non-blocking, cross-prefix capable)
- Update help text for --type flag in list/create commands
- Add test for convoy reactive completion behavior
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
- Add Actor field to MutationEvent struct
- Use new assignee from update args instead of old issue state
- Include actor (who performed the action) in mutation events
- Display actor in bd activity output, falling back to assignee
When pinning/updating status, the activity feed now shows who performed
the action (e.g., "@gastown/crew/jack") instead of showing nothing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When updating role_type or rig on an agent bead, remove existing
role_type:* or rig:* labels before adding the new one. This prevents
label accumulation that would break filtering.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add role_type and rig labels to agent beads for filtering queries.
Changes:
- Add RoleType/Rig to CreateArgs and UpdateArgs in RPC protocol
- Auto-add role_type:<value> and rig:<value> labels when creating/updating agents
- Add --role-type and --agent-rig flags to bd create (requires --type=agent)
- Add bd agent backfill-labels command to update existing agent beads
This enables queries like:
bd list --type=agent --label=role_type:witness
bd list --type=agent --label=rig:gastown
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds non-blocking tracks dependency type for convoy to issue relationships:
- Non-blocking: does not affect ready work calculation
- Cross-prefix capable: convoys in hq-* can track issues in gt-*, bd-*
- Reverse lookup: bd dep list <id> --direction=up -t tracks
Also adds bd dep list command with direction and type filtering for
querying dependencies/dependents.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes:
- Default to excluding closed issues (use --all to include)
- Default limit of 50 issues (use --limit 0 for unlimited)
- --all flag now overrides the closed filter
This addresses agent context blowout from seeing hundreds of closed issues.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tests were failing when BD_ACTOR or other BD_/BEADS_ environment
variables were set. Added envSnapshot helper to save, clear, and
restore environment variables for proper test isolation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add explicit error checking for fmt.Fprintf/Fprintln in claude.go
- Add gosec nolint for safe exec.CommandContext calls in sync_git.go
- Remove unused error return from findTownRoutes in routes.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Code review caught that ".beads" would incorrectly match prefixes like
".beads-backup". Changed to match ".beads/" (with trailing slash) to
ensure we only match the actual .beads directory.
Added test cases for this edge case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The bug: In a bare repo + worktrees setup, jsonlRelPath was calculated
relative to the project root (which contains all worktrees), resulting in
paths like "main/.beads/issues.jsonl". But the sync branch worktree uses
sparse checkout for .beads/*, so files are at ".beads/issues.jsonl".
This caused copyJSONLToMainRepo to look in the wrong location, silently
returning when the file was not found.
Fix: Add normalizeBeadsRelPath() to strip leading path components before
".beads", ensuring correct path resolution in both directions:
- copyJSONLToMainRepo (worktree -> local)
- SyncJSONLToWorktreeWithOptions (local -> worktree)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The --cascade flag was documented but not working for single-issue
deletes. The bug had two causes:
1. CLI direct mode: Single-issue deletes bypassed the batch path where
cascade expansion actually happens. Fixed by routing cascade deletes
through deleteBatch() regardless of issue count.
2. Daemon/RPC mode: handleDelete() iterated through IDs individually
without expanding dependents. Fixed by using DeleteIssues() with
cascade flag when SQLite storage is available.
Now `bd delete <id> --cascade --force` correctly deletes the target
issue plus all issues that depend on it (recursively).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Consolidated 5 duplicate IssueDetails struct definitions into a single
types.IssueDetails in internal/types/types.go:
- Removed 4 inline definitions from cmd/bd/show.go
- Removed 1 inline definition from internal/rpc/server_issues_epics.go
The shared type embeds types.Issue by value and includes:
Labels, Dependencies, Dependents, Comments, and Parent fields.
This improves maintainability and reduces risk of inconsistency.
When the database has orphaned foreign key references (dependencies or labels
pointing to non-existent issues), the migration invariant check would fail,
preventing the database from opening. This created a chicken-and-egg problem:
1. bd doctor --fix tries to open the database
2. Opening triggers migrations with invariant checks
3. Invariant check fails due to orphaned refs
4. Fix never runs because database won't open
The fix adds CleanOrphanedRefs() that runs BEFORE captureSnapshot() in
RunMigrations. This automatically cleans up orphaned dependencies and labels
(preserving external:* refs), allowing the database to open normally.
Added test coverage for the cleanup function.
The routing code now walks up from the current beads directory to find
the Gas Town root (identified by mayor/town.json), then loads routes
from <townRoot>/.beads/routes.jsonl. The '.' path is correctly resolved
to the town beads directory.
Previously, routes.jsonl was only searched in the current beads dir,
which failed when working from rig subdirectories like crew/emma.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename followRedirect to FollowRedirect in internal/beads (export it)
- Update doctor/maintenance.go to use beads.FollowRedirect
- Update doctor/fix/common.go to use beads.FollowRedirect
- Remove 66 lines of duplicated code across 3 implementations
This ensures consistent redirect handling with path canonicalization,
chain prevention, and proper error warnings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Separates semantics of 'pinned' (identity records) from work-on-hook:
- 'pinned' = domain table / identity record (agents, roles) - non-blocking
- 'hooked' = work on agent's hook (GUPP-driven) - blocks dependents
Changes:
- Add StatusHooked constant to types.go
- Update all blocking queries to include 'hooked' status
- Add cyan styling for 'hooked' in UI output
- Create migration 032 to convert pinned work items to hooked
Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add mol_type field to beads for swarm coordination:
- Values: 'swarm' (multi-polecat), 'patrol' (recurring ops), 'work' (default)
- Nullable, defaults to empty string (treated as 'work')
Changes:
- Add mol_type column to SQLite schema and migration 031
- Add MolType type with IsValid() validation in types.go
- Update insertIssue/GetIssue to handle mol_type
- Add --mol-type flag to create command
- Add mol_type filtering to list and ready commands
- Update RPC protocol for daemon mode support
- Update test schema in migrations_test.go
🤝 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Created 7 new beads to track TODOs that were previously inline comments:
- bd-7l27: Integrate migration detection into bd doctor (5 files)
- bd-6x6g: Add multi-repo target repo switching in bd create
- bd-ag35: Add daemon RPC endpoints for config and stale check
- bd-2dwo: Remove deprecated daemon logger function
- bd-0qx5: Implement Jira issue timestamp comparison for sync
- bd-7zka: Implement formula features (repeat, for_each, branch, gate, split)
- bd-h048: Refactor sync_test to use direct import logic
Updated 16 TODO comments to include bead ID references for tracking.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New commands and features:
- bd worktree for parallel development
- bd slot commands for agent bead slot management
- bd agent state for ZFC-compliant state reporting
- bd doctor --deep for full graph integrity validation
- Agent bead support (type=agent, type=role, migration 030)
- Computed .parent field in JSON output
- Auto-bypass daemon for wisp operations
- Pour warning for vapor-phase formulas
Performance:
- O(2^n) → O(V+E) cycle detection (GH#775)
Fixes:
- Import hash mismatch warnings
- Test updates for version tracking thresholds
- Migration test updated for new agent schema fields
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Strip (bd-xxx), (gt-xxx) suffixes from code comments and changelog
entries. The descriptions remain meaningful without the ephemeral
issue IDs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace the recursive SQL CTE in DetectCycles with Go-layer DFS using
shared visited set. The previous implementation enumerated all paths
through the dependency graph, causing exponential blowup with diamond
patterns (multiple issues depending on the same target).
Changes:
- Add loadDependencyGraph() to load deps as adjacency list in one query
- Implement DFS cycle detection with recStack for back-edge detection
- Add normalizeCycle() for consistent cycle deduplication
- Add DetectCycles-specific benchmarks (Linear, Dense, Tree graphs)
- Use direct SQL INSERT in benchmarks to bypass AddDependency overhead
Performance improvement on dense graph (500 nodes, 2500 edges):
- Before: >120s timeout
- After: 1.6ms
Benchmarks:
- DetectCycles_Linear_1000: 0.84ms (1000 nodes, 999 edges)
- DetectCycles_Dense_500: 1.59ms (500 nodes, ~2500 edges)
- DetectCycles_Tree_1000: 0.85ms (1000 nodes, 999 edges)
Add agent commands for self-reporting state:
- bd agent state <agent> <state>: Update agent state and last_activity
- bd agent heartbeat <agent>: Update last_activity timestamp only
- bd agent show <agent>: Display agent bead details
States: idle, spawning, running, working, stuck, done, stopped, dead
Also adds AgentState and LastActivity fields to UpdateArgs in RPC protocol.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Phase field to Formula type to indicate recommended instantiation phase
- Add warning in 'bd mol pour' when formula has phase="vapor"
- Improve pour/wisp help text with clear comparison of when to use each
- Add CheckPersistentMolIssues doctor check to detect mol- issues in JSONL
- Update beads-release.formula.json with phase="vapor"
This helps prevent accidental persistence of ephemeral workflow issues.
Add slot management commands:
- bd slot set <agent> <slot> <bead> - set slot (error if occupied)
- bd slot clear <agent> <slot> - clear slot
- bd slot show <agent> - show all slots
These enforce cardinality constraints for agent bead slots.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update ParseIssueType to use canonical types.IsValid() (includes agent, role, gate, message)
- Add ValidateAgentID function to validate gt-<role>[-<rig>[-<name>]] pattern
- Wire up validation in create.go when --type=agent with explicit ID
- Update --type flag help text to include agent and role types
- Add comprehensive test coverage for agent ID validation
Agent identity fields on Issue struct:
- HookBead: reference to current work (0..1 cardinality)
- RoleBead: reference to role definition bead
- AgentState: self-reported state (idle|spawning|running|working|stuck|done|stopped|dead)
- LastActivity: timestamp for heartbeat/timeout detection
- RoleType: agent type (polecat|crew|witness|refinery|mayor|deacon)
- Rig: rig name (empty for town-level agents)
Also adds:
- AgentState type with IsValid() method
- Validation for agent state in Issue.Validate()
- Agent fields included in content hash
This enables the agent-as-bead architecture where agents are tracked
as first-class beads with self-reported state.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add TypeAgent and TypeRole to IssueType enum in types.go
- Update IsValid() to include new types
- Add UI styles with distinct colors (cyan for agent, green for role)
- Add RenderType cases for consistent display
This enables creating agent beads (identity) and role beads (behavior
definitions) as part of the agent-as-bead architecture.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allows reparenting issues to a different epic/parent:
bd update bd-xyz --parent=bd-epic
Implementation:
- Add Parent field to UpdateArgs in protocol.go
- Handle reparenting in RPC handler (server_issues_epics.go)
- Add --parent flag to updateCmd with both daemon and direct mode support
- Remove old parent-child dependency before adding new one
- Pass empty string to remove parent entirely
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replaced 3 separate caches (isWorktree, mainRepoRoot, repoRoot) with a
single gitContext struct populated by one git call. This reduces git
subprocess calls from up to 4 down to 1 and simplifies ResetCaches().
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When beads is redirected (e.g., in Gas Town crew clones), bd prime now
shows a notice about the redirect. This helps agents understand why
they share issues with other clones.
CLI mode shows:
> ⚠️ **Redirected**: Local .beads → /path/to/target/.beads
> You share issues with other clones using this redirect.
MCP mode shows:
**Note**: Beads redirected to /path/to/target/.beads (shared with other clones)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add nolint:unparam for readOnly param in sqlite_open.go
- Handle cmd.Help() error in wisp.go
- Handle rows.Close() error in migration 028
- Handle targetStore.Close() error in create.go
- Update Nix vendorHash for current dependencies
Cherry-picked from PR #769
Analysis found these commands are dead code:
- gt never calls `bd pin` - uses `bd update --status=pinned` instead
- Beads.Pin() wrapper exists but is never called
- bd hook functionality duplicated by gt mol status
- Code comment says "pinned field is cosmetic for bd hook visibility"
Removed:
- cmd/bd/pin.go
- cmd/bd/unpin.go
- cmd/bd/hook.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds --prefix as a forgiving alias to --rig flag. Accepts:
- Exact prefix: bd-, gt-
- Prefix without hyphen: bd, gt
- Rig name: beads, gastown
All resolve to the correct rig via routes.jsonl lookup.
This matches agents' mental model of prefix-based routing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds --rig flag to bd create that allows creating issues in a different
rig without having to cd to that directory.
Example: bd create --rig beads --title='Bug report'
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When `bd dep add` fails to resolve the dependency ID locally, it now
checks routes.jsonl for a matching prefix and auto-converts to an
external reference format (external:<project>:<id>).
This allows simpler syntax like:
bd dep add gt-xyz bd-abc
Instead of the verbose:
bd dep add gt-xyz external:beads:bd-abc
New functions in routing package:
- ExtractProjectFromPath: Gets project name from route path
- ResolveToExternalRef: Converts foreign ID to external ref using routes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The migration was using SELECT * which fails when migrating databases
that predate the created_by column (34 columns vs 35). Now explicitly
lists columns and provides empty default for created_by if missing.
Also fixes missed Wisp→Ephemeral rename in multirepo_test.go.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>