diff --git a/pkg/agentic/prep.go b/pkg/agentic/prep.go index c2545d1..cdde752 100644 --- a/pkg/agentic/prep.go +++ b/pkg/agentic/prep.go @@ -1041,6 +1041,10 @@ func (s *PrepSubsystem) buildPrompt(ctx context.Context, input PrepInput, branch // ensureWorkspaceTaskFile("/srv/.core/workspace/core/go-io/task-42") // keeps TODO.md present for the prompt and the local agent shell wrapper. func ensureWorkspaceTaskFile(workspaceDir string) error { + if workspaceDir == "" { + return core.E("prepWorkspace", "workspace dir is required", nil) + } + todoPath := core.JoinPath(workspaceDir, "TODO.md") if readResult := fs.Read(todoPath); readResult.OK && core.Trim(readResult.Value.(string)) != "" { return nil @@ -1054,7 +1058,7 @@ func ensureWorkspaceTaskFile(workspaceDir string) error { return core.E("prepWorkspace", "load TODO.md template", nil) } - if writeResult := fs.Write(todoPath, templateResult.Value.(string)); !writeResult.OK { + if writeResult := fs.WriteAtomic(todoPath, templateResult.Value.(string)); !writeResult.OK { if err, ok := writeResult.Value.(error); ok { return core.E("prepWorkspace", "write TODO.md", err) } diff --git a/pkg/agentic/prep_test.go b/pkg/agentic/prep_test.go index a2c43ac..d0e1e85 100644 --- a/pkg/agentic/prep_test.go +++ b/pkg/agentic/prep_test.go @@ -1311,3 +1311,9 @@ func TestPrep_TestPrepWorkspace_Ugly(t *testing.T) { _, _, err := s.TestPrepWorkspace(context.Background(), PrepInput{Repo: ".."}) require.Error(t, err) } + +func TestPrep_EnsureWorkspaceTaskFile_Bad(t *testing.T) { + err := ensureWorkspaceTaskFile("") + require.Error(t, err) + assert.Contains(t, err.Error(), "workspace dir is required") +}