From 114c99e02a521c04f1698b87781778986ae7caca Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 16 Oct 2026 14:31:04 +0200 Subject: [PATCH] The delivery seat promises mark-ready: a reviewer marks a head ready through one audited verb (issue 913) --- internal/catalogue/delivery_seat.go | 11 ++++++++- internal/catalogue/delivery_seat_test.go | 29 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/internal/catalogue/delivery_seat.go b/internal/catalogue/delivery_seat.go index 682723e1..19a2d51b 100644 --- a/internal/catalogue/delivery_seat.go +++ b/internal/catalogue/delivery_seat.go @@ -9,7 +9,7 @@ package catalogue // DeliverySeat is the seat mesh-delivery holds. const DeliverySeat = "mesh-delivery" -// deliveryVerbs are the delivery seat's tools: six that read, and the acts of a person and of healer H2. +// deliveryVerbs are the delivery seat's tools: six that read, and the acts of a person, a reviewer and healer H2. func deliveryVerbs() []Verb { return []Verb{ {Name: "deliveries", Description: "Every delivery not final, and those that ended in the last day, one line " + @@ -84,6 +84,15 @@ func deliveryVerbs() []Verb { "dry": "\"true\": what it would retire, changing nothing"}, []string{"why"}, "dry"), // Added after the seat's holder shipped (novox/hq issue 313): optional until mesh-delivery serves it. Optional: true}, + {Name: "mark-ready", Description: "A reviewer's word that a delivery's head is approved: the holder puts the " + + "label mesh/ready on its pull request and then writes \"ready at \", the order the forge counts, " + + "as the mesh's own forge account, naming who reviewed it and why. Refused when the delivery's commit is " + + "no longer its pull request's head. mesh-delivery then merges it once its checks pass (novox/hq ADR 0364).", + Input: schema(map[string]string{"id": "the delivery's id (owner/repository@commit): the head reviewed", + "reviewed-by": "who reviewed it, as who@node", "why": "the review's verdict in a line"}, + []string{"id", "reviewed-by", "why"}), + // Added after the seat's holder shipped (novox/hq issue 913): optional until mesh-delivery serves it. + Optional: true}, } } diff --git a/internal/catalogue/delivery_seat_test.go b/internal/catalogue/delivery_seat_test.go index 5fe8daf2..783ec06e 100644 --- a/internal/catalogue/delivery_seat_test.go +++ b/internal/catalogue/delivery_seat_test.go @@ -133,3 +133,32 @@ func TestTheDeliverySeatPromisesTimesOptionally(t *testing.T) { t.Fatalf("a holder serving times: %v", err) } } + +// The seat marks a reviewed head ready (novox/hq issue 913): `mark-ready`, with the delivery's id, who reviewed it +// and why, so a reviewer marks a pull request through one audited verb, label and comment in the order the forge +// counts, instead of two raw forge calls. Added after the holder shipped, it is optional. +func TestTheDeliverySeatPromisesMarkReadyOptionally(t *testing.T) { + seat, _ := SeatNamed(DeliverySeat) + var mark *Verb + for i := range seat.Serves { + if seat.Serves[i].Name == "mark-ready" { + mark = &seat.Serves[i] + } + } + if mark == nil || !mark.Optional { + t.Fatalf("the delivery seat promises %v, mark-ready optionally", VerbNames(seat.Serves)) + } + if req, _ := mark.Input["required"].([]string); !reflect.DeepEqual(req, []string{"id", "reviewed-by", "why"}) { + t.Errorf("mark-ready requires %v, wanted id, reviewed-by and why", req) + } + var without []string + for _, v := range VerbNames(seat.Serves) { + if v != "mark-ready" { + without = append(without, v) + } + } + m := Manifest{Module: "mesh-delivery", Claims: []Claim{{Name: DeliverySeat, Scope: ScopeMesh, Serves: without}}} + if err := CanHold(m, seat); err != nil { + t.Fatalf("a holder without mark-ready yet: %v", err) + } +}