chore(beads): update issue tracking

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-07 21:10:34 +11:00
parent 49bfdc2523
commit b59a4645f3

View File

@@ -47,7 +47,7 @@
{"id":"bd-73u","title":"Refactor daemon local-only sync functions to reduce duplication","description":"PR #433 added three new local-only sync functions (createLocalSyncFunc, createLocalExportFunc, createLocalAutoImportFunc) that are largely copy-paste of existing ones with git operations removed. Refactor to use a single implementation with a skipGit bool parameter or extract shared logic into helper functions to reduce ~200 lines of duplication.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-01T17:38:02.632264-08:00","updated_at":"2025-12-02T23:28:48.752202-08:00","closed_at":"2025-12-01T21:08:11.952459-08:00"}
{"id":"bd-7ch","title":"Auto-push after merge with safety check","description":"Make bd sync a true one-command solution by auto-pushing after successful content merge.\n\nBehavior:\n- After successful content merge, auto-push by default\n- Safety check: detect when \u003e50% issues vanished AND \u003e5 existed before\n- On safety check trigger: warn but still push (do not block happy path)\n\nVanished means issues removed from issues.jsonl entirely, NOT status=closed (closed is legitimate swarm completion).\n\nLocation: internal/syncbranch/worktree.go\nParent issue: bd-3s8","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-02T19:30:59.540636-08:00","updated_at":"2025-12-03T22:12:25.328091-08:00","closed_at":"2025-12-03T22:12:25.328091-08:00"}
{"id":"bd-81a","title":"Add programmatic tip injection API","description":"Allow tips to be programmatically injected at runtime based on detected conditions. This enables dynamic tips (not just pre-defined ones) to be shown with custom priority and frequency.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-11T23:29:46.645583-08:00","updated_at":"2025-11-25T17:52:35.096882-08:00","closed_at":"2025-11-25T17:52:35.096882-08:00","dependencies":[{"issue_id":"bd-81a","depends_on_id":"bd-d4i","type":"blocks","created_at":"2025-11-11T23:29:46.646327-08:00","created_by":"daemon"}]}
{"id":"bd-81x6","title":"Tombstone export includes tombstones even with --status filter","description":"In export.go, we set IncludeTombstones: true unconditionally. However, if a user runs:\n\n bd export --status=open\n\nThey might not expect tombstones in the output. The IncludeTombstones flag should probably only be set when no status filter is specified, or when --status=tombstone is explicitly requested.\n\nCurrent behavior: exports tombstones regardless of status filter\nExpected behavior: respect status filter, only include tombstones when explicitly requested or no filter","status":"in_progress","priority":2,"issue_type":"bug","created_at":"2025-12-07T01:40:52.762758-08:00","updated_at":"2025-12-07T01:55:47.446247-08:00","dependencies":[{"issue_id":"bd-81x6","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-07T01:41:28.320845-08:00","created_by":"daemon"}]}
{"id":"bd-81x6","title":"Tombstone export includes tombstones even with --status filter","description":"In export.go, we set IncludeTombstones: true unconditionally. However, if a user runs:\n\n bd export --status=open\n\nThey might not expect tombstones in the output. The IncludeTombstones flag should probably only be set when no status filter is specified, or when --status=tombstone is explicitly requested.\n\nCurrent behavior: exports tombstones regardless of status filter\nExpected behavior: respect status filter, only include tombstones when explicitly requested or no filter","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-07T01:40:52.762758-08:00","updated_at":"2025-12-07T02:00:02.011512-08:00","closed_at":"2025-12-07T02:00:02.011512-08:00","dependencies":[{"issue_id":"bd-81x6","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-07T01:41:28.320845-08:00","created_by":"daemon"}]}
{"id":"bd-8a5","title":"Refactor: deduplicate FindJSONLInDir and FindJSONLPath","description":"## Background\n\nAfter fixing bd-tqo, we now have two nearly identical functions for finding the JSONL file:\n- `autoimport.FindJSONLInDir(dbDir string)` in internal/autoimport/autoimport.go\n- `beads.FindJSONLPath(dbPath string)` in internal/beads/beads.go\n\nBoth implement the same logic:\n1. Prefer issues.jsonl\n2. Fall back to beads.jsonl for legacy support\n3. Skip deletions.jsonl and merge artifacts\n4. Default to issues.jsonl if nothing found\n\n## Problem\n\nCode duplication means bug fixes need to be applied in multiple places (as we just experienced with bd-tqo).\n\n## Proposed Solution\n\nExtract shared logic to a utility package that both can import. Options:\n1. Create `internal/jsonlpath` package with the core logic\n2. Have `autoimport` import `beads` and call `FindJSONLPath` (but APIs differ slightly)\n3. Move to `internal/utils` if appropriate\n\nNeed to verify no import cycles would be created.\n\n## Affected Files\n- internal/autoimport/autoimport.go\n- internal/beads/beads.go","status":"closed","priority":4,"issue_type":"task","created_at":"2025-11-26T23:45:18.974339-08:00","updated_at":"2025-12-02T17:11:19.733265251-05:00","closed_at":"2025-11-28T23:07:08.912247-08:00"}
{"id":"bd-8an","title":"bd import auto-detects wrong prefix from directory name instead of issue IDs","description":"When importing issues.jsonl into a fresh database, 'bd import' prints:\n\n ✓ Initialized database with prefix 'beads' (detected from issues)\n\nBut the issues all have prefix 'bd-' (e.g., bd-03r). It appears to be detecting the prefix from the directory name (.beads/) rather than from the actual issue IDs in the JSONL.\n\nThis causes import to fail with:\n validate ID prefix for bd-03r: issue ID 'bd-03r' does not match configured prefix 'beads'\n\nWorkaround: Run 'bd config set issue_prefix bd' before import, or use 'bd init --prefix bd'.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-26T22:28:01.582564-08:00","updated_at":"2025-12-02T17:11:19.734136748-05:00","closed_at":"2025-11-27T22:38:48.971617-08:00"}
{"id":"bd-8f9","title":"Add bd migrate-tombstones command","description":"Create migration command to convert existing deletions.jsonl entries to tombstones. Support --dry-run and --verbose flags. Archive old file with .migrated suffix. Per design bd-dli.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-05T15:14:45.098831-08:00","updated_at":"2025-12-05T15:14:45.098831-08:00","dependencies":[{"issue_id":"bd-8f9","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-05T15:14:58.968329-08:00","created_by":"daemon"}]}
@@ -64,6 +64,7 @@
{"id":"bd-a0cp","title":"Consider using types.Status in merge package for type safety","description":"The merge package uses string for status comparison (e.g., result.Status == closed, issue.Status == StatusTombstone). The types package defines Status as a type alias with validation. While the merge package needs its own Issue struct for JSONL flexibility, it could import and use types.Status for constants to get compile-time type checking. Current code: if left == closed || right == closed. Could be: if left == string(types.StatusClosed). This is low priority since string comparison works correctly. Files: internal/merge/merge.go:44, 488, 501-521","status":"open","priority":4,"issue_type":"task","created_at":"2025-12-05T16:37:10.690424-08:00","updated_at":"2025-12-05T16:37:10.690424-08:00"}
{"id":"bd-a5z","title":"bd doctor: add --dry-run flag to preview fixes without applying","description":"Currently bd doctor --fix applies all fixes. Add a --dry-run flag to preview what would be fixed without making changes. This helps users understand the impact before committing to repairs.","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-12-02T12:52:10.106929-08:00","updated_at":"2025-12-03T22:13:42.684052-08:00","closed_at":"2025-12-03T22:13:42.684052-08:00"}
{"id":"bd-a6m","title":"isLikelyHash rejects 3-char all-letter base36 hashes","description":"ExtractIssuePrefix fails for multi-hyphen prefixes when the 3-char hash suffix has no digits.\n\nExample: `xa-adt-bat` returns prefix `xa` instead of `xa-adt`.\n\nRoot cause: `isLikelyHash()` requires at least one digit to distinguish hashes from English words, but base36 hashes can be all-letters by chance.\n\nAffected: 20 issues in xa-adapt with suffixes like bat, dev, fbi, oil, etc.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-02T17:11:19.783336327-05:00","updated_at":"2025-12-02T17:12:37.634260315-05:00","closed_at":"2025-12-02T17:12:37.634260315-05:00"}
{"id":"bd-abjw","title":"Consider consolidating config.yaml parsing into shared utility","description":"Multiple places parse config.yaml with custom structs:\n\n1. **autoimport.go:148** - `localConfig{SyncBranch}`\n2. **main.go:310** - strings.Contains for no-db (fragile, see bd-r6k2)\n3. **doctor.go:863** - strings.Contains for no-db (fragile, see bd-r6k2)\n4. **internal/config/config.go** - Uses viper (but caches at startup, problematic for tests)\n\nConsider creating a shared utility in `internal/configfile/` or extending the viper config:\n\n```go\n// internal/configfile/yaml.go\ntype YAMLConfig struct {\n SyncBranch string `yaml:\"sync-branch\"`\n NoDb bool `yaml:\"no-db\"`\n IssuePrefix string `yaml:\"issue-prefix\"`\n Author string `yaml:\"author\"`\n}\n\nfunc LoadYAML(beadsDir string) (*YAMLConfig, error) {\n // Parse config.yaml with proper YAML library\n}\n```\n\nBenefits:\n- Single source of truth for config.yaml structure\n- Proper YAML parsing everywhere\n- Easier to add new config fields\n\nTrade-off: May add complexity for simple one-off reads.","status":"open","priority":4,"issue_type":"task","created_at":"2025-12-07T02:03:26.067311-08:00","updated_at":"2025-12-07T02:03:26.067311-08:00"}
{"id":"bd-alz","title":"bd doctor: add configuration value validation","description":"Currently bd doctor checks for missing config files but doesn't validate config values. Add validation for: invalid priority values, malformed sync intervals, invalid branch names, unsupported storage backends, etc. This would catch misconfigurations before they cause runtime errors.","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-12-02T12:52:31.852532-08:00","updated_at":"2025-12-03T22:15:23.137554-08:00","closed_at":"2025-12-03T22:15:23.137554-08:00"}
{"id":"bd-azh","title":"Fix bd doctor --fix recursive message for deletions manifest","description":"When running bd doctor --fix, if the deletions manifest check fails but there are no deleted issues in git history, the fix succeeds but doesn't create the file. The check then runs again and tells user to run bd doctor --fix - the same command they just ran.\n\nFix: Create empty deletions.jsonl when hydration finds no deletions, and recognize empty file as valid in the check.\n\nFixes: https://github.com/steveyegge/beads/issues/403","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-27T12:41:09.426143-08:00","updated_at":"2025-11-27T12:41:23.521981-08:00","closed_at":"2025-11-27T12:41:23.521981-08:00"}
{"id":"bd-b8h","title":"Refactor check-health DB access to avoid repeated path resolution","description":"The runCheckHealth lightweight checks (hintsDisabled, checkVersionMismatch, checkSyncBranchQuick) each have duplicated database path resolution logic. Extract a helper function to DRY this up.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-25T19:27:35.075929-08:00","updated_at":"2025-11-25T19:50:21.272961-08:00","closed_at":"2025-11-25T19:50:21.272961-08:00"}
@@ -98,7 +99,7 @@
{"id":"bd-fbj","title":"Implement tombstone types and schema migration","description":"Add tombstone fields to Issue struct (deleted_at, deleted_by, delete_reason, original_type), add StatusTombstone constant, create SQLite migration for new columns. Per design bd-2m7.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T15:14:38.250106-08:00","updated_at":"2025-12-05T15:28:50.361654-08:00","closed_at":"2025-12-05T15:28:50.361654-08:00"}
{"id":"bd-fl4","title":"Test sync branch setup","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-30T00:26:47.520507-08:00","updated_at":"2025-11-30T00:33:23.105998-08:00","closed_at":"2025-11-30T00:33:23.105998-08:00"}
{"id":"bd-fmc","title":"string(rune()) pattern in other test files still only works for single digits","description":"The bd-c5m fix only addressed worktree_divergence_test.go, but several other test files have the same issue:\n\n- cmd/bd/stale_test.go:218, 234\n- cmd/bd/export_integrity_integration_test.go:45-47, 279-280\n- internal/storage/sqlite/comments_test.go:146, 165\n- internal/storage/sqlite/blocked_cache_test.go:292\n- internal/storage/sqlite/compact_bench_test.go:117\n- internal/storage/sqlite/cycle_detection_test.go:418\n\nThese use string(rune('0'+i)) which produces wrong characters when i \u003e= 10.\nShould use strconv.Itoa(i) instead.","status":"closed","priority":4,"issue_type":"bug","created_at":"2025-12-02T22:29:12.355705-08:00","updated_at":"2025-12-02T22:39:51.844638-08:00","closed_at":"2025-12-02T22:39:51.844638-08:00"}
{"id":"bd-fmo","title":"Missing test for IsExpiredTombstone edge cases","description":"## Problem\n\nThe `IsExpiredTombstone()` function has several edge cases that aren't directly tested:\n\n1. **Invalid DeletedAt timestamp** - Returns false (safety), but not tested\n2. **ttl=0 fallback to DefaultTombstoneTTL** - Not tested directly\n3. **Tombstone with empty DeletedAt** - Returns false, tested implicitly but not explicitly\n4. **Clock skew grace period effect** - Not tested (would need time mocking)\n\n## Current Test Coverage\n\nThe existing tests use `time.Now()` which makes them non-deterministic:\n```go\nDeletedAt: time.Now().Add(-24 * time.Hour).Format(time.RFC3339)\n```\n\nThis works but doesn't test the expiration boundary precisely.\n\n## Recommendation\n\nAdd explicit unit tests for `IsExpiredTombstone()`:\n\n```go\nfunc TestIsExpiredTombstone(t *testing.T) {\n tests := []struct {\n name string\n status string\n deletedAt string\n ttl time.Duration\n expected bool\n }{\n {\"non-tombstone returns false\", \"open\", \"2024-01-01T00:00:00Z\", 0, false},\n {\"empty deleted_at returns false\", \"tombstone\", \"\", 0, false},\n {\"invalid timestamp returns false\", \"tombstone\", \"not-a-date\", 0, false},\n {\"within TTL returns false\", \"tombstone\", time.Now().Add(-1*time.Hour).Format(time.RFC3339), 24*time.Hour, false},\n {\"beyond TTL returns true\", \"tombstone\", time.Now().Add(-48*time.Hour).Format(time.RFC3339), 24*time.Hour, true},\n }\n // ...\n}\n```\n\n## Files\n- internal/merge/merge.go:255-290\n- internal/merge/merge_test.go (add TestIsExpiredTombstone)","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-05T16:36:09.106135-08:00","updated_at":"2025-12-05T16:36:09.106135-08:00"}
{"id":"bd-fmo","title":"Missing test for IsExpiredTombstone edge cases","description":"## Problem\n\nThe `IsExpiredTombstone()` function has several edge cases that aren't directly tested:\n\n1. **Invalid DeletedAt timestamp** - Returns false (safety), but not tested\n2. **ttl=0 fallback to DefaultTombstoneTTL** - Not tested directly\n3. **Tombstone with empty DeletedAt** - Returns false, tested implicitly but not explicitly\n4. **Clock skew grace period effect** - Not tested (would need time mocking)\n\n## Current Test Coverage\n\nThe existing tests use `time.Now()` which makes them non-deterministic:\n```go\nDeletedAt: time.Now().Add(-24 * time.Hour).Format(time.RFC3339)\n```\n\nThis works but doesn't test the expiration boundary precisely.\n\n## Recommendation\n\nAdd explicit unit tests for `IsExpiredTombstone()`:\n\n```go\nfunc TestIsExpiredTombstone(t *testing.T) {\n tests := []struct {\n name string\n status string\n deletedAt string\n ttl time.Duration\n expected bool\n }{\n {\"non-tombstone returns false\", \"open\", \"2024-01-01T00:00:00Z\", 0, false},\n {\"empty deleted_at returns false\", \"tombstone\", \"\", 0, false},\n {\"invalid timestamp returns false\", \"tombstone\", \"not-a-date\", 0, false},\n {\"within TTL returns false\", \"tombstone\", time.Now().Add(-1*time.Hour).Format(time.RFC3339), 24*time.Hour, false},\n {\"beyond TTL returns true\", \"tombstone\", time.Now().Add(-48*time.Hour).Format(time.RFC3339), 24*time.Hour, true},\n }\n // ...\n}\n```\n\n## Files\n- internal/merge/merge.go:255-290\n- internal/merge/merge_test.go (add TestIsExpiredTombstone)","status":"in_progress","priority":3,"issue_type":"task","created_at":"2025-12-05T16:36:09.106135-08:00","updated_at":"2025-12-07T02:04:40.646331-08:00"}
{"id":"bd-ge7","title":"Improve Beads test coverage from 46% to 80%","description":"","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-20T21:21:03.700271-05:00","updated_at":"2025-12-02T17:11:19.740758435-05:00","closed_at":"2025-11-28T21:56:04.085939-08:00"}
{"id":"bd-ghb","title":"Add --yes flag to bd doctor --fix for non-interactive mode","description":"## Feature Request\n\nAdd a `--yes` or `-y` flag to `bd doctor --fix` that automatically confirms all prompts, enabling non-interactive usage in scripts and CI/CD pipelines.\n\n## Current Behavior\n`bd doctor --fix` prompts for confirmation before applying fixes, which blocks automated workflows.\n\n## Desired Behavior\n`bd doctor --fix --yes` should apply all fixes without prompting.\n\n## Use Cases\n- CI/CD pipelines that need to auto-fix issues\n- Scripts that automate repository setup\n- Pre-commit hooks that want to silently fix issues","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-11-26T23:22:45.486584-08:00","updated_at":"2025-12-02T17:11:19.741550211-05:00","closed_at":"2025-11-28T21:55:06.895066-08:00"}
{"id":"bd-gmf","title":"Update flake.nix vendorHash after dependency bumps","description":"The Nix flake CI is failing due to stale vendorHash.\n\nError from CI:\n```\nerror: hash mismatch in fixed-output derivation beads-0.24.4-go-modules.drv\n```\n\nRoot cause: go.mod/go.sum was updated by dependabot (wazero, anthropic-sdk-go, etc.) but flake.nix vendorHash wasn't updated.\n\n## Immediate Fix\nRun `nix build` locally, get the correct hash from the error message, update flake.nix.\n\n## Long-term Fix\nAdd a GitHub Action that auto-updates vendorHash when go.mod/go.sum changes:\n1. Trigger on push to main when go.mod/go.sum changes\n2. Run `nix build` to get the new hash from the error\n3. Update flake.nix with the correct hash\n4. Commit and push","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-02T23:16:06.851696-08:00","updated_at":"2025-12-02T23:21:39.917239-08:00","closed_at":"2025-12-02T23:21:39.917239-08:00"}
@@ -107,8 +108,9 @@
{"id":"bd-hdt","title":"Implement auto-merge functionality in duplicates command","description":"The duplicates.go file has a TODO at line 95 to implement the performMerge function for automatic duplicate merging. Currently it just prints a warning message. This would automate the merge process instead of just suggesting commands.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-21T18:55:02.828619-05:00","updated_at":"2025-11-28T19:50:01.115881-08:00","closed_at":"2025-11-27T22:36:11.517878-08:00"}
{"id":"bd-hm8","title":"Add uninstall documentation (GH #445)","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-01T21:04:30.313637-08:00","updated_at":"2025-12-01T21:04:57.943192-08:00","closed_at":"2025-12-01T21:04:57.943192-08:00"}
{"id":"bd-ho5","title":"Add 'town report' command for aggregated swarm status","description":"## Problem\nGetting a full swarm status requires running 6+ commands:\n- `town list \u003crig\u003e` for each rig\n- `town mail inbox` as Boss\n- `bd list --status=open/in_progress` per rig\n\nThis is slow and error-prone for both humans and agents.\n\n## Proposed Solution\nAdd `town report [RIG]` command that aggregates:\n- All rigs with polecat states (running/stopped, awake/asleep)\n- Boss inbox summary (unread count, recent senders)\n- Aggregate issue counts per rig (open/in_progress/blocked)\n\nExample output:\n```\n=== beads ===\nPolecats: 5 (5 running, 0 stopped)\nIssues: 20 open, 0 in_progress, 0 blocked\n\n=== gastown ===\nPolecats: 6 (4 running, 2 stopped)\nIssues: 0 open, 0 in_progress, 0 blocked\n\n=== Boss Mail ===\nUnread: 10 | Total: 22\nRecent: rictus (21:19), scrotus (21:14), immortanjoe (21:14)\n```\n\n## Acceptance Criteria\n- [ ] `town report` shows all rigs\n- [ ] `town report \u003crig\u003e` shows single rig detail\n- [ ] Output is concise and scannable\n- [ ] Completes in \u003c2 seconds","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-27T22:55:36.8919-08:00","updated_at":"2025-11-27T22:56:08.071838-08:00","closed_at":"2025-11-27T22:56:08.071838-08:00"}
{"id":"bd-hp0m","title":"Add test for legacy deletions.jsonl to tombstone conversion","description":"The importer now converts legacy deletions.jsonl entries to tombstones (bd-dve), but there's no dedicated test that:\n1. Creates a deletions.jsonl with entries\n2. Imports issues (some in deletions, some not)\n3. Verifies the converted tombstones have correct fields from the deletion record\n\nThe existing TestImportIssues_TombstoneNotFilteredByDeletionsManifest tests that tombstones bypass the filter, but doesn't verify the conversion of legacy deletions to tombstones.\n\nAdd a test: TestImportIssues_LegacyDeletionsConvertedToTombstones","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-07T01:41:12.976726-08:00","updated_at":"2025-12-07T01:41:12.976726-08:00","dependencies":[{"issue_id":"bd-hp0m","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-07T01:41:28.391366-08:00","created_by":"daemon"}]}
{"id":"bd-hp0m","title":"Add test for legacy deletions.jsonl to tombstone conversion","description":"The importer now converts legacy deletions.jsonl entries to tombstones (bd-dve), but there's no dedicated test that:\n1. Creates a deletions.jsonl with entries\n2. Imports issues (some in deletions, some not)\n3. Verifies the converted tombstones have correct fields from the deletion record\n\nThe existing TestImportIssues_TombstoneNotFilteredByDeletionsManifest tests that tombstones bypass the filter, but doesn't verify the conversion of legacy deletions to tombstones.\n\nAdd a test: TestImportIssues_LegacyDeletionsConvertedToTombstones","status":"in_progress","priority":2,"issue_type":"task","created_at":"2025-12-07T01:41:12.976726-08:00","updated_at":"2025-12-07T02:04:40.703606-08:00","dependencies":[{"issue_id":"bd-hp0m","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-07T01:41:28.391366-08:00","created_by":"daemon"}]}
{"id":"bd-ig5","title":"Duplicate tombstone constants in merge and types packages","description":"## Problem\n\nThe tombstone constants are duplicated between two packages:\n\n**internal/types/types.go:**\n```go\nconst DefaultTombstoneTTL = 30 * 24 * time.Hour\nconst ClockSkewGrace = 1 * time.Hour\nconst StatusTombstone Status = \"tombstone\"\n```\n\n**internal/merge/merge.go:**\n```go\nconst StatusTombstone = \"tombstone\"\nconst DefaultTombstoneTTL = 30 * 24 * time.Hour\nconst ClockSkewGrace = 1 * time.Hour\n```\n\nThis violates DRY and creates risk of divergence if one is updated but not the other.\n\n## Root Cause\n\nThe merge package has its own `Issue` struct (for JSONL parsing) and cannot import types.Issue directly due to the different struct design. However, the constants could be shared.\n\n## Recommendation\n\nExport the constants from types package and import them in merge:\n\n```go\n// merge/merge.go\nimport \"github.com/steveyegge/beads/internal/types\"\n\n// Use types.StatusTombstone, types.DefaultTombstoneTTL, types.ClockSkewGrace\n```\n\nOr create a shared constants package if import cycles are a concern.\n\n## Files\n- internal/merge/merge.go:241-248\n- internal/types/types.go:77-84, 170","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-05T16:36:06.159443-08:00","updated_at":"2025-12-05T17:15:57.624376-08:00","closed_at":"2025-12-05T17:15:57.624376-08:00"}
{"id":"bd-iip5","title":"TestImportIssues_LegacyDeletionsConvertedToTombstones is failing","description":"The test TestImportIssues_LegacyDeletionsConvertedToTombstones in internal/importer/importer_test.go is failing:\n\nExpected 3 created (1 regular + 2 tombstones from deletions.jsonl), got 2\nExpected tombstone for test-deleted2 not found\n\nThe test expects legacy deletions.jsonl entries to be converted to tombstones during import, but test-deleted2 is not being converted.\n\nLocation: internal/importer/importer_test.go:1344","status":"open","priority":2,"issue_type":"bug","created_at":"2025-12-07T02:09:19.17774-08:00","updated_at":"2025-12-07T02:09:19.17774-08:00"}
{"id":"bd-imj","title":"Deletion propagation via deletions manifest","description":"## Problem\n\nWhen `bd cleanup -f` or `bd delete` removes issues in one clone, those deletions don't propagate to other clones. The import logic only creates/updates, never deletes. This causes \"resurrection\" where deleted issues reappear.\n\n## Root Cause\n\nImport sees DB issues not in JSONL and assumes they're \"local unpushed work\" rather than \"intentionally deleted upstream.\"\n\n## Solution: Deletions Manifest\n\nAdd `.beads/deletions.jsonl` - an append-only log of deleted issue IDs with metadata.\n\n### Format\n```jsonl\n{\"id\":\"bd-xxx\",\"ts\":\"2025-11-25T10:00:00Z\",\"by\":\"stevey\"}\n{\"id\":\"bd-yyy\",\"ts\":\"2025-11-25T10:05:00Z\",\"by\":\"claude\",\"reason\":\"duplicate of bd-zzz\"}\n```\n\n### Fields\n- `id`: Issue ID (required)\n- `ts`: ISO 8601 UTC timestamp (required)\n- `by`: Actor who deleted (required)\n- `reason`: Optional context (\"cleanup\", \"duplicate of X\", etc.)\n\n### Import Logic\n```\nFor each DB issue not in JSONL:\n 1. Check deletions manifest → if found, delete from DB\n 2. Fallback: check git history → if found, delete + backfill manifest\n 3. Neither → keep (local unpushed work)\n```\n\n### Conflict Resolution\nSimultaneous deletions from multiple clones are handled naturally:\n- Append-only design means both clones append their deletion records\n- On merge, file contains duplicate entries (same ID, different timestamps)\n- `LoadDeletions` deduplicates by ID (keeps any/first entry)\n- Result: deletion propagates correctly, duplicates are harmless\n\n### Pruning Policy\n- Default retention: 7 days (configurable via `deletions.retention_days`)\n- Auto-compact during `bd sync` is **opt-in** (disabled by default)\n- Hard cap: `deletions.max_entries` (default 50000)\n- Git fallback handles pruned entries (self-healing)\n\n### Self-Healing\nWhen git fallback catches a resurrection (pruned entry), it backfills the manifest. One-time git scan cost, then fast again.\n\n### Size Estimates\n- ~80 bytes/entry\n- 7-day retention with 100 deletions/day = ~56KB\n- Git compressed: ~10KB\n\n## Benefits\n- ✅ Deletions propagate across clones\n- ✅ O(1) lookup (no git scan in normal case)\n- ✅ Works in shallow clones\n- ✅ Survives history rewrite\n- ✅ Audit trail (who deleted what when)\n- ✅ Self-healing via git fallback\n- ✅ Bounded size via time-based pruning\n\n## References\n- Investigation session: 2025-11-25\n- Related: bd-2q6d (stale database warnings)","status":"closed","priority":0,"issue_type":"epic","created_at":"2025-11-25T09:56:01.98027-08:00","updated_at":"2025-11-25T16:36:27.965168-08:00","closed_at":"2025-11-25T16:36:27.965168-08:00","dependencies":[{"issue_id":"bd-imj","depends_on_id":"bd-qsm","type":"blocks","created_at":"2025-11-25T09:57:42.821911-08:00","created_by":"daemon"},{"issue_id":"bd-imj","depends_on_id":"bd-x2i","type":"blocks","created_at":"2025-11-25T09:57:42.851712-08:00","created_by":"daemon"},{"issue_id":"bd-imj","depends_on_id":"bd-44e","type":"blocks","created_at":"2025-11-25T09:57:42.88154-08:00","created_by":"daemon"},{"issue_id":"bd-imj","depends_on_id":"bd-bhd","type":"blocks","created_at":"2025-11-25T14:56:23.675787-08:00","created_by":"daemon"},{"issue_id":"bd-imj","depends_on_id":"bd-bgs","type":"blocks","created_at":"2025-11-25T14:56:23.744648-08:00","created_by":"daemon"},{"issue_id":"bd-imj","depends_on_id":"bd-f0n","type":"blocks","created_at":"2025-11-25T14:56:23.80649-08:00","created_by":"daemon"},{"issue_id":"bd-imj","depends_on_id":"bd-v29","type":"blocks","created_at":"2025-11-25T14:56:23.864569-08:00","created_by":"daemon"},{"issue_id":"bd-imj","depends_on_id":"bd-mdw","type":"blocks","created_at":"2025-11-25T14:56:48.592492-08:00","created_by":"daemon"},{"issue_id":"bd-imj","depends_on_id":"bd-03r","type":"blocks","created_at":"2025-11-25T14:56:54.295851-08:00","created_by":"daemon"}]}
{"id":"bd-in6","title":"CONFIG.md docs for sync.require_confirmation_on_mass_delete missing threshold detail","description":"The docs say 'if \u003e50% of issues vanish' but the actual code (worktree.go:380) also requires '\u003e5 issues existed before'. The docs should mention both conditions for completeness.","status":"closed","priority":4,"issue_type":"task","created_at":"2025-12-02T22:29:56.753032-08:00","updated_at":"2025-12-02T22:40:37.385126-08:00","closed_at":"2025-12-02T22:40:37.385126-08:00"}
{"id":"bd-io0","title":"sync.branch config lost on clone - should be in config.yaml","description":"## Problem\n\nThe sync.branch configuration is stored in the SQLite database, which is gitignored. When contributors clone a repo that uses beads:\n\n1. They get .beads/issues.jsonl (tracked)\n2. They don't get .beads/beads.db (gitignored)\n3. They lose the sync.branch config\n\nWhen they run 'bd init' or 'bd doctor --fix', sync.branch gets auto-set to the current branch (usually 'main'), but if the project uses a dedicated sync branch like 'beads-sync', they'll be committing to the wrong branch.\n\n## Root Cause\n\nsyncbranch.Get() only checks:\n1. BEADS_SYNC_BRANCH env var\n2. Database config (store.GetConfig)\n\nIt never reads from config.yaml, which IS tracked in git and persists across clones.\n\n## Proposed Solution\n\nAdd sync-branch support to config.yaml with this precedence:\n1. BEADS_SYNC_BRANCH env var (highest)\n2. config.yaml sync-branch setting\n3. Database config (legacy/local override)\n4. Auto-detect from current branch (lowest)\n\nChanges needed:\n1. Update syncbranch.Get() to check config.GetString('sync-branch') between env and database\n2. Update config.yaml template in init.go to include sync-branch\n3. Update docs to recommend setting sync-branch in config.yaml for team projects\n4. Consider: bd init --branch should also write to config.yaml, not just database","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-30T10:51:29.594627-08:00","updated_at":"2025-11-30T10:54:14.198025-08:00","closed_at":"2025-11-30T10:54:14.198025-08:00"}
@@ -126,6 +128,7 @@
{"id":"bd-md2","title":"Add tombstone validation: require deleted_at for tombstone status","description":"ValidateWithCustomStatuses() doesn't enforce that tombstones must have deleted_at set. Per bd-2m7 design: 'If status == tombstone, then deleted_at MUST be set'. Also should validate that non-tombstones cannot have deleted_at set.\n\nLocation: internal/types/types.go:109-114\n\nAdd validation:\n- if i.Status == StatusTombstone \u0026\u0026 i.DeletedAt == nil: error\n- if i.Status != StatusTombstone \u0026\u0026 i.DeletedAt != nil: error","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-05T15:35:29.458545-08:00","updated_at":"2025-12-05T15:41:14.804544-08:00","closed_at":"2025-12-05T15:41:14.804544-08:00","dependencies":[{"issue_id":"bd-md2","depends_on_id":"bd-vw8","type":"parent-child","created_at":"2025-12-05T15:35:47.141085-08:00","created_by":"daemon"}]}
{"id":"bd-mdw","title":"Add integration test for cross-clone deletion propagation","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-25T14:56:38.997009-08:00","updated_at":"2025-11-25T16:35:59.052914-08:00","closed_at":"2025-11-25T16:35:59.052914-08:00"}
{"id":"bd-mnap","title":"Investigate performance issues in VS Code Copilot (Windows)","description":"Beads unusable in Windows 11 VS Code Copilot chat with Sonnet 4.5.\nSummary event happens every 3-4 turns, taking 3 minutes.\nCopilot summarizes after ~125k tokens despite model supporting 1M.\nLarge context size of beads might be triggering aggressive summarization.\nNeed workaround or optimization for context size.\n","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-20T18:56:30.124918-05:00","updated_at":"2025-12-02T17:11:19.74464837-05:00","closed_at":"2025-11-28T23:37:52.199294-08:00"}
{"id":"bd-mql4","title":"getLocalSyncBranch silently ignores YAML parse errors","description":"In autoimport.go:170-172, YAML parsing errors are silently ignored. If a user has malformed YAML in config.yaml, sync-branch will just silently be empty with no feedback.\n\nRecommendation: Add debug logging since this function is only called during auto-import, and debugging silent failures is painful.\n\nAdd: debug.Logf(\"Warning: failed to parse config.yaml: %v\", err)","status":"open","priority":4,"issue_type":"task","created_at":"2025-12-07T02:03:44.217728-08:00","updated_at":"2025-12-07T02:03:44.217728-08:00"}
{"id":"bd-nl2","title":"No logging/debugging for tombstone resurrection events","description":"Per the design document bd-zvg Open Question 1: Should resurrection log a warning? Recommendation was Yes. Currently, when an expired tombstone loses to a live issue (resurrection), there is no logging or debugging output. This makes it hard to understand why an issue reappeared. Recommendation: Add optional debug logging when resurrection occurs, e.g., Issue bd-abc resurrected (tombstone expired). Files: internal/merge/merge.go:359-366, 371-378, 400-405, 410-415","status":"open","priority":4,"issue_type":"feature","created_at":"2025-12-05T16:36:52.27525-08:00","updated_at":"2025-12-05T16:36:52.27525-08:00"}
{"id":"bd-nq41","title":"Fix Homebrew warning about Ruby file location","description":"Homebrew warning: Found Ruby file outside steveyegge/beads tap formula directory.\nWarning points to: /opt/homebrew/Library/Taps/steveyegge/homebrew-beads/bd.rb\nIt should likely be inside a Formula/ directory or similar structure expected by Homebrew taps.\n","status":"closed","priority":2,"issue_type":"chore","created_at":"2025-11-20T18:56:21.226579-05:00","updated_at":"2025-11-26T22:25:37.362928-08:00","closed_at":"2025-11-26T22:25:37.362928-08:00"}
{"id":"bd-nsb","title":"Doctor should exclude merge artifacts from 'multiple JSONL' warning","description":"Doctor command warns about 'multiple JSONL files' when .base.jsonl and .left.jsonl merge artifacts exist. These are expected during/after merge operations and should be excluded from the warning.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-28T17:27:36.988178-08:00","updated_at":"2025-11-28T18:36:52.087768-08:00","closed_at":"2025-11-28T17:41:50.700658-08:00"}
@@ -139,6 +142,7 @@
{"id":"bd-qn5","title":"bd doctor: handle missing daemon registry gracefully","description":"When no daemon has ever been started, bd doctor shows an error parsing the registry: 'failed to parse registry: invalid character 0 after top-level value'. The doctor should handle the case where ~/.bd/daemon/registry.json doesn't exist, treating it as 'no daemon running' rather than an error.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-02T12:51:56.300983-08:00","updated_at":"2025-12-03T22:11:43.327235-08:00","closed_at":"2025-12-03T22:11:43.327235-08:00"}
{"id":"bd-qsm","title":"Auto-compact deletions during bd sync","description":"Parent: bd-imj\n\n## Task\nOptionally prune deletions manifest during sync when threshold exceeded.\n\n**Note: Opt-in feature** - disabled by default to avoid sync latency.\n\n## Implementation\n\nIn `bd sync`:\n```go\nfunc (s *Syncer) Sync() error {\n // ... existing sync logic ...\n \n // Auto-compact only if enabled\n if s.config.GetBool(\"deletions.auto_compact\", false) {\n deletionCount := deletions.Count(\".beads/deletions.jsonl\")\n threshold := s.config.GetInt(\"deletions.auto_compact_threshold\", 1000)\n \n if deletionCount \u003e threshold {\n retentionDays := s.config.GetInt(\"deletions.retention_days\", 7)\n if err := s.compactor.PruneDeletions(retentionDays); err != nil {\n log.Warnf(\"Failed to auto-compact deletions: %v\", err)\n // Non-fatal, continue sync\n }\n }\n }\n \n // ... rest of sync ...\n}\n```\n\n## Configuration\n```yaml\ndeletions:\n retention_days: 7\n auto_compact: false # Opt-in, disabled by default\n auto_compact_threshold: 1000 # Trigger when \u003e N entries (if enabled)\n```\n\n## Acceptance Criteria\n- [ ] Auto-compact disabled by default\n- [ ] Enabled via config `deletions.auto_compact: true`\n- [ ] Sync checks deletion count only when enabled\n- [ ] Auto-prunes when threshold exceeded\n- [ ] Failure is non-fatal (logged warning)\n- [ ] Test: no compaction when disabled\n- [ ] Test: compaction triggers when enabled and threshold exceeded","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T09:57:04.522795-08:00","updated_at":"2025-11-25T15:03:01.469629-08:00","closed_at":"2025-11-25T15:03:01.469629-08:00"}
{"id":"bd-qvj","title":"Jira import/export integration","description":"Add ability to import issues from Jira and export beads issues to Jira. See GitHub discussion #430 for user request.\n\n**Background**: User @kaihendry configured jira.* settings but found bd sync doesn't sync with Jira - only with git. The config namespace exists but the integration doesn't.\n\n**Existing infrastructure**:\n- external_ref field for linking to external systems\n- Import logic matches by external_ref first (priority over ID matching)\n- Config namespace jira.* documented in CONFIG.md\n- GitHub import example (examples/github-import/gh2jsonl.py) provides pattern\n\n**Schema mapping challenges**:\n- Jira workflows are highly customizable (status mapping)\n- Jira has more field types (components, versions, custom fields)\n- Two-way sync needs conflict resolution\n- Jira Cloud vs Server/Data Center have different APIs\n\n**Approach**: Phased implementation starting with import, then export, then bidirectional sync.","status":"closed","priority":2,"issue_type":"epic","created_at":"2025-11-30T12:55:44.835009-08:00","updated_at":"2025-12-01T21:00:20.193271-08:00","closed_at":"2025-12-01T10:44:53.454483-08:00"}
{"id":"bd-r6k2","title":"Fragile no-db detection uses strings.Contains instead of YAML parsing","description":"Two locations use `strings.Contains(string(configData), \"no-db: true\")` to detect JSONL-only mode:\n\n1. **cmd/bd/main.go:310** - Auto-enabling no-db mode\n2. **cmd/bd/doctor.go:863** - Database status check\n\nThis is fragile because it could match:\n- Comments: `# no-db: true for testing`\n- Nested keys: `settings:\\n no-db: true`\n- String values: `note: \"set no-db: true to disable\"`\n\nShould use proper YAML parsing like we did for sync-branch in bd-0rh:\n\n```go\ntype noDbConfig struct {\n NoDb bool `yaml:\"no-db\"`\n}\n\nvar cfg noDbConfig\nif err := yaml.Unmarshal(configData, \u0026cfg); err == nil {\n isNoDbMode = cfg.NoDb\n}\n```\n\nRelated: bd-0rh (fixed similar issue for sync-branch)","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-12-07T02:03:12.120296-08:00","updated_at":"2025-12-07T02:09:30.628372-08:00","closed_at":"2025-12-07T02:09:30.628372-08:00","dependencies":[{"issue_id":"bd-r6k2","depends_on_id":"bd-0rh","type":"discovered-from","created_at":"2025-12-07T02:03:50.599423-08:00","created_by":"daemon"}]}
{"id":"bd-r9iq","title":"purgeDeletedIssues still writes to deletions.jsonl during git-history-backfill","description":"In purgeDeletedIssues (lines 929-939), when a deletion is recovered from git history, we:\n1. Append to deletions.jsonl (backfill)\n2. Create a tombstone in DB\n\nWith the tombstone approach, writing to deletions.jsonl is redundant since the tombstone will be exported to JSONL. Consider removing the deletions.jsonl backfill once we're confident in the tombstone approach.\n\nThis is related to the Phase 2 migration (bd-vw8) - we should stop writing to deletions.jsonl entirely.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-07T01:40:42.581876-08:00","updated_at":"2025-12-07T01:40:42.581876-08:00","dependencies":[{"issue_id":"bd-r9iq","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-07T01:41:28.285457-08:00","created_by":"daemon"}]}
{"id":"bd-s0z","title":"Consider extracting error handling helpers","description":"Evaluate creating FatalError() and WarnError() helpers as suggested in ERROR_HANDLING.md to reduce boilerplate and enforce consistency. Prototype in a few files first to validate the approach.","status":"closed","priority":4,"issue_type":"task","created_at":"2025-11-24T00:28:57.248959-08:00","updated_at":"2025-12-02T17:11:19.748387872-05:00","closed_at":"2025-11-28T23:28:00.886536-08:00"}
{"id":"bd-s3v","title":"Add tombstone doctor checks","description":"Add bd doctor checks for: unmigrated deletions.jsonl, stale deletions.jsonl in Phase 3, tombstones expiring soon. Per design bd-dli.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-05T15:14:46.733558-08:00","updated_at":"2025-12-05T15:14:46.733558-08:00","dependencies":[{"issue_id":"bd-s3v","depends_on_id":"bd-8f9","type":"blocks","created_at":"2025-12-05T15:14:59.006029-08:00","created_by":"daemon"}]}
@@ -166,7 +170,7 @@
{"id":"bd-y68","title":"Block direct status update to tombstone in UpdateIssue","description":"Per bd-2m7 design: 'Should we support tombstone as valid input to bd update --status? Recommendation: No, tombstones only created via bd delete'\n\nCurrently nothing prevents 'bd update \u003cid\u003e --status=tombstone', which would create an invalid tombstone (missing deleted_at, deleted_by, etc.).\n\nLocation: internal/storage/sqlite/queries.go:500-664 UpdateIssue\n\nAdd validation to reject status=tombstone in updates.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-05T15:35:31.5176-08:00","updated_at":"2025-12-05T15:41:14.813862-08:00","closed_at":"2025-12-05T15:41:14.813862-08:00","dependencies":[{"issue_id":"bd-y68","depends_on_id":"bd-vw8","type":"parent-child","created_at":"2025-12-05T15:35:47.181896-08:00","created_by":"daemon"}]}
{"id":"bd-ybv5","title":"Refactor AGENTS.md to use external references","description":"Suggestion to use external references (e.g., \"ALWAYS REFER TO ./beads/prompt.md\") instead of including all instructions directly within AGENTS.md.\nReasons:\n1. Agents can follow external references.\n2. Prevents context pollution/stuffing in AGENTS.md as more tools append instructions.\n","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-20T18:55:53.259144-05:00","updated_at":"2025-11-26T22:25:57.772875-08:00","closed_at":"2025-11-26T22:25:57.772875-08:00"}
{"id":"bd-ye0d","title":"troubleshoot GH#278 daemon exits every few secs","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-13T06:27:23.39509215-07:00","updated_at":"2025-11-25T17:48:43.62418-08:00","closed_at":"2025-11-25T17:48:43.62418-08:00"}
{"id":"bd-yk8w","title":"Add export test verifying tombstones are included in JSONL output","description":"The export now includes tombstones (bd-dve) but there's no test that:\n1. Creates issues in DB including a tombstone\n2. Runs export\n3. Verifies the JSONL contains the tombstone with all fields\n\nAdd a test: TestExportIncludesTombstones","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-07T01:41:19.987907-08:00","updated_at":"2025-12-07T01:41:19.987907-08:00","dependencies":[{"issue_id":"bd-yk8w","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-07T01:41:28.426945-08:00","created_by":"daemon"}]}
{"id":"bd-yk8w","title":"Add export test verifying tombstones are included in JSONL output","description":"The export now includes tombstones (bd-dve) but there's no test that:\n1. Creates issues in DB including a tombstone\n2. Runs export\n3. Verifies the JSONL contains the tombstone with all fields\n\nAdd a test: TestExportIncludesTombstones","status":"in_progress","priority":2,"issue_type":"task","created_at":"2025-12-07T01:41:19.987907-08:00","updated_at":"2025-12-07T02:04:40.757658-08:00","dependencies":[{"issue_id":"bd-yk8w","depends_on_id":"bd-dve","type":"blocks","created_at":"2025-12-07T01:41:28.426945-08:00","created_by":"daemon"}]}
{"id":"bd-yuv","title":"Add tests for tombstone edge cases","description":"Missing test coverage for tombstone implementation:\n\n1. Test tombstone validation (deleted_at requirement)\n2. Test GetReadyWork excludes tombstones\n3. Test SearchIssues behavior with tombstones\n4. Integration test for creating/retrieving a tombstone via the delete command\n5. Test that status=tombstone update is rejected","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-05T15:35:39.101881-08:00","updated_at":"2025-12-05T15:35:39.101881-08:00","dependencies":[{"issue_id":"bd-yuv","depends_on_id":"bd-vw8","type":"parent-child","created_at":"2025-12-05T15:35:47.335167-08:00","created_by":"daemon"}]}
{"id":"bd-zai","title":"bd init resets metadata.json jsonl_export to beads.jsonl, ignoring existing issues.jsonl","description":"When running 'bd init --prefix bd' in a repo that already has .beads/issues.jsonl, the init command overwrites metadata.json and sets jsonl_export back to 'beads.jsonl' instead of detecting and respecting the existing issues.jsonl file.\n\nSteps to reproduce:\n1. Have a repo with .beads/issues.jsonl (canonical) and metadata.json pointing to issues.jsonl\n2. Delete beads.db and run 'bd init --prefix bd'\n3. Check metadata.json - it now says jsonl_export: beads.jsonl\n\nExpected: Init should detect existing issues.jsonl and use it.\n\nWorkaround: Manually edit metadata.json after init.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-26T22:27:41.653287-08:00","updated_at":"2025-12-02T17:11:19.752292588-05:00","closed_at":"2025-11-28T21:54:32.52461-08:00"}
{"id":"bd-zj8e","title":"Performance Testing Documentation","description":"Create docs/performance-testing.md documenting the performance testing framework.\n\nSections:\n1. Overview - What the framework does, goals\n2. Running Benchmarks\n - make bench command\n - Running specific benchmarks\n - Interpreting output (ns/op, allocs/op)\n3. Profiling and Analysis\n - Viewing CPU profiles with pprof\n - Reading flamegraphs\n - Memory profiling\n - Finding hotspots\n4. User Diagnostics\n - bd doctor --perf usage\n - Sharing profiles with bug reports\n - Understanding the report output\n5. Comparing Performance\n - Using benchstat for before/after comparisons\n - Detecting regressions\n6. Tips for Optimization\n - Common patterns\n - When to profile vs benchmark\n\nStyle:\n- Concise, practical examples\n- Screenshots/examples of pprof output\n- Clear command-line examples\n- Focus on workflow, not theory","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-13T22:23:38.99897-08:00","updated_at":"2025-12-02T17:11:19.753645934-05:00","closed_at":"2025-11-28T23:37:52.227831-08:00"}