From e14b02991e8052649486ec2997029d72a589c1e0 Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 26 Sep 2026 23:40:04 +0200 Subject: [PATCH] The controller marks a deliberately-empty declaration owns_nothing (hq 127) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The host refuses an empty body unless told the emptiness is meant (mesh-host#29). When a node's declaration composes to no resources — which #77 now sends rather than skips — Body() sets owns_nothing, so the node applies it and drops what it last held. A declaration with resources never carries the marker. One test. --- cmd/mesh-controller/sendable.go | 6 ++++++ cmd/mesh-controller/sendable_test.go | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/cmd/mesh-controller/sendable.go b/cmd/mesh-controller/sendable.go index 8c282ac..fdebf7e 100644 --- a/cmd/mesh-controller/sendable.go +++ b/cmd/mesh-controller/sendable.go @@ -38,6 +38,12 @@ func (s sendable) Body() ([]byte, error) { if s.Adoption != nil { envelope["adoption"] = s.Adoption } + // An empty declaration is deliberate here — the node owns nothing the mesh put there + // (novox/hq issue 127) — and the host refuses an empty body unless it is told the emptiness + // is meant, so a truncated or mis-composed body is never mistaken for "own nothing". + if len(s.Resources) == 0 { + envelope["owns_nothing"] = true + } return json.Marshal(envelope) } diff --git a/cmd/mesh-controller/sendable_test.go b/cmd/mesh-controller/sendable_test.go index f831e34..73ce86c 100644 --- a/cmd/mesh-controller/sendable_test.go +++ b/cmd/mesh-controller/sendable_test.go @@ -355,3 +355,25 @@ func TestTheMachineSideOfAMappingIsMovedEverywhereTheNumberIsUsed(t *testing.T) t.Fatalf("the consumer is told the forge answers on %v", told) } } + +func TestAnEmptyDeclarationSaysOwnsNothing(t *testing.T) { + // The host refuses an empty body unless told the emptiness is meant (novox/hq issue 127). + body, err := sendable{}.Body() + if err != nil { + t.Fatal(err) + } + var env map[string]any + if err := json.Unmarshal(body, &env); err != nil { + t.Fatal(err) + } + if env["owns_nothing"] != true { + t.Fatalf("an empty declaration must mark owns_nothing; got %v", env) + } + // A declaration with resources does not carry the marker. + body, _ = sendable{Resources: []map[string]any{{"id": "x"}}}.Body() + var env2 map[string]any + _ = json.Unmarshal(body, &env2) + if _, present := env2["owns_nothing"]; present { + t.Fatalf("a non-empty declaration must not mark owns_nothing; got %v", env) + } +}