mesh-cli: say an outcome not known, and hold the module to placing one file (review of hq ADR 0272)
mesh/merge-gate pass: builds claude-code, route-adapter, new: modules/mesh-cli → ace, g14, novox, shanks; no bus step; every machine composes with the chan…
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery delivered
mesh/merge-gate pass: builds claude-code, route-adapter, new: modules/mesh-cli → ace, g14, novox, shanks; no bus step; every machine composes with the chan…
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery delivered
A line whose answer did not come in time is said as possibly run, with its call, never as nothing having run. A test holds the module to one archive resource unpacking one compiled Go bundle into /usr/local/bin. The README says the MESH_VERB refusal is a courtesy and the controller is the gate. SDK pinned at the go/cli branch's newest commit until go/v0.1.9.
This commit is contained in:
@@ -35,9 +35,11 @@ everywhere say `mesh-cli`. In interactive zsh the alias hides any other `nox` (A
|
||||
It meets every refusal of the generic `command` verb, and a change made at the terminal alone is refused with
|
||||
the reason.
|
||||
- **refused**: any other account, root included. Run it as yourself, not under `sudo`.
|
||||
3. `mesh-cli` prints standard output and standard error as the command wrote them, says why a line was not the
|
||||
terminal or was refused, says when the output was cut to fit one bus message, and exits with the command's
|
||||
status.
|
||||
3. A line still running after ten seconds is followed by its call until it ends. `mesh-cli` prints standard
|
||||
output and standard error as the command wrote them, says why a line was not the terminal or was refused, says
|
||||
when the output was cut to fit one bus message, and exits with the command's status. When no answer comes in
|
||||
time it says the line may have run and names its call; "nothing ran" is said only of a line no controller
|
||||
took.
|
||||
|
||||
A process that runs for a verb (it carries `MESH_VERB`) is refused before anything is asked: a verb is never the
|
||||
operator.
|
||||
@@ -49,11 +51,14 @@ operator.
|
||||
Give settings inline: `nox settings set <module> "$(cat settings.json)" --node <node>`.
|
||||
- **No streaming.** The answer arrives when the command ends, within the controller's bound on a call (five
|
||||
minutes). Interrupting `mesh-cli` stops the wait, not the command.
|
||||
- **The `MESH_VERB` refusal is a courtesy.** A verb's process is refused before asking, but the gate is the
|
||||
controller: it judges the account the node-engine vouches for, whatever the program says.
|
||||
- **No other node is the terminal.** Phase 2 of ADR 0272 adds a node whose agents run under an account of their
|
||||
own (ADR 0266), judged unable to become root.
|
||||
|
||||
## Tests
|
||||
|
||||
`go test ./...`: the line is asked as given and the answer printed with its exit; a reason, a refusal and a cut
|
||||
`go test ./...`: the module places exactly one file (one archive resource, one Go bundle compiled to the binary
|
||||
alone); the line is asked as given and the answer printed with its exit; a reason, a refusal, a cut and an outcome not known
|
||||
are said and a refusal never exits 0; a verb's process is refused before asking; an engine that does not answer
|
||||
is said.
|
||||
|
||||
@@ -69,6 +69,13 @@ func run(ctx context.Context, args []string, stdout, stderr io.Writer) int {
|
||||
if !a.Terminal && a.Why != "" {
|
||||
fmt.Fprintln(stderr, "mesh-cli: "+a.Why)
|
||||
}
|
||||
if a.Unknown != "" {
|
||||
// Asked, and what came of it not known: never said as nothing having run.
|
||||
fmt.Fprintln(stderr, "mesh-cli: "+a.Unknown)
|
||||
if a.Exit == 0 {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
if a.Refused != "" {
|
||||
fmt.Fprintln(stderr, "mesh-cli: "+a.Refused)
|
||||
if a.Exit == 0 {
|
||||
|
||||
@@ -93,3 +93,14 @@ func TestAnEngineThatDoesNotAnswerIsSaid(t *testing.T) {
|
||||
t.Fatalf("exit %d, said %q", code, errOut.String())
|
||||
}
|
||||
}
|
||||
|
||||
// An outcome not known is said as such — the line may have run — and never as nothing having run.
|
||||
func TestAnOutcomeNotKnownIsSaid(t *testing.T) {
|
||||
t.Setenv("MESH_VERB", "")
|
||||
engine(t, cli.NotKnown("call-4", "no answer within 6m0s"))
|
||||
var out, errOut bytes.Buffer
|
||||
code := run(context.Background(), []string{"push", "laptop"}, &out, &errOut)
|
||||
if code == 0 || !strings.Contains(errOut.String(), "may have run") || !strings.Contains(errOut.String(), "call-4") {
|
||||
t.Fatalf("exit %d, said %q", code, errOut.String())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// **The archive places exactly one file, /usr/local/bin/mesh-cli** (review of novox/hq ADR 0272): one archive
|
||||
// resource, unpacking one artifact into /usr/local/bin, and that artifact a compiled Go bundle — the builder writes
|
||||
// such a bundle as its binary alone (`go build -o <out>/<binary>`), named mesh-cli — with nothing the runtime would
|
||||
// load or put beside it. A second file in the bundle, or a second resource writing there, fails here.
|
||||
func TestTheArchivePlacesExactlyOneFile(t *testing.T) {
|
||||
raw, err := os.ReadFile("../../module.json")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var m struct {
|
||||
Resources []map[string]any `json:"resources"`
|
||||
Build struct {
|
||||
Artifacts []map[string]any `json:"artifacts"`
|
||||
} `json:"build"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &m); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(m.Resources) != 1 {
|
||||
t.Fatalf("the module declares %d resources; it places one file", len(m.Resources))
|
||||
}
|
||||
r := m.Resources[0]
|
||||
if r["type"] != "archive" || r["path"] != "/usr/local/bin" {
|
||||
t.Fatalf("its resource is %v", r)
|
||||
}
|
||||
if len(m.Build.Artifacts) != 1 {
|
||||
t.Fatalf("it builds %d artifacts", len(m.Build.Artifacts))
|
||||
}
|
||||
a := m.Build.Artifacts[0]
|
||||
if a["name"] != r["artifact"] || a["kind"] != "bundle" || a["language"] != "go" || a["binary"] != "mesh-cli" ||
|
||||
a["from"] != "cmd/mesh-cli" {
|
||||
t.Fatalf("its artifact is %v, unpacked as %v", a, r["artifact"])
|
||||
}
|
||||
for _, extra := range []string{"loads", "env", "context", "files"} {
|
||||
if _, has := a[extra]; has {
|
||||
t.Fatalf("its artifact says %q, which would put more than the binary in the bundle or load it", extra)
|
||||
}
|
||||
}
|
||||
entries, err := os.ReadDir(".")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, e := range entries {
|
||||
if e.IsDir() {
|
||||
t.Fatalf("cmd/mesh-cli holds a directory %s, which a build could carry into the bundle", e.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,4 +2,4 @@ module mesh-cli
|
||||
|
||||
go 1.22
|
||||
|
||||
require git.novox.be/novox/mesh-sdk/go v0.1.8-0.20261009100314-bfe82315f42c
|
||||
require git.novox.be/novox/mesh-sdk/go v0.1.8-0.20261009103748-a5a040c9049b
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.8-0.20261009100314-bfe82315f42c h1:8hjQ3FYt7mGdZv+HX0Vk+n3pdaS3W5EIlwsrvSXXhRY=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.8-0.20261009100314-bfe82315f42c/go.mod h1:GFuZUElBZ9A++mxgIKo97aXXo+kV0uJ/UkbhQPPIbrY=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.8-0.20261009103748-a5a040c9049b h1:HmasScQ02QeFlAFDnmRCOEserbtDJJtutK+acBmGlNs=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.8-0.20261009103748-a5a040c9049b/go.mod h1:GFuZUElBZ9A++mxgIKo97aXXo+kV0uJ/UkbhQPPIbrY=
|
||||
|
||||
Reference in New Issue
Block a user