Say what each verb replaces, so the agent is pointed at it instead of a shell command (hq ADR 0245)
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer delivery to the same trunk took over its walk
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer delivery to the same trunk took over its walk
A seat's verb names the shell commands it is the mesh's way to do, and a module says it for its own tools in its manifest; the tools verb and module list --json carry both, for the mesh MCP server's search, the agent's instructions and the guard on its shell.
This commit is contained in:
@@ -182,6 +182,9 @@ func moduleCommand(ctx context.Context, args []string) error {
|
||||
Requires []string `json:"requires,omitempty"`
|
||||
Claims []string `json:"claims,omitempty"`
|
||||
Capabilities []string `json:"capabilities,omitempty"`
|
||||
// Replaces is what each of its own tools replaces (novox/hq ADR 0245), for the console's
|
||||
// search and the agent's instructions.
|
||||
Replaces map[string][]string `json:"replaces,omitempty"`
|
||||
}
|
||||
out := make([]listed, 0, len(entries))
|
||||
for _, e := range entries {
|
||||
@@ -189,7 +192,7 @@ func moduleCommand(ctx context.Context, args []string) error {
|
||||
l := listed{Module: m.Module, Version: m.Version, Built: e.Source.BuiltFrom, Head: e.Source.Head,
|
||||
Current: e.Provided || e.Source.Repository == "" || e.Source.Current(), Provided: e.Provided,
|
||||
On: append([]string{}, e.On...), Provides: m.Offers(), Requires: m.Requires,
|
||||
Capabilities: m.Capabilities, Tools: declaresTools(m)}
|
||||
Capabilities: m.Capabilities, Tools: declaresTools(m), Replaces: m.Replaces}
|
||||
for _, c := range m.Claims {
|
||||
l.Claims = append(l.Claims, c.At()+"/"+c.Name)
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ func planFor(ctx context.Context, open *stores, nodeName string) (catalogue.Reso
|
||||
}
|
||||
|
||||
// A recorded module is composed at the build this machine runs, on any send but a person's push
|
||||
// (novox/hq issue 295, ADR 0242).
|
||||
// (novox/hq issue 295, ADR 0245).
|
||||
if _, err := keepRecorded(ctx, open, nodeName, shelf); err != nil {
|
||||
return catalogue.Resolution{}, nil, err
|
||||
}
|
||||
@@ -439,7 +439,7 @@ func declarationWith(ctx context.Context, open *stores, node string,
|
||||
names = append(names, m.Module)
|
||||
}
|
||||
out.Builds = carriedBuilds(names, composed.LeftOut, current, before)
|
||||
// A recorded module kept at the build the machine runs is recorded as carrying that one (ADR 0242).
|
||||
// A recorded module kept at the build the machine runs is recorded as carrying that one (ADR 0245).
|
||||
kept, err := recordedKept(ctx, open, node)
|
||||
if err != nil {
|
||||
return sendable{}, err
|
||||
|
||||
@@ -1082,7 +1082,7 @@ func sendToEach(ctx context.Context, open *stores, names []string) ([]string, er
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// **A recorded build moves only by a person's push** (novox/hq issue 295, ADR 0242): this send — a
|
||||
// **A recorded build moves only by a person's push** (novox/hq issue 295, ADR 0245): this send — a
|
||||
// plan's, a release plan's, a rollback's, a healer's, a rotation's — composes every recorded module at
|
||||
// the build its machine runs. The bus step is a person's word for the bus alone.
|
||||
if ctx, err = sendKeeps(ctx, inv); err != nil {
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/novox/mesh-controller/internal/inventory"
|
||||
)
|
||||
|
||||
// A recorded build reaches a machine only by a person's push (novox/hq issue 295, ADR 0242).
|
||||
// A recorded build reaches a machine only by a person's push (novox/hq issue 295, ADR 0245).
|
||||
//
|
||||
// **A send carries the machine's whole declaration** (ADR 0221), composed from the build the mesh holds
|
||||
// of every module on it. A module whose upgrade policy records — postgres, mongodb, keycloak, the
|
||||
@@ -121,7 +121,7 @@ func keepRecorded(ctx context.Context, open *stores, node string, shelf map[stri
|
||||
if !found {
|
||||
return nil, fmt.Errorf("%s records rather than rolls out, and %s runs its build %s, which the build "+
|
||||
"records no longer hold: this send cannot keep it and does not move it — `push %s` sends the new "+
|
||||
"one on a person's word (novox/hq ADR 0242)", m, node, short(kept[m]), node)
|
||||
"one on a person's word (novox/hq ADR 0245)", m, node, short(kept[m]), node)
|
||||
}
|
||||
shelf[m] = ran
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/novox/mesh-controller/internal/link"
|
||||
)
|
||||
|
||||
// A recorded build reaches a machine only by a person's push (novox/hq issue 295, ADR 0242).
|
||||
// A recorded build reaches a machine only by a person's push (novox/hq issue 295, ADR 0245).
|
||||
|
||||
// aContainerBuild is a build outcome of a module of containers, each named by id with the image and the
|
||||
// health it is given; a policy when one is said.
|
||||
@@ -189,7 +189,7 @@ func TestARecordedBuildIsCarriedOnlyByAPersonsPush(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// The send says what it recreates (ADR 0242): mail's health checks adopted recreate both its
|
||||
// The send says what it recreates (ADR 0245): mail's health checks adopted recreate both its
|
||||
// containers, with no new image, every one at once.
|
||||
func TestASendSaysWhatItRecreates(t *testing.T) {
|
||||
image := "registry.invalid:5000/mailu/smtp@sha256:" + strings.Repeat("c", 64)
|
||||
|
||||
@@ -671,7 +671,7 @@ func backlogCommand(ctx context.Context, sub string, args []string) error {
|
||||
}
|
||||
|
||||
// sayRecreations says, on each move a send carries, what it does to the module's containers (novox/hq
|
||||
// ADR 0242): the build the machine ran against the one it is sent, container by container. Left unsaid
|
||||
// ADR 0245): the build the machine ran against the one it is sent, container by container. Left unsaid
|
||||
// for a move whose earlier build is not in the records.
|
||||
func sayRecreations(ctx context.Context, open *stores, moves []inventory.CarriedMove) {
|
||||
if len(moves) == 0 {
|
||||
|
||||
@@ -904,7 +904,7 @@ func firstSend(ctx context.Context, open *stores, p *inventory.Plan, node string
|
||||
strings.Join(sent, ", "))
|
||||
fmt.Printf("%s: tier %d built; sent %d module(s) to %s first in one send (%s), the rest once its gate passes\n",
|
||||
p.ID, p.Tier, len(modules), strings.Join(sent, ", "), strings.Join(modules, ", "))
|
||||
// What the send recreates, said with it (novox/hq ADR 0242).
|
||||
// What the send recreates, said with it (novox/hq ADR 0245).
|
||||
if said := recreationsSaid(carried); said != "" {
|
||||
p.Note += "; " + said
|
||||
fmt.Printf("%s: %s\n", p.ID, said)
|
||||
@@ -1287,7 +1287,7 @@ func plansCommand(ctx context.Context, args []string) error {
|
||||
case s != nil && s.Gate != nil:
|
||||
fmt.Printf(" %-22s %s\n", "", gateLine(s.Gate))
|
||||
}
|
||||
// What the send to its first machine did to its containers (ADR 0242).
|
||||
// What the send to its first machine did to its containers (ADR 0245).
|
||||
if s != nil && s.Gate != nil {
|
||||
for _, c := range s.Gate.Carried {
|
||||
if c.Recreates != "" {
|
||||
|
||||
@@ -970,9 +970,15 @@ func seatTools() map[string]any {
|
||||
}
|
||||
var tools []map[string]any
|
||||
for _, v := range s.Serves {
|
||||
tools = append(tools, map[string]any{
|
||||
tool := map[string]any{
|
||||
"name": v.Name, "description": v.Description, "input": v.Input, "output": v.Output,
|
||||
})
|
||||
}
|
||||
// What the verb is the mesh's way to do (novox/hq ADR 0245): read by the console's search and
|
||||
// the agent's instructions.
|
||||
if len(v.Replaces) > 0 {
|
||||
tool["replaces"] = v.Replaces
|
||||
}
|
||||
tools = append(tools, tool)
|
||||
}
|
||||
seats = append(seats, map[string]any{"seat": s.Name, "scope": s.Scope, "tools": tools})
|
||||
}
|
||||
|
||||
@@ -144,6 +144,23 @@ func TestToolsAnswersTheSeatsRecords(t *testing.T) {
|
||||
if !found {
|
||||
t.Fatal("the mesh-controller seat is not in the listing")
|
||||
}
|
||||
// And what a verb replaces travels with it (novox/hq ADR 0245): the console and the agent's
|
||||
// instructions read it from here.
|
||||
var journal []string
|
||||
for _, s := range seats {
|
||||
if s["seat"] != catalogue.ServiceManagerSeat {
|
||||
continue
|
||||
}
|
||||
tools, _ := s["tools"].([]map[string]any)
|
||||
for _, tool := range tools {
|
||||
if tool["name"] == "journal" {
|
||||
journal, _ = tool["replaces"].([]string)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(journal) == 0 || journal[0] != "journalctl" {
|
||||
t.Fatalf("the service manager's journal does not say it replaces journalctl: %v", journal)
|
||||
}
|
||||
}
|
||||
|
||||
// A JSON verb's answer is parsed from what the command wrote to standard output alone; a warning it
|
||||
|
||||
Reference in New Issue
Block a user