Say in every declaration the assignment generation it came from, and record every send (hq issue 234)
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

A declaration newer in sequence than every other named four fewer modules
than the assignments held, a machine applied it, and nothing the mesh kept
said who sent it or from what view. The store now raises an assignment
generation in the same transaction as every assignment change (a trigger,
so a cascade counts too); a send reads it before composing, carries it to
engines that said they read it, marks a gate's put-back, and is recorded
with its sequence, sender, generation and modules. The would-send is
stamped with what was last sent, so nothing reads behind for it; a refusal
is kept on the send it refused and raised as S20 naming the sender; plan
says what the machine was last told.
This commit is contained in:
2026-10-11 11:30:16 +02:00
parent 72fde0ee1a
commit 313efa826c
20 changed files with 889 additions and 12 deletions
+25
View File
@@ -27,6 +27,25 @@ type sendable struct {
// said it reads one is sent none, because an older node-engine refuses a key it does not know, whole
// (link/order.go, the contract).
Epoch uint64
// Generation is the assignment generation it was composed from (novox/hq issue 234): a machine that
// applied a later one refuses it, so a send composed from a view of the assignments the mesh has moved
// past cannot undeclare what is still assigned. Zero is not sent at all — every machine whose
// node-engine has not said it reads one is sent none, for the reason the epoch is not (an older
// node-engine refuses a key it does not know, whole).
Generation int64
// PutBack marks a gate's put-back (novox/hq issue 234): it carries the generation of what it puts
// back and is not refused for it. Sent only beside a generation.
PutBack bool
// composedFrom is the generation read before this declaration was composed, and actingEpoch the
// lease epoch its sender acted under — whether or not the machine is sent either — for the record of
// the send; never on the wire.
composedFrom int64
actingEpoch uint64
// putBackSend is whether a gate sent it to put the machine back, for the record; PutBack is the mark
// on the wire, only beside a generation.
putBackSend bool
// modules are the modules this declaration names, for the record of the send; never on the wire.
modules []string
// Adoption is nil for a converged node, and then the body is byte for byte what it was before
// adoption existed: an older host parses the envelope strictly and would refuse the key.
Adoption *adoptionEnvelope
@@ -94,6 +113,12 @@ func (s sendable) Body() ([]byte, error) {
if len(s.LeftOut) > 0 {
envelope["left_out"] = s.LeftOut
}
if s.Generation > 0 {
envelope["generation"] = s.Generation
if s.PutBack {
envelope["put_back"] = true
}
}
// 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".