A check step that errors after its fetch merged still answers its fetch
mesh/delivery merged: source.main moved to novox/mesh-catalog@f1c04801e477
mesh/delivery-group group fix/checker-preview-after-failed-step merged: every member is merged
mesh/check checking fff3b819d383 on f1c04801e477 | novox/mesh-catalog#663 in group fix/checker-preview-after-failed-step

A level that does not compile or generate ended the check step failed with no
result, so the checker could not tell a merged fetch from one that never
answered, and previewed and judged no manifest or composition of the member.
The step now ends failed with its answer all the same: its fetch and the
levels so far beside the error, which the step's end already keeps.

Builds: design 47 G A-286 (G-22-lead-answers-2.md at hq 41dd30fe; issue 1921; principle 3)
Quick: this checker on main; thorough: the same rule in G's checker (join 11, J15).

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-12 15:23:48 +01:00
parent 6d000647de
commit fff3b819d3
2 changed files with 31 additions and 1 deletions
+4 -1
View File
@@ -303,7 +303,10 @@ func (s AskSteps) check(ctx context.Context, job sdkstep.CheckJob) (any, error)
_, err := s.level(ctx, job, level, f, runner, &la)
answer.Levels = append(answer.Levels, la)
if err != nil {
return nil, err
// A level that errors after the fetch merged (it does not compile or generate) ends the step failed with its
// answer all the same: its fetch and the levels so far beside the error, which the step's end keeps, so the
// checker previews the merge from it (design 47 G, A-286).
return answer, err
}
}
return answer, nil
@@ -285,6 +285,33 @@ func TestRunAskChecksNodeModulesAndConflicts(t *testing.T) {
if err != nil || len(r.calls) != 1 || len(out.(sdkstep.CheckAnswer).Levels) != 0 {
t.Fatalf("a conflict: %v %v", err, r.calls)
}
// A-286: a level that errors after the fetch merged ends the step failed with its answer all the same, its fetch and
// the levels so far beside the error, and the step's end keeps it, so the checker previews the merge from it.
r = &recorder{fetch: map[string]any{"workspace": "/w", "merge": "m1", "modules": []string{"a"}}, tests: map[string]bool{"a": true}}
s = r.steps()
s.Digest = nil
passing := s.Test
s.Test = func(ctx context.Context, args map[string]any) (any, error) {
if args["level"] == sdkstep.LevelIntegration {
return nil, errors.New("does not compile")
}
return passing(ctx, args)
}
errs := ask(sdkstep.CheckJob{Levels: []string{sdkstep.LevelUnit, sdkstep.LevelIntegration}, Fetch: sdkstep.Fetch{Repository: "novox/x", Commit: runCommit}})
out, err = RunAsk(context.Background(), s, errs)
if a, _ := out.(sdkstep.CheckAnswer); err == nil || a.Fetch.Merge != "m1" || len(a.Levels) != 2 || len(a.Levels[0].Tests) != 1 {
t.Fatalf("an erring level: %v, answer %+v: want the error beside the fetch and both levels", err, out)
}
k := newKeys()
id, err := Start(context.Background(), k.put, "ace", "test", func(ctx context.Context) (any, error) { return RunAsk(ctx, s, errs) })
if err != nil {
t.Fatal(err)
}
k.waitEnd(t)
var kept sdkstep.CheckAnswer
if end := k.last("ace." + id); end.State != sdkstep.StepFailed || json.Unmarshal(end.Result, &kept) != nil || kept.Fetch.Merge != "m1" {
t.Fatalf("the failed end %+v keeps no answer with its fetch", end)
}
}
// Issue 1289: the packages whose tests changed run first. Since 2026-11-02 (the operator: "A failed check shows only its