Fix all gosec, misspell, and unparam linter errors
- Add #nosec directives with explanations for all gosec warnings in worktree operations - Tighten directory permissions from 0755 to 0750 for better security - Fix misspellings: archaeological -> archeological, cancelled -> canceled - Remove unused jsonlPath parameter from syncBranchCommitAndPush - Change branchExists to return bool instead of (bool, error) - error was never used All changes maintain backward compatibility and improve code quality. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -279,7 +279,7 @@ func createExportFunc(ctx context.Context, store storage.Storage, autoCommit, au
|
||||
// Auto-commit if enabled
|
||||
if autoCommit {
|
||||
// Try sync branch commit first
|
||||
committed, err := syncBranchCommitAndPush(exportCtx, store, jsonlPath, autoPush, log)
|
||||
committed, err := syncBranchCommitAndPush(exportCtx, store, autoPush, log)
|
||||
if err != nil {
|
||||
log.log("Sync branch commit failed: %v", err)
|
||||
return
|
||||
@@ -470,7 +470,7 @@ func createSyncFunc(ctx context.Context, store storage.Storage, autoCommit, auto
|
||||
|
||||
if autoCommit {
|
||||
// Try sync branch commit first
|
||||
committed, err := syncBranchCommitAndPush(syncCtx, store, jsonlPath, autoPush, log)
|
||||
committed, err := syncBranchCommitAndPush(syncCtx, store, autoPush, log)
|
||||
if err != nil {
|
||||
log.log("Sync branch commit failed: %v", err)
|
||||
return
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
|
||||
// syncBranchCommitAndPush commits JSONL to the sync branch using a worktree
|
||||
// Returns true if changes were committed, false if no changes or sync.branch not configured
|
||||
func syncBranchCommitAndPush(ctx context.Context, store storage.Storage, jsonlPath string, autoPush bool, log daemonLogger) (bool, error) {
|
||||
func syncBranchCommitAndPush(ctx context.Context, store storage.Storage, autoPush bool, log daemonLogger) (bool, error) {
|
||||
// Get sync.branch config
|
||||
syncBranch, err := store.GetConfig(ctx, "sync.branch")
|
||||
if err != nil {
|
||||
@@ -113,7 +113,7 @@ func gitHasChangesInWorktree(ctx context.Context, worktreePath, filePath string)
|
||||
return false, fmt.Errorf("failed to make path relative: %w", err)
|
||||
}
|
||||
|
||||
cmd := exec.CommandContext(ctx, "git", "-C", worktreePath, "status", "--porcelain", relPath)
|
||||
cmd := exec.CommandContext(ctx, "git", "-C", worktreePath, "status", "--porcelain", relPath) // #nosec G204 - worktreePath and relPath are derived from trusted git operations
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("git status failed in worktree: %w", err)
|
||||
@@ -130,7 +130,7 @@ func gitCommitInWorktree(ctx context.Context, worktreePath, filePath, message st
|
||||
}
|
||||
|
||||
// Stage the file
|
||||
addCmd := exec.CommandContext(ctx, "git", "-C", worktreePath, "add", relPath)
|
||||
addCmd := exec.CommandContext(ctx, "git", "-C", worktreePath, "add", relPath) // #nosec G204 - worktreePath and relPath are derived from trusted git operations
|
||||
if err := addCmd.Run(); err != nil {
|
||||
return fmt.Errorf("git add failed in worktree: %w", err)
|
||||
}
|
||||
@@ -148,7 +148,7 @@ func gitCommitInWorktree(ctx context.Context, worktreePath, filePath, message st
|
||||
// gitPushFromWorktree pushes the sync branch from the worktree
|
||||
func gitPushFromWorktree(ctx context.Context, worktreePath, branch string) error {
|
||||
// Get remote name (usually "origin")
|
||||
remoteCmd := exec.CommandContext(ctx, "git", "-C", worktreePath, "config", "--get", fmt.Sprintf("branch.%s.remote", branch))
|
||||
remoteCmd := exec.CommandContext(ctx, "git", "-C", worktreePath, "config", "--get", fmt.Sprintf("branch.%s.remote", branch)) // #nosec G204 - worktreePath and branch are from config
|
||||
remoteOutput, err := remoteCmd.Output()
|
||||
if err != nil {
|
||||
// If no remote configured, default to "origin" and set up tracking
|
||||
@@ -157,7 +157,7 @@ func gitPushFromWorktree(ctx context.Context, worktreePath, branch string) error
|
||||
remote := strings.TrimSpace(string(remoteOutput))
|
||||
|
||||
// Push with explicit remote and branch, set upstream if not set
|
||||
cmd := exec.CommandContext(ctx, "git", "-C", worktreePath, "push", "--set-upstream", remote, branch)
|
||||
cmd := exec.CommandContext(ctx, "git", "-C", worktreePath, "push", "--set-upstream", remote, branch) // #nosec G204 - worktreePath, remote, and branch are from config
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("git push failed from worktree: %w\n%s", err, output)
|
||||
@@ -226,12 +226,12 @@ func syncBranchPull(ctx context.Context, store storage.Storage, log daemonLogger
|
||||
}
|
||||
|
||||
// Copy JSONL from worktree to main repo
|
||||
data, err := os.ReadFile(worktreeJSONLPath)
|
||||
data, err := os.ReadFile(worktreeJSONLPath) // #nosec G304 - path is derived from trusted git worktree
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to read worktree JSONL: %w", err)
|
||||
}
|
||||
|
||||
if err := os.WriteFile(mainJSONLPath, data, 0644); err != nil {
|
||||
|
||||
if err := os.WriteFile(mainJSONLPath, data, 0644); err != nil { // #nosec G306 - JSONL needs to be readable
|
||||
return false, fmt.Errorf("failed to write main JSONL: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ func TestSyncBranchCommitAndPush_NotConfigured(t *testing.T) {
|
||||
// Test with no sync.branch configured
|
||||
log, logMsgs := newTestSyncBranchLogger()
|
||||
_ = logMsgs // unused in this test
|
||||
committed, err := syncBranchCommitAndPush(ctx, store, jsonlPath, false, log)
|
||||
committed, err := syncBranchCommitAndPush(ctx, store, false, log)
|
||||
|
||||
// Should return false (not committed), no error
|
||||
if err != nil {
|
||||
@@ -153,7 +153,7 @@ func TestSyncBranchCommitAndPush_Success(t *testing.T) {
|
||||
// Test sync branch commit (without push)
|
||||
log, logMsgs := newTestSyncBranchLogger()
|
||||
_ = logMsgs // unused in this test
|
||||
committed, err := syncBranchCommitAndPush(ctx, store, jsonlPath, false, log)
|
||||
committed, err := syncBranchCommitAndPush(ctx, store, false, log)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("syncBranchCommitAndPush failed: %v", err)
|
||||
@@ -258,7 +258,7 @@ func TestSyncBranchCommitAndPush_NoChanges(t *testing.T) {
|
||||
log, logMsgs := newTestSyncBranchLogger()
|
||||
|
||||
// First commit should succeed
|
||||
committed, err := syncBranchCommitAndPush(ctx, store, jsonlPath, false, log)
|
||||
committed, err := syncBranchCommitAndPush(ctx, store, false, log)
|
||||
if err != nil {
|
||||
t.Fatalf("First commit failed: %v", err)
|
||||
}
|
||||
@@ -267,7 +267,7 @@ func TestSyncBranchCommitAndPush_NoChanges(t *testing.T) {
|
||||
}
|
||||
|
||||
// Second commit with no changes should return false
|
||||
committed, err = syncBranchCommitAndPush(ctx, store, jsonlPath, false, log)
|
||||
committed, err = syncBranchCommitAndPush(ctx, store, false, log)
|
||||
if err != nil {
|
||||
t.Fatalf("Second commit failed: %v", err)
|
||||
}
|
||||
@@ -343,7 +343,7 @@ func TestSyncBranchCommitAndPush_WorktreeHealthCheck(t *testing.T) {
|
||||
log, logMsgs := newTestSyncBranchLogger()
|
||||
|
||||
// First commit to create worktree
|
||||
committed, err := syncBranchCommitAndPush(ctx, store, jsonlPath, false, log)
|
||||
committed, err := syncBranchCommitAndPush(ctx, store, false, log)
|
||||
if err != nil {
|
||||
t.Fatalf("First commit failed: %v", err)
|
||||
}
|
||||
@@ -372,7 +372,7 @@ func TestSyncBranchCommitAndPush_WorktreeHealthCheck(t *testing.T) {
|
||||
*logMsgs = "" // Reset log
|
||||
|
||||
// Should detect corruption and repair (CreateBeadsWorktree handles this silently)
|
||||
committed, err = syncBranchCommitAndPush(ctx, store, jsonlPath, false, log)
|
||||
committed, err = syncBranchCommitAndPush(ctx, store, false, log)
|
||||
if err != nil {
|
||||
t.Fatalf("Commit after corruption failed: %v", err)
|
||||
}
|
||||
@@ -512,7 +512,7 @@ func TestSyncBranchPull_Success(t *testing.T) {
|
||||
// Push to sync branch using syncBranchCommitAndPush
|
||||
log, logMsgs := newTestSyncBranchLogger()
|
||||
_ = logMsgs // unused in this test
|
||||
committed, err := syncBranchCommitAndPush(ctx, store1, clone1JSONLPath, true, log)
|
||||
committed, err := syncBranchCommitAndPush(ctx, store1, true, log)
|
||||
if err != nil {
|
||||
t.Fatalf("syncBranchCommitAndPush failed: %v", err)
|
||||
}
|
||||
@@ -639,7 +639,7 @@ func TestSyncBranchIntegration_EndToEnd(t *testing.T) {
|
||||
// Agent A commits to sync branch
|
||||
log, logMsgs := newTestSyncBranchLogger()
|
||||
_ = logMsgs // unused in this test
|
||||
committed, err := syncBranchCommitAndPush(ctx, store1, clone1JSONLPath, true, log)
|
||||
committed, err := syncBranchCommitAndPush(ctx, store1, true, log)
|
||||
if err != nil {
|
||||
t.Fatalf("syncBranchCommitAndPush failed: %v", err)
|
||||
}
|
||||
@@ -694,7 +694,7 @@ func TestSyncBranchIntegration_EndToEnd(t *testing.T) {
|
||||
exportToJSONLWithStore(ctx, store2, clone2JSONLPath)
|
||||
|
||||
// Agent B commits to sync branch
|
||||
committed, err = syncBranchCommitAndPush(ctx, store2, clone2JSONLPath, true, log2)
|
||||
committed, err = syncBranchCommitAndPush(ctx, store2, true, log2)
|
||||
if err != nil {
|
||||
t.Fatalf("syncBranchCommitAndPush failed for clone2: %v", err)
|
||||
}
|
||||
@@ -800,7 +800,7 @@ func TestSyncBranchConfigChange(t *testing.T) {
|
||||
log, _ := newTestSyncBranchLogger()
|
||||
|
||||
// First commit to v1 branch
|
||||
committed, err := syncBranchCommitAndPush(ctx, store, jsonlPath, false, log)
|
||||
committed, err := syncBranchCommitAndPush(ctx, store, false, log)
|
||||
if err != nil {
|
||||
t.Fatalf("First commit failed: %v", err)
|
||||
}
|
||||
@@ -832,7 +832,7 @@ func TestSyncBranchConfigChange(t *testing.T) {
|
||||
}
|
||||
|
||||
// Commit to v2 branch (should create new worktree)
|
||||
committed, err = syncBranchCommitAndPush(ctx, store, jsonlPath, false, log)
|
||||
committed, err = syncBranchCommitAndPush(ctx, store, false, log)
|
||||
if err != nil {
|
||||
t.Fatalf("Second commit failed: %v", err)
|
||||
}
|
||||
@@ -934,7 +934,7 @@ func TestSyncBranchMultipleConcurrentClones(t *testing.T) {
|
||||
exportToJSONLWithStore(ctx, store1, jsonlPath1)
|
||||
|
||||
log1, _ := newTestSyncBranchLogger()
|
||||
committed, err := syncBranchCommitAndPush(ctx, store1, jsonlPath1, true, log1)
|
||||
committed, err := syncBranchCommitAndPush(ctx, store1, true, log1)
|
||||
if err != nil || !committed {
|
||||
t.Fatalf("Clone1 commit failed: err=%v, committed=%v", err, committed)
|
||||
}
|
||||
@@ -957,7 +957,7 @@ func TestSyncBranchMultipleConcurrentClones(t *testing.T) {
|
||||
}
|
||||
store2.CreateIssue(ctx, issueB, "agent2")
|
||||
exportToJSONLWithStore(ctx, store2, jsonlPath2)
|
||||
committed, err = syncBranchCommitAndPush(ctx, store2, jsonlPath2, true, log2)
|
||||
committed, err = syncBranchCommitAndPush(ctx, store2, true, log2)
|
||||
if err != nil || !committed {
|
||||
t.Fatalf("Clone2 commit failed: err=%v, committed=%v", err, committed)
|
||||
}
|
||||
@@ -980,7 +980,7 @@ func TestSyncBranchMultipleConcurrentClones(t *testing.T) {
|
||||
}
|
||||
store3.CreateIssue(ctx, issueC, "agent3")
|
||||
exportToJSONLWithStore(ctx, store3, jsonlPath3)
|
||||
committed, err = syncBranchCommitAndPush(ctx, store3, jsonlPath3, true, log3)
|
||||
committed, err = syncBranchCommitAndPush(ctx, store3, true, log3)
|
||||
if err != nil || !committed {
|
||||
t.Fatalf("Clone3 commit failed: err=%v, committed=%v", err, committed)
|
||||
}
|
||||
@@ -1068,7 +1068,7 @@ func TestSyncBranchPerformance(t *testing.T) {
|
||||
|
||||
// First commit (creates worktree - expected to be slower)
|
||||
start := time.Now()
|
||||
committed, err := syncBranchCommitAndPush(ctx, store, jsonlPath, false, log)
|
||||
committed, err := syncBranchCommitAndPush(ctx, store, false, log)
|
||||
firstDuration := time.Since(start)
|
||||
if err != nil || !committed {
|
||||
t.Fatalf("First commit failed: err=%v, committed=%v", err, committed)
|
||||
@@ -1088,7 +1088,7 @@ func TestSyncBranchPerformance(t *testing.T) {
|
||||
exportToJSONLWithStore(ctx, store, jsonlPath)
|
||||
|
||||
start = time.Now()
|
||||
committed, err = syncBranchCommitAndPush(ctx, store, jsonlPath, false, log)
|
||||
committed, err = syncBranchCommitAndPush(ctx, store, false, log)
|
||||
duration := time.Since(start)
|
||||
totalDuration += duration
|
||||
|
||||
@@ -1154,7 +1154,7 @@ func TestSyncBranchNetworkFailure(t *testing.T) {
|
||||
log, logMsgs := newTestSyncBranchLogger()
|
||||
|
||||
// Commit locally (without push to simulate offline mode)
|
||||
committed, err := syncBranchCommitAndPush(ctx, store, jsonlPath, false, log)
|
||||
committed, err := syncBranchCommitAndPush(ctx, store, false, log)
|
||||
if err != nil {
|
||||
t.Fatalf("Local commit failed: %v", err)
|
||||
}
|
||||
@@ -1173,7 +1173,7 @@ func TestSyncBranchNetworkFailure(t *testing.T) {
|
||||
exportToJSONLWithStore(ctx, store, jsonlPath)
|
||||
|
||||
// Try commit with push - should handle network error gracefully
|
||||
committed, err = syncBranchCommitAndPush(ctx, store, jsonlPath, true, log)
|
||||
committed, err = syncBranchCommitAndPush(ctx, store, true, log)
|
||||
|
||||
// The commit should succeed locally even if push fails
|
||||
// (Current implementation may vary - this documents expected behavior)
|
||||
|
||||
@@ -120,7 +120,7 @@ history/
|
||||
- ✅ Clean repository root
|
||||
- ✅ Clear separation between ephemeral and permanent documentation
|
||||
- ✅ Easy to exclude from version control if desired
|
||||
- ✅ Preserves planning history for archaeological research
|
||||
- ✅ Preserves planning history for archeological research
|
||||
- ✅ Reduces noise when browsing the project
|
||||
|
||||
### Important Rules
|
||||
|
||||
Reference in New Issue
Block a user