diff --git a/pkg/campaign/orchestrator.go b/pkg/campaign/orchestrator.go index 212223511b8..9504569ef4a 100644 --- a/pkg/campaign/orchestrator.go +++ b/pkg/campaign/orchestrator.go @@ -405,6 +405,12 @@ func BuildOrchestrator(spec *CampaignSpec, campaignFilePath string) (*workflow.W orchestratorLog.Printf("Campaign orchestrator '%s' configured with dispatch_workflow for %d workflows", spec.ID, len(spec.Workflows)) } + // Enable append-only comments for campaigns - create new comments instead of updating existing ones + // This ensures full history of campaign run updates is preserved + safeOutputs.Messages = &workflow.SafeOutputMessagesConfig{ + AppendOnlyComments: true, + } + orchestratorLog.Printf("Campaign orchestrator '%s' built successfully with safe outputs enabled", spec.ID) // Extract file-glob patterns from memory-paths or metrics-glob to support diff --git a/pkg/campaign/orchestrator_test.go b/pkg/campaign/orchestrator_test.go index 87ba41979d2..6e19cb1d080 100644 --- a/pkg/campaign/orchestrator_test.go +++ b/pkg/campaign/orchestrator_test.go @@ -336,6 +336,34 @@ func TestBuildOrchestrator_GovernanceOverridesSafeOutputMaxima(t *testing.T) { }) } +func TestBuildOrchestrator_AppendOnlyCommentsEnabled(t *testing.T) { + withTempGitRepoWithInstalledCampaignPrompts(t, func(_ string) { + spec := &CampaignSpec{ + ID: "test-campaign", + Name: "Test Campaign", + ProjectURL: "https://github.com/orgs/test/projects/1", + Workflows: []string{"test-workflow"}, + } + + mdPath := ".github/workflows/test-campaign.campaign.md" + data, _ := BuildOrchestrator(spec, mdPath) + if data == nil { + t.Fatalf("expected non-nil WorkflowData") + } + + // Verify that Messages configuration is present + if data.SafeOutputs == nil || data.SafeOutputs.Messages == nil { + t.Fatalf("expected SafeOutputs.Messages to be configured") + } + + // Verify that AppendOnlyComments is enabled for campaigns + // This ensures campaign run updates create new comments instead of updating existing ones + if !data.SafeOutputs.Messages.AppendOnlyComments { + t.Errorf("expected AppendOnlyComments to be true for campaign orchestrator, got false") + } + }) +} + func TestExtractFileGlobPatterns(t *testing.T) { tests := []struct { name string