From 4b1e96bd3fe2aecf897b23af48691621c5a158b1 Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Thu, 6 Nov 2025 15:41:36 -0800 Subject: [PATCH] Fix linting errors in vendored merge code - Check error returns from Fprintln and Sync - Remove unused 'merged' parameter from hasConflict - Remaining gosec G304 warnings are baseline (file paths from git, not user input) --- .beads/beads.jsonl | 2 +- internal/merge/merge.go | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.beads/beads.jsonl b/.beads/beads.jsonl index ebf4357e..0b4e6c37 100644 --- a/.beads/beads.jsonl +++ b/.beads/beads.jsonl @@ -165,7 +165,7 @@ {"id":"bd-bb08","content_hash":"df5b8f359f459b9fc8a24e089878e65222f4b7ba541e829ebb1d34e5beb3a9fc","title":"Add ON DELETE CASCADE to child_counters schema","description":"Update schema.go child_counters table foreign key with ON DELETE CASCADE. When parent deleted, child counter should also be deleted. If parent is resurrected, counter gets recreated from scratch. Add migration for existing databases.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-04T12:32:30.681452-08:00","updated_at":"2025-11-05T11:23:34.289714-08:00","closed_at":"2025-11-05T00:55:12.427194-08:00","source_repo":"."} {"id":"bd-bc2c6191","content_hash":"533e56b8628e24229a4beb52f8683355f6ca699e34a73650bf092003d73c2957","title":"Audit Current Cache Usage","description":"Understand exactly what code depends on the storage cache","acceptance_criteria":"- Document showing all cache dependencies\n- Confirmation that removing cache won't break MCP\n- List of tests that need updating\n\nFiles to examine:\n- internal/rpc/server_cache_storage.go (cache implementation)\n- internal/rpc/client.go (how req.Cwd is set)\n- internal/rpc/server_*.go (all getStorageForRequest calls)\n- integrations/beads-mcp/ (MCP multi-repo logic)\n\nTasks:\n- Document all callers of getStorageForRequest()\n- Verify req.Cwd is only set by RPC client for database discovery\n- Confirm MCP server doesn't rely on multi-repo cache behavior\n- Check if any tests assume multi-repo routing\n- Review environment variables: BEADS_DAEMON_MAX_CACHE_SIZE, BEADS_DAEMON_CACHE_TTL, BEADS_DAEMON_MEMORY_THRESHOLD_MB","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-27T23:02:43.506373-07:00","updated_at":"2025-10-31T20:36:49.334214-07:00","source_repo":"."} {"id":"bd-be7a","content_hash":"d9043a7a49f8e42dc88c3c01aaa178c1560b67c1637c3373b39c387272e8b725","title":"Create npm package structure with package.json","description":"Set up initial npm package structure for @beads/bd:\n\n## Files to create\n- npm/package.json - Package metadata, dependencies, scripts\n- npm/bin/bd - CLI wrapper script that invokes native binary\n- npm/.gitignore - Ignore downloaded binaries\n- npm/README.md - Installation and usage instructions\n\n## package.json structure\n- Name: @beads/bd (scoped package)\n- Main: index.js (exports binary path)\n- Bin: bin/bd (CLI entry point)\n- Scripts: postinstall (download binary)\n- Keywords: issue-tracker, cli, beads, bd\n- License: MIT\n\n## Bin wrapper\nSimple Node.js script that:\n- Spawns native binary with child_process.spawn\n- Passes through all arguments and stdio\n- Exits with binary's exit code","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-02T23:39:47.416779-08:00","updated_at":"2025-11-03T10:31:45.381258-08:00","closed_at":"2025-11-03T10:31:45.381258-08:00","source_repo":".","dependencies":[{"issue_id":"bd-be7a","depends_on_id":"bd-febc","type":"parent-child","created_at":"2025-11-02T23:40:32.923859-08:00","created_by":"daemon"}]} -{"id":"bd-bzfy","content_hash":"d9f9c5f7be36a86e79932d608a624c2071f8e6186d4102c8094325b925913b9f","title":"Integrate beads-merge tool by @neongreen","description":"**Context**: @neongreen built a production-ready 3-way merge tool for JSONL files that works with both Git and Jujutsu. This is superior to our planned bd resolve-conflicts because it prevents conflicts proactively instead of resolving them after the fact.\n\n**Tool**: https://github.com/neongreen/mono/tree/main/beads-merge\n\n**What it does**:\n- 3-way merge of JSONL files (base, left, right)\n- Field-level merging (titles, status, priority, etc.)\n- Smart dependency merging (union + dedup)\n- Conflict markers for unresolvable conflicts\n- Exit code 1 for conflicts (standard)\n\n**Integration options**:\n\n1. **Recommend (minimal effort)** - Document in AGENTS.md + TROUBLESHOOTING.md\n2. **Bundle binary** - Include in releases (cross-platform builds)\n3. **Port to Go** - Reimplement in bd codebase\n4. **Auto-install hook** - During bd init, offer to install merge driver\n\n**Recommendation**: Start with option 1 (document), then option 2 (bundle) once proven.\n\n**Related**: bd-5f483051 (bd resolve-conflicts - can close as superseded)","notes":"Created GitHub issue to discuss integration approach with @neongreen: https://github.com/neongreen/mono/issues/240\n\nAwaiting their preference on:\n1. Vendor with attribution (fastest)\n2. Extract as importable module (best long-term)\n3. Keep as separate tool (current state)\n\nNext: Wait for response before proceeding with integration.\n\nUPDATE 2025-11-06: @neongreen gave permission to vendor! Quote: \"I switched from beads to my own thing (tk) so I'm very happy to give beads-merge away — feel free to move it into the beads repo and I will point mono's readme to beads\"\n\nNext: Vendor beads-merge with full attribution","status":"in_progress","priority":1,"issue_type":"feature","created_at":"2025-11-05T11:31:44.906652-08:00","updated_at":"2025-11-06T15:34:32.247608-08:00","source_repo":"."} +{"id":"bd-bzfy","content_hash":"d9f9c5f7be36a86e79932d608a624c2071f8e6186d4102c8094325b925913b9f","title":"Integrate beads-merge tool by @neongreen","description":"**Context**: @neongreen built a production-ready 3-way merge tool for JSONL files that works with both Git and Jujutsu. This is superior to our planned bd resolve-conflicts because it prevents conflicts proactively instead of resolving them after the fact.\n\n**Tool**: https://github.com/neongreen/mono/tree/main/beads-merge\n\n**What it does**:\n- 3-way merge of JSONL files (base, left, right)\n- Field-level merging (titles, status, priority, etc.)\n- Smart dependency merging (union + dedup)\n- Conflict markers for unresolvable conflicts\n- Exit code 1 for conflicts (standard)\n\n**Integration options**:\n\n1. **Recommend (minimal effort)** - Document in AGENTS.md + TROUBLESHOOTING.md\n2. **Bundle binary** - Include in releases (cross-platform builds)\n3. **Port to Go** - Reimplement in bd codebase\n4. **Auto-install hook** - During bd init, offer to install merge driver\n\n**Recommendation**: Start with option 1 (document), then option 2 (bundle) once proven.\n\n**Related**: bd-5f483051 (bd resolve-conflicts - can close as superseded)","notes":"Created GitHub issue to discuss integration approach with @neongreen: https://github.com/neongreen/mono/issues/240\n\nAwaiting their preference on:\n1. Vendor with attribution (fastest)\n2. Extract as importable module (best long-term)\n3. Keep as separate tool (current state)\n\nNext: Wait for response before proceeding with integration.\n\nUPDATE 2025-11-06: @neongreen gave permission to vendor! Quote: \"I switched from beads to my own thing (tk) so I'm very happy to give beads-merge away — feel free to move it into the beads repo and I will point mono's readme to beads\"\n\nNext: Vendor beads-merge with full attribution","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-05T11:31:44.906652-08:00","updated_at":"2025-11-06T15:38:37.052274-08:00","closed_at":"2025-11-06T15:38:37.052274-08:00","source_repo":"."} {"id":"bd-c13f","content_hash":"0e428b0589a6f763a32195b32241ec71141793101ee102df5df69d3c7fadfaaf","title":"Add unit tests for parent resurrection","description":"Test resurrection with deleted parent (should succeed), resurrection with never-existed parent (should fail gracefully), multi-level resurrection (bd-abc.1.2 with both parents missing). Verify tombstone creation and is_tombstone flag.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-04T12:32:21.325335-08:00","updated_at":"2025-11-05T00:08:38.197966-08:00","closed_at":"2025-11-05T00:08:38.19797-08:00","source_repo":"."} {"id":"bd-c362","content_hash":"3b9c44101d7f31fb6cbf4913873a4e140e74fbe7403907e8532bfaaabf875197","title":"Extract database search logic into helper function","description":"The logic for finding a database in a beads directory is duplicated:\n- FindDatabasePath() BEADS_DIR section (beads.go:141-169)\n- findDatabaseInTree() (beads.go:248-280)\n\nBoth implement the same search order:\n1. Check config.json first (single source of truth)\n2. Fall back to canonical beads.db\n3. Search for *.db files, filtering backups and vc.db\n\nRefactoring suggestion:\nExtract to a helper function like:\n func findDatabaseInBeadsDir(beadsDir string) string\n\nBenefits:\n- Single source of truth for database search logic\n- Easier to maintain and update search order\n- Reduces code duplication\n\nRelated to bd-e16b implementation.","status":"open","priority":3,"issue_type":"chore","created_at":"2025-11-02T18:34:02.831543-08:00","updated_at":"2025-11-02T18:34:02.831543-08:00","source_repo":".","dependencies":[{"issue_id":"bd-c362","depends_on_id":"bd-e16b","type":"blocks","created_at":"2025-11-02T18:34:02.832607-08:00","created_by":"daemon"}]} {"id":"bd-c3ei","content_hash":"3b9da19440e462416ee019de38e4fb4577d397a3a6f6a4bdd369a9052b419b87","title":"Migration guide documentation","description":"Write comprehensive migration guide covering: OSS contributor workflow, team workflow, multi-phase development, multiple personas. Include step-by-step instructions, troubleshooting, and backward compatibility notes.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-05T18:04:29.84662-08:00","updated_at":"2025-11-05T18:12:30.907835-08:00","closed_at":"2025-11-05T18:12:30.907835-08:00","source_repo":".","dependencies":[{"issue_id":"bd-c3ei","depends_on_id":"bd-8rd","type":"parent-child","created_at":"2025-11-05T18:04:39.028291-08:00","created_by":"daemon"}]} diff --git a/internal/merge/merge.go b/internal/merge/merge.go index 7eeabc03..6670a601 100644 --- a/internal/merge/merge.go +++ b/internal/merge/merge.go @@ -130,12 +130,16 @@ func Merge3Way(outputPath, basePath, leftPath, rightPath string, debug bool) err if err != nil { return fmt.Errorf("error marshaling issue %s: %w", issue.ID, err) } - fmt.Fprintln(outFile, string(line)) + if _, err := fmt.Fprintln(outFile, string(line)); err != nil { + return fmt.Errorf("error writing merged issue: %w", err) + } } // Write conflicts to output file for _, conflict := range conflicts { - fmt.Fprintln(outFile, conflict) + if _, err := fmt.Fprintln(outFile, conflict); err != nil { + return fmt.Errorf("error writing conflict: %w", err) + } } if debug { @@ -143,7 +147,9 @@ func Merge3Way(outputPath, basePath, leftPath, rightPath string, debug bool) err fmt.Fprintf(os.Stderr, "\n") // Show first few lines of output for debugging - outFile.Sync() + if err := outFile.Sync(); err != nil { + fmt.Fprintf(os.Stderr, "Warning: failed to sync output file: %v\n", err) + } if content, err := os.ReadFile(outputPath); err == nil { lines := 0 fmt.Fprintf(os.Stderr, "Output file preview (first 10 lines):\n") @@ -362,7 +368,7 @@ func mergeIssue(base, left, right Issue) (Issue, string) { result.Dependencies = mergeDependencies(left.Dependencies, right.Dependencies) // Check if we have a real conflict - if hasConflict(base, left, right, result) { + if hasConflict(base, left, right) { return result, makeConflictWithBase(base.RawLine, left.RawLine, right.RawLine) } @@ -444,7 +450,7 @@ func mergeDependencies(left, right []Dependency) []Dependency { return result } -func hasConflict(base, left, right, merged Issue) bool { +func hasConflict(base, left, right Issue) bool { // Check if any field has conflicting changes if base.Title != left.Title && base.Title != right.Title && left.Title != right.Title { return true