CAT-NR1: every build narrates its asks of a seat in one place

asked, waiting on the seat every five minutes, stored or refused, as the ask's
phase on its step key, so a publish or a copy that stands still is readable on
the bus. PublishOne and PublishFiles narrate for every build module; the image
copy and the late publish use the same narration.

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-04 16:05:27 +01:00
parent 1c4739698a
commit 37a1f2be53
6 changed files with 262 additions and 8 deletions
@@ -12,6 +12,7 @@ package main
import (
"context"
"encoding/json"
"errors"
"fmt"
"regexp"
"sort"
@@ -106,8 +107,10 @@ func (m *Module) copy(ctx context.Context, args map[string]any) (any, error) {
return nil, fmt.Errorf("%s%s: keeping the copy's wait in %s: %v", delivery.NotStored, name, MirrorWaitsState, err)
}
defer m.Outcomes.drop(key, asked.Token)
said := buildstep.NarrateSeat(ctx, buildstep.ImageSeat, "mirror of "+from)
raw, err := m.call()("seat:"+buildstep.ImageSeat+"."+reg.VerbMirror, reg.MirrorInput{Name: module + "/" + name, Source: from, Digest: digest})
if err != nil {
said.Refused(err)
return nil, fmt.Errorf("%s%s: %s's mirror: %v", delivery.NotStored, name, buildstep.ImageSeat, err)
}
var answer reg.MirrorAnswer
@@ -121,13 +124,24 @@ func (m *Module) copy(ctx context.Context, args map[string]any) (any, error) {
for {
// The state first: an outcome written there while this copy did not hear it is this copy's.
if o, ok := m.Outcomes.kept(key); ok {
return copyEnd(name, o, answer.Reference)
res, err := copyEnd(name, o, answer.Reference)
if err != nil {
said.Refused(errors.New(o.Reason))
} else {
said.Stored(res.(CopyResult).Reference)
}
return res, err
}
select {
case <-heard:
case <-said.Waiting():
said.StillWaiting()
case <-bound:
return nil, fmt.Errorf("%s%s: %s said no outcome of the copy of %s in %s", delivery.NotStored, name, buildstep.ImageSeat, from, wait)
err := fmt.Errorf("%s said no outcome of the copy of %s in %s", buildstep.ImageSeat, from, wait)
said.Refused(err)
return nil, fmt.Errorf("%s%s: %w", delivery.NotStored, name, err)
case <-ctx.Done():
said.Refused(ctx.Err())
return nil, fmt.Errorf("%s%s: stopped while waiting for the copy of %s: %w", delivery.NotStored, name, from, ctx.Err())
}
}