Each issue is resolved with its fix and a replay or the reason none exists, or re-checked against main and the live mesh on 2026-10-08.
5.0 KiB
status, opened, located-in, fixed-by, replay-none, amended-design
| status | opened | located-in | fixed-by | replay-none | amended-design | ||
|---|---|---|---|---|---|---|---|
| resolved | 2026-10-05 |
|
novox/mesh-controller PR | opened and fixed before ADR 0237 made a replay a condition of resolving; the fix's own tests, named above, guard it, but none was laid over the commit before the fix and registered, and doing so now would be a new test written after the fact rather than a replay; the controller's schema tests walk every verb it serves, so a verb added later fails them |
244 — A verb whose published schema is empty cannot be called through the console, and says only that it needs the argument it will not take
What was observed
Through the console, 2026-10-05, composing one machine's declaration before pushing it:
mesh_describe mesh-controller.plan
→ {"properties": {}, "type": "object"} ... it takes nothing
mesh_call mesh-controller.plan {}
→ plan failed: plan needs "node" ... it takes something
mesh_call mesh-controller.plan {"node": "novox"}
→ plan failed: plan needs "node" ... and not that
mesh-controller.node describes the same way and behaves the same way. Both are listed in the
node's own instructions as the mesh's verbs, so they are the first thing a session reaches for.
The verb is not broken where it runs: the same plan novox --json through the machine's login
shell answers in full. What cannot be done is calling it through the console, which the
node's instructions say is the only way to the mesh.
Why
Not diagnosed past the symptom, and the symptom is specific enough to place it: the published schema declares no properties, and an argument that is not in the schema does not reach the verb. So the verb reports a missing argument that the console has dropped, every time, whatever is sent. The two halves are each defensible — publish a schema, honour it — and together they make a verb that can only refuse.
Why it matters beyond this instance
A tool that cannot be called is worse than one that is absent, because it is listed. It
appears in mesh_overview, it describes itself, and the only thing it will say is that it wants
something it will not accept. A reader has no way to tell that from their own mistake, and the
obvious next move — pass the argument it names — is the one that does not work.
It also marks what the console does not check. Nothing compares a verb's published schema against the arguments the verb actually requires, so a verb can be published in a shape that makes it uncallable and nothing says so. That is the shape of an unenforced rule: the schema is believed, and it is wrong.
What a fix has to settle
- Where the schema for a seat's verbs comes from, and why these two publish an empty one while
the verbs beside them (
status,builds,push) take their arguments and answer. - Whether the console should refuse to publish a verb whose schema cannot satisfy it, rather than listing one that can only fail.
- How it is checked: every verb the console lists is callable with the arguments its own schema describes — a test that calls each with its schema's required set and asserts the answer is not "needs" an argument the schema does not have.
Seen again, 2026-10-05 and 2026-10-06 — and once it did harm
The same picture for more of the mesh's own verbs, read through the console:
mesh_describe mesh-controller.push → {"properties": {}}
mesh_describe mesh-controller.plan → {"properties": {}}
mesh_describe mesh-controller.assign → module only, no node
mesh_describe mesh-controller.pin → provision, from, module — no node
mesh_describe mesh-controller.settings → module, values, clear — no node
build and queue, which take no machine, described in full. For plan this is the refusal above.
For push it was worse than a refusal: a push takes no required argument, so a call naming one
machine arrived empty, ran as a push of every machine behind, and answered "N node(s) told" — an
operator who believed they had pushed one machine had pushed the mesh. Nothing in the answer said the
machine had been lost.
The diagnosis is in 01-diagnosis.md.
Worked around, for now
Through <node>/node-login-shell.execute, running the controller's own command line on the
machine. That is the path the console exists to replace, so it is a workaround and not an answer.
Resolved — 2026-10-08
Both pull requests named above are merged and live. Read through the console on 2026-10-08:
mesh_describe mesh-controller.plan declares node (required) and files; mesh-controller.push
declares node, behind, cause and why, and its description says that a push naming no machine
is a push of the whole mesh. The controller's seatverbs_schema_test.go walks every verb it serves:
an argument a verb does not declare is refused, and every flag of a verb's command is in its schema
or accounted for.