The condition keeper stops watching the controller's conditions (ADR 0564 clause 9)

The keeper watches the controller's lease alone; the watch of mesh-controller.conditions, its constant and its manifest
read are gone, so no condition is carried from the controller's bucket any more. The manifest test now refuses that read.
The carry code in the keeper (Controller, the compare tool) stays, unfed, until the controller is removed. No test
added.

(issue 774, 774/S8)

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
2026-11-02 00:13:19 +01:00
parent 4497f26257
commit c1a32b4385
4 changed files with 9 additions and 17 deletions
@@ -1,8 +1,8 @@
package main
// The condition keeper (novox/hq ADR 0564 clauses 2, 3, 7, 8, 9 and 13; issue 1952 C2, C3, C7): the one writer of the
// mesh's open conditions. It watches every observer's `findings`, the healers' `attempts`, the controller's lease and,
// until the lease write, the controller's `conditions`, and the assigner's wants and the nodes' haves for the hold. From
// mesh's open conditions. It watches every observer's `findings`, the healers' `attempts`, the controller's lease
// alone (its `conditions` are no longer read, issue 774), and the assigner's wants and the nodes' haves for the hold. From
// all of them it derives, per key, the condition that should be open, and writes the difference by compare-and-set,
// saying each transition as the controller says it (go/health) and keeping it in `history`. Nothing clears a condition
// but its finding going (ADR 0231 §14).
@@ -46,11 +46,10 @@ var Observers = []string{health.WatchmanModule, health.SelfCheckModule, health.H
// The other states it reads, as `<module>.<name>`.
const (
AttemptsRead = health.HealersModule + "." + health.AttemptsState
ControllerConditions = "mesh-controller.conditions"
ControllerLease = "mesh-controller.lease"
ControllerLeaseKey = "holder"
WantsRead = delivery.AssignerModule + ".wants"
AttemptsRead = health.HealersModule + "." + health.AttemptsState
ControllerLease = "mesh-controller.lease"
ControllerLeaseKey = "holder"
WantsRead = delivery.AssignerModule + ".wants"
// PlacementRead is the mesh-placement seat's placement, read for which module holds a seat on a node (hold.go; the
// lead, 2026-10-29, for ADR 0564 clause 2's inputs).
PlacementRead = delivery.PlacementRead
@@ -119,12 +119,6 @@ func Keep(k *Keeper) {
watch(k, AttemptsRead, health.HealersModule+" attempts", func(c stdio.StateChange) error {
return said(k.Attempt(c.Key, c.Value, c.Op != "put"))
})
watch(k, ControllerConditions, "", func(c stdio.StateChange) error {
if k.LeaseAway() {
return nil
}
return said(k.Controller(c.Key, c.Value, c.Op != "put"))
})
for _, o := range Observers {
watch(k, o+"."+health.FindingsState, o, func(c stdio.StateChange) error {
return said(k.Finding(o, c.Key, c.Value, c.Op != "put"))
@@ -12,7 +12,7 @@ import (
// ADR 0564 clauses 1, 2, 3 and 12 (issue 1952 C1): the manifest says what the code does. It claims the seat
// mesh-conditions once for the mesh with the verbs mesh-sdk defines for it; reads every observer's findings, the healers'
// attempts, the controller's conditions and lease, the wants and the haves, and never the healers' would; keeps its
// attempts, the controller's lease alone (never its conditions, ADR 0564 clause 9), the wants and the haves, and never the healers' would; keeps its
// states, history ninety days and each delivery's bound as long as the bound; and every state has a tool that reads it,
// every act a tool that starts it.
func TestTheManifestSaysWhatTheCodeDoes(t *testing.T) {
@@ -29,14 +29,14 @@ func TestTheManifestSaysWhatTheCodeDoes(t *testing.T) {
!slices.Equal(Verbs, catalogue.VerbNames(seat.Serves)) {
t.Errorf("module %s runs as %s and claims %+v; the seat serves %v", m.Module, m.RunsAs, m.Claims, catalogue.VerbNames(seat.Serves))
}
reads := []string{ControllerConditions, ControllerLease, WantsRead, HavesRead, AttemptsRead, PlacementRead}
reads := []string{ControllerLease, WantsRead, HavesRead, AttemptsRead, PlacementRead}
for _, o := range Observers {
reads = append(reads, o+"."+health.FindingsState)
}
slices.Sort(reads)
got := slices.Clone(m.Reads)
slices.Sort(got)
if !slices.Equal(got, reads) || slices.Contains(m.Reads, health.HealersModule+"."+health.WouldState) {
if slices.Contains(m.Reads, "mesh-controller.conditions") || !slices.Equal(got, reads) || slices.Contains(m.Reads, health.HealersModule+"."+health.WouldState) {
t.Errorf("reads %v, want %v and never the healers' would", got, reads)
}
ttl, keyTTL := map[string]int{}, map[string]bool{}
-1
View File
@@ -28,7 +28,6 @@
"mesh-provisioner.findings",
"artifact-store-tools.findings",
"mesh-healers.attempts",
"mesh-controller.conditions",
"mesh-controller.lease",
"mesh-delivery-assigner.wants",
"node-engine.have",