Files
hq/04-ISSUES/244-a-verb-whose-schema-is-empty-cannot-be-called-through-the-console/01-diagnosis.md
T
jochen 3ee27b870d Issue 244: located — the console drops a mesh seat's node, and a push ran on every machine
The same empty schemas recurred for push, plan, assign, pin and settings;
for push the dropped machine became a push of the whole mesh. Record the
evidence, the cause in the console's address form, and the open fixes.
2026-10-06 00:38:37 +02:00

4.3 KiB

Diagnosis

2026-10-06

The schema is not empty where it is kept. The controller's verb table declares node for every verb that acts on a machine, and so does the seat's record: asked through the console, mesh-controller.tools answers push, plan, assign, pin and settings each with node among their properties. The controller's announcement on the bus carries the same schemas. So the controller publishes them whole, and the loss is after it.

The console takes node out of every schema and every call. The console's address grammar (ADR 0195) puts the machine in the address for a seat held on every machine (<node>/<seat>.<verb>) and for a module on one machine (<node>/<module>.<tool>), and so describes those tools without a node argument and deletes one from their calls. It did both for every address — including a seat held once for the mesh, where there is no machine in the address and node is the verb's own argument: the machine the verb acts on. That is exactly the set observed: each verb lost node and nothing else, push and plan had nothing else and described as empty, and the verbs that take no machine (build, queue) were untouched. The older flat listing of the same console had this right (it kept a mesh seat's schema as declared); the address form did not carry the distinction over.

Why the verb then refused, or did the wrong thing. The controller's verbs read the arguments they know and ignore the rest. Given nothing, plan and node said they needed node; push, whose node is optional, read its absence as "every machine behind" and did that. A verb that ignores what it does not read cannot tell "nothing was asked" from "something was lost on the way".

Ruled out.

  • A stale seat record. The record is older than the controller's current source (some verbs lack arguments added since), but it carries node wherever the source does.
  • The controller's announcement. It sends the record's schema per verb, unchanged.

Located in mesh-tools (the console: the schema it describes and the arguments it sends) and mesh-controller (verbs that pass over what they are given).

What the fix does, and how it is checked

Pull requests: novox/mesh-tools#14 and novox/mesh-controller#71 — open, not merged.

  • The console takes node out only where the address names the machine. There, a node naming the same machine is redundant and dropped; one naming another machine is refused. A call to a seat's verb carrying an argument the verb does not declare is refused, naming it — the seat's record is the mesh's own description of the verb, so the console can judge it.
  • The controller refuses, naming the argument: one the verb does not declare; one it declares but did not use for the command it composed (two arguments where one wins, or half of a two-argument shape); a switch that is neither "true" nor "false". A push that names no machine says, as the first line of its answer, that it is a push of the whole mesh and which machines it is sending, and its last line names the machines told. plan gains files, push gains behind (the whole mesh said outright, refused beside node), and the listing verbs a limit.
  • Checked by tests that walk every verb the controller announces: for every combination of a verb's declared arguments, the verb either refuses or every argument given changes the command it runs; every verb refuses an argument it does not declare, and node where it takes none; and every flag of the command a verb runs — read from the command's own source — is an argument of the verb's schema or is listed, with the reason, as set by the verb or withheld from it. A verb added later, or a flag added to a command, fails these until its schema says how a caller reaches it.

What the tests do not check is the console's own describe-and-call path against a live bus; its unit test covers the choice of when node is the address's and when it is the verb's.

Issue 259 is another way a named push reached every machine: there the machine arrived and the controller's flush after it sent the others. Different cause, same reader's harm — the answer of a push is the only place that says how far it went, which is why the whole-mesh line is in the answer.