bd sync: 2025-10-30 15:21:53
This commit is contained in:
@@ -64,7 +64,7 @@
|
||||
{"id":"bd-168","content_hash":"1a53798d7a2eaf014f90a399745beb62b4bb265c9d03713f0b00dbc54c3073e2","title":"Implement hash ID generation in CreateIssue","description":"Implement hash ID generation in CreateIssue function.\n\n## For Top-Level Issues\n```go\nfunc generateHashID(prefix, title, description, creator string, timestamp time.Time) string {\n content := fmt.Sprintf(\"%s|%s|%s|%d\", title, description, creator, timestamp.UnixNano())\n hash := sha256.Sum256([]byte(content))\n shortHash := hex.EncodeToString(hash[:4]) // 8 hex chars\n return fmt.Sprintf(\"%s-%s\", prefix, shortHash)\n}\n```\n\n## For Child Issues\n```go\nfunc (s *SQLiteStorage) createChildIssue(parentID string, issue *types.Issue) error {\n // Validate parent exists and depth \u003c= 3\n childNum := s.getNextChildID(parentID)\n issue.ID = fmt.Sprintf(\"%s.%d\", parentID, childNum)\n // ... create issue\n}\n```\n\n## CLI Integration\n```bash\nbd create \"Auth System\" # → bd-a3f8e9a2\nbd create \"Login Flow\" --parent a3f8e9 # → bd-a3f8e9a2.1\nbd create \"Design UI\" --parent a3f8e9.1 # → bd-a3f8e9a2.1.1\n```\n\n## Validation\n- Reject depth \u003e 3\n- Ensure parent exists\n- Check parent is epic type (optional, for UX)","notes":"Work completed on feature/hash-ids branch. Reverted from main to avoid breaking changes. Will merge after migration strategy (bd-173) is ready.","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-29T21:24:29.412237-07:00","updated_at":"2025-10-30T14:17:14.485149-07:00","dependencies":[{"issue_id":"bd-168","depends_on_id":"bd-165","type":"parent-child","created_at":"2025-10-29T21:24:29.413417-07:00","created_by":"stevey"},{"issue_id":"bd-168","depends_on_id":"bd-166","type":"blocks","created_at":"2025-10-29T21:24:29.413823-07:00","created_by":"stevey"}]}
|
||||
{"id":"bd-169","content_hash":"d565476761fdf87fd8ec031cdae0e6698734ace357c4f00e1b9947e4d7101eb7","title":"Update JSONL format to use hash IDs","description":"Update JSONL format to store hierarchical hash-based IDs.\n\n## Changes\n- ID field: bd-af78e9a2 (top-level) or bd-af78e9a2.1.2 (hierarchical)\n- No alias field needed (removed from original plan)\n- All other fields remain the same\n\n## Example\n```json\n{\"id\":\"bd-af78e9a2\",\"title\":\"Auth System\",\"type\":\"epic\",...}\n{\"id\":\"bd-af78e9a2.1\",\"title\":\"Login Flow\",\"type\":\"epic\",...}\n{\"id\":\"bd-af78e9a2.1.1\",\"title\":\"Design UI\",\"type\":\"task\",...}\n```\n\n## Benefits\n- Hierarchical structure visible in JSONL\n- Git merge conflicts reduced (different IDs = different lines)\n- Easy to grep for epic children: grep \"bd-af78e9a2\\.\" issues.jsonl\n\n## Backward Compatibility\nMigration tool will convert bd-1 → bd-{hash} with mapping preserved.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T21:24:47.408106-07:00","updated_at":"2025-10-30T14:27:39.953114-07:00","closed_at":"2025-10-30T14:27:39.953114-07:00","dependencies":[{"issue_id":"bd-169","depends_on_id":"bd-165","type":"parent-child","created_at":"2025-10-29T21:24:47.409489-07:00","created_by":"stevey"},{"issue_id":"bd-169","depends_on_id":"bd-168","type":"blocks","created_at":"2025-10-29T21:24:47.409977-07:00","created_by":"stevey"},{"issue_id":"bd-169","depends_on_id":"bd-167","type":"blocks","created_at":"2025-10-29T21:29:45.975499-07:00","created_by":"stevey"},{"issue_id":"bd-169","depends_on_id":"bd-192","type":"blocks","created_at":"2025-10-30T14:22:59.347557-07:00","created_by":"import-remap"}]}
|
||||
{"id":"bd-17","content_hash":"404b82a19dde2fdece7eb6bb3b816db7906e81a03a5a05341ed631af7a2a8e87","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","acceptance_criteria":"- Remove the 4 unreachable methods (~80 LOC total)\n- Verify no callers: `grep -r \"GetLastImportTime\\|SetLastImportTime\\|findJSONLPath\" .`\n- All tests pass: `go test ./internal/rpc/...`\n- Daemon functionality works: test daemon start/stop/operations","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T20:30:19.962209-07:00","updated_at":"2025-10-28T16:07:26.103703-07:00","closed_at":"2025-10-28T16:07:26.103703-07:00","labels":["cleanup","dead-code","phase-1","rpc"],"dependencies":[{"issue_id":"bd-17","depends_on_id":"bd-26","type":"parent-child","created_at":"2025-10-27T20:30:19.965239-07:00","created_by":"daemon"}]}
|
||||
{"id":"bd-170","content_hash":"9a2120c5d56a818ae4d0b2acc3518b6705d62b6cb866703dd524e3bc1a462397","title":"CLI accepts hash ID prefixes (Git-style)","description":"Implement prefix-optional parsing for hash IDs throughout CLI.\n\n## Parsing Logic\n```go\n// internal/utils/id_parser.go\nfunc ParseIssueID(input string) (issueID string, err error) {\n // Already has prefix: bd-a3f8e9 or bd-a3f8e9.1.2\n if strings.HasPrefix(input, \"bd-\") {\n return input, nil\n }\n \n // Add prefix: a3f8e9 → bd-a3f8e9\n // Works with hierarchical too: a3f8e9.1.2 → bd-a3f8e9.1.2\n return \"bd-\" + input, nil\n}\n\n// Prefix matching for partial IDs\nfunc ResolvePartialID(input string) (fullID string, err error) {\n parsedID := ParseIssueID(input) // Ensure prefix\n \n // Query with LIKE for prefix match\n matches := storage.FindByPrefix(parsedID)\n \n if len(matches) == 0 {\n return \"\", fmt.Errorf(\"no issue found matching %q\", input)\n }\n if len(matches) \u003e 1 {\n return \"\", fmt.Errorf(\"ambiguous ID %q matches: %v\", input, matches)\n }\n return matches[0].ID, nil\n}\n```\n\n## Behavior Examples\n```bash\n# All these inputs work:\nbd show a3f8e9 # Add prefix → bd-a3f8e9\nbd show bd-a3f8e9 # Already has prefix\nbd show a3f8 # Shorter prefix match\nbd show a3f8e9.1 # Hierarchical without prefix\nbd show bd-a3f8e9.1.2 # Full hierarchical with prefix\n\n# Output always shows full ID with prefix:\nbd-a3f8e9 [epic] Auth System\nbd-a3f8e9.1 [epic] Login Flow\nbd-a3f8e9.1.2 [task] Backend validation\n```\n\n## Error Handling\n```bash\n# Not found\n$ bd show xyz789\nError: no issue found matching \"bd-xyz789\"\n\n# Ambiguous (multiple matches)\n$ bd show a3\nError: ambiguous ID \"bd-a3\" matches: bd-a3f8e9, bd-a34721, bd-a38f92\nUse more characters to disambiguate.\n```\n\n## Commands to Update\nAll commands that accept issue IDs:\n\n### Read operations\n- bd show \u003cid\u003e\n- bd list --id \u003cids\u003e\n- bd dep tree \u003cid\u003e\n\n### Write operations\n- bd update \u003cid\u003e\n- bd close \u003cid\u003e\n- bd reopen \u003cid\u003e\n- bd label add \u003cid\u003e\n- bd dep add \u003cid1\u003e \u003cid2\u003e\n- bd comment add \u003cid\u003e\n\n### Multiple IDs\n```bash\n# All work with optional prefix:\nbd show a3f8e9 b7c2d1 # → bd-a3f8e9 bd-b7c2d1\nbd dep add a3f8e9.1 b7c2d1 # → bd-a3f8e9.1 blocks bd-b7c2d1\n```\n\n## Display Format\n**Always show full ID with prefix** in output for:\n- Copy-paste clarity\n- External reference (git commits, docs)\n- Unambiguous identification\n\n```bash\n$ bd list\nbd-a3f8e9 [P1] Auth System [epic] open\nbd-b7c2d1 [P2] Fix daemon crash [bug] open\nbd-1a2b3c4d [P3] Add logging [task] open\n```\n\n## Files to Create/Modify\n- internal/utils/id_parser.go (new - parsing logic)\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/comment.go\n- cmd/bd/list.go\n\n## Testing\n- Test prefix omitted: a3f8e9 → bd-a3f8e9\n- Test prefix included: bd-a3f8e9 → bd-a3f8e9\n- Test hierarchical: a3f8e9.1.2 → bd-a3f8e9.1.2\n- Test partial match: a3f8 → bd-a3f8e9\n- Test ambiguous ID error\n- Test not found error\n- Test mixed input: bd show a3f8e9 bd-b7c2d1","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-29T21:25:06.256317-07:00","updated_at":"2025-10-30T00:32:47.510446-07:00","dependencies":[{"issue_id":"bd-170","depends_on_id":"bd-165","type":"parent-child","created_at":"2025-10-29T21:25:06.257796-07:00","created_by":"stevey"},{"issue_id":"bd-170","depends_on_id":"bd-167","type":"blocks","created_at":"2025-10-29T21:25:06.258307-07:00","created_by":"stevey"},{"issue_id":"bd-170","depends_on_id":"bd-169","type":"blocks","created_at":"2025-10-29T21:29:45.993274-07:00","created_by":"stevey"}]}
|
||||
{"id":"bd-170","content_hash":"d61902568b1a156bfd31273e9ceaa1f32296dd00153f2485f2bbb712e44284d6","title":"CLI accepts hash ID prefixes (Git-style)","description":"Implement prefix-optional parsing for hash IDs throughout CLI.\n\n## Parsing Logic\n```go\n// internal/utils/id_parser.go\nfunc ParseIssueID(input string) (issueID string, err error) {\n // Already has prefix: bd-a3f8e9 or bd-a3f8e9.1.2\n if strings.HasPrefix(input, \"bd-\") {\n return input, nil\n }\n \n // Add prefix: a3f8e9 → bd-a3f8e9\n // Works with hierarchical too: a3f8e9.1.2 → bd-a3f8e9.1.2\n return \"bd-\" + input, nil\n}\n\n// Prefix matching for partial IDs\nfunc ResolvePartialID(input string) (fullID string, err error) {\n parsedID := ParseIssueID(input) // Ensure prefix\n \n // Query with LIKE for prefix match\n matches := storage.FindByPrefix(parsedID)\n \n if len(matches) == 0 {\n return \"\", fmt.Errorf(\"no issue found matching %q\", input)\n }\n if len(matches) \u003e 1 {\n return \"\", fmt.Errorf(\"ambiguous ID %q matches: %v\", input, matches)\n }\n return matches[0].ID, nil\n}\n```\n\n## Behavior Examples\n```bash\n# All these inputs work:\nbd show a3f8e9 # Add prefix → bd-a3f8e9\nbd show bd-a3f8e9 # Already has prefix\nbd show a3f8 # Shorter prefix match\nbd show a3f8e9.1 # Hierarchical without prefix\nbd show bd-a3f8e9.1.2 # Full hierarchical with prefix\n\n# Output always shows full ID with prefix:\nbd-a3f8e9 [epic] Auth System\nbd-a3f8e9.1 [epic] Login Flow\nbd-a3f8e9.1.2 [task] Backend validation\n```\n\n## Error Handling\n```bash\n# Not found\n$ bd show xyz789\nError: no issue found matching \"bd-xyz789\"\n\n# Ambiguous (multiple matches)\n$ bd show a3\nError: ambiguous ID \"bd-a3\" matches: bd-a3f8e9, bd-a34721, bd-a38f92\nUse more characters to disambiguate.\n```\n\n## Commands to Update\nAll commands that accept issue IDs:\n\n### Read operations\n- bd show \u003cid\u003e\n- bd list --id \u003cids\u003e\n- bd dep tree \u003cid\u003e\n\n### Write operations\n- bd update \u003cid\u003e\n- bd close \u003cid\u003e\n- bd reopen \u003cid\u003e\n- bd label add \u003cid\u003e\n- bd dep add \u003cid1\u003e \u003cid2\u003e\n- bd comment add \u003cid\u003e\n\n### Multiple IDs\n```bash\n# All work with optional prefix:\nbd show a3f8e9 b7c2d1 # → bd-a3f8e9 bd-b7c2d1\nbd dep add a3f8e9.1 b7c2d1 # → bd-a3f8e9.1 blocks bd-b7c2d1\n```\n\n## Display Format\n**Always show full ID with prefix** in output for:\n- Copy-paste clarity\n- External reference (git commits, docs)\n- Unambiguous identification\n\n```bash\n$ bd list\nbd-a3f8e9 [P1] Auth System [epic] open\nbd-b7c2d1 [P2] Fix daemon crash [bug] open\nbd-1a2b3c4d [P3] Add logging [task] open\n```\n\n## Files to Create/Modify\n- internal/utils/id_parser.go (new - parsing logic)\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/comment.go\n- cmd/bd/list.go\n\n## Testing\n- Test prefix omitted: a3f8e9 → bd-a3f8e9\n- Test prefix included: bd-a3f8e9 → bd-a3f8e9\n- Test hierarchical: a3f8e9.1.2 → bd-a3f8e9.1.2\n- Test partial match: a3f8 → bd-a3f8e9\n- Test ambiguous ID error\n- Test not found error\n- Test mixed input: bd show a3f8e9 bd-b7c2d1","status":"in_progress","priority":1,"issue_type":"task","created_at":"2025-10-29T21:25:06.256317-07:00","updated_at":"2025-10-30T15:15:36.477196-07:00","dependencies":[{"issue_id":"bd-170","depends_on_id":"bd-165","type":"parent-child","created_at":"2025-10-29T21:25:06.257796-07:00","created_by":"stevey"},{"issue_id":"bd-170","depends_on_id":"bd-167","type":"blocks","created_at":"2025-10-29T21:25:06.258307-07:00","created_by":"stevey"},{"issue_id":"bd-170","depends_on_id":"bd-169","type":"blocks","created_at":"2025-10-29T21:29:45.993274-07:00","created_by":"stevey"}]}
|
||||
{"id":"bd-171","content_hash":"e81f6af609fb707773b386ead4defedd146fc0f937eb60e6bfcf3bb63224237d","title":"Implement hierarchical child ID generation","description":"Implement sequential child ID generation within parent contexts.\n\n## Function Signature\n```go\nfunc (s *SQLiteStorage) getNextChildID(ctx context.Context, parentID string) (string, error)\n```\n\n## Logic\n1. Insert or update child_counters for parent_id\n2. Return incremented counter\n3. Format as parentID.{counter}\n4. Works at any depth (bd-a3f8e9.1 → bd-a3f8e9.1.5)\n\n## Collision Handling\n- In single-player mode: No collisions (sequential)\n- In multi-player mode (future): Rare collisions, manual resolution needed\n- Epic ownership makes collisions naturally rare\n\n## Integration\n- Called from CreateIssue when --parent flag is used\n- Validates parent exists and depth \u003c= 3","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-29T21:25:27.389191-07:00","updated_at":"2025-10-30T14:39:56.341051-07:00","closed_at":"2025-10-30T14:39:56.341051-07:00","dependencies":[{"issue_id":"bd-171","depends_on_id":"bd-165","type":"parent-child","created_at":"2025-10-29T21:25:27.390611-07:00","created_by":"stevey"},{"issue_id":"bd-171","depends_on_id":"bd-167","type":"blocks","created_at":"2025-10-29T21:25:27.391127-07:00","created_by":"stevey"},{"issue_id":"bd-171","depends_on_id":"bd-169","type":"blocks","created_at":"2025-10-29T21:25:27.39154-07:00","created_by":"stevey"}]}
|
||||
{"id":"bd-172","content_hash":"cb24777a804129f91ae8d96937c762ba4877e2a0273d389d099f678ed2080a54","title":"Delete collision resolution code","description":"Remove ~2,100 LOC of ID collision detection and resolution code (no longer needed with hash IDs).\n\n## Files to Delete Entirely\n```\ninternal/storage/sqlite/collision.go (~800 LOC)\ninternal/storage/sqlite/collision_test.go (~300 LOC)\ncmd/bd/autoimport_collision_test.go (~400 LOC)\n```\n\n## Code to Remove from Existing Files\n\n### internal/importer/importer.go\nRemove:\n- `DetectCollisions()` calls\n- `ScoreCollisions()` logic\n- `RemapCollisions()` calls\n- `handleRename()` function\n- All collision-related error handling\n\nKeep:\n- Basic import logic\n- Exact match detection (idempotent import)\n\n### beads_twoclone_test.go\nRemove:\n- `TestTwoCloneCollision` (bd-86)\n- `TestThreeCloneCollision` (bd-185)\n- `TestFiveCloneCollision` (bd-151)\n- All N-way collision tests\n\n### cmd/bd/import.go\nRemove:\n- `--resolve-collisions` flag\n- `--dry-run` collision preview\n- Collision reporting\n\n## Issues Closed by This Change\n- bd-86: Add test for symmetric collision\n--89: Content-hash collision resolution\n- bd-185: N-way collision resolution epic\n- bd-95: Add ScoreCollisions (already done but now unnecessary)\n- bd-96: Make DetectCollisions read-only\n- bd-97: ResolveNWayCollisions function\n- bd-98: Multi-round import convergence\n- bd-108: Multi-round convergence for N-way collisions\n- bd-109: Transaction + retry logic for collisions\n- bd-160: Test case for symmetric collision\n\n## Verification Steps\n1. `grep -r \"collision\" --include=\"*.go\"` → should only find alias conflicts\n2. `go test ./...` → all tests pass\n3. `go build ./cmd/bd` → clean build\n4. Check LOC reduction: `git diff --stat`\n\n## Expected Metrics\n- **Files deleted**: 3\n- **LOC removed**: ~2,100\n- **Test coverage**: Should increase (less untested code)\n- **Binary size**: Slightly smaller\n\n## Caution\nDo NOT delete:\n- Alias conflict resolution (new code in bd-171)\n- Duplicate detection (bd-59, bd-149) - different from ID collisions\n- Merge conflict resolution (bd-65, bd-103) - git conflicts, not ID collisions\n\n## Files to Modify\n- internal/importer/importer.go (remove collision handling)\n- cmd/bd/import.go (remove --resolve-collisions flag)\n- beads_twoclone_test.go (remove collision tests)\n- Delete: internal/storage/sqlite/collision.go\n- Delete: internal/storage/sqlite/collision_test.go \n- Delete: cmd/bd/autoimport_collision_test.go\n\n## Testing\n- Ensure all remaining tests pass\n- Manual test: create issue on two clones, sync → no collisions\n- Verify error if somehow hash collision occurs (extremely unlikely)","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-29T21:25:50.976383-07:00","updated_at":"2025-10-29T23:14:44.171339-07:00","dependencies":[{"issue_id":"bd-172","depends_on_id":"bd-165","type":"parent-child","created_at":"2025-10-29T21:25:50.977857-07:00","created_by":"stevey"},{"issue_id":"bd-172","depends_on_id":"bd-168","type":"blocks","created_at":"2025-10-29T21:25:50.978395-07:00","created_by":"stevey"},{"issue_id":"bd-172","depends_on_id":"bd-169","type":"blocks","created_at":"2025-10-29T21:25:50.978842-07:00","created_by":"stevey"},{"issue_id":"bd-172","depends_on_id":"bd-192","type":"blocks","created_at":"2025-10-30T14:22:59.348038-07:00","created_by":"import-remap"}]}
|
||||
{"id":"bd-173","content_hash":"9d78f9471bf147696d5295cc89324d3486feb4bbe16c6e89524320fab229bcd1","title":"Migration tool: sequential → hash IDs","description":"Create migration tool to convert sequential IDs to hierarchical hash-based IDs.\n\n## Command\n```bash\nbd migrate --to-hash-ids [--dry-run]\n```\n\n## Process\n1. For each top-level issue (no parent):\n - Generate hash ID from content\n - Create mapping: bd-1 → bd-a3f8e9a2\n \n2. For each child issue (has parent):\n - Find parent's new hash ID\n - Assign sequential child number based on creation order\n - bd-5 (parent: bd-1) → bd-a3f8e9a2.1\n \n3. Update all references:\n - Dependencies (blocks, parent-child)\n - Comments (issue_id foreign keys)\n - External refs (if containing old IDs)\n\n4. Preserve:\n - Creation timestamps\n - All content\n - All relationships\n - History in comments\n\n## Output\n- Mapping file: old_id → new_id (for reference)\n- Updated JSONL with new IDs\n- Migration log\n\n## Validation\n- Verify all relationships intact\n- Check no orphaned issues\n- Confirm total count unchanged\n- Test rollback procedure\n\n## Safety\n- Backup database before migration\n- Dry-run mode shows what would change\n- Rollback script provided","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-29T21:26:24.563993-07:00","updated_at":"2025-10-30T00:26:03.862157-07:00","dependencies":[{"issue_id":"bd-173","depends_on_id":"bd-165","type":"parent-child","created_at":"2025-10-29T21:26:24.565325-07:00","created_by":"stevey"},{"issue_id":"bd-173","depends_on_id":"bd-168","type":"blocks","created_at":"2025-10-29T21:26:24.565945-07:00","created_by":"stevey"},{"issue_id":"bd-173","depends_on_id":"bd-192","type":"blocks","created_at":"2025-10-30T14:22:59.348502-07:00","created_by":"import-remap"}]}
|
||||
|
||||
Reference in New Issue
Block a user