From fa1bd237d1117b2c138b4bbd32654eee352ac93b Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Sat, 23 May 2026 17:32:30 +0000 Subject: [PATCH] Centralize diagnostics artifact names and report metadata paths --- internal/cli/run.go | 27 +++------- internal/core/diagnostics/artifacts.go | 42 ++++++++++++++++ internal/core/diagnostics/artifacts_test.go | 55 +++++++++++++++++++++ internal/core/diagnostics/run_dir.go | 18 +++---- 4 files changed, 113 insertions(+), 29 deletions(-) create mode 100644 internal/core/diagnostics/artifacts.go create mode 100644 internal/core/diagnostics/artifacts_test.go diff --git a/internal/cli/run.go b/internal/cli/run.go index d40eeab..953f95a 100644 --- a/internal/cli/run.go +++ b/internal/cli/run.go @@ -531,9 +531,9 @@ func runProcess(args []string, stdout, stderr io.Writer) int { if runErr != nil { if runDir != nil && runOutput != nil { if runOutput.Utilization != nil { - _ = runDir.WriteJSONArtifact("utilization-diagnostics.json", runOutput.Utilization) + _ = runDir.WriteJSONArtifact(diagnostics.ArtifactUtilizationSummary, runOutput.Utilization) } - _ = runDir.WriteJSONArtifact("correction-ledger.json", buildCorrectionLedger(runDir.Path(), runOutput)) + _ = runDir.WriteJSONArtifact(diagnostics.ArtifactCorrectionLedger, buildCorrectionLedger(runDir.Path(), runOutput)) } errorPhase, errorMessage := extractErrorPhase(runErr) report := buildProcessReport("failed", inv, runDir, startedAt, completedAt, errorMessage, errorPhase, nil, nil, runOutput) @@ -560,9 +560,9 @@ func runProcess(args []string, stdout, stderr io.Writer) int { if runDir != nil && runOutput != nil { if runOutput.Utilization != nil { - _ = runDir.WriteJSONArtifact("utilization-diagnostics.json", runOutput.Utilization) + _ = runDir.WriteJSONArtifact(diagnostics.ArtifactUtilizationSummary, runOutput.Utilization) } - _ = runDir.WriteJSONArtifact("correction-ledger.json", buildCorrectionLedger(runDir.Path(), runOutput)) + _ = runDir.WriteJSONArtifact(diagnostics.ArtifactCorrectionLedger, buildCorrectionLedger(runDir.Path(), runOutput)) } report := buildProcessReport("success", inv, runDir, startedAt, completedAt, "", "", normSummary, chunkSummary, runOutput) @@ -743,22 +743,9 @@ func buildProcessReport(status string, inv processInvocation, runDir *diagnostic ErrorPhase: errorPhase, } if runDir != nil { - diagnosticsDir := runDir.Path() - report.Diagnostics = &reporting.DiagnosticsMetadata{ - DirectoryPath: diagnosticsDir, - SourceTranscriptPath: filepath.Join(diagnosticsDir, "source-transcript.json"), - ParsedSourceTranscriptPath: filepath.Join(diagnosticsDir, "source-transcript-parsed.json"), - NormalizedTranscriptPath: filepath.Join(diagnosticsDir, "normalized-transcript.json"), - NormalizationSummaryPath: filepath.Join(diagnosticsDir, "normalization-summary.json"), - ChunkingSummaryPath: filepath.Join(diagnosticsDir, "chunking-summary.json"), - UtilizationSummaryPath: filepath.Join(diagnosticsDir, "utilization-diagnostics.json"), - CorrectionLedgerPath: filepath.Join(diagnosticsDir, "correction-ledger.json"), - InvocationMetadataPath: filepath.Join(diagnosticsDir, "invocation.json"), - RedactedEffectiveConfigPath: filepath.Join(diagnosticsDir, "effective-config.json"), - } - if status == "failed" { - report.Diagnostics.ErrorLogPath = filepath.Join(diagnosticsDir, "error.log") - } + runSucceeded := status == "success" + metadata := diagnostics.BuildDiagnosticsMetadata(runDir.Path(), runSucceeded) + report.Diagnostics = &metadata } if errorMessage != "" { report.ErrorMessage = errorMessage diff --git a/internal/core/diagnostics/artifacts.go b/internal/core/diagnostics/artifacts.go new file mode 100644 index 0000000..13f4f41 --- /dev/null +++ b/internal/core/diagnostics/artifacts.go @@ -0,0 +1,42 @@ +package diagnostics + +import ( + "path/filepath" + + "gitea.maximumdirect.net/eric/audita/internal/core/reporting" +) + +const ( + ArtifactSourceTranscript = "source-transcript.json" + ArtifactParsedSourceTranscript = "source-transcript-parsed.json" + ArtifactNormalizedTranscript = "normalized-transcript.json" + ArtifactNormalizationSummary = "normalization-summary.json" + ArtifactChunkingSummary = "chunking-summary.json" + ArtifactUtilizationSummary = "utilization-diagnostics.json" + ArtifactCorrectionLedger = "correction-ledger.json" + ArtifactInvocationMetadata = "invocation.json" + ArtifactEffectiveConfig = "effective-config.json" + ArtifactReport = "report.json" + ArtifactErrorLog = "error.log" +) + +func BuildDiagnosticsMetadata(runDirectoryPath string, runSucceeded bool) reporting.DiagnosticsMetadata { + metadata := reporting.DiagnosticsMetadata{ + DirectoryPath: runDirectoryPath, + SourceTranscriptPath: filepath.Join(runDirectoryPath, ArtifactSourceTranscript), + ParsedSourceTranscriptPath: filepath.Join(runDirectoryPath, ArtifactParsedSourceTranscript), + NormalizedTranscriptPath: filepath.Join(runDirectoryPath, ArtifactNormalizedTranscript), + NormalizationSummaryPath: filepath.Join(runDirectoryPath, ArtifactNormalizationSummary), + ChunkingSummaryPath: filepath.Join(runDirectoryPath, ArtifactChunkingSummary), + UtilizationSummaryPath: filepath.Join(runDirectoryPath, ArtifactUtilizationSummary), + CorrectionLedgerPath: filepath.Join(runDirectoryPath, ArtifactCorrectionLedger), + InvocationMetadataPath: filepath.Join(runDirectoryPath, ArtifactInvocationMetadata), + RedactedEffectiveConfigPath: filepath.Join(runDirectoryPath, ArtifactEffectiveConfig), + } + + if !runSucceeded { + metadata.ErrorLogPath = filepath.Join(runDirectoryPath, ArtifactErrorLog) + } + + return metadata +} diff --git a/internal/core/diagnostics/artifacts_test.go b/internal/core/diagnostics/artifacts_test.go new file mode 100644 index 0000000..7540870 --- /dev/null +++ b/internal/core/diagnostics/artifacts_test.go @@ -0,0 +1,55 @@ +package diagnostics + +import ( + "path/filepath" + "testing" +) + +func TestBuildDiagnosticsMetadataSuccessPathsMatchArtifactConstants(t *testing.T) { + runPath := filepath.Join("tmp", "run-123") + metadata := BuildDiagnosticsMetadata(runPath, true) + + if metadata.DirectoryPath != runPath { + t.Fatalf("unexpected diagnostics directory path: got=%q want=%q", metadata.DirectoryPath, runPath) + } + if metadata.SourceTranscriptPath != filepath.Join(runPath, ArtifactSourceTranscript) { + t.Fatalf("unexpected source transcript path: %q", metadata.SourceTranscriptPath) + } + if metadata.ParsedSourceTranscriptPath != filepath.Join(runPath, ArtifactParsedSourceTranscript) { + t.Fatalf("unexpected parsed source transcript path: %q", metadata.ParsedSourceTranscriptPath) + } + if metadata.NormalizedTranscriptPath != filepath.Join(runPath, ArtifactNormalizedTranscript) { + t.Fatalf("unexpected normalized transcript path: %q", metadata.NormalizedTranscriptPath) + } + if metadata.NormalizationSummaryPath != filepath.Join(runPath, ArtifactNormalizationSummary) { + t.Fatalf("unexpected normalization summary path: %q", metadata.NormalizationSummaryPath) + } + if metadata.ChunkingSummaryPath != filepath.Join(runPath, ArtifactChunkingSummary) { + t.Fatalf("unexpected chunking summary path: %q", metadata.ChunkingSummaryPath) + } + if metadata.UtilizationSummaryPath != filepath.Join(runPath, ArtifactUtilizationSummary) { + t.Fatalf("unexpected utilization summary path: %q", metadata.UtilizationSummaryPath) + } + if metadata.CorrectionLedgerPath != filepath.Join(runPath, ArtifactCorrectionLedger) { + t.Fatalf("unexpected correction ledger path: %q", metadata.CorrectionLedgerPath) + } + if metadata.InvocationMetadataPath != filepath.Join(runPath, ArtifactInvocationMetadata) { + t.Fatalf("unexpected invocation metadata path: %q", metadata.InvocationMetadataPath) + } + if metadata.RedactedEffectiveConfigPath != filepath.Join(runPath, ArtifactEffectiveConfig) { + t.Fatalf("unexpected redacted effective config path: %q", metadata.RedactedEffectiveConfigPath) + } + if metadata.ErrorLogPath != "" { + t.Fatalf("did not expect error log path on success: %q", metadata.ErrorLogPath) + } +} + +func TestBuildDiagnosticsMetadataFailureIncludesErrorLogPath(t *testing.T) { + runPath := filepath.Join("tmp", "run-123") + metadata := BuildDiagnosticsMetadata(runPath, false) + + want := filepath.Join(runPath, ArtifactErrorLog) + if metadata.ErrorLogPath != want { + t.Fatalf("unexpected error log path: got=%q want=%q", metadata.ErrorLogPath, want) + } +} diff --git a/internal/core/diagnostics/run_dir.go b/internal/core/diagnostics/run_dir.go index 1c03303..aa9d232 100644 --- a/internal/core/diagnostics/run_dir.go +++ b/internal/core/diagnostics/run_dir.go @@ -106,7 +106,7 @@ func (r *RunDirectory) WriteInvocationMetadata(metadata InvocationMetadata) erro metadata.StartedAt = r.createdAt } - path := filepath.Join(r.path, "invocation.json") + path := filepath.Join(r.path, ArtifactInvocationMetadata) bytes, err := json.MarshalIndent(metadata, "", " ") if err != nil { return fmt.Errorf("failed to marshal invocation metadata: %w", err) @@ -120,7 +120,7 @@ func (r *RunDirectory) WriteInvocationMetadata(metadata InvocationMetadata) erro // WriteEffectiveConfig writes redacted effective config metadata for this run. func (r *RunDirectory) WriteEffectiveConfig(cfg config.Config) error { - path := filepath.Join(r.path, "effective-config.json") + path := filepath.Join(r.path, ArtifactEffectiveConfig) redacted := cfg.Redacted() bytes, err := json.MarshalIndent(redacted, "", " ") if err != nil { @@ -136,13 +136,13 @@ func (r *RunDirectory) WriteEffectiveConfig(cfg config.Config) error { // WriteSourceTranscript writes the source transcript artifact func (r *RunDirectory) WriteSourceTranscript(transcript *schema.SourceTranscript, raw []byte) error { // Write raw source for reference - sourcePath := filepath.Join(r.path, "source-transcript.json") + sourcePath := filepath.Join(r.path, ArtifactSourceTranscript) if err := os.WriteFile(sourcePath, raw, 0o644); err != nil { return fmt.Errorf("failed to write source transcript: %w", err) } // Write parsed source for debugging - parsedPath := filepath.Join(r.path, "source-transcript-parsed.json") + parsedPath := filepath.Join(r.path, ArtifactParsedSourceTranscript) parsedBytes, err := json.MarshalIndent(transcript, "", " ") if err != nil { return fmt.Errorf("failed to marshal parsed source transcript: %w", err) @@ -157,7 +157,7 @@ func (r *RunDirectory) WriteSourceTranscript(transcript *schema.SourceTranscript // WriteNormalizedTranscript writes the normalized transcript artifact func (r *RunDirectory) WriteNormalizedTranscript(transcript *schema.Transcript) error { - normalizedPath := filepath.Join(r.path, "normalized-transcript.json") + normalizedPath := filepath.Join(r.path, ArtifactNormalizedTranscript) bytes, err := schema.TranscriptToJSON(transcript) if err != nil { return fmt.Errorf("failed to serialize normalized transcript: %w", err) @@ -170,7 +170,7 @@ func (r *RunDirectory) WriteNormalizedTranscript(transcript *schema.Transcript) // WriteNormalizationSummary writes the normalization summary artifact func (r *RunDirectory) WriteNormalizationSummary(summary *normalization.NormalizationSummary) error { - summaryPath := filepath.Join(r.path, "normalization-summary.json") + summaryPath := filepath.Join(r.path, ArtifactNormalizationSummary) bytes, err := json.MarshalIndent(summary, "", " ") if err != nil { return fmt.Errorf("failed to marshal normalization summary: %w", err) @@ -184,7 +184,7 @@ func (r *RunDirectory) WriteNormalizationSummary(summary *normalization.Normaliz // WriteReport writes the authoritative report artifact func (r *RunDirectory) WriteReport(report reporting.ProcessReport) error { - reportPath := filepath.Join(r.path, "report.json") + reportPath := filepath.Join(r.path, ArtifactReport) bytes, err := json.MarshalIndent(report, "", " ") if err != nil { return fmt.Errorf("failed to marshal report: %w", err) @@ -198,13 +198,13 @@ func (r *RunDirectory) WriteReport(report reporting.ProcessReport) error { // WriteErrorLog writes an error log on failure func (r *RunDirectory) WriteErrorLog(errorMessage string) error { - errorPath := filepath.Join(r.path, "error.log") + errorPath := filepath.Join(r.path, ArtifactErrorLog) return os.WriteFile(errorPath, []byte(errorMessage+"\n"), 0o644) } // WriteChunkingSummary writes the chunking summary artifact func (r *RunDirectory) WriteChunkingSummary(summary *chunking.DetailedSummary) error { - summaryPath := filepath.Join(r.path, "chunking-summary.json") + summaryPath := filepath.Join(r.path, ArtifactChunkingSummary) bytes, err := json.MarshalIndent(summary, "", " ") if err != nil { return fmt.Errorf("failed to marshal chunking summary: %w", err)