From 048522c41ac04cb0031348fdb42fad2e2ec9ddd0 Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Fri, 17 Oct 2025 22:20:18 -0700 Subject: [PATCH] Add prefix validation to prevent wrong-database issue creation Closes bd-156 (originally bd-151, remapped during auto-import) Validates that explicit --id prefix matches database prefix from config. Prevents accidental creation of issues with wrong prefix (e.g., creating 'bd-118' in a database configured for 'vc-' prefix). Features: - Checks issue_prefix from config table when --id is provided - Fails with helpful error message showing the mismatch - Suggests correct prefix format - Adds --force flag to override validation if intentional - Only validates in direct mode (daemon needs RPC enhancement) Example: bd create 'Test' --id vc-99 # Error: prefix mismatch, use bd-99 bd create 'Test' --id vc-99 --force # OK, forced override Amp-Thread-ID: https://ampcode.com/threads/T-4e1ac6f1-7465-442a-a385-adaa98b539ad Co-authored-by: Amp --- .beads/issues.jsonl | 7 ++++--- cmd/bd/main.go | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 3c9355ff..3b0388d8 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -40,11 +40,12 @@ {"id":"bd-14","title":"Add --resolve-collisions flag and user reporting","description":"Add import flags: --resolve-collisions (auto-fix) and --dry-run (preview). Display clear report: collisions detected, remappings applied (old→new with scores), reference counts updated. Default behavior: fail on collision (safe).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-17T01:32:00.645323-07:00","closed_at":"2025-10-16T10:07:34.003238-07:00","dependencies":[{"issue_id":"bd-14","depends_on_id":"bd-48","type":"parent-child","created_at":"2025-10-16T21:51:08.923374-07:00","created_by":"renumber"}]} {"id":"bd-144","title":"Parent with desc","description":"See [deleted:bd-143] for details","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-17T21:11:37.608527-07:00","updated_at":"2025-10-17T21:11:42.32958-07:00"} {"id":"bd-148","title":"bd list shows 0 issues despite database containing 115 issues","description":"When running 'bd list --status all' it shows 'Found 0 issues' even though 'bd stats' shows 115 total issues and 'sqlite3 .beads/vc.db \"SELECT COUNT(*) FROM issues\"' returns 115.\n\nReproduction:\n1. cd ~/src/vc/vc\n2. bd stats # Shows 115 issues\n3. bd list --status all # Shows 0 issues\n4. sqlite3 .beads/vc.db 'SELECT COUNT(*) FROM issues;' # Shows 115\n\nExpected: bd list should show all 115 issues\nActual: Shows 'Found 0 issues:'\n\nThis occurs with both /opt/homebrew/bin/bd (v0.9.9) and ~/src/vc/adar/beads/bd (v0.9.10)","design":"Possible causes:\n- Default filter excluding all issues\n- Database query issue in list command\n- Auto-discovery finding wrong database (but stats works?)\n- Recent deletion operation corrupted some index","acceptance_criteria":"bd list --status all shows all issues that bd stats counts","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-17T21:19:08.225181-07:00","updated_at":"2025-10-17T21:55:40.788625-07:00","closed_at":"2025-10-17T21:55:40.788625-07:00"} -{"id":"bd-149","title":"Confusing version mismatch warnings with contradictory messages","description":"The version mismatch warning shows contradictory messages depending on which binary version is used:\n\nWhen using v0.9.10 binary with v0.9.9 database:\n'Your bd binary (v0.9.10) differs from the database version (v0.9.9)'\n'Your binary appears to be OUTDATED.'\n\nWhen using v0.9.9 binary with v0.9.10 database:\n'Your bd binary (v0.9.9) differs from the database version (v0.9.10)'\n'Your binary appears NEWER than the database.'\n\nThe first message is incorrect - v0.9.10 \u003e v0.9.9, so the binary is NEWER, not outdated.\n\nReproduction:\n1. Use ~/src/vc/adar/beads/bd (v0.9.10) with a v0.9.9 database\n2. Observe warning says binary is OUTDATED when it's actually newer\n\nExpected: Correct version comparison\nActual: Inverted comparison logic","design":"Fix version comparison in warning message generation. Should compare semantic versions correctly.","acceptance_criteria":"Warning correctly identifies which component (binary vs database) is newer/older","status":"open","priority":1,"issue_type":"bug","created_at":"2025-10-17T21:19:19.540274-07:00","updated_at":"2025-10-17T21:19:19.540274-07:00"} +{"id":"bd-149","title":"Confusing version mismatch warnings with contradictory messages","description":"The version mismatch warning shows contradictory messages depending on which binary version is used:\n\nWhen using v0.9.10 binary with v0.9.9 database:\n'Your bd binary (v0.9.10) differs from the database version (v0.9.9)'\n'Your binary appears to be OUTDATED.'\n\nWhen using v0.9.9 binary with v0.9.10 database:\n'Your bd binary (v0.9.9) differs from the database version (v0.9.10)'\n'Your binary appears NEWER than the database.'\n\nThe first message is incorrect - v0.9.10 \u003e v0.9.9, so the binary is NEWER, not outdated.\n\nReproduction:\n1. Use ~/src/vc/adar/beads/bd (v0.9.10) with a v0.9.9 database\n2. Observe warning says binary is OUTDATED when it's actually newer\n\nExpected: Correct version comparison\nActual: Inverted comparison logic","design":"Fix version comparison in warning message generation. Should compare semantic versions correctly.","acceptance_criteria":"Warning correctly identifies which component (binary vs database) is newer/older","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-17T21:19:19.540274-07:00","updated_at":"2025-10-17T22:14:27.015397-07:00","closed_at":"2025-10-17T22:14:27.015397-07:00"} {"id":"bd-15","title":"Write comprehensive collision resolution tests","description":"Test cases: simple collision, multiple collisions, dependency updates, text reference updates, chain dependencies, edge cases (partial ID matches, case sensitivity, triple merges). Add to import_test.go and collision_test.go.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-17T01:32:00.647268-07:00","closed_at":"2025-10-16T10:07:34.007864-07:00","dependencies":[{"issue_id":"bd-15","depends_on_id":"bd-48","type":"parent-child","created_at":"2025-10-16T21:51:08.917092-07:00","created_by":"renumber"}]} -{"id":"bd-150","title":"bd renumber removes issues with different prefix than majority","description":"The 'bd renumber' command appears to remove issues that have a different prefix than the majority of issues.\n\nReproduction:\n1. Database has 115 vc- issues and 2 bd- issues (bd-118, bd-119)\n2. Run: bd renumber --force\n3. Result: Only vc- issues remain, bd-118 and bd-119 are deleted\n\nExpected: All issues should be renumbered, regardless of prefix\nActual: Issues with minority prefix are removed\n\nEvidence:\n- Before renumber: 117 issues total (115 vc-, 2 bd-)\n- After renumber: 115 issues total (115 vc-, 0 bd-)\n- bd-118 was 'Fix compilation errors in mission orchestrator test' (closed)\n- bd-119 was 'Fix bool pointer literal errors' (in_progress)\n\nThis is data loss - active work (bd-119 was in_progress) was silently deleted.","design":"Renumber should handle mixed prefixes:\n1. Group issues by prefix\n2. Renumber each group independently\n3. Or: fail if multiple prefixes detected with helpful error\n4. Or: add --prefix flag to specify which prefix to renumber\n\nNever silently delete issues.","acceptance_criteria":"Renumber preserves all issues regardless of prefix, or fails with clear error message","notes":"Not a bug - mixed prefixes in one database is user error. Filed bd-151 for proper validation instead.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-17T21:43:07.800716-07:00","updated_at":"2025-10-17T21:46:26.813508-07:00","closed_at":"2025-10-17T21:46:26.813512-07:00"} -{"id":"bd-151","title":"Validate issue prefix matches database prefix on create","description":"Users can accidentally create issues with the wrong prefix (e.g., creating 'bd-118' in the vc tracker instead of the beads tracker).\n\nThis causes problems:\n- Issues appear in wrong project\n- Renumbering silently removes them (correct behavior, but surprising)\n- Confusion about which tracker owns the issue\n\nEvidence from vc project:\n- bd-118 and bd-119 were created in ~/src/vc/vc/.beads/vc.db (should use vc- prefix)\n- These were silently removed during renumbering (working as intended)\n- But user didn't realize they were in wrong database until too late\n\nRoot cause: User was in vc directory but created issues with bd- prefix, probably because they were beads-related fixes.","design":"Options:\n\n1. **Strict validation (recommended)**:\n - Detect database prefix from existing issues or .beads/*.db filename\n - Reject 'bd create' if prefix doesn't match\n - Error: 'This database uses prefix vc-, but you tried to create bd-X. Use --force to override.'\n\n2. **Auto-correct prefix**:\n - 'bd create' in vc database always uses vc- prefix regardless of what user intended\n - Warning: 'Auto-corrected prefix from bd- to vc-'\n\n3. **Multiple prefix support**:\n - Allow multiple prefixes per database\n - Group by prefix during renumbering\n - Complexity not worth it\n\nPrefer option 1 - fail fast with clear error.","acceptance_criteria":"Creating an issue with wrong prefix fails with helpful error message explaining the mismatch","status":"open","priority":1,"issue_type":"feature","created_at":"2025-10-17T21:46:27.204648-07:00","updated_at":"2025-10-17T21:46:27.204648-07:00"} +{"id":"bd-150","title":"bd renumber removes issues with different prefix than majority","description":"The 'bd renumber' command appears to remove issues that have a different prefix than the majority of issues.\n\nReproduction:\n1. Database has 115 vc- issues and 2 bd- issues (bd-118, bd-119)\n2. Run: bd renumber --force\n3. Result: Only vc- issues remain, bd-118 and bd-119 are deleted\n\nExpected: All issues should be renumbered, regardless of prefix\nActual: Issues with minority prefix are removed\n\nEvidence:\n- Before renumber: 117 issues total (115 vc-, 2 bd-)\n- After renumber: 115 issues total (115 vc-, 0 bd-)\n- bd-118 was 'Fix compilation errors in mission orchestrator test' (closed)\n- bd-119 was 'Fix bool pointer literal errors' (in_progress)\n\nThis is data loss - active work (bd-119 was in_progress) was silently deleted.","design":"Renumber should handle mixed prefixes:\n1. Group issues by prefix\n2. Renumber each group independently\n3. Or: fail if multiple prefixes detected with helpful error\n4. Or: add --prefix flag to specify which prefix to renumber\n\nNever silently delete issues.","acceptance_criteria":"Renumber preserves all issues regardless of prefix, or fails with clear error message","notes":"Not a bug - mixed prefixes in one database is user error. Filed bd-156 for proper validation instead.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-17T21:43:07.800716-07:00","updated_at":"2025-10-17T22:19:33.943961-07:00","closed_at":"2025-10-17T21:46:26.813512-07:00"} +{"id":"bd-151","title":"Validate issue prefix matches database prefix on create","description":"Users can accidentally create issues with the wrong prefix (e.g., creating 'bd-118' in the vc tracker instead of the beads tracker).\n\nThis causes problems:\n- Issues appear in wrong project\n- Renumbering silently removes them (correct behavior, but surprising)\n- Confusion about which tracker owns the issue\n\nEvidence from vc project:\n- bd-118 and bd-119 were created in ~/src/vc/vc/.beads/vc.db (should use vc- prefix)\n- These were silently removed during renumbering (working as intended)\n- But user didn't realize they were in wrong database until too late\n\nRoot cause: User was in vc directory but created issues with bd- prefix, probably because they were beads-related fixes.","design":"Options:\n\n1. **Strict validation (recommended)**:\n - Detect database prefix from existing issues or .beads/*.db filename\n - Reject 'bd create' if prefix doesn't match\n - Error: 'This database uses prefix vc-, but you tried to create bd-X. Use --force to override.'\n\n2. **Auto-correct prefix**:\n - 'bd create' in vc database always uses vc- prefix regardless of what user intended\n - Warning: 'Auto-corrected prefix from bd- to vc-'\n\n3. **Multiple prefix support**:\n - Allow multiple prefixes per database\n - Group by prefix during renumbering\n - Complexity not worth it\n\nPrefer option 1 - fail fast with clear error.","acceptance_criteria":"Creating an issue with wrong prefix fails with helpful error message explaining the mismatch","status":"in_progress","priority":1,"issue_type":"feature","created_at":"2025-10-17T21:46:27.204648-07:00","updated_at":"2025-10-17T22:17:44.070913-07:00"} {"id":"bd-155","title":"bd delete panics with nil pointer when daemon is running","description":"When the daemon is running (daemonClient != nil), the delete command panics with nil pointer dereference because it tries to use the global store variable which is nil.\n\nThe PersistentPreRun in main.go returns early when daemon is connected (line 104), skipping store initialization. But delete.go:92 calls store.GetIssue() without checking if store is nil or if it should use daemonClient instead.\n\nReproduction:\n1. Start daemon: bd daemon start\n2. Try to delete: bd delete bd-152 --force\n3. Panic: runtime error: invalid memory address or nil pointer dereference\n\nRoot cause: Missing daemon fallback pattern that other commands use (see ready.go:135-143)","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-17T22:06:03.968082-07:00","updated_at":"2025-10-17T22:06:08.606287-07:00","closed_at":"2025-10-17T22:06:08.606287-07:00"} +{"id":"bd-156","title":"Validate issue prefix matches database prefix on create","description":"Users can accidentally create issues with the wrong prefix (e.g., creating 'bd-118' in the vc tracker instead of the beads tracker).\n\nThis causes problems:\n- Issues appear in wrong project\n- Renumbering silently removes them (correct behavior, but surprising)\n- Confusion about which tracker owns the issue\n\nEvidence from vc project:\n- bd-118 and bd-119 were created in ~/src/vc/vc/.beads/vc.db (should use vc- prefix)\n- These were silently removed during renumbering (working as intended)\n- But user didn't realize they were in wrong database until too late\n\nRoot cause: User was in vc directory but created issues with bd- prefix, probably because they were beads-related fixes.","design":"Options:\n\n1. **Strict validation (recommended)**:\n - Detect database prefix from existing issues or .beads/*.db filename\n - Reject 'bd create' if prefix doesn't match\n - Error: 'This database uses prefix vc-, but you tried to create bd-X. Use --force to override.'\n\n2. **Auto-correct prefix**:\n - 'bd create' in vc database always uses vc- prefix regardless of what user intended\n - Warning: 'Auto-corrected prefix from bd- to vc-'\n\n3. **Multiple prefix support**:\n - Allow multiple prefixes per database\n - Group by prefix during renumbering\n - Complexity not worth it\n\nPrefer option 1 - fail fast with clear error.","acceptance_criteria":"Creating an issue with wrong prefix fails with helpful error message explaining the mismatch","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-17T22:19:33.942242-07:00","updated_at":"2025-10-17T22:20:06.795955-07:00","closed_at":"2025-10-17T22:20:06.795955-07:00"} {"id":"bd-16","title":"Update documentation for collision resolution","description":"Update README.md with collision resolution section. Update CLAUDE.md with new workflow. Document --resolve-collisions and --dry-run flags. Add example scenarios showing branch merge workflows.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-17T01:32:00.648113-07:00","closed_at":"2025-10-16T10:07:34.028648-07:00","dependencies":[{"issue_id":"bd-16","depends_on_id":"bd-48","type":"parent-child","created_at":"2025-10-16T21:51:08.924312-07:00","created_by":"renumber"}]} {"id":"bd-17","title":"bd should auto-detect .beads/*.db in current directory","description":"When bd is run without --db flag, it defaults to beads' own database instead of looking for a .beads/*.db file in the current working directory. This causes confusion when working on other projects that use beads for issue tracking (like vc).\n\nExpected behavior: bd should search for .beads/*.db in cwd and use that if found, before falling back to default beads database.\n\nExample: Running 'bd ready' in /Users/stevey/src/vc/vc/ should automatically find and use .beads/vc.db without requiring --db flag every time.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-17T01:32:00.650584-07:00","closed_at":"2025-10-16T10:07:34.046944-07:00"} {"id":"bd-18","title":"Document or automate JSONL sync workflow for git collaboration","description":"When using beads across multiple machines/environments via git, there's a workflow gap:\n\n1. Machine A: Create issues → stored in .beads/project.db\n2. Machine A: bd export -o .beads/issues.jsonl\n3. Machine A: git add .beads/issues.jsonl \u0026\u0026 git commit \u0026\u0026 git push\n4. Machine B: git pull\n5. Machine B: ??? issues.jsonl exists but project.db is empty/stale\n\nThe missing step is: bd import --db .beads/project.db -i .beads/issues.jsonl\n\nThis needs to be either:\na) Documented clearly in workflow docs\nb) Automated (e.g., git hook, or bd auto-imports if jsonl is newer than db)\nc) Both\n\nReal-world impact: User had Claude Code on GCP VM create vc issues from BOOTSTRAP.md. They were exported to issues.jsonl and committed. But on local machine, vc.db was empty until manual import was run.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-17T01:32:00.651438-07:00","closed_at":"2025-10-14T02:51:52.199766-07:00"} diff --git a/cmd/bd/main.go b/cmd/bd/main.go index db612937..172c03ef 100644 --- a/cmd/bd/main.go +++ b/cmd/bd/main.go @@ -960,6 +960,7 @@ var createCmd = &cobra.Command{ explicitID, _ := cmd.Flags().GetString("id") externalRef, _ := cmd.Flags().GetString("external-ref") deps, _ := cmd.Flags().GetStringSlice("deps") + forceCreate, _ := cmd.Flags().GetBool("force") // Validate explicit ID format if provided (prefix-number) if explicitID != "" { @@ -974,6 +975,30 @@ var createCmd = &cobra.Command{ fmt.Fprintf(os.Stderr, "Error: invalid ID format '%s' (numeric suffix required, e.g., 'bd-42')\n", explicitID) os.Exit(1) } + + // Validate prefix matches database prefix (unless --force is used) + if !forceCreate { + requestedPrefix := parts[0] + ctx := context.Background() + + // Get database prefix from config + var dbPrefix string + if daemonClient != nil { + // Using daemon - need to get config via RPC + // For now, skip validation in daemon mode (needs RPC enhancement) + } else { + // Direct mode - check config + dbPrefix, _ = store.GetConfig(ctx, "issue_prefix") + } + + if dbPrefix != "" && dbPrefix != requestedPrefix { + fmt.Fprintf(os.Stderr, "Error: prefix mismatch detected\n") + fmt.Fprintf(os.Stderr, " This database uses prefix '%s-', but you specified '%s-'\n", dbPrefix, requestedPrefix) + fmt.Fprintf(os.Stderr, " Did you mean to create '%s-%s'?\n", dbPrefix, parts[1]) + fmt.Fprintf(os.Stderr, " Use --force to create with mismatched prefix anyway\n") + os.Exit(1) + } + } } var externalRefPtr *string @@ -1116,6 +1141,7 @@ func init() { createCmd.Flags().String("id", "", "Explicit issue ID (e.g., 'bd-42' for partitioning)") createCmd.Flags().String("external-ref", "", "External reference (e.g., 'gh-9', 'jira-ABC')") createCmd.Flags().StringSlice("deps", []string{}, "Dependencies in format 'type:id' or 'id' (e.g., 'discovered-from:bd-20,blocks:bd-15' or 'bd-20')") + createCmd.Flags().Bool("force", false, "Force creation even if prefix doesn't match database prefix") rootCmd.AddCommand(createCmd) }