bd sync: 2025-11-01 22:39:37

This commit is contained in:
Steve Yegge
2025-11-01 22:39:37 -07:00
parent 98ecaec2ec
commit 440d9bf913

View File

@@ -184,7 +184,7 @@
{"id":"bd-f8b764c9.7","content_hash":"0cd1edbd677f73f3a21e571709eca026db7c6e0d158a3d41d7c4e37deb8bc4c2","title":"CLI accepts both hash IDs and aliases","description":"Update all CLI commands to accept both hash IDs (bd-af78e9a2) and aliases (#42, or just 42).\n\n## Parsing Logic\n```go\n// internal/utils/id_parser.go\nfunc ParseIssueID(input string) (issueID string, err error) {\n // Hash ID: bd-af78e9a2\n if strings.HasPrefix(input, \"bd-\") {\n return input, nil\n }\n \n // Alias: #42 or 42\n aliasStr := strings.TrimPrefix(input, \"#\")\n alias, err := strconv.Atoi(aliasStr)\n if err != nil {\n return \"\", fmt.Errorf(\"invalid issue ID: %s\", input)\n }\n \n // Resolve alias to hash ID\n return storage.GetIssueIDByAlias(alias)\n}\n```\n\n## Commands to Update\nAll commands that accept issue IDs:\n\n### 1. bd show\n```bash\nbd show bd-af78e9a2 # Hash ID\nbd show #42 # Alias\nbd show 42 # Alias (shorthand)\nbd show bd-af78e9a2 #42 # Mixed (multiple IDs)\n```\n\n### 2. bd update\n```bash\nbd update #42 --status in_progress\nbd update bd-af78e9a2 --priority 1\n```\n\n### 3. bd close\n```bash\nbd close #42 --reason \"Done\"\n```\n\n### 4. bd dep add/tree\n```bash\nbd dep add #42 #1 --type blocks\nbd dep tree bd-af78e9a2\n```\n\n### 5. bd label add/remove\n```bash\nbd label add #42 critical\n```\n\n### 6. bd merge\n```bash\nbd merge #42 #43 --into #41\n```\n\n## Display Format\nDefault to showing aliases in output:\n```bash\n$ bd list\n#1 Fix authentication bug P1 open\n#2 Add logging to daemon P2 open \n#42 Investigate jujutsu integration P3 open\n```\n\nWith `--format=hash` flag:\n```bash\n$ bd list --format=hash\nbd-af78e9a2 Fix authentication bug P1 open\nbd-e5f6a7b8 Add logging to daemon P2 open\nbd-1a2b3c4d Investigate jujutsu integration P3 open\n```\n\n## Files to Modify\n- internal/utils/id_parser.go (new)\n- cmd/bd/show.go\n- cmd/bd/update.go\n- cmd/bd/close.go\n- cmd/bd/reopen.go\n- cmd/bd/dep.go\n- cmd/bd/label.go\n- cmd/bd/merge.go\n- cmd/bd/list.go (add --format flag)\n\n## Testing\n- Test hash ID parsing\n- Test alias parsing (#42, 42)\n- Test mixed IDs in single command\n- Test error on invalid ID\n- Test alias resolution failure","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T21:25:06.256317-07:00","updated_at":"2025-10-31T12:32:32.609634-07:00","closed_at":"2025-10-31T12:32:32.609634-07:00","dependencies":[{"issue_id":"bd-f8b764c9.7","depends_on_id":"bd-f8b764c9","type":"parent-child","created_at":"2025-10-29T21:25:06.257796-07:00","created_by":"stevey"},{"issue_id":"bd-f8b764c9.7","depends_on_id":"bd-f8b764c9.10","type":"blocks","created_at":"2025-10-29T21:25:06.258307-07:00","created_by":"stevey"},{"issue_id":"bd-f8b764c9.7","depends_on_id":"bd-f8b764c9.8","type":"blocks","created_at":"2025-10-29T21:29:45.993274-07:00","created_by":"stevey"}]}
{"id":"bd-f8b764c9.8","content_hash":"d047b706654f9e5b0cc59fde73e88fed242932c3c024d90af22327a5c2f2fced","title":"Update JSONL format to use hash IDs","description":"Update JSONL import/export to use hash IDs, store aliases separately.\n\n## Current JSONL Format\n```jsonl\n{\"id\":\"bd-1c63eb84\",\"title\":\"Fix bug\",\"status\":\"open\",...}\n{\"id\":\"bd-9063acda\",\"title\":\"Add test\",\"status\":\"open\",...}\n```\n\n## New JSONL Format (Option A: Include Alias)\n```jsonl\n{\"id\":\"bd-af78e9a2\",\"alias\":1,\"title\":\"Fix bug\",\"status\":\"open\",...}\n{\"id\":\"bd-e5f6a7b8\",\"alias\":2,\"title\":\"Add test\",\"status\":\"open\",...}\n```\n\n## New JSONL Format (Option B: Hash ID Only)\n```jsonl\n{\"id\":\"bd-af78e9a2\",\"title\":\"Fix bug\",\"status\":\"open\",...}\n{\"id\":\"bd-e5f6a7b8\",\"title\":\"Add test\",\"status\":\"open\",...}\n```\n\nStore aliases in separate .beads/aliases.jsonl (local only, git-ignored):\n```jsonl\n{\"hash\":\"bd-af78e9a2\",\"alias\":1}\n{\"hash\":\"bd-e5f6a7b8\",\"alias\":2}\n```\n\n**Recommendation**: Option B (hash only in main JSONL)\n- Cleaner git diffs (no alias conflicts)\n- Aliases are workspace-local preference\n- Main JSONL is canonical, portable\n\n## Export Changes\nFile: cmd/bd/export.go\n```go\n// Export issues with hash IDs\nfor _, issue := range issues {\n json := marshalIssue(issue) // Uses issue.ID (hash)\n // Don't include alias in JSONL\n}\n\n// Separately export aliases to .beads/aliases.jsonl\nexportAliases(issues)\n```\n\n## Import Changes \nFile: cmd/bd/import.go, internal/importer/importer.go\n```go\n// Import issues by hash ID\nissue := unmarshalIssue(line)\n// Assign new alias on import (don't use incoming alias)\nissue.Alias = getNextAlias()\n\n// No collision detection needed! Hash IDs are globally unique\n```\n\n## Dependency Reference Format\nNo change needed - already uses issue IDs:\n```json\n{\"depends_on_id\":\"bd-af78e9a2\",\"type\":\"blocks\"}\n```\n\n## Files to Modify\n- cmd/bd/export.go (use hash IDs)\n- cmd/bd/import.go (import hash IDs, assign aliases)\n- internal/importer/importer.go (remove collision detection!)\n- .gitignore (add .beads/aliases.jsonl)\n\n## Testing\n- Test export produces hash IDs\n- Test import assigns new aliases\n- Test dependencies preserved with hash IDs\n- Test no collision detection triggered","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T21:24:47.408106-07:00","updated_at":"2025-10-31T12:32:32.609925-07:00","closed_at":"2025-10-31T12:32:32.609925-07:00","dependencies":[{"issue_id":"bd-f8b764c9.8","depends_on_id":"bd-f8b764c9","type":"parent-child","created_at":"2025-10-29T21:24:47.409489-07:00","created_by":"stevey"},{"issue_id":"bd-f8b764c9.8","depends_on_id":"bd-f8b764c9.9","type":"blocks","created_at":"2025-10-29T21:24:47.409977-07:00","created_by":"stevey"},{"issue_id":"bd-f8b764c9.8","depends_on_id":"bd-f8b764c9.10","type":"blocks","created_at":"2025-10-29T21:29:45.975499-07:00","created_by":"stevey"}]}
{"id":"bd-f8b764c9.9","content_hash":"5b040bec47ef5353a04d90d73ac8237f0302137c27ef7f6bfc84379b84cbb7ec","title":"Implement hash ID generation in CreateIssue","description":"Replace sequential ID generation with hash-based IDs in CreateIssue function.\n\n## Current Behavior (internal/storage/sqlite/sqlite.go)\n```go\nfunc (s *SQLiteStorage) CreateIssue(ctx context.Context, issue *types.Issue) error {\n // ID comes from auto-increment counter\n // Collisions possible across clones\n}\n```\n\n## New Behavior\n```go\nfunc (s *SQLiteStorage) CreateIssue(ctx context.Context, issue *types.Issue) error {\n // Generate hash ID if not provided\n if issue.ID == \"\" {\n issue.ID = idgen.GenerateHashID(\n issue.Title,\n issue.Description,\n time.Now(),\n s.workspaceID,\n )\n }\n \n // Assign next alias\n issue.Alias = s.getNextAlias()\n \n // Insert with hash ID + alias\n // ...\n}\n```\n\n## Workspace ID Generation\nAdd to database initialization:\n```go\n// Generate stable workspace ID (persisted in .beads/workspace_id)\nworkspaceID := getOrCreateWorkspaceID()\n```\n\nOptions for workspace ID:\n1. Hostname + random suffix\n2. UUID (random)\n3. Git remote URL hash (deterministic per repo)\n\nRecommended: Option 3 (git remote hash) for reproducibility\n\n## Hash Collision Detection\n```go\n// On insert, check for collision (unlikely but possible)\nexisting, err := s.GetIssue(ctx, issue.ID)\nif err == nil {\n // Hash collision! Add random suffix and retry\n issue.ID = issue.ID + \"-\" + randomSuffix(4)\n}\n```\n\n## Files to Create/Modify\n- internal/types/id_generator.go (new)\n- internal/storage/sqlite/sqlite.go (CreateIssue)\n- internal/storage/sqlite/workspace.go (new - workspace ID management)\n- .beads/workspace_id (new file, git-ignored)\n\n## Testing\n- Test hash ID generation is deterministic\n- Test collision detection and retry\n- Test workspace ID persistence\n- Benchmark: hash generation performance (\u003c1μs)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T21:24:29.412237-07:00","updated_at":"2025-10-31T12:32:32.610403-07:00","closed_at":"2025-10-31T12:32:32.610403-07:00","dependencies":[{"issue_id":"bd-f8b764c9.9","depends_on_id":"bd-f8b764c9","type":"parent-child","created_at":"2025-10-29T21:24:29.413417-07:00","created_by":"stevey"},{"issue_id":"bd-f8b764c9.9","depends_on_id":"bd-f8b764c9.11","type":"blocks","created_at":"2025-10-29T21:24:29.413823-07:00","created_by":"stevey"}]}
{"id":"bd-fb05","content_hash":"f72d292b5bf2e258a5f59a1097339daa0db7d6cd9c7c7f21faa476b1a40e6041","title":"Refactor sqlite.go into focused modules","description":"Split sqlite.go (2,298 lines) into focused modules: migrations.go, ids.go, issues.go, events.go, dirty.go, db.go. This will improve maintainability and reduce cognitive load.","design":"Files to create:\n- migrations.go: Migration registry + runner\n- ids.go: ID generation/validation \n- issues.go: CRUD helpers\n- events.go: Event helpers\n- dirty.go: dirty_issues helpers\n- db.go: New/open, DSN construction\n- tx.go: Transaction helper","status":"open","priority":1,"issue_type":"epic","created_at":"2025-11-01T11:41:14.805895-07:00","updated_at":"2025-11-01T11:41:14.805895-07:00"}
{"id":"bd-fb05","content_hash":"d8c34c8c2f87c9c726a9a5f90d451e65583bd3269180a9ca30d0864bc960aa99","title":"Refactor sqlite.go into focused modules","description":"Split sqlite.go (2,298 lines) into focused modules: migrations.go, ids.go, issues.go, events.go, dirty.go, db.go. This will improve maintainability and reduce cognitive load.","design":"Files to create:\n- migrations.go: Migration registry + runner\n- ids.go: ID generation/validation \n- issues.go: CRUD helpers\n- events.go: Event helpers\n- dirty.go: dirty_issues helpers\n- db.go: New/open, DSN construction\n- tx.go: Transaction helper","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-01T11:41:14.805895-07:00","updated_at":"2025-11-01T22:30:09.833675-07:00","closed_at":"2025-11-01T22:30:09.833675-07:00"}
{"id":"bd-fb95094c","content_hash":"99f456d7a5d3a4288c3f60dd65212480c54d3b0161e57d7eccffe01875d2eb5e","title":"Code Health \u0026 Technical Debt Cleanup","description":"Comprehensive codebase cleanup to remove dead code, refactor monolithic files, deduplicate utilities, and improve maintainability. Based on ultrathink code health analysis conducted 2025-10-27.\n\nGoals:\n- Remove ~1,500 LOC of dead/unreachable code\n- Split 2 monolithic files (server.go 2,273 LOC, sqlite.go 2,136 LOC) into focused modules\n- Deduplicate scattered utility functions (normalizeLabels, BD_DEBUG checks)\n- Consolidate test coverage (2,019 LOC of collision tests)\n- Improve code navigation and reduce merge conflicts\n\nImpact: Reduces codebase by ~6-8%, improves maintainability, faster CI/CD\n\nEstimated Effort: 11 days across 4 phases","acceptance_criteria":"- All unreachable code identified by `deadcode` analyzer is removed\n- RPC server split into \u003c500 LOC files with clear responsibilities\n- Duplicate utility functions centralized\n- Test coverage maintained or improved\n- All tests passing\n- Documentation updated","status":"open","priority":2,"issue_type":"epic","created_at":"2025-10-27T20:39:22.22227-07:00","updated_at":"2025-10-30T17:12:58.210295-07:00","labels":["cleanup","epic"]}
{"id":"bd-fb95094c.1","content_hash":"d28bd9b00ae5586a782aec012344d1c29eec3bc9fdfa06d5804984a3b3c78e4f","title":"Run final validation and cleanup checks","description":"Final validation pass to ensure all cleanup objectives met and no regressions introduced.\n\nValidation checklist:\n1. Dead code verification: `go run golang.org/x/tools/cmd/deadcode@latest -test ./...`\n2. Test coverage: `go test -cover ./...`\n3. Build verification: `go build ./cmd/bd/`\n4. Linting: `golangci-lint run`\n5. Integration tests\n6. Metrics verification\n7. Git clean check\n\nFinal metrics to report:\n- LOC removed: ~____\n- Files deleted: ____\n- Files created: ____\n- Test coverage: ____%\n- Build time: ____ (before/after)\n- Test run time: ____ (before/after)\n\nImpact: Confirms all cleanup objectives achieved successfully","acceptance_criteria":"- Zero unreachable functions per deadcode analyzer\n- All tests pass: `go test ./...`\n- Test coverage maintained or improved\n- Builds cleanly: `go build ./...`\n- Linting shows improvements\n- Integration tests all pass\n- LOC reduction target achieved (~2,500 LOC)\n- No unintended behavior changes\n- Git commit messages document all changes","notes":"Validation completed:\n- LOC: 52,372 lines total\n- Dead code: 4 functions in import_shared.go (tracked in bd-6fe4622f)\n- Build: ✓ Successful\n- Test coverage: ~20-82% across packages\n- Test failure: TestTwoCloneCollision (timeout issue)\n- Linting: errcheck warnings present (defer close, fmt errors)\n- Test time: ~20s\n\nIssues found:\n1. bd-6fe4622f: Remove unreachable import functions (renameImportedIssuePrefixes, etc)\n2. TestTwoCloneCollision: Daemon killall timeout causing test failure\n3. Linting: errcheck violations need fixing","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T20:32:00.14166-07:00","updated_at":"2025-10-30T17:12:58.209988-07:00","closed_at":"2025-10-28T14:11:25.218801-07:00","labels":["phase-4","validation"],"dependencies":[{"issue_id":"bd-fb95094c.1","depends_on_id":"bd-fb95094c","type":"parent-child","created_at":"2025-10-27T20:32:00.144113-07:00","created_by":"daemon"}]}
{"id":"bd-fb95094c.10","content_hash":"0d499f79a6336ca36c7e459e3393cd7cfe471d184e5e443fa9757a22740744ab","title":"Consider central serialization package for JSON handling","description":"Multiple parts of the codebase handle JSON serialization of issues with slightly different approaches. Consider creating a centralized serialization package to ensure consistency.\n\nCurrent serialization locations:\n- `cmd/bd/export.go` - JSONL export (issues to file)\n- `cmd/bd/import.go` - JSONL import (file to issues)\n- `internal/rpc/protocol.go` - RPC JSON marshaling\n- `internal/storage/memory/memory.go` - In-memory marshaling\n\nPotential benefits:\n- Single source of truth for JSON format\n- Consistent field naming\n- Easier to add new fields\n- Centralized validation\n\nNote: This is marked **optional** because:\n- Current serialization mostly works\n- May not provide enough benefit to justify refactor\n- Risk of breaking compatibility\n\nDecision point: Evaluate if benefits outweigh refactoring cost\n\nImpact: TBD based on investigation - may defer to future work","acceptance_criteria":"- Create serialization package with documented JSON format\n- Migrate export/import to use centralized serialization\n- All existing JSONL files can be read with new code\n- All tests pass: `go test ./...`\n- Export/import round-trip works perfectly\n- RPC protocol unchanged (or backwards compatible)","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-27T20:31:19.090608-07:00","updated_at":"2025-10-30T17:12:58.208871-07:00","labels":["deduplication","optional","phase-3","refactor","serialization"],"dependencies":[{"issue_id":"bd-fb95094c.10","depends_on_id":"bd-fb95094c","type":"parent-child","created_at":"2025-10-27T20:31:19.092328-07:00","created_by":"daemon"}]}