Fixes from review of gt-8tmz.25 implementation:
1. Dry-run no longer cooks formulas - added resolveOrDescribe() for
dry-run mode that checks if operand exists without cooking
2. Ephemeral protos now cleaned up after successful bond, not just
on error
3. Unique proto IDs to avoid collision - ephemeral protos use format
"_ephemeral-<formula>-<timestamp>" instead of formula name
4. Removed unused vars parameter from resolveOrCookFormula
5. Added informative output showing formulas will be cooked and
cleaned up
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Bond command now accepts formula names (e.g., mol-polecat-arm) in addition
to issue IDs. When a formula name is given:
1. Looks up the formula using formula.Parser
2. Resolves inheritance and applies transformations (control flow, advice,
expansions, aspects)
3. Cooks the formula inline to create an ephemeral proto
4. Uses the cooked proto for bonding
This eliminates the need for pre-cooked proto beads in the database,
enabling more dynamic workflow composition.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add SourceFormula and SourceLocation fields to track where each step
came from during the cooking process. This enables debugging of complex
compositions with inheritance, expansion, and advice.
Changes:
- Added SourceFormula and SourceLocation fields to Step struct (formula/types.go)
- Added same fields to Issue struct (types/types.go)
- Added SetSourceInfo() to parser.go - sets source on all steps after parsing
- Updated cook.go to copy source fields from Step to Issue
- Updated dry-run output to display source info: [from: formula@location]
- Updated advice.go to set source on advice-generated steps
- Updated controlflow.go to preserve source on loop-expanded steps
- Updated expand.go to preserve source on template-expanded steps
The source location format is:
- steps[N] - regular step at index N
- steps[N].children[M] - child step
- steps[N].loop.body[M] - loop body step
- template[N] - expansion template step
- advice - step inserted by advice transformation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Claude Code's installed_plugins.json changed from v1 (plugins as structs)
to v2 (plugins as arrays). Update GetClaudePluginVersion() to handle both.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add loop, branch, and gate operators for formula step transformation:
- LoopSpec: Fixed-count loops expand body N times with chained iterations.
Conditional loops expand once with runtime metadata labels.
- BranchRule: Fork-join patterns wire dependencies for parallel paths.
- GateRule: Adds condition labels for runtime evaluation before steps.
Types added to types.go:
- LoopSpec (count/until/max/body)
- BranchRule (from/steps/join)
- GateRule (before/condition)
- Loop field on Step
- Branch/Gate arrays on ComposeRules
New controlflow.go with ApplyLoops, ApplyBranches, ApplyGates, and
ApplyControlFlow convenience function. Wired into cook.go before
advice and expansion operators.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Users who want manual control over git commits can now set:
bd config set no-git-ops true
This makes `bd prime` output the stealth-mode session close protocol
(just `bd sync --flush-only`) instead of the full git add/commit/push
workflow. Useful when:
- You want to verify work before committing
- Claude tries to auto-commit after context compaction
- You have a custom git workflow
The --stealth flag still works as before for one-off use.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
On Windows, running `bd init` outside a git repository could hang
indefinitely because git.IsWorktree() runs `git rev-parse --git-dir`
which may hang on Windows when not in a git repo.
The fix adds an isGitRepo() check before calling git.IsWorktree() in
both the main init flow and the checkExistingBeadsData helper.
Regression introduced in e01b7412 (Git worktree compatibility).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
GH#740: bd doctor --fix was auto-removing child→parent dependencies,
calling them an 'anti-pattern'. While these often indicate modeling
mistakes (deadlock), they may be intentional in some workflows.
Changes:
- Add --fix-child-parent flag (required to remove child→parent deps)
- Remove ChildParentDependencies from default --fix set
- Update warning message to reference new flag
- Update comments to reflect more nuanced understanding
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace fmt.Fprintf(os.Stderr, ...) + os.Exit(1) patterns with
FatalErrorRespectJSON() in updateCmd, closeCmd, and editCmd.
This ensures that when --json flag is set, errors are returned as
JSON objects ({"error": "message"}) instead of plain text.
Fixes: bd-28sq.1
Extends bd doctor to detect complete-but-unclosed molecules (epics where
all children are closed but root is still open).
- Added CheckStaleMolecules() to doctor/maintenance.go
- Added resolveBeadsDir() helper to follow Gas Town redirect files
- Check appears in Maintenance category with warning severity
- Shows example IDs and suggests 'bd mol stale' for review
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements formula management commands:
- bd formula list: Lists formulas from all search paths
- bd formula show <name>: Shows formula details, steps, composition rules
Search paths in priority order:
1. .beads/formulas/ (project)
2. ~/.beads/formulas/ (user)
3. ~/gt/.beads/formulas/ (town)
Features:
- Type filtering (--type workflow|expansion|aspect)
- JSON output support (--json)
- Shows variables, steps, advice, bond points, and aspects
- Formulas in earlier paths shadow later ones
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements command to find epics/molecules where all children are closed
but the root is still open. Helps identify work that's done but not
formally closed.
Flags:
--blocking Only show molecules blocking other work
--unassigned Only show unassigned molecules
--all Include molecules with 0 children
--json Machine-readable output
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Aspects field to ComposeRules for listing aspect formulas
- Apply aspects during cooking after expansions
- Aspects are loaded by name and their advice rules are applied
Usage in formula:
"compose": {
"aspects": ["security-audit", "logging"]
}
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
gitCommit() was adding the JSONL file but then committing ALL staged
changes (no pathspec). If other files were staged (e.g., deletions from
git add -A), they would be swept into the bd sync commit.
Fixed by adding pathspec to both gitCommit() and commitToExternalBeadsRepo()
so they only commit what they explicitly staged.
This was the root cause of PR #722 files being deleted - they were staged
for deletion in the working tree and got committed by bd sync.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The fix for GH#709 updated FindJSONLInDir to skip interactions.jsonl,
but the doctor check in CheckLegacyJSONLFilename was not updated.
This caused `bd doctor` to warn about multiple JSONL files when
both issues.jsonl and interactions.jsonl exist (which is normal
after `bd init`).
Also skip molecules.jsonl which is another system file that shouldn't
be counted as a duplicate issue database.
Distilled protos (via `bd mol distill`) now get bd-proto-xxx IDs.
Summary of distinct prefixes:
- bd-proto-xxx: templates created via distill
- bd-mol-xxx: instances created via pour
- bd-wisp-xxx: ephemeral instances via wisp create
- bd-xxx: regular issues
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add expand and map operators that apply macro-style template expansion:
- expand(target, template) - replace a single step with expanded template
- map(select, template) - replace all matching steps with expanded template
The expansion formula type (e.g., rule-of-five) uses a template field with
{target} and {target.description} placeholders that are substituted when
applied to target steps.
Changes:
- Add Template field to Formula struct for expansion formulas
- Add ExpandRule and MapRule types to ComposeRules
- Implement ApplyExpansions in new expand.go
- Add LoadByName method to Parser for loading expansion formulas
- Integrate expansion into bd cook command
- Add comprehensive tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added type-specific ID prefixes for better visual recognition:
- `bd pour` now generates IDs with "mol-" prefix
- `bd wisp create` now generates IDs with "wisp-" prefix
- Regular issues continue using the configured prefix
Implementation:
- Added IDPrefix field to types.Issue (internal, not exported to JSONL)
- Added Prefix field to CloneOptions for spawning operations
- Added IDPrefix to RPC CreateArgs for daemon communication
- Updated storage layer to use issue.IDPrefix when generating IDs
- Updated pour.go and wisp.go to pass appropriate prefixes
This enables instant visual recognition of entity types and prevents
accidental modification of templates.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Wisps are now just issues with Wisp=true flag in the main database,
not exported to JSONL. Removes all references to .beads-wisp/ directory.
- Update docs: CLAUDE.md, CLI_REFERENCE.md, MOLECULES.md, DELETIONS.md
- Update code comments: wisp.go
- Update changelog and info.go version notes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change file extension from .formula.yaml to .formula.json
- Replace gopkg.in/yaml.v3 with encoding/json in parser
- Remove yaml struct tags, keep json tags only
- Update all test cases to use JSON format
- Update documentation references
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
bd should not assume specific orchestrator agents exist. Gates are just
data records - the orchestrator decides who processes them.
- Remove Assignee: deacon/ from gate creation
- Update help text to say orchestrator instead of Deacon patrol
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
bd mol run was a convenience combo (pour + assign + pin + start) that
felt like orchestration but lived in the data layer. This blurred the
architectural boundary between bd (data) and gt (orchestration).
- Delete cmd/bd/mol_run.go entirely
- Update mol.go help text to remove run reference
- Update mol_current.go to suggest bd pour instead
gt spawn will implement the orchestration combo by calling the atomic
bd commands (pour, update, pin) directly.
Closes bd-00u3
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Two issues fixed:
1. bd-c8d5: mol run only created partial children from proto
- Root cause: children with missing/wrong dependencies were not loaded
- Fix: loadDescendants now uses two strategies:
- Strategy 1: Check dependency records for parent-child relationships
- Strategy 2: Find hierarchical children by ID pattern (parent.N)
- This catches children that may have broken dependency data
2. bd-drcx: mol run now supports proto lookup by title
- Can use: bd mol run mol-polecat-work --var issue=gt-xxx
- Or by ID: bd mol run gt-lwuu --var issue=gt-xxx
- Title matching is case-insensitive and supports partial matches
- Shows helpful error on ambiguous matches
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The sync command's exportToJSONL function was not filtering wisps,
causing them to be re-added to JSONL during bd sync re-export step.
autoflush.go had wisp filtering but sync_export.go did not. Added
the same filtering logic to prevent wisps from being exported to JSONL.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove cross-store squash logic from mol_squash.go
- Delete runWispSquash() and squashWispToPermanent() functions
- Simplify runMolSquash() to work with main store only
- Update mol_burn.go to work with main database
- Remove .beads-wisp/ directory references
- Look for Wisp=true issues in main store instead
- Update mol_bond.go to use Wisp flag instead of separate store
- --wisp now creates issues with Wisp=true in main store
- --pour creates issues with Wisp=false (persistent)
- Update bondProtoMol signature to accept both flags
- Deprecate wisp storage functions in beads.go
- WispDirName, FindWispDir, FindWispDatabasePath
- NewWispStorage, EnsureWispGitignore, IsWispDatabase
- All marked deprecated with reference to bd-bkul
- Remove obsolete cross-store squash tests
- TestSquashWispToPermanent
- TestSquashWispToPermanentWithSummary
- TestSquashWispToPermanentKeepChildren
All tests pass. Build succeeds.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Progress on eliminating separate .beads-wisp/ directory:
- Add --wisp flag to bd create (creates issue with Wisp=true)
- Update bd wisp create to use main db instead of separate wisp storage
- Update bd wisp list to query main db with Wisp filter
- Update bd wisp gc to work with main database
- Add Wisp field to RPC ListArgs for daemon mode support
- Fix terminology: use "old/abandoned" for time-based cleanup,
reserve "stale" for graph-pressure staleness (per Gas Town taxonomy)
Still TODO:
- Finish mol squash simplification (remove cross-store logic)
- Remove runWispSquash and squashWispToPermanent functions
- Update mol burn similarly
- Deprecate .beads-wisp/ functions in internal/beads/beads.go
- Test all changes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds release notes for v0.36.0 including:
- Formula system and gate issue type
- bd list --pretty --watch enhancements
- Child→parent dep prevention (LLM temporal trap)
- Multiple bug fixes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- bd-hr39: Add `needs` field to Step as alias for depends_on. Converts
to blocking dependencies between sibling steps during cooking.
- bd-j4cr: Add `waits_for` field to Step. Values: all-children or
any-children. Preserved as gate:<value> label during cooking.
- bd-47qx: Add --prefix flag to bd cook command to prepend a prefix
to proto IDs, enabling use of project prefixes like gt-.
Includes validation, dry-run output, and comprehensive tests.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes from self-review of formula parser and bd cook:
1. Atomicity: Add cleanup on failure in cookFormula - if labels/deps
transaction fails, delete the already-created issues
2. Validation: Add recursive depends_on validation for child steps
and validate priority ranges for children
3. Documentation: Mark unimplemented fields (Expand, ExpandVars,
Condition, Gate) with TODO(future) comments
4. Thread safety: Add note that Parser is NOT thread-safe
5. Error messages: Track first definition location for duplicate ID
errors (e.g., "duplicate id at steps[1], first defined at steps[0]")
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements a new formula system for defining workflow templates in YAML:
- internal/formula/types.go: YAML schema types for .formula.yaml files
- Formula, Step, VarDef, ComposeRules, BondPoint, Gate types
- Support for workflow, expansion, and aspect formula types
- Variable definitions with required, default, enum, and pattern
- internal/formula/parser.go: Parser with extends/inheritance support
- Parse formula files from multiple search paths
- Resolve extends references for formula inheritance
- Variable extraction and substitution
- Variable validation (required, enum, pattern)
- cmd/bd/cook.go: bd cook command to compile formulas into protos
- Parse and resolve formula YAML
- Create proto bead with template label
- Create child issues for each step
- Set up parent-child and blocking dependencies
- Support --dry-run, --force, --search-path flags
Example workflow:
bd cook mol-feature.formula.yaml
bd pour mol-feature --var component=Auth --var framework=react
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This prevents a common mistake where users add dependencies from child
issues to their parent epics. This creates a deadlock:
- Child can't start (blocked by open parent)
- Parent can't close (children not done)
Changes:
- dep.go: Reject child→parent deps at creation time with clear error
- server_labels_deps_comments.go: Same check for daemon RPC
- doctor/validation.go: New check detects existing bad deps
- doctor/fix/validation.go: Auto-fix removes bad deps
- doctor.go: Wire up check and fix handler
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove the spawn command from bd mol. Proto instantiation now uses:
- bd pour <proto> - Instantiate as persistent mol (liquid phase)
- bd wisp create <proto> - Instantiate as ephemeral wisp (vapor phase)
Rationale:
- 'spawn' doesn't fit the chemistry metaphor
- Two phase transitions (pour/wisp) are clearer than one command with flags
- Avoids confusion about defaults
Changes:
- Delete mol_spawn.go
- Update mol.go, mol_catalog.go, mol_distill.go to reference pour/wisp
- Update pour.go and wisp.go to remove 'Equivalent to spawn' comments
- Update info.go changelog entries
- Update CHANGELOG.md, ARCHITECTURE.md, DELETIONS.md
Closes bd-8y9t
The daemon sync functions (gitPushFromWorktree, syncBranchPull) were
checking git's branch tracking config and falling back to 'origin',
but ignoring bd's sync.remote config setting.
Now these functions check sync.remote config first, matching the
behavior of sync_check.go and sync_import.go.
Closes#736
Removes unnecessary parenthetical explanation about possible JSONL file names since findJSONLPath() already encapsulates that logic.
Co-authored-by: Charles P. Cross <cpdata@users.noreply.github.com>
Remove verbose parenthetical explanation from comment on line 73.
The comment now reads '// Get the actual JSONL path' instead of
'// Get the actual JSONL path (could be issues.jsonl, beads.base.jsonl, etc.)'
This is a documentation cleanup with no functional changes.
When 'bd doctor --fix' detects DB has more issues than JSONL, it runs
'bd export' to sync them. However, 'bd export' without -o flag outputs
to stdout instead of writing to .beads/issues.jsonl, making the fix a
no-op.
Add -o .beads/issues.jsonl --force to the export command to ensure the
JSONL file is actually updated.
Add a new --prune mode to `bd compact` that removes expired tombstones from
issues.jsonl without requiring AI compaction or deleting closed issues.
Features:
- `bd compact --prune` removes tombstones older than 30 days (default TTL)
- `bd compact --prune --older-than N` uses custom N-day TTL
- `bd compact --prune --dry-run` previews what would be pruned
- Supports --json output for programmatic use
This reduces sync overhead by eliminating accumulated tombstones that were
previously only pruned as a side effect of compaction or cleanup operations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add integration tests for the deleteViaDaemon function that handles
client-side RPC deletion calls:
- TestDeleteViaDaemon_SuccessfulDeletion: Single issue deletion
- TestDeleteViaDaemon_CascadeDeletion: Cascade deletion through daemon
- TestDeleteViaDaemon_ForceDeletion: Force delete bypassing deps
- TestDeleteViaDaemon_DryRunMode: Preview without actual deletion
- TestDeleteViaDaemon_InvalidIssueID: Error handling for invalid IDs
- TestDeleteViaDaemon_BatchDeletion: Multiple issues at once
- TestDeleteViaDaemon_JSONOutput: JSON output validation
- TestDeleteViaDaemon_HumanReadableOutput: Human-readable formatting
- TestDeleteViaDaemon_DependencyConflict: Dependency conflict handling
- TestDeleteViaDaemon_EmptyIDs: Empty ID list handling
- TestDeleteViaDaemon_MultipleErrors: Mixed valid/invalid batch
- TestDeleteViaDaemon_DirectCall: Direct call with global client
- TestDeleteViaDaemon_DirectDryRun: Direct dry-run test
- TestDeleteViaDaemon_DirectHumanOutput: Direct human output test
- TestDeleteViaDaemon_DirectBatch: Direct batch deletion test
Coverage: 59.4% for deleteViaDaemon (remaining 40% is os.Exit paths)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add FatalErrorRespectJSON helper for JSON-aware error output
- Fix bd comments list returning null instead of [] for empty arrays
- Remove redundant local --json flags from show/update/close commands
that were shadowing the global persistent --json flag
- Update show command error handlers to use FatalErrorRespectJSON
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>