diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 58fd481f..06e9c547 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -198,9 +198,9 @@ {"id":"bd-7xrg","title":"Refinery Patrol","description":"Merge queue processor patrol loop with verification gates.","status":"closed","priority":2,"issue_type":"molecule","created_at":"2025-12-27T18:14:31.190713-08:00","updated_at":"2025-12-30T18:12:30.974709-08:00","closed_at":"2025-12-30T18:11:14.234636-08:00"} {"id":"bd-7yg","title":"Git merge driver uses invalid placeholders (%L, %R instead of %A, %B)","description":"## Problem\n\nThe beads git merge driver is configured with invalid Git placeholders:\n\n```\ngit config merge.beads.driver \"bd merge %A %O %L %R\"\n```\n\nGit doesn't recognize `%L` or `%R` as valid merge driver placeholders. The valid placeholders are:\n- `%O` = base (common ancestor)\n- `%A` = current version (ours)\n- `%B` = other version (theirs)\n\n## Impact\n\n- Affects ALL users when they have `.beads/beads.jsonl` merge conflicts\n- Automatic JSONL merge fails with error: \"error reading left file: failed to open file: open 7: no such file or directory\"\n- Users must manually resolve conflicts instead of getting automatic merge\n\n## Root Cause\n\nThe `bd init` command (or wherever the merge driver is configured) is using non-standard placeholders. When Git encounters `%L` and `%R`, it either passes them literally or interprets them incorrectly.\n\n## Fix\n\nUpdate the merge driver configuration to:\n```\ngit config merge.beads.driver \"bd merge %A %O %A %B\"\n```\n\nWhere:\n- 1st `%A` = output file (current file, will be overwritten)\n- `%O` = base (common ancestor)\n- 2nd `%A` = left/current version\n- `%B` = right/other version\n\n## Action Items\n\n1. Fix `bd init` (or equivalent setup command) to use correct placeholders\n2. Add migration/warning for existing users with misconfigured merge driver\n3. Update documentation with correct merge driver setup\n4. Consider adding validation when `bd init` is run","status":"tombstone","priority":1,"issue_type":"bug","created_at":"2025-11-21T19:51:55.747608-05:00","updated_at":"2025-12-25T01:21:01.952723-08:00","deleted_at":"2025-12-25T01:21:01.952723-08:00","deleted_by":"batch delete","delete_reason":"batch delete","original_type":"bug"} {"id":"bd-7z4","title":"Add tests for delete operations","description":"Core delete functionality including deleteViaDaemon, createTombstone, and deleteIssue functions have 0% coverage. These are critical for data integrity and need comprehensive test coverage.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-18T07:00:34.867680882-07:00","updated_at":"2025-12-23T23:48:50.087306-08:00","closed_at":"2025-12-23T23:48:50.087306-08:00","dependencies":[{"issue_id":"bd-7z4","depends_on_id":"bd-6ss","type":"discovered-from","created_at":"2025-12-18T07:00:34.870254935-07:00","created_by":"matt"}]} -{"id":"bd-7zka","title":"Implement formula features: Step.Condition and Step.Gate","description":"Multiple formula features in internal/formula/types.go are marked as \"Not yet implemented\":\n\nIMPLEMENTED (TODOs removed):\n- Step.Expand: Inline expansion - implemented in ApplyInlineExpansions (expand.go)\n- Step.ExpandVars: Variable overrides for expansion - implemented alongside Expand\n\nSTILL NOT IMPLEMENTED (TODOs remain):\n- Step.Condition: Make step optional based on variable (types.go:177-180)\n- Step.Gate: Async wait condition for step (types.go:185-187)\n- Gate struct: Schema defined but not processed in bd cook (types.go:209-210)\n\nFile: internal/formula/types.go","status":"hooked","priority":3,"issue_type":"feature","assignee":"beads/polecats/jasper","created_at":"2025-12-28T16:32:54.493002-08:00","created_by":"stevey","updated_at":"2026-01-01T16:11:22.018289-08:00"} +{"id":"bd-7zka","title":"Implement formula features: Step.Condition and Step.Gate","description":"Multiple formula features in internal/formula/types.go are marked as \"Not yet implemented\":\n\nIMPLEMENTED (TODOs removed):\n- Step.Expand: Inline expansion - implemented in ApplyInlineExpansions (expand.go)\n- Step.ExpandVars: Variable overrides for expansion - implemented alongside Expand\n\nSTILL NOT IMPLEMENTED (TODOs remain):\n- Step.Condition: Make step optional based on variable (types.go:177-180)\n- Step.Gate: Async wait condition for step (types.go:185-187)\n- Gate struct: Schema defined but not processed in bd cook (types.go:209-210)\n\nFile: internal/formula/types.go","status":"closed","priority":3,"issue_type":"feature","assignee":"beads/polecats/jasper","created_at":"2025-12-28T16:32:54.493002-08:00","created_by":"stevey","updated_at":"2026-01-01T16:24:44.939885-08:00","closed_at":"2026-01-01T16:24:44.939885-08:00","close_reason":"Both features implemented: Step.Condition and Step.Gate (Phase 1)"} {"id":"bd-7zka.1","title":"Implement Step.Condition evaluation in bd cook","description":"## Summary\nImplement conditional step execution based on variable values.\n\n## Location\n- Schema: `internal/formula/types.go:177-180`\n- Implement in: `internal/formula/cook.go` (or new file `condition.go`)\n\n## Current Schema\n```go\n// Condition makes this step optional based on a variable.\n// Format: \"{{var}}\" (truthy) or \"{{var}} == value\".\n// TODO(bd-7zka): Not yet implemented in bd cook. Filed as future work.\nCondition string `json:\"condition,omitempty\"`\n```\n\n## Implementation\n\n### Parsing\nSupport two formats:\n1. `\"{{var}}\"` - truthy check (non-empty, non-\"false\", non-\"0\")\n2. `\"{{var}} == value\"` - equality check\n\n```go\nfunc evaluateCondition(condition string, vars map[string]string) (bool, error) {\n // Check for equality format\n if strings.Contains(condition, \"==\") {\n parts := strings.SplitN(condition, \"==\", 2)\n varExpr := strings.TrimSpace(parts[0])\n expected := strings.TrimSpace(parts[1])\n \n // Extract variable name from {{var}}\n varName := extractVarName(varExpr)\n actual := vars[varName]\n return actual == expected, nil\n }\n \n // Truthy check\n varName := extractVarName(condition)\n val := vars[varName]\n return val != \"\" \u0026\u0026 val != \"false\" \u0026\u0026 val != \"0\", nil\n}\n```\n\n### Integration with bd cook\nIn the step processing loop, check condition before creating issue:\n```go\nif step.Condition != \"\" {\n include, err := evaluateCondition(step.Condition, vars)\n if err != nil {\n return fmt.Errorf(\"invalid condition %q: %w\", step.Condition, err)\n }\n if !include {\n continue // Skip this step\n }\n}\n```\n\n## Example Usage\n```yaml\nsteps:\n - title: \"Run integration tests\"\n condition: \"{{run_integration}}\"\n \n - title: \"Deploy to staging\"\n condition: \"{{environment}} == staging\"\n```\n\n## Testing\n- Test truthy evaluation (empty, \"false\", \"0\", valid value)\n- Test equality check\n- Test invalid condition format\n- Test missing variable (should be falsy)\n\n## Acceptance Criteria\n- [x] Truthy conditions work\n- [x] Equality conditions work\n- [x] Steps are skipped when condition is false\n- [x] Clear error on malformed condition\n- [x] Works with variable substitution","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-30T19:31:57.979217-08:00","created_by":"beads/crew/emma","updated_at":"2025-12-31T00:33:25.954831-08:00","closed_at":"2025-12-31T00:33:25.954831-08:00","close_reason":"Implemented Step.Condition evaluation in stepcondition.go with tests","dependencies":[{"issue_id":"bd-7zka.1","depends_on_id":"bd-7zka","type":"parent-child","created_at":"2025-12-30T19:31:57.97973-08:00","created_by":"beads/crew/emma"}]} -{"id":"bd-7zka.2","title":"Implement Gate evaluation in bd cook","description":"## Summary\nImplement async wait conditions (gates) for formula steps.\n\n## Design Decision: RESOLVED\n\n**Gates are issues.** A gate is a `bd-gate-*` prefixed issue that blocks the step it guards.\n\n### Gate Issue Structure\n```\nbd-gate-abc: Gate: gh:run test.yml\n type: gate\n gate_type: gh:run\n gate_target: test.yml\n gate_timeout: 1h\n gate_created: 2025-01-01T12:00:00Z\n blocks: bd-xyz # The step issue waiting on this gate\n```\n\n### Gate Types and Watchers\n\n| Gate Type | Signal Source | Watcher | Trigger |\n|-----------|---------------|---------|---------|\n| bead (cross-rig) | bd sync | Existing dep resolution | Sync |\n| gh:run | GitHub API | Refinery | Patrol poll |\n| gh:pr | GitHub API | Refinery | Patrol poll |\n| timer | Clock | Witness | Patrol cycle |\n| human | Human | None | bd close |\n| mail | Inbox | Deacon | Mail receipt (future) |\n\n### Visibility\n- bd list hides gate-type issues by default\n- bd gate list shows all open gates\n- bd mol show displays gates inline in molecule view\n\n### Timeouts\n- Gate timeout triggers escalation to Deacon/Overseer inbox\n- See: bd-0sgd (escalation inbox design)\n\n## Implementation Phases\n\n### Phase 1: Gate Issues + Human Gates\n- bd cook creates bd-gate-* issues for steps with gates\n- Gate issues block the next step via dependency\n- Human gates: just bd close bd-gate-xxx\n- bd list filters out type=gate by default\n- bd gate list command\n\n### Phase 2: Timer Gates\n- Witness patrol includes bd gate check --type=timer\n- Gate metadata: timeout, created_at\n- Expired gates escalate (not auto-close)\n\n### Phase 3: GitHub Gates\n- Refinery patrol includes bd gate check --type=gh\n- Uses gh CLI to check workflow/PR status\n- Resolved gates close\n\n### Phase 4: Cross-Rig Bead Gates\n- Leverage existing external dep resolution\n- bd cook creates gate with external dep on target bead\n- bd ready / bd sync resolves naturally\n\n### Phase 5: Mail Gates (future)\n- Deacon watches for mail responses\n- Complex - may YAGNI\n\n## Commands\n\n```bash\nbd gate list # Show open gates\nbd gate check # Evaluate all gates\nbd gate check --type=timer # Check only timer gates\nbd gate check --type=gh # Check only GitHub gates\nbd gate resolve \u003cid\u003e [--reason] # Force-close a gate\n```\n\n## Location\n- Schema: internal/formula/types.go\n- Gate issue creation: internal/formula/cook.go\n- Gate commands: cmd/bd/gate.go (new)\n- List filtering: cmd/bd/list.go\n\n## Acceptance Criteria\n- [ ] bd cook creates bd-gate-* issues for gated steps\n- [ ] Gate issues block subsequent steps\n- [ ] bd list hides gates by default\n- [ ] bd gate list shows all gates\n- [ ] bd gate check --type=timer works (Witness integration)\n- [ ] bd mol show displays gates in molecule view\n- [ ] Human gates closeable via bd close","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-30T19:32:19.664542-08:00","created_by":"beads/crew/emma","updated_at":"2026-01-01T15:35:02.840468-08:00","dependencies":[{"issue_id":"bd-7zka.2","depends_on_id":"bd-7zka","type":"parent-child","created_at":"2025-12-30T19:32:19.666332-08:00","created_by":"beads/crew/emma"},{"issue_id":"bd-7zka.2","depends_on_id":"bd-0sgd","type":"related","created_at":"2026-01-01T15:04:06.917484-08:00","created_by":"beads/crew/fang"}]} +{"id":"bd-7zka.2","title":"Implement Gate evaluation in bd cook","description":"## Summary\nImplement async wait conditions (gates) for formula steps.\n\n## Design Decision: RESOLVED\n\n**Gates are issues.** A gate is a `bd-gate-*` prefixed issue that blocks the step it guards.\n\n### Gate Issue Structure\n```\nbd-gate-abc: Gate: gh:run test.yml\n type: gate\n gate_type: gh:run\n gate_target: test.yml\n gate_timeout: 1h\n gate_created: 2025-01-01T12:00:00Z\n blocks: bd-xyz # The step issue waiting on this gate\n```\n\n### Gate Types and Watchers\n\n| Gate Type | Signal Source | Watcher | Trigger |\n|-----------|---------------|---------|---------|\n| bead (cross-rig) | bd sync | Existing dep resolution | Sync |\n| gh:run | GitHub API | Refinery | Patrol poll |\n| gh:pr | GitHub API | Refinery | Patrol poll |\n| timer | Clock | Witness | Patrol cycle |\n| human | Human | None | bd close |\n| mail | Inbox | Deacon | Mail receipt (future) |\n\n### Visibility\n- bd list hides gate-type issues by default\n- bd gate list shows all open gates\n- bd mol show displays gates inline in molecule view\n\n### Timeouts\n- Gate timeout triggers escalation to Deacon/Overseer inbox\n- See: bd-0sgd (escalation inbox design)\n\n## Implementation Phases\n\n### Phase 1: Gate Issues + Human Gates\n- bd cook creates bd-gate-* issues for steps with gates\n- Gate issues block the next step via dependency\n- Human gates: just bd close bd-gate-xxx\n- bd list filters out type=gate by default\n- bd gate list command\n\n### Phase 2: Timer Gates\n- Witness patrol includes bd gate check --type=timer\n- Gate metadata: timeout, created_at\n- Expired gates escalate (not auto-close)\n\n### Phase 3: GitHub Gates\n- Refinery patrol includes bd gate check --type=gh\n- Uses gh CLI to check workflow/PR status\n- Resolved gates close\n\n### Phase 4: Cross-Rig Bead Gates\n- Leverage existing external dep resolution\n- bd cook creates gate with external dep on target bead\n- bd ready / bd sync resolves naturally\n\n### Phase 5: Mail Gates (future)\n- Deacon watches for mail responses\n- Complex - may YAGNI\n\n## Commands\n\n```bash\nbd gate list # Show open gates\nbd gate check # Evaluate all gates\nbd gate check --type=timer # Check only timer gates\nbd gate check --type=gh # Check only GitHub gates\nbd gate resolve \u003cid\u003e [--reason] # Force-close a gate\n```\n\n## Location\n- Schema: internal/formula/types.go\n- Gate issue creation: internal/formula/cook.go\n- Gate commands: cmd/bd/gate.go (new)\n- List filtering: cmd/bd/list.go\n\n## Acceptance Criteria\n- [ ] bd cook creates bd-gate-* issues for gated steps\n- [ ] Gate issues block subsequent steps\n- [ ] bd list hides gates by default\n- [ ] bd gate list shows all gates\n- [ ] bd gate check --type=timer works (Witness integration)\n- [ ] bd mol show displays gates in molecule view\n- [ ] Human gates closeable via bd close","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-30T19:32:19.664542-08:00","created_by":"beads/crew/emma","updated_at":"2026-01-01T16:24:11.51872-08:00","closed_at":"2026-01-01T16:24:11.51872-08:00","close_reason":"Implemented Phase 1: Gate Issues + Human Gates","dependencies":[{"issue_id":"bd-7zka.2","depends_on_id":"bd-7zka","type":"parent-child","created_at":"2025-12-30T19:32:19.666332-08:00","created_by":"beads/crew/emma"},{"issue_id":"bd-7zka.2","depends_on_id":"bd-0sgd","type":"related","created_at":"2026-01-01T15:04:06.917484-08:00","created_by":"beads/crew/fang"}]} {"id":"bd-801b","title":"Merge: bd-bqcc","description":"branch: polecat/capable\ntarget: main\nsource_issue: bd-bqcc\nrig: beads","status":"closed","priority":2,"issue_type":"merge-request","created_at":"2025-12-23T00:26:04.306756-08:00","updated_at":"2025-12-23T01:33:25.728087-08:00","closed_at":"2025-12-23T01:33:25.728087-08:00"} {"id":"bd-83f5","title":"Remove top-level comment alias","description":"Remove 'comment' as top-level command. Users should use 'comments add' instead. Reduces command surface area.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-28T12:59:12.33579-08:00","created_by":"stevey","updated_at":"2025-12-28T13:06:53.335122-08:00","closed_at":"2025-12-28T13:06:53.335122-08:00"} {"id":"bd-89f89fc0","title":"Remove unreachable RPC methods","description":"Several RPC server and client methods are unreachable and should be removed:\n\nServer methods (internal/rpc/server.go):\n- `Server.GetLastImportTime` (line 2116)\n- `Server.SetLastImportTime` (line 2123)\n- `Server.findJSONLPath` (line 2255)\n\nClient methods (internal/rpc/client.go):\n- `Client.Import` (line 311) - RPC import not used (daemon uses autoimport)\n\nEvidence:\n```bash\ngo run golang.org/x/tools/cmd/deadcode@latest -test ./...\n```\n\nImpact: Removes ~80 LOC of unused RPC code","status":"tombstone","priority":2,"issue_type":"task","created_at":"2025-10-28T16:20:02.432202-07:00","updated_at":"2025-12-25T01:21:01.952723-08:00","deleted_at":"2025-12-25T01:21:01.952723-08:00","deleted_by":"batch delete","delete_reason":"batch delete","original_type":"task"} @@ -535,6 +535,7 @@ {"id":"bd-lfak.5","title":"Implement version-sync check (version.go vs default.nix)","description":"## Summary\nCheck that version in `cmd/bd/version.go` matches version in `default.nix`.\n\n## Current State (as of writing)\n- version.go: Version = \"0.41.0\"\n- default.nix: version = \"0.37.0\"\n- **These are already out of sync!** This check would catch this.\n\n## Implementation Details\n\n### Location\nFile: `cmd/bd/preflight.go`\n\n### Key Files\n- `cmd/bd/version.go` line 17: `Version = \"0.41.0\"`\n- `default.nix` line 4: `version = \"0.37.0\";`\n\n### Implementation\n\n```go\nfunc runVersionSyncCheck() CheckResult {\n // Read version.go\n versionGoContent, err := os.ReadFile(\"cmd/bd/version.go\")\n if err != nil {\n return CheckResult{\n Name: \"version-sync\",\n Passed: false,\n Output: fmt.Sprintf(\"Cannot read cmd/bd/version.go: %v\", err),\n Skipped: true,\n }\n }\n \n // Extract version from version.go\n // Pattern: Version = \"X.Y.Z\"\n versionGoRe := regexp.MustCompile(`Version\\s*=\\s*\"([^\"]+)\"`)\n versionGoMatch := versionGoRe.FindSubmatch(versionGoContent)\n if versionGoMatch == nil {\n return CheckResult{\n Name: \"version-sync\",\n Passed: false,\n Output: \"Cannot parse version from version.go\",\n Skipped: true,\n }\n }\n goVersion := string(versionGoMatch[1])\n \n // Read default.nix\n nixContent, err := os.ReadFile(\"default.nix\")\n if err != nil {\n return CheckResult{\n Name: \"version-sync\",\n Passed: true, // No nix file = no sync needed\n Output: \"default.nix not found (skipping nix version check)\",\n Skipped: true,\n }\n }\n \n // Extract version from default.nix\n // Pattern: version = \"X.Y.Z\";\n nixRe := regexp.MustCompile(`version\\s*=\\s*\"([^\"]+)\"`)\n nixMatch := nixRe.FindSubmatch(nixContent)\n if nixMatch == nil {\n return CheckResult{\n Name: \"version-sync\",\n Passed: false,\n Output: \"Cannot parse version from default.nix\",\n Skipped: true,\n }\n }\n nixVersion := string(nixMatch[1])\n \n if goVersion != nixVersion {\n return CheckResult{\n Name: \"version-sync\",\n Passed: false,\n Output: fmt.Sprintf(\"Version mismatch: version.go=%s, default.nix=%s\", goVersion, nixVersion),\n Command: \"Compare cmd/bd/version.go and default.nix\",\n }\n }\n \n return CheckResult{\n Name: \"version-sync\",\n Passed: true,\n Output: fmt.Sprintf(\"Versions match: %s\", goVersion),\n Command: \"Compare cmd/bd/version.go and default.nix\",\n }\n}\n```\n\n### Output Format\n```\n$ bd preflight --check\n✓ Version sync (0.41.0)\n\n# On mismatch:\n✗ Version mismatch\n version.go: 0.41.0\n default.nix: 0.37.0\n Fix: Update default.nix to match version.go\n```\n\n### Future: Auto-fix\nFor --fix mode, update default.nix automatically:\n```go\n// Replace version line in default.nix\nnewContent := nixRe.ReplaceAll(nixContent, \n []byte(fmt.Sprintf(`version = \"%s\"`, goVersion)))\nos.WriteFile(\"default.nix\", newContent, 0644)\n```\n\n### Testing\n- Test with matching versions\n- Test with mismatched versions (current state!)\n- Test with missing files\n\n### Acceptance Criteria\n- [x] Reads version from both files\n- [x] Compares and reports mismatch\n- [x] Shows both versions clearly on mismatch\n- [x] Works when default.nix is missing (skip gracefully)\n- [x] Works with --json flag","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-30T18:06:33.380378-08:00","created_by":"mayor","updated_at":"2025-12-31T00:08:48.691805-08:00","closed_at":"2025-12-31T00:08:48.691805-08:00","close_reason":"Implemented version sync check comparing version.go and default.nix; also fixed existing mismatch","dependencies":[{"issue_id":"bd-lfak.5","depends_on_id":"bd-lfak","type":"parent-child","created_at":"2025-12-30T18:06:33.382134-08:00","created_by":"mayor"},{"issue_id":"bd-lfak.5","depends_on_id":"bd-lfak.1","type":"blocks","created_at":"2025-12-30T18:06:48.64101-08:00","created_by":"mayor"},{"issue_id":"bd-lfak.5","depends_on_id":"bd-lfak.2","type":"blocks","created_at":"2025-12-30T19:31:30.989707-08:00","created_by":"beads/crew/emma"}]} {"id":"bd-lfiu","title":"bd dep add: Auto-resolve cross-rig IDs using routes.jsonl","description":"Currently, adding a dependency to an issue in another rig requires verbose external reference syntax:\n\n```bash\n# This fails - can't resolve bd-* from gastown context\nbd dep add gt-xyz bd-abc\n\n# This works but is verbose\nbd dep add gt-xyz external:beads:bd-abc\n```\n\nThe town-level routing (~/gt/.beads/routes.jsonl) already knows how to map prefixes to rigs:\n```json\n{\"prefix\": \"gt-\", \"path\": \"gastown/mayor/rig\"}\n{\"prefix\": \"bd-\", \"path\": \"beads/mayor/rig\"}\n```\n\nEnhancement: When `bd dep add` encounters an ID with a foreign prefix, it should:\n1. Check routes.jsonl for the prefix mapping\n2. Auto-resolve to external:\u003cproject\u003e:\u003cid\u003e internally\n3. Allow the simpler `bd dep add gt-xyz bd-abc` syntax\n\nThis would make cross-rig dependencies much more ergonomic.","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-12-26T20:20:40.814713-08:00","updated_at":"2025-12-26T23:47:52.82107-08:00","closed_at":"2025-12-26T23:47:52.82107-08:00"} {"id":"bd-likt","title":"Add daemon RPC support for gate commands","description":"Add daemon RPC support for gate commands.\n\n## Current State\nGate commands require --no-daemon flag because they use direct SQLite access:\n- Gate create needs to write await_type, await_id, timeout_ns, waiters fields\n- Gate wait needs to update waiters JSON array\n- Daemon RPC doesnt have methods for these operations\n\n## Implementation\n\n### 1. Add RPC methods to internal/rpc/protocol.go\n\n```go\n// Gate operations\ntype GateCreateArgs struct {\n Title string \\`json:\"title\"\\`\n AwaitType string \\`json:\"await_type\"\\`\n AwaitID string \\`json:\"await_id\"\\`\n Timeout time.Duration \\`json:\"timeout\"\\`\n Waiters []string \\`json:\"waiters\"\\`\n}\n\ntype GateCreateResult struct {\n Issue *types.Issue \\`json:\"issue\"\\`\n}\n\ntype GateListArgs struct {\n All bool \\`json:\"all\"\\` // Include closed gates\n}\n\ntype GateListResult struct {\n Gates []*types.Issue \\`json:\"gates\"\\`\n}\n\ntype GateWaitArgs struct {\n GateID string \\`json:\"gate_id\"\\`\n Waiters []string \\`json:\"waiters\"\\` // Additional waiters to add\n}\n\ntype GateWaitResult struct {\n Gate *types.Issue \\`json:\"gate\"\\`\n AddedCount int \\`json:\"added_count\"\\`\n}\n```\n\n### 2. Add handler methods to internal/daemon/rpc_handler.go\n\n```go\nfunc (h *RPCHandler) GateCreate(ctx context.Context, args *rpc.GateCreateArgs) (*rpc.GateCreateResult, error) {\n now := time.Now()\n gate := \u0026types.Issue{\n Title: args.Title,\n IssueType: types.TypeGate,\n Status: types.StatusOpen,\n Priority: 1,\n Assignee: \"deacon/\",\n Wisp: true,\n AwaitType: args.AwaitType,\n AwaitID: args.AwaitID,\n Timeout: args.Timeout,\n Waiters: args.Waiters,\n CreatedAt: now,\n UpdatedAt: now,\n }\n gate.ContentHash = gate.ComputeContentHash()\n \n if err := h.store.CreateIssue(ctx, gate, h.actor); err != nil {\n return nil, err\n }\n \n return \u0026rpc.GateCreateResult{Issue: gate}, nil\n}\n\nfunc (h *RPCHandler) GateList(ctx context.Context, args *rpc.GateListArgs) (*rpc.GateListResult, error) {\n gateType := types.TypeGate\n filter := types.IssueFilter{IssueType: \u0026gateType}\n if !args.All {\n openStatus := types.StatusOpen\n filter.Status = \u0026openStatus\n }\n \n gates, err := h.store.SearchIssues(ctx, \"\", filter)\n if err != nil {\n return nil, err\n }\n \n return \u0026rpc.GateListResult{Gates: gates}, nil\n}\n\nfunc (h *RPCHandler) GateWait(ctx context.Context, args *rpc.GateWaitArgs) (*rpc.GateWaitResult, error) {\n gate, err := h.store.GetIssue(ctx, args.GateID)\n if err != nil {\n return nil, err\n }\n if gate.IssueType != types.TypeGate {\n return nil, fmt.Errorf(\"%s is not a gate\", args.GateID)\n }\n \n // Merge waiters (dedupe)\n waiterSet := make(map[string]bool)\n for _, w := range gate.Waiters {\n waiterSet[w] = true\n }\n added := 0\n for _, w := range args.Waiters {\n if !waiterSet[w] {\n gate.Waiters = append(gate.Waiters, w)\n waiterSet[w] = true\n added++\n }\n }\n \n if added \u003e 0 {\n // Update via store\n updates := map[string]interface{}{\n \"waiters\": gate.Waiters,\n }\n if err := h.store.UpdateIssue(ctx, args.GateID, updates, h.actor); err != nil {\n return nil, err\n }\n }\n \n return \u0026rpc.GateWaitResult{Gate: gate, AddedCount: added}, nil\n}\n```\n\n### 3. Register methods in daemon\n\nIn internal/daemon/server.go, register the new methods:\n```go\nrpc.RegisterMethod(\"gate.create\", h.GateCreate)\nrpc.RegisterMethod(\"gate.list\", h.GateList)\nrpc.RegisterMethod(\"gate.wait\", h.GateWait)\n```\n\n### 4. Add client methods to internal/rpc/client.go\n\n```go\nfunc (c *Client) GateCreate(ctx context.Context, args *GateCreateArgs) (*GateCreateResult, error) {\n var result GateCreateResult\n err := c.Call(ctx, \"gate.create\", args, \u0026result)\n return \u0026result, err\n}\n\nfunc (c *Client) GateList(ctx context.Context, args *GateListArgs) (*GateListResult, error) {\n var result GateListResult\n err := c.Call(ctx, \"gate.list\", args, \u0026result)\n return \u0026result, err\n}\n\nfunc (c *Client) GateWait(ctx context.Context, args *GateWaitArgs) (*GateWaitResult, error) {\n var result GateWaitResult\n err := c.Call(ctx, \"gate.wait\", args, \u0026result)\n return \u0026result, err\n}\n```\n\n### 5. Update cmd/bd/gate.go to use daemon\n\n```go\n// In gateCreateCmd Run:\nif daemonClient != nil {\n result, err := daemonClient.GateCreate(ctx, \u0026rpc.GateCreateArgs{\n Title: title,\n AwaitType: awaitType,\n AwaitID: awaitID,\n Timeout: timeout,\n Waiters: notifyAddrs,\n })\n if err != nil {\n FatalError(\"gate create: %v\", err)\n }\n gate = result.Issue\n} else {\n // Existing direct store code\n}\n```\n\n## Files to Modify\n\n1. **internal/rpc/protocol.go** - Add Gate*Args/Result types\n2. **internal/daemon/rpc_handler.go** - Add handler methods\n3. **internal/daemon/server.go** - Register methods\n4. **internal/rpc/client.go** - Add client methods\n5. **cmd/bd/gate.go** - Use daemon client when available\n\n## Testing\n\n```bash\n# Start daemon\nbd daemon start\n\n# Test via daemon (should work without --no-daemon)\nbd gate create --await timer:5m --notify beads/dave\nbd gate list\nbd gate wait \u003cid\u003e --notify beads/alice\n\n# Verify daemon handled it\nbd daemons logs . | grep gate\n```\n\n## Success Criteria\n- All gate commands work without --no-daemon\n- Same behavior in daemon vs direct mode\n- Waiters array updates correctly via RPC\n- Tests pass for RPC gate operations","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-23T12:13:25.778412-08:00","updated_at":"2025-12-23T13:45:58.398604-08:00","closed_at":"2025-12-23T13:45:58.398604-08:00","dependencies":[{"issue_id":"bd-likt","depends_on_id":"bd-udsi","type":"discovered-from","created_at":"2025-12-23T12:13:36.174822-08:00","created_by":"daemon"},{"issue_id":"bd-likt","depends_on_id":"bd-iz5t","type":"parent-child","created_at":"2025-12-23T12:44:07.891992-08:00","created_by":"daemon"}]} +{"id":"bd-ljp1","title":"Merge: onyx-mjw4oxsi","description":"branch: polecat/onyx-mjw4oxsi\ntarget: main\nsource_issue: onyx-mjw4oxsi\nrig: beads\nagent_bead: gt-beads-polecat-onyx","status":"open","priority":2,"issue_type":"merge-request","created_at":"2026-01-01T16:25:15.980399-08:00","created_by":"beads/polecats/onyx","updated_at":"2026-01-01T16:25:15.980399-08:00"} {"id":"bd-lk39","title":"Add composite index (issue_id, event_type) on events table","description":"GetCloseReason and GetCloseReasonsForIssues filter by both issue_id and event_type.\n\n**Query (queries.go:355-358):**\n```sql\nSELECT comment FROM events\nWHERE issue_id = ? AND event_type = ?\nORDER BY created_at DESC LIMIT 1\n```\n\n**Problem:** Currently uses idx_events_issue but must filter event_type in memory.\n\n**Solution:** Add migration:\n```sql\nCREATE INDEX IF NOT EXISTS idx_events_issue_type ON events(issue_id, event_type);\n```\n\n**Priority:** Low - events table is typically small relative to issues.","status":"closed","priority":4,"issue_type":"task","created_at":"2025-12-22T22:58:54.070587-08:00","updated_at":"2025-12-22T23:15:13.841988-08:00","closed_at":"2025-12-22T23:15:13.841988-08:00","dependencies":[{"issue_id":"bd-lk39","depends_on_id":"bd-h0we","type":"discovered-from","created_at":"2025-12-22T22:58:54.071286-08:00","created_by":"daemon"}]} {"id":"bd-ll2n","title":"Move relate/unrelate under dep command","description":"Make relate and unrelate subcommands of dep (dep relate, dep unrelate). They're dependency operations and belong there.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-28T12:59:10.379321-08:00","created_by":"stevey","updated_at":"2025-12-28T13:04:02.520266-08:00","closed_at":"2025-12-28T13:04:02.520266-08:00"} {"id":"bd-llfl","title":"Improve test coverage for cmd/bd CLI (26.2% → 50%)","description":"The main CLI package (cmd/bd) has only 26.2% test coverage. CLI commands should have at least 50% coverage to ensure reliability.\n\nKey areas with low/no coverage:\n- daemon_autostart.go (multiple 0% functions)\n- compact.go (several 0% functions)\n- Various command handlers\n\nCurrent coverage: 26.2%\nTarget coverage: 50%","notes":"## Progress Update (2025-12-30 - Session 2)\n\n### Tests Added\nAdded 479 lines of new tests across 4 files:\n- cmd/bd/utils_unit_test.go (214 lines) - NEW\n - TestTruncateString, TestPluralize, TestFormatTimeAgo\n - TestContainsLabel, TestGetContributorsSorted, TestExtractIDSuffix \n - TestTruncate, TestTruncateDescription\n - TestShowCleanupDeprecationHint, TestClearAutoFlushState\n\n- cmd/bd/hooks_test.go (117 lines added)\n - TestFormatHookWarnings, TestIsRebaseInProgress, TestHasBeadsJSONL\n\n- cmd/bd/list_test.go (140 lines added)\n - TestFormatIssueLong, TestFormatIssueCompact\n\n- cmd/bd/version_tracking_test.go (8 lines)\n - Fixed flaky tests by setting BEADS_DIR env var\n\n### Coverage Results\n- Before: 21.6%\n- After: 22.0%\n- Delta: +0.4%\n\n### Remaining Work\nCoverage is still at 22% vs target 50%. The remaining 78% involves:\n1. Daemon/RPC operations (runDaemonLoop, tryAutoStartDaemon, etc.)\n2. Command handlers requiring database/daemon setup\n3. Git operations (runPreCommitHook, runPostMergeHook, etc.)\n\nTo reach 50%, would need:\n- Integration tests with mocked daemon (use -tags=integration)\n- scripttest tests for command handlers\n- More database-dependent tests\n\nCommit: 8c7d94d3","status":"hooked","priority":2,"issue_type":"task","created_at":"2025-12-13T20:43:03.123341-08:00","updated_at":"2025-12-30T18:12:30.981243-08:00"} @@ -677,6 +678,7 @@ {"id":"bd-ox1o","title":"Code Review Round 2: Beads Refactoring","description":"Second pass code review of Beads codebase. Found 10 HIGH/MEDIUM priority issues.\n\n**HIGH (P2):**\n- bd-6dnt: Duplicated IssueDetails struct (4 definitions)\n- bd-vqh9: init.go is 1928 lines\n- bd-it19: show.go is 1592 lines\n\n**MEDIUM (P3):**\n- bd-qobn: 20+ global variables in main.go\n- bd-0e02: Inconsistent error handling patterns\n- bd-g6m5: Mixed daemon/direct mode logic\n- bd-qe7j: Incomplete TODOs in formula/types.go\n- bd-4sxh: Issue struct ~100 fields\n- bd-yuxq: 262 uses of interface{}\n- bd-jbqx: Repeated validation patterns","status":"closed","priority":2,"issue_type":"epic","created_at":"2025-12-28T19:00:15.483532-08:00","created_by":"beads/crew/dave","updated_at":"2025-12-29T13:40:29.721916-08:00","closed_at":"2025-12-29T13:40:29.721916-08:00","close_reason":"Stale/spurious - test artifacts, merged PRs, or auto-close candidates"} {"id":"bd-oxgi","title":"Add mol_type schema field to beads","description":"Add mol_type field to distinguish molecule types (swarm/patrol/work).\n\n## Context\nSwarms need to be distinguishable from regular work molecules. The mol_type field enables:\n- Filtering: bd list --type=swarm \n- Queries: Find all active swarm molecules\n- Coordinator logic: Different handling for different mol types\n\n## Implementation\n1. Add mol_type column to SQLite schema (nullable, default null = work)\n2. Add mol_type to JSONL format\n3. Update create command to accept --mol-type\n4. Update list/ready commands to filter by mol_type\n5. Values: 'swarm', 'patrol', 'work', null (null = work)\n\n## Reference\n~/gt/docs/swarm-architecture.md - 'Data Model' section\n\n## Acceptance\n- bd create --mol-type=swarm works\n- bd list --mol-type=swarm filters correctly\n- Existing molecules work unchanged (backward compatible)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-28T19:11:07.616818-08:00","created_by":"mayor","updated_at":"2025-12-28T19:50:33.213538-08:00","closed_at":"2025-12-28T19:50:33.213538-08:00"} {"id":"bd-oy6c","title":"Bump version in all files","description":"Run ./scripts/bump-version.sh 0.33.2 to update 10 version files. Then run with --commit after info.go is updated.","status":"tombstone","priority":1,"issue_type":"task","created_at":"2025-12-21T16:10:13.759706-08:00","updated_at":"2025-12-21T17:29:31.791368-08:00","deleted_at":"2025-12-21T17:29:31.791368-08:00","deleted_by":"batch delete","delete_reason":"batch delete","original_type":"task"} +{"id":"bd-oy7n","title":"Merge: jasper-mjw4bxkx","description":"branch: polecat/jasper-mjw4bxkx\ntarget: main\nsource_issue: jasper-mjw4bxkx\nrig: beads\nagent_bead: gt-beads-polecat-jasper","status":"closed","priority":2,"issue_type":"merge-request","created_at":"2026-01-01T16:25:12.663026-08:00","created_by":"beads/polecats/jasper","updated_at":"2026-01-01T16:26:55.339728-08:00","closed_at":"2026-01-01T16:26:55.339728-08:00","close_reason":"Merged to main"} {"id":"bd-p5za","title":"mol-christmas-launch: 3-day execution plan","description":"Christmas Launch Molecule - execute phases in order, survive restarts.\n\nPIN THIS BEAD. Check progress each session start.\n\n## Step: phase0-beads-foundation\nFix blocking issues before swarming:\n1. Verify gastown beads schema works: bd list --status=open\n2. Ensure bd mol bond exists (check bd-usro)\n3. Verify bd-2vh3 (squash) is filed\n\n## Step: phase1-polecat-loop\nSerial work on polecat execution:\n1. gt-9nf: Fresh polecats only\n2. gt-975: Molecule execution support\n3. gt-8v8: Refuse uncommitted work\nThen swarm: gt-e1y, gt-f8v, gt-eu9\nNeeds: phase0-beads-foundation\n\n## Step: phase2-refinery\nSerial work on refinery autonomy:\n1. gt-5gkd: Refinery CLAUDE.md\n2. gt-bj6f: Refinery context in gt prime\n3. gt-0qki: Refinery-Witness protocol\nNeeds: phase1-polecat-loop\n\n## Step: phase3-deacon\nHealth monitoring infrastructure:\n1. gt-5af.4: Simplify daemon\n2. gt-5af.7: Crew session patterns\n3. gt-976: Crew lifecycle\nNeeds: phase2-refinery\n\n## Step: phase4-code-review\nSelf-improvement flywheel:\n1. Define mol-code-review (gt-fjvo)\n2. Test on open MRs\n3. Integrate with Refinery\nNeeds: phase3-deacon\n\n## Step: phase5-polish\nDemo readiness:\n1. gt-b2hj: Find orphaned work\n2. Doctor checks\n3. Clean up open MRs\nNeeds: phase4-code-review\n\n## Step: verify-flywheel\nSuccess criteria:\n- gt spawn works with molecules\n- Refinery processes MRs autonomously\n- mol-code-review runs on a PR\n- bd cleanup --ephemeral works\nNeeds: phase5-polish","status":"closed","priority":0,"issue_type":"epic","created_at":"2025-12-20T21:20:02.462889-08:00","updated_at":"2025-12-21T17:23:25.471749-08:00","closed_at":"2025-12-21T17:23:25.471749-08:00"} {"id":"bd-pbh","title":"Release v0.30.4","description":"## Version Bump Workflow\n\nCoordinating release from 0.30.3 to 0.30.4.\n\n### Components Updated\n- Go CLI (cmd/bd/version.go)\n- Claude Plugin (.claude-plugin/*.json)\n- MCP Server (integrations/beads-mcp/)\n- npm Package (npm-package/package.json)\n- Git hooks (cmd/bd/templates/hooks/)\n\n### Release Channels\n- GitHub Releases (GoReleaser)\n- PyPI (beads-mcp)\n- npm (@beads/cli)\n- Homebrew (homebrew-beads tap)\n","status":"tombstone","priority":1,"issue_type":"epic","created_at":"2025-12-17T21:19:10.926133-08:00","updated_at":"2025-12-25T01:21:01.952723-08:00","labels":["release","v0.30.4","workflow"],"deleted_at":"2025-12-25T01:21:01.952723-08:00","deleted_by":"batch delete","delete_reason":"batch delete","original_type":"epic"} {"id":"bd-pbh.1","title":"Update cmd/bd/version.go to 0.30.4","description":"Update the Version constant in cmd/bd/version.go:\n```go\nVersion = \"0.30.4\"\n```\n\n\n```verify\ngrep -q 'Version = \"0.30.4\"' cmd/bd/version.go\n```","status":"tombstone","priority":1,"issue_type":"task","created_at":"2025-12-17T21:19:10.9462-08:00","updated_at":"2025-12-25T01:21:01.952723-08:00","labels":["workflow"],"dependencies":[{"issue_id":"bd-pbh.1","depends_on_id":"bd-pbh","type":"parent-child","created_at":"2025-12-17T21:19:10.946633-08:00","created_by":"daemon"}],"deleted_at":"2025-12-25T01:21:01.952723-08:00","deleted_by":"batch delete","delete_reason":"batch delete","original_type":"task"} @@ -777,7 +779,7 @@ {"id":"bd-s5kf","title":"Merge: onyx-1767083477016","description":"branch: polecat/onyx-1767083477016\ntarget: main\nsource_issue: onyx-1767083477016\nrig: beads","status":"closed","priority":2,"issue_type":"merge-request","created_at":"2025-12-30T00:37:08.214926-08:00","created_by":"beads/polecats/onyx","updated_at":"2025-12-30T00:54:59.041942-08:00","closed_at":"2025-12-30T00:54:59.041942-08:00","close_reason":"Branch polecat/onyx-1767083477016 no longer exists on remote"} {"id":"bd-sal9","title":"bd mol current: soft cursor showing current/next step","description":"Add bd mol current command for molecule navigation orientation.\n\n## Usage\n\nbd mol current [mol-id]\n\nIf mol-id given, show status for that molecule.\nIf not given, infer from in_progress issues assigned to current agent.\n\n## Output\n\nYou're working on molecule gt-abc (Feature X)\n\n [done] gt-abc.1: Design\n [done] gt-abc.2: Scaffold \n [done] gt-abc.3: Implement\n [current] gt-abc.4: Write tests [in_progress] \u003c- YOU ARE HERE\n [pending] gt-abc.5: Documentation\n [pending] gt-abc.6: Exit decision\n\nProgress: 3/6 steps complete\n\n## Key behaviors\n- Shows full molecule structure with status indicators\n- Highlights current in_progress step\n- If no in_progress, highlights first ready step\n- Works without explicit cursor tracking (inferred from state)\n\n## Implementation notes\n- Query children of mol-id\n- Sort by dependency order\n- Find first in_progress or first ready\n- Format with status indicators\n\n## Gas Town integration\n- gt-lz13: Update templates with nav workflow\n- gt-um6q: Update docs with nav workflow","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-22T17:03:30.245964-08:00","updated_at":"2025-12-22T17:36:31.936007-08:00","closed_at":"2025-12-22T17:36:31.936007-08:00"} {"id":"bd-sco6","title":"Emit issue title with dep/label mutation events","description":"When dependencies or labels are added, mutations are emitted without title/assignee:\n\n```go\ns.emitMutation(MutationUpdate, depArgs.FromID, \"\", \"\") // server_labels_deps_comments.go:68\ns.emitMutation(MutationUpdate, issueID, \"\", \"\") // server_labels_deps_comments.go:101\n```\n\nThis causes bd activity (and gt feed) to show less informative entries like:\n```\n[20:42:17] → gt-4ntnq updated\n```\n\nInstead of:\n```\n[20:42:17] → gt-4ntnq updated · Pipeline Reliability: Fix work loss...\n```\n\n**Fix**: Look up issue title in dep/label handlers before emitting mutation. This adds one extra DB read per dep/label operation, but these are infrequent enough that it's acceptable.\n\n**Related**: gt feed now deduplicates rapid updates in gastown commit (to be pushed).","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-12-30T21:13:31.574249-08:00","created_by":"gastown/crew/joe","updated_at":"2025-12-30T21:21:45.081602-08:00","closed_at":"2025-12-30T21:21:45.081602-08:00","close_reason":"Added lookupIssueMeta helper; mutation events now include title/assignee for dep/label/comment operations"} -{"id":"bd-sfcq","title":"Tests fail due to .beads directory discovery escaping temp dirs","description":"Multiple tests fail when run from within the beads repo tree:\n\n- TestFindBeadsDir (autoimport_test.go)\n- TestFindBeadsDir_ParentDirectory (autoimport_test.go)\n- TestFindDatabasePathEnvVar (beads_test.go)\n- TestFindDatabasePathInTree (beads_test.go)\n- TestIsConfiguredWithDB (syncbranch_test.go)\n\nRoot cause: Tests create temp directories and call functions that walk upward to find .beads directories. When tests run inside the beads repo, the walk escapes the temp dir and finds /Users/stevey/gt/beads/mayor/rig/.beads instead.\n\nFix approaches:\n1. Set BEADS_DB env var in tests to prevent discovery\n2. Use t.Setenv() with BEADS_DISCOVERY_ROOT or similar\n3. Add a stop-at-git-root behavior\n4. Mock the discovery function in tests","status":"open","priority":1,"issue_type":"bug","assignee":"beads/polecats/obsidian","created_at":"2026-01-01T15:50:04.141197-08:00","created_by":"beads/refinery","updated_at":"2026-01-01T16:20:07.066132-08:00"} +{"id":"bd-sfcq","title":"Tests fail due to .beads directory discovery escaping temp dirs","description":"Multiple tests fail when run from within the beads repo tree:\n\n- TestFindBeadsDir (autoimport_test.go)\n- TestFindBeadsDir_ParentDirectory (autoimport_test.go)\n- TestFindDatabasePathEnvVar (beads_test.go)\n- TestFindDatabasePathInTree (beads_test.go)\n- TestIsConfiguredWithDB (syncbranch_test.go)\n\nRoot cause: Tests create temp directories and call functions that walk upward to find .beads directories. When tests run inside the beads repo, the walk escapes the temp dir and finds /Users/stevey/gt/beads/mayor/rig/.beads instead.\n\nFix approaches:\n1. Set BEADS_DB env var in tests to prevent discovery\n2. Use t.Setenv() with BEADS_DISCOVERY_ROOT or similar\n3. Add a stop-at-git-root behavior\n4. Mock the discovery function in tests","status":"closed","priority":1,"issue_type":"bug","assignee":"beads/polecats/onyx","created_at":"2026-01-01T15:50:04.141197-08:00","created_by":"beads/refinery","updated_at":"2026-01-01T16:24:45.907692-08:00","closed_at":"2026-01-01T16:24:45.907692-08:00","close_reason":"Fixed: added missing session parameter to two CloseIssue calls in daemon mode"} {"id":"bd-sh4c","title":"Improve test coverage for cmd/bd/setup (28.4% → 50%)","description":"The setup package has only 28.4% test coverage. Setup commands are critical for first-time user experience.\n\nCurrent coverage: 28.4%\nTarget coverage: 50%","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-13T20:43:04.409346-08:00","updated_at":"2025-12-23T22:37:13.494999-08:00","closed_at":"2025-12-23T22:37:13.494999-08:00"} {"id":"bd-si4g","title":"Verify release artifacts","description":"Check GitHub releases page - binaries for darwin/linux/windows should be available","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-19T22:56:04.183029-08:00","updated_at":"2025-12-20T00:49:51.92894-08:00","closed_at":"2025-12-20T00:25:52.720816-08:00","dependencies":[{"issue_id":"bd-si4g","depends_on_id":"bd-6s61","type":"parent-child","created_at":"2025-12-19T22:56:15.173619-08:00","created_by":"daemon"},{"issue_id":"bd-si4g","depends_on_id":"bd-otli","type":"blocks","created_at":"2025-12-19T22:56:23.428507-08:00","created_by":"daemon"}]} {"id":"bd-siz1","title":"GH#532: bd sync circular error (suggests running bd sync)","description":"bd sync error message recommends running bd sync to fix the bd sync error. Fix error handling to provide useful guidance. See GitHub issue #532.","status":"tombstone","priority":2,"issue_type":"bug","created_at":"2025-12-16T01:04:00.543573-08:00","updated_at":"2025-12-17T16:11:17.070763-08:00","deleted_at":"2025-12-17T16:11:17.070763-08:00","deleted_by":"batch delete","delete_reason":"batch delete","original_type":"bug"}