Add Phase 2 normalization diagnostics

This commit is contained in:
2026-05-11 00:19:28 +00:00
parent aeb9c4f062
commit 14e51698c2
3 changed files with 488 additions and 24 deletions

View File

@@ -9,6 +9,7 @@ import (
"time"
"gitea.maximumdirect.net/eric/audita/internal/core/config"
"gitea.maximumdirect.net/eric/audita/internal/core/diagnostics"
"gitea.maximumdirect.net/eric/audita/internal/core/io"
"gitea.maximumdirect.net/eric/audita/internal/core/normalization"
"gitea.maximumdirect.net/eric/audita/internal/core/reporting"
@@ -24,25 +25,49 @@ type processInvocation struct {
}
var processRunner = func(inv processInvocation, stdout io.Writer) (*normalization.NormalizationSummary, error) {
// Create run directory early to capture artifacts
runDir, err := diagnostics.NewRunDirectory(inv.Config.WorkDir, string(inv.Config.WorkDirRetention))
if err != nil {
return nil, fmt.Errorf("run_dir_creation: %w", err)
}
defer func() {
// Apply retention policy - failed runs are always kept
// For now, we consider any run that saved source as successful
if runDir != nil {
_ = runDir.ApplyRetention()
}
}()
transcriptBytes, err := io.ReadRequiredFile(inv.TranscriptPath, "transcript")
if err != nil {
// Best effort to write error log on failure
_ = runDir.WriteErrorLog(fmt.Sprintf("transcript_read: %v", err))
return nil, fmt.Errorf("transcript_read: %w", err)
}
glossaryBytes, err := io.ReadRequiredFile(inv.GlossaryPath, "glossary")
if err != nil {
_ = runDir.WriteErrorLog(fmt.Sprintf("glossary_read: %v", err))
return nil, fmt.Errorf("glossary_read: %w", err)
}
// Parse and validate transcript using typed schema
transcript, err := schema.ParseSourceTranscriptJSON(transcriptBytes)
if err != nil {
_ = runDir.WriteErrorLog(fmt.Sprintf("transcript_schema: %v", err))
return nil, fmt.Errorf("transcript_schema: %w", err)
}
// Write source transcript artifacts
if err := runDir.WriteSourceTranscript(transcript, transcriptBytes); err != nil {
_ = runDir.WriteErrorLog(fmt.Sprintf("source_artifact: %v", err))
// Continue without failing the whole process
}
// Parse and validate glossary using typed schema
glossary, err := schema.ParseGlossaryYAML(glossaryBytes)
if err != nil {
_ = runDir.WriteErrorLog(fmt.Sprintf("glossary_schema: %v", err))
return nil, fmt.Errorf("glossary_schema: %w", err)
}
@@ -75,21 +100,36 @@ var processRunner = func(inv processInvocation, stdout io.Writer) (*normalizatio
normalizedTranscript, normalizationSummary := normalizer.Normalize(normalizedTranscript)
// Write normalized transcript artifact
if err := runDir.WriteNormalizedTranscript(normalizedTranscript); err != nil {
_ = runDir.WriteErrorLog(fmt.Sprintf("normalized_artifact: %v", err))
// Continue without failing the whole process
}
// Write normalization summary artifact
if err := runDir.WriteNormalizationSummary(normalizationSummary); err != nil {
_ = runDir.WriteErrorLog(fmt.Sprintf("normalization_summary: %v", err))
// Continue without failing the whole process
}
// Serialize normalized transcript to JSON
outputBytes, err := schema.TranscriptToJSON(normalizedTranscript)
if err != nil {
return nil, fmt.Errorf("failed to serialize transcript: %w", err)
_ = runDir.WriteErrorLog(fmt.Sprintf("serialization: %v", err))
return nil, fmt.Errorf("serialization: %w", err)
}
if strings.TrimSpace(inv.OutputPath) != "" {
if err := io.WriteFile(inv.OutputPath, outputBytes); err != nil {
_ = runDir.WriteErrorLog(fmt.Sprintf("output_write: %v", err))
return nil, err
}
return normalizationSummary, nil
}
if _, err := stdout.Write(outputBytes); err != nil {
return nil, fmt.Errorf("failed to write transcript to stdout: %w", err)
_ = runDir.WriteErrorLog(fmt.Sprintf("stdout_write: %v", err))
return nil, fmt.Errorf("stdout_write: %w", err)
}
return normalizationSummary, nil
}