H-15: the apply guard and the yields read the node-engine's module from the entry claiming its seat

The module is the one whose catalog entry claims node-engine, else the one this node heard run the build its own
fingerprint names; no name is fixed in the guard or in the compose.

Builds: design 47 G §364, §527, §428

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
2026-11-11 14:05:43 +01:00
parent a073a001c5
commit 602ed830e9
9 changed files with 143 additions and 13 deletions
+21 -1
View File
@@ -33,6 +33,7 @@ import (
"github.com/novox/mesh-host/internal/compositions"
engcomp "github.com/novox/mesh-host/internal/compositions"
"maps"
"os"
"reflect"
"slices"
"sort"
@@ -180,6 +181,8 @@ type Composer struct {
// node's own consumer (NoteRunning), under mu; heardRead is whether the first read of the stream ended (RunningRead).
heard map[string]map[string]heardRun
heardRead bool
// engine is the node-engine's own module as the last composing of the node's input found it (Scope.Engine), under mu.
engine string
// rehand asks for a pass that hands again what the agent waits for (Waiting).
rehand chan struct{}
// sealedOwn is each own secret's sealed value as first handed, by module/name and generation: a value sealed again
@@ -1002,7 +1005,7 @@ func (c *Composer) compose(ctx context.Context) []agent.Update {
var keptMu sync.Mutex
var holds map[string]compose.Hold
fromManifest := map[string]string{} // by module, why it is composed from the indexer's manifest and not a build
scope := frombus.Scope{Node: c.env.Node, KeptAt: kept, InOwn: inOwn, Running: running, Heard: c.heardNow(), Kept: func(module, words string) {
scope := frombus.Scope{Node: c.env.Node, KeptAt: kept, InOwn: inOwn, Running: running, Heard: c.heardNow(), Engine: c.noteEngine, OwnFingerprint: os.Getenv(engcomp.FingerprintVar), Kept: func(module, words string) {
keptMu.Lock()
defer keptMu.Unlock()
if !slices.Contains(keptRuns[module], words) {
@@ -2351,3 +2354,20 @@ func (c *Composer) heardNow() map[string]map[string]frombus.Heard {
}
return out
}
// noteEngine keeps the node-engine's own module a composing of the node's input found; one that finds none changes nothing.
func (c *Composer) noteEngine(module string) {
if module == "" {
return
}
c.mu.Lock()
c.engine = module
c.mu.Unlock()
}
// EngineModule is the node-engine's own module (design 47 G §527), for the apply guard; "" until a composing found it.
func (c *Composer) EngineModule() string {
c.mu.Lock()
defer c.mu.Unlock()
return c.engine
}