Compose resilient CLI processing and report lifecycle

This commit is contained in:
2026-09-24 17:48:52 +00:00
parent 87b8d9ad5c
commit 2f036b0356
11 changed files with 676 additions and 777 deletions

View File

@@ -43,7 +43,7 @@ func Build(input BuildInput) reporting.Snapshot {
for i, spec := range input.ModuleSpecs {
snapshot.StageNames[i] = spec.InstanceName
}
if input.RunOutput != nil {
if input.RunOutput != nil && input.RunOutput.InventoryAvailable {
units := append([]runner.WorkUnitOutcome(nil), input.RunOutput.WorkUnits...)
sort.SliceStable(units, func(i, j int) bool {
if units[i].ModuleIndex != units[j].ModuleIndex {
@@ -200,6 +200,8 @@ func safeMessage(reason outcomes.ReasonCode) string {
return "Processing was canceled."
case outcomes.ReasonSetupFailure:
return "Processing setup failed."
case outcomes.ReasonInputInvalid:
return "Input was invalid."
default:
return "Processing failed."
}

View File

@@ -23,7 +23,7 @@ func TestBuildPartialUnitsAndCombinedRecovery(t *testing.T) {
batch := 1
validation := outcomes.Operation{Reference: outcomes.Reference{Kind: outcomes.OperationValidation, ValidatorName: "review", ValidatorOrder: intPtr(1), BatchIndex: &batch}, FailureReason: outcomes.ReasonTransportFailed, ProposalIndices: []int{9, 3}}
inputFailure := outcomes.Operation{Reference: outcomes.Reference{Kind: outcomes.OperationValidationInput, ValidatorName: "review", ValidatorOrder: intPtr(1)}, FailureReason: outcomes.ReasonValidationInputTooLarge, ProposalIndices: []int{7}}
output := &runner.RunOutput{WorkUnits: []runner.WorkUnitOutcome{
output := &runner.RunOutput{InventoryAvailable: true, WorkUnits: []runner.WorkUnitOutcome{
{ModuleIndex: 1, ModuleKey: "grammar", ModuleInstance: "grammar_2", Section: contracts.SectionMetadata{Index: 0, StartSegmentID: 1, EndSegmentID: 2}, State: outcomes.WorkNotStarted},
{ModuleIndex: 0, ModuleKey: "grammar", ModuleInstance: "grammar_1", Section: contracts.SectionMetadata{Index: 0, StartSegmentID: 1, EndSegmentID: 2}, State: outcomes.WorkCompleted, CorrectionsApplied: 1, Operations: []outcomes.Operation{validation, proposal, inputFailure}},
}}
@@ -64,7 +64,7 @@ func TestBuildInitializationNoWorkAndRunFailure(t *testing.T) {
if initialDoc.CompletedAt != nil || initialDoc.Summary.WorkUnitsTotal != nil || initialDoc.Errors == nil {
t.Fatalf("initial: %+v", initialDoc)
}
finished := Build(BuildInput{RunID: "r", Status: reporting.StatusCompleted, StartedAt: start, RunOutput: &runner.RunOutput{}})
finished := Build(BuildInput{RunID: "r", Status: reporting.StatusCompleted, StartedAt: start, RunOutput: &runner.RunOutput{InventoryAvailable: true}})
if finished.Summary.WorkUnitsTotal == nil || *finished.Summary.WorkUnitsTotal != 0 || finished.RecoveriesDocument().Recoveries == nil {
t.Fatalf("empty: %+v", finished)
}