Commit Graph

740 Commits

Author SHA1 Message Date
Steve Yegge
fd57f61f34 fix: Prevent aspect self-matching infinite recursion (gt-8tmz.16)
ApplyAdvice now collects original step IDs before applying rules and
only matches steps in that set. This prevents advice patterns (like "*")
from matching their own inserted before/after steps.

Added test case demonstrating that a "*" pattern only adds advice to
original steps, not to inserted steps.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 12:21:23 -08:00
Steve Yegge
516c62e543 feat: Add aspect composition support (gt-8tmz.5)
- 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>
2025-12-25 12:15:12 -08:00
Steve Yegge
de1a9559fa fix: Map expansion now matches nested child steps (gt-8tmz.33)
The map rule was only iterating over top-level steps, missing nested
children. Now uses buildStepMap to include all steps at any depth.

Added test case for map expansion over nested children.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 12:08:05 -08:00
Steve Yegge
acb4aeee55 Fix misleading comment in replaceStep 2025-12-25 11:51:03 -08:00
Steve Yegge
b82d0e7c0f Fix expansion operators: update dependencies after expansion
When a step is expanded (e.g., implement -> implement.draft, implement.refine-1,
etc.), any steps that depended on the original step should now depend on the
last step of the expansion.

Call UpdateDependenciesForExpansion after both expand and map operations.

Fixes gt-8tmz.3

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 11:44:28 -08:00
Steve Yegge
127a36dd5f Formula cycle detection: show full extends chain in error message (gt-8tmz.15)
When bd cook encounters a circular extends chain (A extends B extends A),
the error message now shows the full chain: "cycle-a -> cycle-b -> cycle-a"
instead of just "circular extends detected: cycle-a".

This makes debugging circular dependencies much easier by showing exactly
which formulas are involved in the cycle.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 02:33:22 -08:00
Steve Yegge
84c124fc3d Implement max expansion depth limit (default 5) (gt-8tmz.17)
Add DefaultMaxExpansionDepth constant and depth tracking in expandStep
to prevent runaway nested expansions. The limit applies to template
children during expansion.

Changes:
- Add DefaultMaxExpansionDepth = 5 constant
- Update expandStep to track depth and return error when exceeded
- Update ApplyExpansions callers to handle errors
- Add TestExpandStepDepthLimit test for depth limiting

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 02:23:20 -08:00
Steve Yegge
cfb1196044 Implement expansion operators for formula composition (gt-8tmz.3)
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>
2025-12-25 02:11:03 -08:00
Steve Yegge
9c1bf7d4ea fix: Combine db prefix with type prefix for mol/wisp IDs (bd-hobo)
Changed prefix logic to combine the database prefix with the type prefix:
- bd-wisp-xxx (was: wisp-xxx)
- bd-mol-xxx (was: mol-xxx)

This ensures IDs like hq-wisp-xxx at town level and gt-mol-xxx for gastown,
maintaining database namespace while adding type recognition.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 02:10:08 -08:00
Steve Yegge
f78fe883d0 feat: Distinct prefixes for protos, molecules, wisps (bd-hobo)
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>
2025-12-25 02:05:25 -08:00
Steve Yegge
a643b9ab67 Implement advice operators for formula composition (gt-8tmz.2)
Add Lisp-style advice operators to the formula DSL:
- before(target, step) - insert step before target
- after(target, step) - insert step after target
- around(target, wrapper) - wrap target with before/after

Features:
- Glob pattern matching for targets (*.implement, shiny.*, etc)
- Pointcut matching by type or label
- Step reference substitution ({step.id}, {step.title})
- Automatic dependency chaining

New types: AdviceRule, AdviceStep, AroundAdvice, Pointcut
New functions: ApplyAdvice, MatchGlob, MatchPointcut

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 01:53:43 -08:00
Steve Yegge
e6ce0d6365 refactor: Switch formula format from YAML to JSON
- 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>
2025-12-25 01:37:22 -08:00
Steve Yegge
2a6191e49b fix: use content-level merge for divergence recovery (bd-kpy)
Replace fetchAndRebaseInWorktree with contentMergeRecovery in pushFromWorktree.

The problem: When push fails due to non-fast-forward, the old code used git
rebase to recover. But git rebase is text-level and does not invoke the JSONL
merge driver. This could resurrect tombstones - if remote had a tombstone and
local had closed, the rebase would overwrite the tombstone.

