Raise the mesh as it is in the gate, call a baseline that does not compose an error, and let a check run by hand as the seat runs it
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 head of the same pull request

The gate composed 0 of 4 machines with the change and without, and passed every change: the store it
raised held each module's bus credential but no account for it (issue 203's refusal), no outward links
(so no filter could be composed), and refused settings the mesh holds. Now the account is minted with
its credential, the facts carry each machine's outward links (a stand-in for an older snapshot), the
mesh's layers are kept as held, and a withheld path keeps a path's shape. A machine the mesh composes
that the gate cannot raise makes the verdict an error, never a pass; the verdict alone is on stdout.

A merge-check.sh that passed on an agent's machine failed on the build seat: a newer gofmt, siblings at
a feature branch, another user. `mesh-controller check-here` runs builder.Check with the ask the
controller would make, from facts that now name the toolchains and the refs cloned beside; a failed
script is said by what failed. (novox/hq issues 282, 283)
This commit is contained in:
jochen
2026-10-07 01:33:18 +02:00
parent 72d7802415
commit a011743c69
12 changed files with 640 additions and 31 deletions
+18 -2
View File
@@ -755,6 +755,18 @@ func profileFrom(raw []byte) ([]Capability, error) {
// this is a statement of the whole layer, so removing a key is done by leaving it out, which is
// the only way removing one could work at all.
func (i *Inventory) SetSettings(ctx context.Context, nodeName, module string, values map[string]any) error {
return i.setSettings(ctx, nodeName, module, values, true)
}
// KeepSettings records a layer the mesh already holds, as it holds it, without judging it alone: for a
// store raised from the facts snapshot (the merge gate), where the layers arrive one at a time and a
// mesh-wide layer that needs a machine's own value to compose would be refused before that machine's
// layer is there — though the mesh keeps both and composes. Composition still judges every layer.
func (i *Inventory) KeepSettings(ctx context.Context, nodeName, module string, values map[string]any) error {
return i.setSettings(ctx, nodeName, module, values, false)
}
func (i *Inventory) setSettings(ctx context.Context, nodeName, module string, values map[string]any, judge bool) error {
raw, err := json.Marshal(values)
if err != nil {
return err
@@ -762,8 +774,12 @@ func (i *Inventory) SetSettings(ctx context.Context, nodeName, module string, va
// Judged here, against the module's current definition, before it is kept (novox/hq ADR 0163,
// rule 6): a setting that cannot compose is refused where it is set, naming the node, the
// module, the layer and the key — never stored to refuse the whole machine where it is read.
if err := i.judgeSettings(ctx, nodeName, module, values); err != nil {
return err
if judge {
if err := i.judgeSettings(ctx, nodeName, module, values); err != nil {
return err
}
} else if _, err := i.declared(ctx, module); err != nil {
return fmt.Errorf("%w: %s", ErrNoSuchModule, module)
}
if nodeName == "" {
// A port is a fact about one machine (novox/hq ADR 0100). Refused here, in composition's