From 35d9dfe222c8a7e3f2bb192b1bda394aae8af848 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 18 Sep 2026 23:54:52 +0000 Subject: [PATCH 1/3] Fix cached logs audit reuse Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/cli/audit_cache.go | 12 +++++- pkg/cli/logs_cached_json.go | 11 ++++-- pkg/cli/logs_cached_json_test.go | 54 ++++++++++++++++++++++++--- pkg/cli/logs_models.go | 2 + pkg/cli/logs_orchestrator_download.go | 2 +- pkg/cli/logs_orchestrator_stdin.go | 2 +- pkg/cli/logs_run_processor.go | 2 + 7 files changed, 73 insertions(+), 12 deletions(-) diff --git a/pkg/cli/audit_cache.go b/pkg/cli/audit_cache.go index 7fb4be0f8f2..d559d101e30 100644 --- a/pkg/cli/audit_cache.go +++ b/pkg/cli/audit_cache.go @@ -80,7 +80,13 @@ func writeLogsAuditFiles(processedRuns []ProcessedRun, verbose bool) { func writeLogsAuditFile(processedRun ProcessedRun, processedRuns []ProcessedRun, verbose bool) { runOutputDir := processedRun.Run.LogsPath - auditData, ok := loadCachedAuditData(runOutputDir, processedRun.Run, auditCacheSourceLogs) + var auditData AuditData + ok := processedRun.cachedAudit != nil + if ok { + auditData = *processedRun.cachedAudit + } else { + auditData, ok = loadCachedAuditData(runOutputDir, processedRun.Run, auditCacheSourceLogs) + } if !ok { metrics := LogMetrics{} if summary, ok := loadRunSummary(runOutputDir, verbose); ok { @@ -92,5 +98,9 @@ func writeLogsAuditFile(processedRun ProcessedRun, processedRuns []ProcessedRun, auditData.Comparison = buildAuditComparisonForProcessedRuns(processedRun, processedRuns) if err := writeAuditData(runOutputDir, auditData); err != nil { logsOrchestratorLog.Printf("Failed to write audit file for run %d: %v", processedRun.Run.DatabaseID, err) + return + } + if processedRun.cachedData != nil { + processedRun.cachedData.AuditPath = auditPath(runOutputDir) } } diff --git a/pkg/cli/logs_cached_json.go b/pkg/cli/logs_cached_json.go index 444ff250af6..3e67881c3b6 100644 --- a/pkg/cli/logs_cached_json.go +++ b/pkg/cli/logs_cached_json.go @@ -799,12 +799,13 @@ func normalizeCachedLogRun(run *RunData) error { // cachedJSONLCanSatisfy permits cached records only for the compact usage // artifact, whose JSON includes the metadata required for cached reports. -// Parsing, auditing, training, and tool graphs require raw artifact files. -func cachedJSONLCanSatisfy(artifactFilter []string, parse, audit, train, toolGraph bool) bool { - return isUsageOnlyArtifactFilter(artifactFilter) && !parse && !audit && !train && !toolGraph +// Audit mode uses the available cached data on a best-effort basis. Parsing, +// explicit training, and tool graphs require raw artifact files. +func cachedJSONLCanSatisfy(artifactFilter []string, parse, _ bool, train, toolGraph bool) bool { + return isUsageOnlyArtifactFilter(artifactFilter) && !parse && !train && !toolGraph } -func processedRunFromCachedData(data RunData) ProcessedRun { +func processedRunFromCachedData(data RunData, audit *AuditData, outputDir string) ProcessedRun { return ProcessedRun{ Run: WorkflowRun{ DatabaseID: data.RunID, @@ -832,6 +833,7 @@ func processedRunFromCachedData(data RunData) ProcessedRun { MissingToolCount: data.MissingToolCount, MissingDataCount: data.MissingDataCount, SafeItemsCount: data.SafeItemsCount, + LogsPath: filepath.Join(outputDir, fmt.Sprintf("run-%d", data.RunID)), }, AwContext: data.AwContext, TaskDomain: data.TaskDomain, @@ -840,5 +842,6 @@ func processedRunFromCachedData(data RunData) ProcessedRun { TokenUsage: data.TokenUsageSummary, WorkingSet: data.WorkingSet, cachedData: &data, + cachedAudit: audit, } } diff --git a/pkg/cli/logs_cached_json_test.go b/pkg/cli/logs_cached_json_test.go index 1ae434915db..5e426399a18 100644 --- a/pkg/cli/logs_cached_json_test.go +++ b/pkg/cli/logs_cached_json_test.go @@ -10,9 +10,11 @@ import ( "path/filepath" "strings" "sync" + "sync/atomic" "testing" "time" + "github.com/github/gh-aw/pkg/console" "github.com/github/gh-aw/pkg/constants" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -692,12 +694,19 @@ func TestCachedJSONLCanSatisfy(t *testing.T) { assert.False(t, cachedJSONLCanSatisfy(agentFilter, false, false, false, false)) assert.False(t, cachedJSONLCanSatisfy(nil, false, false, false, false)) assert.False(t, cachedJSONLCanSatisfy(usageFilter, true, false, false, false)) - assert.False(t, cachedJSONLCanSatisfy(usageFilter, false, true, false, false)) + assert.True(t, cachedJSONLCanSatisfy(usageFilter, false, true, false, false)) assert.False(t, cachedJSONLCanSatisfy(usageFilter, false, false, true, false)) assert.False(t, cachedJSONLCanSatisfy(usageFilter, false, false, false, true)) } func TestDownloadRunArtifactsConcurrentReusesCachedJSONRecord(t *testing.T) { + originalProcess := processConcurrentRunDownload + t.Cleanup(func() { processConcurrentRunDownload = originalProcess }) + processConcurrentRunDownload = func(context.Context, WorkflowRun, concurrentRunDownloadParams, *atomic.Int64, *console.ProgressBar) (DownloadResult, error) { + t.Fatal("cached run should not be downloaded") + return DownloadResult{}, nil + } + cached := RunData{ RunID: 42, WorkflowName: "cached-workflow", @@ -708,11 +717,12 @@ func TestDownloadRunArtifactsConcurrentReusesCachedJSONRecord(t *testing.T) { UpdatedAt: time.Date(2026, time.September, 1, 0, 0, 0, 0, time.UTC), LogsPath: "/previous/run-42", } + cachedAudit := &AuditData{Overview: OverviewData{RunID: 42}} results := downloadRunArtifactsConcurrent(context.Background(), []WorkflowRun{{DatabaseID: 42, Repository: "github/gh-aw", Status: "completed", Conclusion: "success", Attempt: 1, UpdatedAt: cached.UpdatedAt}}, runArtifactsConcurrentOptions{ outputDir: t.TempDir(), maxRuns: 1, - cachedRuns: cachedLogsRuns{42: {RunData: cached}}, + cachedRuns: cachedLogsRuns{42: {RunData: cached, Audit: cachedAudit}}, storageLimit: newLogsStorageLimit(t.TempDir(), 0, false), }) @@ -720,6 +730,39 @@ func TestDownloadRunArtifactsConcurrentReusesCachedJSONRecord(t *testing.T) { require.NotNil(t, results[0].CachedRun) assert.True(t, results[0].Cached) assert.Equal(t, cached, *results[0].CachedRun) + assert.Same(t, cachedAudit, results[0].cachedAudit) +} + +func TestPrepareLogsDataAuditUsesCachedDataBestEffort(t *testing.T) { + outputDir := t.TempDir() + cached := RunData{ + RunID: 42, + Status: "completed", + Conclusion: "success", + UpdatedAt: time.Date(2026, time.September, 1, 0, 0, 0, 0, time.UTC), + } + cachedAudit := &AuditData{ + CacheSource: auditCacheSourceLogs, + Overview: OverviewData{ + RunID: cached.RunID, + Status: cached.Status, + Conclusion: cached.Conclusion, + UpdatedAt: cached.UpdatedAt, + }, + } + processedRun := processedRunFromCachedData(cached, cachedAudit, outputDir) + + logsData, err := prepareLogsData([]ProcessedRun{processedRun}, renderLogsOutputOptions{ + audit: true, + outputDir: outputDir, + }) + require.NoError(t, err) + require.Len(t, logsData.Runs, 1) + assert.Equal(t, filepath.Join(outputDir, "run-42", auditFileName), logsData.Runs[0].AuditPath) + + written, ok := loadCachedAuditData(processedRun.Run.LogsPath, processedRun.Run, auditCacheSourceLogs) + require.True(t, ok) + assert.Equal(t, cachedAudit.Overview, written.Overview) } func TestBuildLogsDataPreservesCachedRunRecord(t *testing.T) { @@ -747,10 +790,11 @@ func TestBuildLogsDataPreservesCachedRunRecord(t *testing.T) { IntentionalFailure: true, } - processedRun := processedRunFromCachedData(cached) - assert.Empty(t, processedRun.Run.LogsPath) + outputDir := t.TempDir() + processedRun := processedRunFromCachedData(cached, nil, outputDir) + assert.Equal(t, filepath.Join(outputDir, "run-42"), processedRun.Run.LogsPath) - data := buildLogsData([]ProcessedRun{processedRun}, t.TempDir(), nil) + data := buildLogsData([]ProcessedRun{processedRun}, outputDir, nil) require.Equal(t, []RunData{cached}, data.Runs) assert.Equal(t, 1, data.Summary.TotalRuns) diff --git a/pkg/cli/logs_models.go b/pkg/cli/logs_models.go index ea25911917e..361fa9e7b14 100644 --- a/pkg/cli/logs_models.go +++ b/pkg/cli/logs_models.go @@ -136,6 +136,7 @@ type ProcessedRun struct { JobDetails []JobInfoWithDuration SafeOutputs []CreatedItemReport cachedData *RunData + cachedAudit *AuditData } // ReportProvenance holds the shared provenance fields common to all report record types. @@ -317,6 +318,7 @@ type DownloadResult struct { Cached bool // True if loaded from cached summary CachedRun *RunData LogsPath string + cachedAudit *AuditData storageReserved bool } diff --git a/pkg/cli/logs_orchestrator_download.go b/pkg/cli/logs_orchestrator_download.go index a6d442e83d7..9323fa1347c 100644 --- a/pkg/cli/logs_orchestrator_download.go +++ b/pkg/cli/logs_orchestrator_download.go @@ -904,7 +904,7 @@ func (c *orderedLogsRunCollector) processReadyResult(index int) { } if result.CachedRun != nil { if c.opts.countLimit.tryAdd() { - c.candidates[index] = processedRunFromCachedData(*result.CachedRun) + c.candidates[index] = processedRunFromCachedData(*result.CachedRun, result.cachedAudit, c.opts.outputDir) c.accepted[index] = true c.acceptedCount++ } diff --git a/pkg/cli/logs_orchestrator_stdin.go b/pkg/cli/logs_orchestrator_stdin.go index fe306644ccb..6e9c0cfc81f 100644 --- a/pkg/cli/logs_orchestrator_stdin.go +++ b/pkg/cli/logs_orchestrator_stdin.go @@ -218,7 +218,7 @@ func DownloadWorkflowLogsFromStdin(ctx context.Context, opts StdinLogsOptions) ( for _, result := range downloadResults { collectionStats.recordResult(result) if result.CachedRun != nil { - processedRuns = append(processedRuns, processedRunFromCachedData(*result.CachedRun)) + processedRuns = append(processedRuns, processedRunFromCachedData(*result.CachedRun, result.cachedAudit, opts.OutputDir)) continue } if errors.Is(result.Error, errLogsStorageLimitReached) { diff --git a/pkg/cli/logs_run_processor.go b/pkg/cli/logs_run_processor.go index 1536384a0c4..88c2299d43e 100644 --- a/pkg/cli/logs_run_processor.go +++ b/pkg/cli/logs_run_processor.go @@ -289,12 +289,14 @@ func cachedJSONDownloadResult(run WorkflowRun, cachedRuns cachedLogsRuns, filter if !ok { return DownloadResult{}, false } + cachedAudit := cachedRuns[run.DatabaseID].Audit logsOrchestratorLog.Printf("Cache hit for run %d from cached JSONL; skipping artifact download and processing", run.DatabaseID) return DownloadResult{ RunAnalysis: RunAnalysis{Run: run}, Cached: true, CachedRun: &cachedRun, LogsPath: cachedRun.LogsPath, + cachedAudit: cachedAudit, }, true } From 0826c8eba15651f9f6d8ae6f34477c9fb682eabc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 19 Sep 2026 01:17:42 +0000 Subject: [PATCH 2/3] Preserve cached audit comparison evidence Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- pkg/cli/audit_cache.go | 31 ++++++++++++++- pkg/cli/logs_cached_json_test.go | 65 ++++++++++++++++++++++++++------ 2 files changed, 84 insertions(+), 12 deletions(-) diff --git a/pkg/cli/audit_cache.go b/pkg/cli/audit_cache.go index d559d101e30..586ed035e9c 100644 --- a/pkg/cli/audit_cache.go +++ b/pkg/cli/audit_cache.go @@ -95,7 +95,8 @@ func writeLogsAuditFile(processedRun ProcessedRun, processedRuns []ProcessedRun, auditData, _ = buildLocalAuditData(processedRun, metrics, processedRun.MCPToolUsage) auditData.CacheSource = auditCacheSourceLogs } - auditData.Comparison = buildAuditComparisonForProcessedRuns(processedRun, processedRuns) + hydratedProcessedRuns := hydrateProcessedRunsWithCachedAudit(processedRuns) + auditData.Comparison = buildAuditComparisonForProcessedRuns(hydrateProcessedRunWithCachedAudit(processedRun), hydratedProcessedRuns) if err := writeAuditData(runOutputDir, auditData); err != nil { logsOrchestratorLog.Printf("Failed to write audit file for run %d: %v", processedRun.Run.DatabaseID, err) return @@ -104,3 +105,31 @@ func writeLogsAuditFile(processedRun ProcessedRun, processedRuns []ProcessedRun, processedRun.cachedData.AuditPath = auditPath(runOutputDir) } } + +func hydrateProcessedRunsWithCachedAudit(processedRuns []ProcessedRun) []ProcessedRun { + hydrated := make([]ProcessedRun, len(processedRuns)) + for i, processedRun := range processedRuns { + hydrated[i] = hydrateProcessedRunWithCachedAudit(processedRun) + } + return hydrated +} + +func hydrateProcessedRunWithCachedAudit(processedRun ProcessedRun) ProcessedRun { + if processedRun.cachedAudit == nil { + return processedRun + } + audit := processedRun.cachedAudit + if processedRun.Run.Turns == 0 { + processedRun.Run.Turns = audit.Metrics.Turns + } + if len(processedRun.SafeOutputs) == 0 { + processedRun.SafeOutputs = audit.CreatedItems + } + if processedRun.FirewallAnalysis == nil { + processedRun.FirewallAnalysis = audit.FirewallAnalysis + } + if len(processedRun.MCPFailures) == 0 { + processedRun.MCPFailures = audit.MCPFailures + } + return processedRun +} diff --git a/pkg/cli/logs_cached_json_test.go b/pkg/cli/logs_cached_json_test.go index 5e426399a18..972b0aff7c2 100644 --- a/pkg/cli/logs_cached_json_test.go +++ b/pkg/cli/logs_cached_json_test.go @@ -735,34 +735,77 @@ func TestDownloadRunArtifactsConcurrentReusesCachedJSONRecord(t *testing.T) { func TestPrepareLogsDataAuditUsesCachedDataBestEffort(t *testing.T) { outputDir := t.TempDir() + baseline := RunData{ + RunID: 41, + WorkflowName: "cached-workflow", + Status: "completed", + Conclusion: "success", + CreatedAt: time.Date(2026, time.September, 1, 0, 0, 0, 0, time.UTC), + UpdatedAt: time.Date(2026, time.September, 1, 0, 0, 0, 0, time.UTC), + } cached := RunData{ - RunID: 42, - Status: "completed", - Conclusion: "success", - UpdatedAt: time.Date(2026, time.September, 1, 0, 0, 0, 0, time.UTC), + RunID: 42, + WorkflowName: "cached-workflow", + Status: "completed", + Conclusion: "success", + CreatedAt: baseline.CreatedAt.Add(time.Minute), + UpdatedAt: baseline.UpdatedAt, + } + baselineAudit := &AuditData{ + CacheSource: auditCacheSourceLogs, + Overview: OverviewData{ + RunID: baseline.RunID, + WorkflowName: baseline.WorkflowName, + Status: baseline.Status, + Conclusion: baseline.Conclusion, + CreatedAt: baseline.CreatedAt, + UpdatedAt: baseline.UpdatedAt, + }, + Metrics: MetricsData{Turns: 2}, + FirewallAnalysis: &FirewallAnalysis{AnalysisBase: AnalysisBase{BlockedRequests: 1}}, } cachedAudit := &AuditData{ CacheSource: auditCacheSourceLogs, Overview: OverviewData{ - RunID: cached.RunID, - Status: cached.Status, - Conclusion: cached.Conclusion, - UpdatedAt: cached.UpdatedAt, + RunID: cached.RunID, + WorkflowName: cached.WorkflowName, + Status: cached.Status, + Conclusion: cached.Conclusion, + CreatedAt: cached.CreatedAt, + UpdatedAt: cached.UpdatedAt, }, + Metrics: MetricsData{Turns: 5}, + CreatedItems: []CreatedItemReport{{ + Type: "create_issue", + Timestamp: "cache-only-created-item", + }}, + FirewallAnalysis: &FirewallAnalysis{AnalysisBase: AnalysisBase{BlockedRequests: 7}}, + MCPFailures: []MCPFailureReport{{ServerName: "cache-only-mcp", Status: "failed"}}, } + baselineRun := processedRunFromCachedData(baseline, baselineAudit, outputDir) processedRun := processedRunFromCachedData(cached, cachedAudit, outputDir) - logsData, err := prepareLogsData([]ProcessedRun{processedRun}, renderLogsOutputOptions{ + logsData, err := prepareLogsData([]ProcessedRun{baselineRun, processedRun}, renderLogsOutputOptions{ audit: true, outputDir: outputDir, }) require.NoError(t, err) - require.Len(t, logsData.Runs, 1) - assert.Equal(t, filepath.Join(outputDir, "run-42", auditFileName), logsData.Runs[0].AuditPath) + require.Len(t, logsData.Runs, 2) + assert.Equal(t, filepath.Join(outputDir, "run-42", auditFileName), logsData.Runs[1].AuditPath) written, ok := loadCachedAuditData(processedRun.Run.LogsPath, processedRun.Run, auditCacheSourceLogs) require.True(t, ok) assert.Equal(t, cachedAudit.Overview, written.Overview) + assert.Equal(t, cachedAudit.CreatedItems, written.CreatedItems) + assert.Equal(t, cachedAudit.FirewallAnalysis, written.FirewallAnalysis) + assert.Equal(t, cachedAudit.MCPFailures, written.MCPFailures) + require.NotNil(t, written.Comparison) + require.NotNil(t, written.Comparison.Delta) + assert.Equal(t, AuditComparisonIntDelta{Before: 2, After: 5, Changed: true}, written.Comparison.Delta.Turns) + assert.Equal(t, AuditComparisonStringDelta{Before: "read_only", After: "write_capable", Changed: true}, written.Comparison.Delta.Posture) + assert.Equal(t, AuditComparisonIntDelta{Before: 1, After: 7, Changed: true}, written.Comparison.Delta.BlockedRequests) + require.NotNil(t, written.Comparison.Delta.MCPFailure) + assert.Equal(t, []string{"cache-only-mcp"}, written.Comparison.Delta.MCPFailure.After) } func TestBuildLogsDataPreservesCachedRunRecord(t *testing.T) { From 80435b7bf7e26fcf40d5592ea1d97f9d6b4ada42 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 19 Sep 2026 01:24:49 +0000 Subject: [PATCH 3/3] Clarify cached JSONL audit reuse gate Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- pkg/cli/logs_cached_json.go | 2 +- pkg/cli/logs_cached_json_test.go | 13 ++++++------- pkg/cli/logs_orchestrator_download.go | 2 +- pkg/cli/logs_orchestrator_stdin.go | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/pkg/cli/logs_cached_json.go b/pkg/cli/logs_cached_json.go index 3e67881c3b6..fb660afa202 100644 --- a/pkg/cli/logs_cached_json.go +++ b/pkg/cli/logs_cached_json.go @@ -801,7 +801,7 @@ func normalizeCachedLogRun(run *RunData) error { // artifact, whose JSON includes the metadata required for cached reports. // Audit mode uses the available cached data on a best-effort basis. Parsing, // explicit training, and tool graphs require raw artifact files. -func cachedJSONLCanSatisfy(artifactFilter []string, parse, _ bool, train, toolGraph bool) bool { +func cachedJSONLCanSatisfy(artifactFilter []string, parse, train, toolGraph bool) bool { return isUsageOnlyArtifactFilter(artifactFilter) && !parse && !train && !toolGraph } diff --git a/pkg/cli/logs_cached_json_test.go b/pkg/cli/logs_cached_json_test.go index 972b0aff7c2..369a8fb087f 100644 --- a/pkg/cli/logs_cached_json_test.go +++ b/pkg/cli/logs_cached_json_test.go @@ -690,13 +690,12 @@ func TestCachedLogsLookupRejectsUnknownIdentity(t *testing.T) { func TestCachedJSONLCanSatisfy(t *testing.T) { usageFilter := []string{constants.UsageArtifactName.String()} agentFilter := []string{constants.AgentArtifactName.String()} - assert.True(t, cachedJSONLCanSatisfy(usageFilter, false, false, false, false)) - assert.False(t, cachedJSONLCanSatisfy(agentFilter, false, false, false, false)) - assert.False(t, cachedJSONLCanSatisfy(nil, false, false, false, false)) - assert.False(t, cachedJSONLCanSatisfy(usageFilter, true, false, false, false)) - assert.True(t, cachedJSONLCanSatisfy(usageFilter, false, true, false, false)) - assert.False(t, cachedJSONLCanSatisfy(usageFilter, false, false, true, false)) - assert.False(t, cachedJSONLCanSatisfy(usageFilter, false, false, false, true)) + assert.True(t, cachedJSONLCanSatisfy(usageFilter, false, false, false)) + assert.False(t, cachedJSONLCanSatisfy(agentFilter, false, false, false)) + assert.False(t, cachedJSONLCanSatisfy(nil, false, false, false)) + assert.False(t, cachedJSONLCanSatisfy(usageFilter, true, false, false)) + assert.False(t, cachedJSONLCanSatisfy(usageFilter, false, true, false)) + assert.False(t, cachedJSONLCanSatisfy(usageFilter, false, false, true)) } func TestDownloadRunArtifactsConcurrentReusesCachedJSONRecord(t *testing.T) { diff --git a/pkg/cli/logs_orchestrator_download.go b/pkg/cli/logs_orchestrator_download.go index 9323fa1347c..64e0d94a7fe 100644 --- a/pkg/cli/logs_orchestrator_download.go +++ b/pkg/cli/logs_orchestrator_download.go @@ -209,7 +209,7 @@ func prepareLogsDownload(ctx context.Context, opts LogsDownloadOptions) (logsDow if opts.cachedJSONLCache != nil { cachedRuns = opts.cachedJSONLCache.runs } - if !cachedJSONLCanSatisfy(artifactFilter, opts.Parse, opts.Audit, opts.Train, opts.ToolGraph) { + if !cachedJSONLCanSatisfy(artifactFilter, opts.Parse, opts.Train, opts.ToolGraph) { cachedRuns = nil } if err := prepareLogsDownloadOutput(ctx, opts); err != nil { diff --git a/pkg/cli/logs_orchestrator_stdin.go b/pkg/cli/logs_orchestrator_stdin.go index 6e9c0cfc81f..dbc4e480296 100644 --- a/pkg/cli/logs_orchestrator_stdin.go +++ b/pkg/cli/logs_orchestrator_stdin.go @@ -46,7 +46,7 @@ func DownloadWorkflowLogsFromStdin(ctx context.Context, opts StdinLogsOptions) ( if preparedCachedJSONL.cache != nil { cachedRuns = preparedCachedJSONL.cache.runs } - if !cachedJSONLCanSatisfy(artifactFilter, opts.Parse, opts.Audit, opts.Train, opts.ToolGraph) { + if !cachedJSONLCanSatisfy(artifactFilter, opts.Parse, opts.Train, opts.ToolGraph) { cachedRuns = nil } cachedJSONLWriter := preparedCachedJSONL.writer