The fix: Use the same content-level merge algorithm that PullFromSyncBranch
uses. This respects tombstone semantics - recent tombstones always win over
live issues.

Changes:
- Add contentMergeRecovery() that does content-level merge instead of rebase
- Update pushFromWorktree to call contentMergeRecovery
- Mark fetchAndRebaseInWorktree as deprecated (kept for reference)
- Add tests for tombstone preservation during merge recovery

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 22:41:40 -08:00
Steve Yegge
5a46879741 refactor: remove deprecated .beads-wisp directory support (bd-bkul)
Wisps now use Wisp=true flag in the main database. The separate
.beads-wisp/ directory is no longer needed.

Removed:
- WispDirName constant
- FindWispDir()
- FindWispDatabasePath()
- NewWispStorage()
- EnsureWispGitignore()
- IsWispDatabase()
- All related tests
- .beads-wisp/ from .gitignore
2025-12-24 21:30:20 -08:00
Steve Yegge
f2e6df95c0 refactor: simplify wisp architecture - single DB with Wisp flag (bd-bkul)
- 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>
2025-12-24 20:42:54 -08:00
Steve Yegge
c0271aedbf wip: simplify wisp architecture - single db with Wisp flag (bd-bkul)
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>
2025-12-24 20:31:27 -08:00
Steve Yegge
42c23e24df fix(lint): add nosec directive for formula parser file read
Also: comprehensive CHANGELOG update for v0.36.0 prep
- Formula system (bd cook, extends, needs/waits_for)
- Gate issue type for async coordination
- bd list --pretty/--watch viewer enhancements
- bd search date/priority/content filters
- 15+ bug fixes since v0.35.0
- Test coverage improvements (daemon 72%, compact 82%)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 15:22:01 -08:00
Steve Yegge
c28defb710 fix(sqlite): handle dots in prefix for extractParentChain (GH#664)
extractParentChain was using strings.Split(id, ".") which incorrectly
parsed prefixes containing dots (like "alicealexandra.com"). This caused
--parent to fail with "parent does not exist" even when the parent was
present in the database.

The fix uses IsHierarchicalID to walk up the hierarchy correctly, only
splitting on dots followed by numeric suffixes (the actual hierarchy
delimiter).

Example:
- "test.example-abc.1" now correctly returns ["test.example-abc"]
- Previously it incorrectly returned ["test", "test.example-abc"]

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 14:39:30 -08:00
Steve Yegge
25402184a6 fix: respect allowed_prefixes config during import (gt-2z6s)
The buildAllowedPrefixSet function now parses the allowed_prefixes config
and includes those prefixes when validating imports. This allows mol-*
prefixes to be imported without errors when configured.

Config example: bd config set allowed_prefixes "gt-,mol-"
2025-12-24 14:28:23 -08:00
Steve Yegge
f28785d2dc feat(formula): support needs and waits_for fields, add --prefix flag
- 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>
2025-12-24 13:59:38 -08:00
Steve Yegge
d1c4526e6e fix(formula): address code review findings
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>
2025-12-24 13:50:19 -08:00
Steve Yegge
4fdcda4568 feat(formula): add formula parser and bd cook command (bd-weu8, bd-wa2l)
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>
2025-12-24 13:42:01 -08:00
Steve Yegge
1e7c7f5e54 fix(sqlite): update child_counters when explicit child IDs are created (GH#728)
When creating issues with explicit hierarchical IDs (e.g., bd-test.1, bd-test.2
via --id flag or import), the child_counters table was not being updated.
This caused GetNextChildID to return colliding IDs when later called with
--parent.

Changes:
- Add ensureChildCounterUpdatedWithConn() to update counter on explicit child creation
- Add ParseHierarchicalID() to extract parent and child number from IDs
- Update CreateIssue to call counter update after hierarchical ID validation
- Update EnsureIDs to call counter update when parent exists
- Add post-insert phase in batch operations to update counters after FK
  constraint can be satisfied
- Update tests to reflect new behavior where counter is properly initialized

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 13:22:55 -08:00
Steve Yegge
ce2b05356a feat(deps): detect/prevent child→parent dependency anti-pattern (bd-nim5)
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>
2025-12-24 13:03:27 -08:00
Steve Yegge
9743b45c6d fix(import): preserve comment created_at timestamps during import (#735)
Comment timestamps were being overwritten with CURRENT_TIMESTAMP during
import, causing infinite sync loops between hosts as each import would
update timestamps.

Added ImportIssueComment() method that accepts and preserves the original
timestamp from JSONL, and updated importComments() to use it.

Closes #735
2025-12-24 12:45:20 -08:00
Charles P. Cross
cdbca65ed4 feat(config): add override notification for config parameters (#731)
feat(config): add override notification for config parameters

Adds verbose logging when config values are overridden by flags/env vars.
2025-12-24 12:35:54 -08:00
Charles P. Cross
48b96c9411 fix(config): normalize yaml config keys to canonical format (#732)
fix(config): normalize yaml config keys to canonical format

Fixes sync.branch vs sync-branch config key mismatch.
2025-12-24 12:35:50 -08:00
Charles P. Cross
8676c41c18 fix: address CI lint errors (gosec, errcheck, unparam, duplicate tests) (#730)
* fix: address CI lint errors (gosec, errcheck, unparam, duplicate tests)

- Remove duplicate TestHandleDelete_DryRun and TestHandleDelete_PartialSuccess
  from server_mutations_test.go (already defined in server_delete_test.go)
- Add nolint:gosec comments for exec.CommandContext calls in sync_branch.go
  (variables come from trusted config/git sources)
- Fix gosec G304/G306 in yaml_config.go (file read/write permissions)
- Fix errcheck in mol_run.go (templateStore.Close)
- Add nolint:unparam for updateYamlKey error return

* fix: add remaining nolint:gosec comments for exec.CommandContext calls

- sync_branch.go: diffCmd, logCmd (dry-run), commitCmd, pushCmd, remoteCmd
- sync_check.go: checkLocalCmd

* fix: add more nolint:gosec comments for exec.CommandContext calls

- sync_branch.go: pullCmd
- sync_check.go: localRefCmd, remoteRefCmd, aheadCmd
- sync_import.go: checkoutCmd

* fix: add final nolint:gosec comments for exec.CommandContext calls

- sync_check.go: behindCmd
- sync_import.go: fetchCmd

---------

Co-authored-by: Charles P. Cross <cpdata@users.noreply.github.com>
2025-12-24 12:35:32 -08:00
Steve Yegge
5cabb0f3d7 test(storage): add interface conformance tests for storage package (bd-a15d)
Add storage_test.go with:
- Compile-time interface conformance checks for Storage and Transaction
- Mock implementations for interface testing
- Config struct tests for sqlite and postgres configurations
- Interface documentation tests that verify all method groups exist

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 00:10:42 -08:00
Steve Yegge
d75eb2c409 test(rpc): Add comprehensive tests for daemon RPC delete handler
Adds tests for the daemon-side RPC delete handler (bd-dxtc):
- Dry-run mode returns preview without actual deletion
- Invalid issue IDs return appropriate errors
- Partial success when some IDs valid, some invalid
- No IDs provided error case
- Invalid JSON args handling
- Response structure validation (deleted_count, total_count)
- Storage not available error
- Tombstone creation with SQLite storage
- All failures error handling
- Dry-run preserves data across multiple runs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 00:10:23 -08:00
Steve Yegge
1a818cbced test(rpc): add comprehensive daemon delete RPC handler tests (bd-dxtc)
Add tests for the daemon Delete RPC handler to verify:

- Dry-run mode returns preview without actual deletion
- Error handling for empty issue IDs
- Error handling for non-existent issues
- Partial success when some issues exist and others do not
- Templates cannot be deleted (read-only protection)
- Invalid JSON args are properly rejected
- Reason field is passed through correctly
- Cascade and Force flags are accepted (documents current behavior)

All test scenarios from bd-dxtc issue are covered.

🤝 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 00:06:51 -08:00
Steve Yegge
143f5c80bf Fix TestMain to find module root before building bd binary
The TestMain in beads_hash_multiclone_test.go was running `go build ./cmd/bd`
from the package directory (internal/beads) instead of the module root, causing
the build to fail with "directory not found".

Now uses `go list -m -f '{{.Dir}}'` to locate the module root and sets cmd.Dir
appropriately before building.

This fixes the integration test setup that was preventing TestRoutingIntegration
from running. (bd-g9eu)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 00:06:41 -08:00
Steve Yegge
e67f27c092 bd sync: 2025-12-23 23:38:57 2025-12-24 00:06:41 -08:00
Steve Yegge
05e10b6759 Add comprehensive RPC test coverage (44.7% → 61.7%)
Removed Gate RPC tests that referenced undefined API methods.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 23:08:04 -08:00
Steve Yegge
f437ce2628 Improve internal/daemon test coverage from 27.3% to 72.0% (bd-n386)
Add discovery_unit_test.go with comprehensive unit tests that run without
the integration build tag. Tests cover:
- walkWithDepth: depth limiting, hidden dir skipping, callback errors
- checkDaemonErrorFile: file presence/absence, content reading
- CleanupStaleSockets: stale removal, alive daemon preservation
- findBeadsDirForWorkspace: regular repos, nonexistent paths
- discoverDaemon: socket missing, not listening, with error file
- discoverDaemonsLegacy: multiple roots, deduplication, filtering
- StopDaemon: not alive error, connection failures
- KillAllDaemons: empty list, not alive daemons, mixed states, force mode

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 22:39:22 -08:00
Steve Yegge
2de1695615 bd sync: 2025-12-23 22:33:32 2025-12-23 22:33:33 -08:00
Steve Yegge
cf9e5a597b bd sync: 2025-12-23 20:50:50 2025-12-23 20:50:50 -08:00
Steve Yegge
9c8761abc9 bd sync: 2025-12-23 20:45:19 2025-12-23 20:45:19 -08:00
Steve Yegge
f777093386 feat(rpc): add GetMoleculeProgress endpoint (bd-0oqz)
New RPC endpoint to get detailed progress for a molecule (parent issue
with child steps). Returns moleculeID, title, assignee, and list of
steps with their status (done/current/ready/blocked) and timestamps.

Used when user expands a worker in the activity feed TUI.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 18:27:35 -08:00
Steve Yegge
3a82ce2929 feat(rpc): add GetWorkerStatus RPC endpoint (bd-l13p)
New RPC endpoint to get all workers and their current molecule/step in one call.
Returns: assignee, moleculeID, moleculeTitle, currentStep, totalSteps, stepTitle,
lastActivity, status. Enables activity feed TUI to show worker state without
multiple round trips.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 17:12:58 -08:00
Steve Yegge
0d66aed954 feat(types): add omitempty to JSONL fields for smaller output
Add omitempty json tag to:
- Issue.Description: often empty for quick tasks
- Dependency.CreatedBy: often empty

This reduces JSONL file size when these fields are empty, leading to
faster syncs and smaller repository size.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 17:11:06 -08:00
Steve Yegge
3405f0c684 feat(rpc): enrich MutationEvent with Title and Assignee fields
Add Title and Assignee fields to MutationEvent struct so activity feeds
can display meaningful context without extra lookups. Updated emitMutation
signature to accept these values and modified all callers:

- Create: passes issue.Title and issue.Assignee directly
- Update/Close: moved emitMutation after GetIssue to access enriched data
- Delete: uses existing issue lookup before deletion
- Dep/Label/Comment ops: passes empty strings (would require extra lookup)

Fixes bd-gqxd

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 17:09:56 -08:00
Steve Yegge
e0f1d43c2c fix: write startup config keys to config.yaml instead of SQLite (GH#536)
`bd config set no-db true` now correctly writes to config.yaml instead of
SQLite. Previously, startup flags like no-db, no-daemon, no-auto-flush were
stored in SQLite but read from config.yaml at startup - making the command
appear to work while having no effect.

This adds:
- yaml_config.go: Defines yaml-only keys and provides SetYamlConfig/GetYamlConfig
- Updated config set/get commands to route yaml-only keys appropriately
- Comprehensive tests for yaml config handling

Startup flags affected: no-db, no-daemon, no-auto-flush, no-auto-import,
json, auto-start-daemon, flush-debounce, lock-timeout, git.*, sync.*, routing.*

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 17:03:39 -08:00
Steve Yegge
3d924f88f3 fix: handle multi-hyphen prefixes correctly (GH#422)
The prefix mismatch detection was using ExtractIssuePrefix() which
tries to guess the prefix by analyzing suffix patterns. This failed
for multi-hyphen prefixes like "asianops-audit-" when issue IDs had
word-like suffixes (e.g., "asianops-audit-test") - the heuristic
would fall back to the first hyphen and report "asianops-" as the
prefix.

Fixed by checking directly if the issue ID starts with the configured
prefix using strings.HasPrefix(). This is more reliable than guessing
since we know the expected prefix from the database config.

Added test case TestImportMultiHyphenPrefix to prevent regression.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 16:20:04 -08:00
Steve Yegge
fe2ac97597 fix: Exclude workflow types from bd ready by default (gt-7xtn)
merge-request, gate, molecule, and message types are internal workflow
items processed by Refinery/Deacon, not work for polecats to claim.
These are now excluded from bd ready unless explicitly requested via
--type flag.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 15:05:51 -08:00
Steve Yegge
7b671662aa bd sync: 2025-12-23 13:49:07 2025-12-23 14:39:07 -08:00
Steve Yegge
0d31e4209d fix: preserve pinned field during JSONL import (bd-phtv)
Fixed two code paths where pinned=false from JSONL would overwrite
existing pinned=true in database:
- importer.go: Only update pinned if explicitly true in JSONL
- multirepo.go: Use COALESCE to preserve existing pinned value

Added tests for pinned field preservation.

Note: Bug may have additional code path - investigation ongoing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 13:49:22 -08:00
Steve Yegge
f503a5ae43 test: improve syncbranch coverage from 27% to 67% (bd-io8c)
Add comprehensive tests for internal/syncbranch package:

syncbranch.go:
- TestGetFromYAML: env var and default behavior
- TestIsConfigured: env var presence detection
- TestIsConfiguredWithDB: database and env var checks
- TestGetConfigFromDB: direct DB value retrieval

worktree.go helper functions:
- TestIsNonFastForwardError: git push error detection
- TestHasChangesInWorktree: dirty state detection
- TestCommitInWorktree: worktree commit flow
- TestCopyJSONLToMainRepo: file sync between worktrees
- TestGetRemoteForBranch: remote name resolution
- TestGetRepoRoot: repo root detection including worktrees
- TestHasGitRemote: remote existence check
- TestGetCurrentBranch: branch name detection
- TestFormatVanishedIssues: forensic logging

worktree.go main functions:
- TestCommitToSyncBranch: basic commit flow
- TestPullFromSyncBranch: pull and fast-forward scenarios
- TestResetToRemote: remote reset error handling
- TestPushSyncBranch: push with worktree recreation
- TestPreemptiveFetchAndFastForward: pre-fetch behavior
- TestFetchAndRebaseInWorktree: rebase error handling
- TestRunCmdWithTimeoutMessage: command execution

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 13:48:40 -08:00
Steve Yegge
a129e36054 Add daemon RPC support for gate commands (bd-likt)
- Add gate operation constants (OpGateCreate, OpGateList, OpGateShow,
  OpGateClose, OpGateWait) to protocol.go
- Add Gate*Args and Gate*Result types to protocol.go
- Add gate handler methods (handleGateCreate, handleGateList,
  handleGateShow, handleGateClose, handleGateWait) to server_issues_epics.go
- Register gate handlers in handleRequest switch
- Add gate client methods (GateCreate, GateList, GateShow, GateClose,
  GateWait) to client.go
- Update cmd/bd/gate.go to use daemon client when available, falling
  back to direct store access

Gate commands now work with the daemon, eliminating the need for
--no-daemon flag.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 13:47:24 -08:00
Steve Yegge
1c2e7068ad test: improve internal/compact coverage from 17% to 82% (bd-thgk)
Add comprehensive unit tests for the compact package:

- haiku.go: Mock API tests for SummarizeTier1, retry logic tests for
  callWithRetry (429/500 handling, exhaust retries, context timeout),
  expanded isRetryable tests for network timeouts and API error codes
- git.go: Tests for GetCurrentCommitHash in various git states
  (in repo, outside repo, new repo, empty repo)
- compactor.go: Unit tests for New(), CompactTier1(), CompactTier1Batch()
  with mock API server, config validation, error paths

Small production change: NewHaikuClient now accepts variadic options
for testing (option.WithBaseURL, option.WithMaxRetries).

Coverage: 17.3% → 81.8%

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 13:42:24 -08:00