diff --git a/go/catalogue/delivery_seat.go b/go/catalogue/delivery_seat.go
index 7df4d86..9296f5e 100644
--- a/go/catalogue/delivery_seat.go
+++ b/go/catalogue/delivery_seat.go
@@ -9,7 +9,26 @@ 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, a reviewer and healer H2.
+// RemovedDeliveryVerbs are the delivery seat's verbs release 6 removed (novox/hq ADR 0539 clause 17): with no plan the
+// gate keeps the merge's states and derives nothing after the merge. Each stays in deliveryVerbs as an optional row
+// with no input, so the holder of before and the holder of release 6 both hold the seat and a caller is answered by
+// name with its replacement, given here.
+var RemovedDeliveryVerbs = map[string]string{
+ "times": "the delivery view (nox-delivery): each machine's want and have, and since when",
+ "what-if": "the merge check's composition, which composes every machine a change touches",
+ "release": "the assigner's asks (hold, restore, backup, record), answered on the phone or in the delivery view",
+ "stop": "a bad fingerprint is held and its canary set back by the assigner (ADR 0429 §6, ADR 0539 clause 18)",
+ "retire-history": "nothing to retire: the gate keeps no delivery after its merge",
+}
+
+// deliveryRemovedInR6 is the row of a verb release 6 removed from the delivery seat.
+func deliveryRemovedInR6(name string) Verb {
+ return Verb{Name: name, Description: "Removed in R6 (ADR 0539): refused by name, naming its replacement: " +
+ RemovedDeliveryVerbs[name], Input: schema(nil, nil), Optional: true}
+}
+
+// deliveryVerbs are the delivery seat's tools: what reads the merges and checks, and the acts of a person and healer H2
+// on a merge (ADR 0539 clause 17).
func deliveryVerbs() []Verb {
return []Verb{
{Name: "deliveries", Description: "Every delivery not final, and those that ended in the last day, one line " +
@@ -18,15 +37,7 @@ func deliveryVerbs() []Verb {
Input: schema(map[string]string{"state": "one state, e.g. delivering or held",
"repository": "owner/repository", "group": "a group's id (its branch name)",
"all": "\"true\": the final ones of the last thirty days too"}, nil, "all")},
- // Delivery time against the delivery budgets (novox/hq ADR 0282): what probe D16 reads, optional until its
- // holder serves it.
- {Name: "times", Description: "Delivery time: from a merge to every machine of its walk running the build. " +
- "Each class's delivery budget (a leaf module three minutes, a core module ten), the last days' median and " +
- "worst, how many within and over, the newest delivery of each class, every delivery over its budget with its " +
- "longest phase, and the delivered ones whose time is not known. Given a delivery's id, its time phase by phase.",
- Input: schema(map[string]string{"days": "how many days back (default 7)", "id": "one delivery's id: its phases"}, nil),
- // Optional until mesh-delivery serves it: its holder lives in the catalogue (design 33 §7).
- Optional: true},
+ deliveryRemovedInR6("times"),
{Name: "show", Description: "One delivery or group whole: its delivery plan (what it builds, what each " +
"machine receives, what is not an ordinary send), every transition with when and why, the machine " +
"steps of its walk, its group and its order.",
@@ -35,12 +46,7 @@ func deliveryVerbs() []Verb {
"(declared, built by, version skew, engine before controller, by name), its composed check and its " +
"state, derived from its members.",
Input: schema(map[string]string{"all": "\"true\": the groups that ended too"}, nil, "all")},
- {Name: "what-if", Description: "The delivery plan a change would have, asked of the controller's planner " +
- "and kept nowhere: the modules it moves and their dependents in tiers, what each machine would receive, " +
- "the steps that are not an ordinary send.",
- Input: schema(map[string]string{"repository": "owner/repository",
- "paths": "the files it changes, comma-separated, from the repository's root",
- "base": "the branch it merges into (default main)"}, []string{"repository", "paths"})},
+ deliveryRemovedInR6("what-if"),
{Name: "checks", Description: "What the mesh's checks said of a pull request's head or of one commit: each " +
"of the commit's mesh statuses (mesh/check, the one a main requires from R4e, hq's mesh/repo-check, " +
"mesh/delivery, …) with its state, " +
@@ -62,40 +68,13 @@ func deliveryVerbs() []Verb {
"controller is asked for its check. With why.",
Input: schema(map[string]string{"id": "the delivery's id", "why": "why, kept with the transition"},
[]string{"id", "why"})},
- {Name: "release", Description: "A person's word that a held delivery goes on: it starts delivering. With why.",
- Input: schema(map[string]string{"id": "the delivery's id", "why": "why, kept with the transition"},
- []string{"id", "why"})},
- {Name: "stop", Description: "Stop a delivery that is not final, with why; its walk is ended through the " +
- "controller, and in a group every member after it is stopped too, naming it.",
- Input: schema(map[string]string{"id": "the delivery's id", "why": "why, kept with the transition"},
- []string{"id", "why"})},
+ deliveryRemovedInR6("release"),
+ deliveryRemovedInR6("stop"),
{Name: "close", Description: "Healer H2's verb: take the one transition the table names for a delivery held " +
"past its bound. Refused for any other.",
Input: schema(map[string]string{"id": "the delivery's id", "why": "the condition it answers"},
[]string{"id", "why"})},
- {Name: "retire-history", Description: "Retire held deliveries that are history, on a person's word, with " +
- "why: each made from the forge's word for a merge on the trunk heard long after it happened — replayed " +
- "when the holder first held the seat — with no walk of it open. Never released, delivered or put back: " +
- "retired, final. One by id, refused when the rule does not take it; or every held one, of one " +
- "repository when named, answering how many it retired and naming those it left held. dry \"true\" " +
- "answers what it would do and changes nothing.",
- Input: schema(map[string]string{"why": "why, kept with every transition",
- "id": "one delivery's id; every held one when empty",
- "repository": "owner/repository: only its held deliveries",
- "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"}),
- // Kept one more release, optional (novox/hq issue 1022): mesh-delivery no longer serves it, but the manifest
- // it still has on the mesh does until its catalogue member merges, and a seat refuses a holder that serves
- // a verb it does not promise. The next release removes this entry.
- Optional: true},
+ deliveryRemovedInR6("retire-history"),
}
}
diff --git a/go/catalogue/delivery_seat_test.go b/go/catalogue/delivery_seat_test.go
index 7d3a619..046b93d 100644
--- a/go/catalogue/delivery_seat_test.go
+++ b/go/catalogue/delivery_seat_test.go
@@ -58,107 +58,3 @@ func TestTheDeliverySeatPromisesChecks(t *testing.T) {
t.Fatalf("a holder without %s: %v", before[0], err)
}
}
-
-// The seat retires history on a person's word (novox/hq issue 313): `retire-history`, with why, one delivery by
-// id or every held one, dry to see first. Added after the holder shipped, it is optional, so the holder that
-// does not serve it yet still holds the seat, and one that does is not refused for a verb the seat lacks.
-func TestTheDeliverySeatPromisesRetireHistoryOptionally(t *testing.T) {
- seat, _ := SeatNamed(DeliverySeat)
- var retire *Verb
- for i := range seat.Serves {
- if seat.Serves[i].Name == "retire-history" {
- retire = &seat.Serves[i]
- }
- }
- if retire == nil || !retire.Optional {
- t.Fatalf("the delivery seat promises %v, retire-history optionally", VerbNames(seat.Serves))
- }
- props, _ := retire.Input["properties"].(map[string]any)
- for _, arg := range []string{"why", "id", "repository", "dry"} {
- if _, has := props[arg]; !has {
- t.Errorf("retire-history takes no %q", arg)
- }
- }
- if req, _ := retire.Input["required"].([]string); !reflect.DeepEqual(req, []string{"why"}) {
- t.Errorf("retire-history requires %v, wanted only why", req)
- }
- var without []string
- for _, v := range VerbNames(seat.Serves) {
- if v != "retire-history" {
- 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 retire-history yet: %v", err)
- }
- m.Claims[0].Serves = VerbNames(seat.Serves)
- if err := CanHold(m, seat); err != nil {
- t.Fatalf("a holder serving retire-history: %v", err)
- }
-}
-
-// The seat says delivery times (novox/hq ADR 0282, issue 382): `times`, over some days or for one delivery. Added
-// after the holder shipped, it is optional, so the holder that does not serve it yet still holds the seat, and one
-// that does is not refused for a verb the seat lacks.
-func TestTheDeliverySeatPromisesTimesOptionally(t *testing.T) {
- seat, _ := SeatNamed(DeliverySeat)
- var times *Verb
- for i := range seat.Serves {
- if seat.Serves[i].Name == "times" {
- times = &seat.Serves[i]
- }
- }
- if times == nil || !times.Optional {
- t.Fatalf("the delivery seat promises %v, times optionally", VerbNames(seat.Serves))
- }
- props, _ := times.Input["properties"].(map[string]any)
- for _, arg := range []string{"days", "id"} {
- if _, has := props[arg]; !has {
- t.Errorf("times takes no %q", arg)
- }
- }
- var without []string
- for _, v := range VerbNames(seat.Serves) {
- if v != "times" {
- 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 times yet: %v", err)
- }
- m.Claims[0].Serves = VerbNames(seat.Serves)
- if err := CanHold(m, seat); err != nil {
- t.Fatalf("a holder serving times: %v", err)
- }
-}
-
-// The seat still promises `mark-ready`, optionally, for one more release (issue 1022); it was added by 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)
- }
-}
diff --git a/go/catalogue/verbs.go b/go/catalogue/verbs.go
index aad0f6d..2218d95 100644
--- a/go/catalogue/verbs.go
+++ b/go/catalogue/verbs.go
@@ -74,6 +74,29 @@ func VerbNames(verbs []Verb) []string {
return out
}
+// RemovedControllerVerbs are the controller seat's verbs release 6 removed (novox/hq ADR 0539, ADR 0429 §8): no
+// delivery plan, batch, tier or push exists, so nothing starts, stops, retries, follows or reads one. Each stays in
+// ControllerVerbs as a row with no input, so a caller is answered by name with its replacement, given here.
+var RemovedControllerVerbs = map[string]string{
+ "plans": "the delivery view (nox-delivery): each machine's want and have, read from the assigner's wants and the " +
+ "node-engine's haves",
+ "plan": "the node's compositions: mesh-controller_composed holds each module's digest and judgement per node, and " +
+ "mesh-compose prints one module's composition for one node",
+ "push": "a want: the assigner writes want.. by its rules, and by hand the operator's credential writes " +
+ "it, naming a kept composition (ADR 0539 clause 10)",
+ "deliver": "nothing to start: a merged change reaches each machine by its want",
+ "delivery-stop": "a bad fingerprint is held and its canary set back by the assigner (ADR 0429 §6, ADR 0539 clause 18)",
+ "delivery-backups-again": "the assigner's backup ask, answered on the phone or in the delivery view (ADR 0539 clause 16)",
+ "delivery-walks": "the delivery view (nox-delivery) and the wants, haves and compositions on the bus",
+ "delivery-order": "no order to keep: each module reaches its machines by its own want, its providers first by rule 5",
+}
+
+// removedInR6 is the row of a verb release 6 removed from the controller's seat: no input, refused by name.
+func removedInR6(name string) Verb {
+ return Verb{Name: name, Description: "Removed in R6 (ADR 0539): refused by name, naming its replacement: " +
+ RemovedControllerVerbs[name], Input: schema(nil, nil)}
+}
+
// ControllerSeatName is the seat the control plane holds, whose tools are the mesh's own verbs.
const ControllerSeatName = "mesh-controller"
@@ -115,87 +138,23 @@ var ControllerVerbs = []Verb{
"log": "a build's id (as `builds` lists it): print what the build machine said, line by line",
"limit": "how many builds to list (default 20); not with log",
}, nil)},
- {Name: "plans", Description: "What the last merges produced and where each stands (novox/hq ADR 0162): " +
- "the tiers, the tier a plan is at, what it waits for and since when; one plan whole, given its id; " +
- "or, given wait, one plan followed until it moves.",
- Input: schema(map[string]string{
- "id": "a plan's id (as `plans` lists them): that plan, tier by tier",
- "wait": "a plan's id: wait until it moves, then answer it as data — the plan, and what ended the wait " +
- "(moved, tier, done, or bound); ask again to follow it further (novox/hq issue 229)",
- "until": "with wait: moved (any change, the default), tier (it reaches another tier) or done (it ends)",
- "bound": "with wait: how long to wait at most, as 15s or seconds — 20s, the default, is the longest, " +
- "inside what a call is answered within",
- "stop": "a plan's id: stop it — what was asked still builds, nothing further is asked",
- "close": "a plan's id: close a plan that will not move again, as failed by hand (novox/hq issue 254)",
- "retry": "a failed plan's id: ask its failed builds again under new ids, and carry the plan on from that tier (novox/hq ADR 0219)",
- "go": "a walk's id that waits for its delivery's word: start it by hand, in place of mesh-delivery — with why, " +
- "recorded in the hand-act log (novox/hq ADR 0239)",
- "repository": "owner/repository: the plan a merge there would produce, saving nothing (what-if); with paths or modules",
- "paths": "with repository: the files the merge would change, comma-separated, from the repository's root",
- "modules": "with repository: or the modules it would change, comma-separated",
- "module-dirs": "with repository and paths: the directories holding a module.json at the commit, comma-separated, " +
- "as the forge's announcer says them (novox/hq issue 278); without it, a directory is a module only when the paths hold its manifest",
- "data": "with repository and paths: true answers the change plan as data, the document delivery-plan answers " +
- "(moved, dependents, new, tiers, machines with what each receives and waits for, steps, summary, class, head, base); " +
- "without it the answer is text (novox/hq ADR 0450 §2)",
- "head": "with data: the commit at hand",
- "base": "with data: the branch it merges into (default main)",
- "removed": "with data: the files among paths the change deletes, comma-separated",
- "limit": "how many plans to list (default 10); only when listing",
- "why": "with stop, close or go: why it is done by hand — required, and recorded in the hand-act log (novox/hq to-be 45 §7)",
- "cause": "with stop, close or go: the cause in a word, or a condition's kind (optional)",
- }, nil, "data")},
+ removedInR6("plans"),
// The verbs the delivery's owner asks with (novox/hq ADR 0239): the planner's answer, a group's order and
// composed check, and the start and end of a walk. Callable by a person too; mesh-delivery is who needs them.
{Name: "delivery-plan", Description: "Removed in R4e (ADR 0501 §5 / ADR 0503 §3): refused by name, naming its replacement",
Input: schema(nil, nil)},
- {Name: "delivery-order", Description: "A delivery group's order (novox/hq ADR 0419): its members in the order " +
- "they are delivered, every pair and why — built by, verb before caller, version skew, engine before " +
- "controller — read from the module graph and the manifests' change alone; no `after:` line is read. The " +
- "cycle, with every module and edge of it, is the one refusal.",
- Input: schema(map[string]string{"members": "the members, as JSON: [{id, repository, base, head, number, paths, " +
- "module_dirs, module_dirs_said, removed}]"}, []string{"members"})},
+ removedInR6("delivery-order"),
{Name: "delivery-check", Description: "Answers that the checker (mesh-delivery-checker) judges a group (novox/hq " +
"ADR 0503 §3); asks nothing. Its inputs stay, since hq's repository check still names it (ADR 0513 §4).",
Input: schema(map[string]string{"group": "the group's id (none for one head checked again)",
"members": "the members, as JSON, as delivery-order takes them",
"ready": "\"true\" when the pull request is marked ready: its check is queued before every other check (novox/hq ADR 0406 §3)"},
[]string{"members"})},
- {Name: "deliver", Description: "The delivery's word that a walk waiting for it may start (novox/hq ADR 0239): its " +
- "first tier is asked at the controller's next pass. Refused for a walk that waits for nobody.",
- Input: schema(map[string]string{"plan": "the walk's id", "why": "what lets it go: its turn, a person's release"},
- []string{"plan"})},
- {Name: "delivery-stop", Description: "End a walk on its delivery's word (novox/hq ADR 0239): failed, said as stopped " +
- "by whom and why; what it asked still builds and registers, nothing further is asked or sent. Given merges to " +
- "leave out, every other merge the walk answered is walked again — in the open batch of its kind, or a new one — " +
- "without them, without each later merge of their repository, which contains one, and without each merge moving " +
- "a module one moves, each left out too and named (novox/hq ADR 0299); a batch not yet cut drops the merges. The " +
- "answer names the batch, the merges walked again, the merges left out, the modules the stopped walk sent that " +
- "stay on their machines, and the merges elsewhere that will still deliver a stopped change.",
- Input: schema(map[string]string{"plan": "the walk's id", "why": "why", "by": "who stopped the delivery",
- "without": "merges to leave out, @, comma-separated"},
- []string{"plan", "why"})},
- {Name: "delivery-backups-again", Description: "Ask again the backups a walk was held for (novox/hq ADR 0404 " +
- "decision 4): a walk whose backup before its send failed or did not answer is held, nothing asked or sent; this " +
- "clears those failed backups and the next look at the plans asks them again, and only them. Refused for a walk " +
- "with no failed backup. The delivery's release calls it. The answer names the walk and the backups asked again.",
- Input: schema(map[string]string{"plan": "the held walk's id", "why": "a person's reason, as release passes it",
- "by": "who released the delivery"}, []string{"plan", "why"})},
- {Name: "delivery-walks", Description: "The walks the controller keeps (novox/hq ADR 0239): every open one and the " +
- "last ended ones, each whole — its tiers, each module's state, first machines and first-node gate with its readings, and its " +
- "phases from its merge to every machine running it (novox/hq ADR 0282) — and whether the delivery seat has a " +
- "holder on record. Given a plan, that one.",
- Input: schema(map[string]string{"plan": "one walk's id", "limit": "how many ended walks beside the open ones (default 50)"},
- nil)},
- {Name: "plan", Description: "What one machine would run, and why: the declaration the mesh would send it — " +
- "or, with files, the files it would be given; or, with diff, what a push would change there against what " +
- "it was last sent: resources added, removed and changed, a container's changed fields (it is recreated), " +
- "and any mount whose directory on the machine would move (novox/hq ADR 0217).",
- Input: schema(map[string]string{
- "node": "the machine's name",
- "files": "\"true\": the files this machine would be given, instead of the declaration as JSON",
- "diff": "\"true\": what a push would change on this machine, against what it was last sent; not with files",
- }, []string{"node"}, "files", "diff")},
+ removedInR6("deliver"),
+ removedInR6("delivery-stop"),
+ removedInR6("delivery-backups-again"),
+ removedInR6("delivery-walks"),
+ removedInR6("plan"),
{Name: "assign", Description: "Put a module on a machine. Refused with the mesh's own words when it cannot resolve there, " +
"or when a seat its resources are applied through is held by nothing on the machine (novox/hq ADR 0207). " +
"A module not registered yet is looked for (novox/hq issue 325, ADR 0261): while its build runs — a merge " +
@@ -221,22 +180,7 @@ var ControllerVerbs = []Verb{
}, []string{"node", "provision", "from", "module"})},
{Name: "unpin", Description: "Take that choice back, putting the question to the mesh again.",
Input: schema(map[string]string{"node": "the machine's name", "provision": "the provision"}, []string{"node", "provision"})},
- {Name: "push", Description: "Send one machine everything it should be. With no machine named it is a push of the " +
- "WHOLE mesh — every machine that is behind — and the answer says so first; behind says that outright. " +
- "Answers at once that it is running, with a call id: `calls` with that id says what it sent and, for a " +
- "machine named, how that machine applied it — applied, refused with its reason, or each failed resource — " +
- "once it reports within wait (a push can reload the bus, which then refuses any answer still to come). A push by hand is a repair, " +
- "and says why: recorded in the hand-act log (novox/hq to-be 45 §7). A machine whose push would give a " +
- "running module's data another directory is held and named, the others sent (novox/hq ADR 0217): read " +
- "`plan` with diff, and name the machine with move to send it.",
- Input: schema(map[string]string{
- "node": "the machine's name; without it, every machine that is behind",
- "move": "with node: the modules whose data may move with this push, comma-separated (optional)",
- "wait": "with node: how long the call waits for the machine to report how it applied what it was sent, as \"90s\" or \"2m\"; \"0\" waits for nothing; without it, the controller's setting push-wait (optional)",
- "behind": "\"true\": every machine that is behind, the whole mesh — the same as naming none, said outright; not with node",
- "why": "why this is pushed by hand: recorded in the hand-act log",
- "cause": "the cause in a word, or a condition's kind — the word a second push for the same reason uses (optional)",
- }, []string{"why"}, "behind")},
+ removedInR6("push"),
{Name: "rotate", Description: "Replace a credential. A pair credential, by provision (and a consuming machine and module, " +
"else every holder): both ends are re-sent together. Or a module's own secret, by machine, module and " +
"name: made anew and the machine sent, so the module starts again on it — for a secret its definition " +
@@ -457,26 +401,22 @@ var ControllerVerbs = []Verb{
"probe": "one probe's id (D14): its verdict alone, with every finding — the verdict shows at most twenty a probe",
}, nil, "run", "probes", "signals")},
// How a module's new builds reach its machines, and the bus's planned step (novox/hq ADR 0236).
- {Name: "upgrade", Description: "How each module's new builds reach its machines (novox/hq ADR 0236): rolled " +
- "out one machine first and judged there at the gate, then the rest — or recorded, waiting for a person's " +
- "push — with where that comes from (a person, the module, the bus, its irreplaceable data, the default) and " +
- "why. With module, that one; with policy, a person's choice for it — roll-out, record (with why) or default " +
- "to take the choice back. The bus is never rolled out.",
+ {Name: "upgrade", Description: "Whether each module's new builds wait for a person (novox/hq ADR 0236, ADR 0539 clause 14): " +
+ "for a module of policy record, the assigner writes no want naming a composition judged to recreate a container or move " +
+ "data until the operator answers its ask; with where the policy comes from (a person, the module, the bus, its " +
+ "irreplaceable data, the default) and why. With module, that one; with policy, a person's choice for it — roll-out, " +
+ "record (with why) or default to take the choice back. The bus is never moved by the assigner (ADR 0539 clause 15).",
Input: schema(map[string]string{
- "module": "one module",
- "policy": "with module: roll-out, record or default",
- "together": "\"true\": with roll-out, every machine at once instead of one machine first",
- "why": "with policy or release-backlog: why — required for record and for a release, kept",
- "backlog": "\"true\": every build waiting for a gate, per machine — what a release plan would send",
- "release-backlog": "\"true\": release what waits now, one machine at a time, each judged — after a release " +
- "plan failed, the mesh waits for this; with why",
- "cause": "with release-backlog: the cause in a word (optional)",
- }, nil, "together", "backlog", "release-backlog")},
- {Name: "bus", Description: "The bus as a planned step (novox/hq to-be 45 §8, ADR 0236): what a bus upgrade " +
- "would do — the bus's build on each machine against the one the mesh holds — and how the last step went. " +
- "With upgrade, start one: a person's act with why, after the streams are snapshotted (snapshot-taken says " +
- "where, while the mesh takes none itself), saying first whether it can be reverted; bus-maintenance is open " +
- "while it runs and every stream, consumer and a round trip are checked after.",
+ "module": "one module",
+ "policy": "with module: roll-out, record or default",
+ "why": "with policy: why — required for record, kept",
+ }, nil)},
+ {Name: "bus", Description: "The bus as a person's step (novox/hq to-be 45 §8, ADR 0236, ADR 0539 clause 15): what a bus " +
+ "upgrade would do — the bus's build on each machine against the one the mesh holds — and how the last step went. " +
+ "With upgrade, check one: a person's act with why, after the streams are snapshotted (snapshot-taken says where, " +
+ "while the mesh takes none itself), saying first whether it can be reverted; then it answers the want the operator " +
+ "writes with the operator's credential, want.., recorded — nothing is sent, and the assigner never " +
+ "moves the bus.",
Input: schema(map[string]string{
"upgrade": "\"true\": start the bus's upgrade",
"why": "with upgrade: why — required, recorded in the hand-act log",
diff --git a/go/catalogue/verbs_r6_test.go b/go/catalogue/verbs_r6_test.go
new file mode 100644
index 0000000..8e595db
--- /dev/null
+++ b/go/catalogue/verbs_r6_test.go
@@ -0,0 +1,103 @@
+package catalogue
+
+import (
+ "strings"
+ "testing"
+)
+
+// 1943/AC4: the controller's seat no longer offers a verb that starts, stops, retries, follows or reads a delivery
+// plan, nor a push: each is a row with no input whose description refuses it by name and names its replacement, and
+// each is in the removed list the holder answers from. upgrade keeps its policy and drops the plan's backlog.
+func TestTheControllerSeatHasNoPlanVerbs(t *testing.T) {
+ rows := map[string]Verb{}
+ for _, v := range ControllerVerbs {
+ rows[v.Name] = v
+ }
+ gone := []string{"plans", "plan", "push", "deliver", "delivery-stop", "delivery-backups-again", "delivery-walks", "delivery-order"}
+ for _, name := range gone {
+ v, ok := rows[name]
+ if !ok {
+ t.Errorf("%s is not in the table, so a caller is not answered by name", name)
+ continue
+ }
+ replacement, removed := RemovedControllerVerbs[name]
+ if !removed || replacement == "" {
+ t.Errorf("%s is not in the removed list with its replacement", name)
+ }
+ if !strings.HasPrefix(v.Description, "Removed in R6 (ADR 0539): refused by name") || !strings.Contains(v.Description, replacement) {
+ t.Errorf("%s = %q, want refused by name, naming %q", name, v.Description, replacement)
+ }
+ if props, _ := v.Input["properties"].(map[string]any); len(props) > 0 {
+ t.Errorf("%s still takes %v", name, props)
+ }
+ }
+ props, _ := rows["upgrade"].Input["properties"].(map[string]any)
+ for _, arg := range []string{"together", "backlog", "release-backlog", "cause"} {
+ if _, has := props[arg]; has {
+ t.Errorf("upgrade still takes %s, a plan's", arg)
+ }
+ }
+ for _, arg := range []string{"module", "policy", "why"} {
+ if _, has := props[arg]; !has {
+ t.Errorf("upgrade no longer takes %s", arg)
+ }
+ }
+ for _, word := range []string{"rolled", "gate", "backlog", "push"} {
+ if strings.Contains(rows["upgrade"].Description, word) {
+ t.Errorf("upgrade's description still speaks of %q: %q", word, rows["upgrade"].Description)
+ }
+ }
+ if !strings.Contains(rows["bus"].Description, "want") {
+ t.Errorf("bus does not say the operator writes the bus's want: %q", rows["bus"].Description)
+ }
+ for name := range RemovedControllerVerbs {
+ if v := rows[name]; !strings.HasPrefix(v.Description, "Removed in R6") {
+ t.Errorf("%s is in the removed list and its row says %q", name, v.Description)
+ }
+ }
+}
+
+// 1943/AC4: the delivery seat keeps the merge's verbs and no longer offers times, what-if, release, stop or
+// retire-history: each is a row with no input, optional so the holder of before and the holder of release 6 both hold
+// the seat, refusing it by name; mark-ready, served by nobody since issue 1022, is gone.
+func TestTheDeliverySeatHasNoPlanVerbs(t *testing.T) {
+ seat, ok := SeatNamed(DeliverySeat)
+ if !ok {
+ t.Fatal("the delivery seat is not in the set")
+ }
+ rows := map[string]Verb{}
+ for _, v := range seat.Serves {
+ rows[v.Name] = v
+ }
+ for _, name := range []string{"times", "what-if", "release", "stop", "retire-history"} {
+ v, ok := rows[name]
+ replacement, removed := RemovedDeliveryVerbs[name]
+ if !ok || !removed || replacement == "" {
+ t.Errorf("%s: in the table %v, in the removed list %v", name, ok, removed)
+ continue
+ }
+ if !strings.HasPrefix(v.Description, "Removed in R6 (ADR 0539): refused by name") || !strings.Contains(v.Description, replacement) || !v.Optional {
+ t.Errorf("%s = %q (optional %v), want an optional row refusing it by name", name, v.Description, v.Optional)
+ }
+ if props, _ := v.Input["properties"].(map[string]any); len(props) > 0 {
+ t.Errorf("%s still takes %v", name, props)
+ }
+ }
+ if _, ok := rows["mark-ready"]; ok {
+ t.Errorf("mark-ready is still promised")
+ }
+ for _, kept := range []string{"deliveries", "show", "groups", "checks", "table", "recheck", "close", "stalled"} {
+ if v, ok := rows[kept]; !ok || strings.HasPrefix(v.Description, "Removed") {
+ t.Errorf("%s is not kept (ADR 0539 clause 17)", kept)
+ }
+ }
+ gate := Manifest{Module: "mesh-delivery", Claims: []Claim{{Name: DeliverySeat, Scope: ScopeMesh,
+ Serves: []string{"deliveries", "show", "groups", "checks", "table", "stalled", "recheck", "close"}}}}
+ if err := CanHold(gate, seat); err != nil {
+ t.Errorf("the gate of release 6 cannot hold the seat: %v", err)
+ }
+ gate.Claims[0].Serves = append(gate.Claims[0].Serves, "times", "what-if", "release", "stop", "retire-history")
+ if err := CanHold(gate, seat); err != nil {
+ t.Errorf("the gate of release 5 cannot hold the seat: %v", err)
+ }
+}