diff --git a/node-tools/internal/runtime/own_account_test.go b/node-tools/internal/runtime/own_account_test.go index eaf433d..a44d681 100644 --- a/node-tools/internal/runtime/own_account_test.go +++ b/node-tools/internal/runtime/own_account_test.go @@ -38,6 +38,26 @@ func TestNoBusWordReachesABundle(t *testing.T) { } } +// design 47 G §618, §519: the runtime's own fingerprint reaches no bundle; the fingerprint a module's composed words hold does. +func TestTheRuntimesOwnFingerprintReachesNoBundle(t *testing.T) { + base := []string{"MESH_FINGERPRINT=runner-build", "PATH=/usr/bin"} + for name, c := range map[string]struct { + given map[string]string + want string + }{ + "composed with none sees none": {nil, ""}, + "composed with one sees its own": {map[string]string{"MESH_FINGERPRINT": "module-build"}, "MESH_FINGERPRINT=module-build"}, + } { + env := strings.Join(BundleEnv(base, c.given, "telegram", "anchor"), "\n") + if strings.Contains(env, "runner-build") { + t.Errorf("%s: the runtime's own fingerprint reached the bundle: %s", name, env) + } + if c.want == "" && strings.Contains(env, "MESH_FINGERPRINT") || !strings.Contains(env, c.want) { + t.Errorf("%s: the environment is %s", name, env) + } + } +} + // A tool call reaches only a tool's subject: whatever key a caller names, it is never a seat's event, accept // or proof — so no tool call says a choice, a link or a code, or submits an ask, in anybody's name. func TestAToolCallNeverReachesASeatsEventAcceptOrProof(t *testing.T) { diff --git a/node-tools/internal/runtime/runtime.go b/node-tools/internal/runtime/runtime.go index f3bc178..bc982f5 100644 --- a/node-tools/internal/runtime/runtime.go +++ b/node-tools/internal/runtime/runtime.go @@ -59,6 +59,10 @@ type ListedTool struct { // NodeRuntimeModule is the module that is a machine's runtime, serving every module on it. const NodeRuntimeModule = "node-tools" +// fingerprintEnv is the word the node-engine starts each process with, the fingerprint of the want it applies (mesh-sdk's +// process.FingerprintEnv; this package imports no SDK): the runtime's own is no bundle's. +const fingerprintEnv = "MESH_FINGERPRINT" + // runtimeOnly are the words of the runtime's own environment no bundle is given. var runtimeOnly = map[string]bool{ToolEnv: true, ToolModules: true, "MESH_BROKER_FILE": true, "MESH_BROKER_URL": true, "MESH_CONSOLE_LISTEN": true, LedgersFile: true} @@ -1369,11 +1373,13 @@ func (b *moduleBus) bind(key string, stop func()) { // BundleEnv is what one module's bundle is started with: the runtime's environment without its own words, // the module's composed words over it, and the module's and machine's names. **No bus word reaches a // bundle** (security review of 2026-10-08): the credential and the bus's address are the runtime's, and a -// bundle reaches the bus only through the runtime. +// bundle reaches the bus only through the runtime. **The runtime's own fingerprint reaches none either**: a bundle reads +// only the `MESH_FINGERPRINT` its module's composed words hold, the build the node-engine applied for that module, and with +// none it has none (design 47 G §519, §618). func BundleEnv(base []string, given map[string]string, module, node string) []string { words := map[string]string{} for _, kv := range base { - if k, v, ok := strings.Cut(kv, "="); ok && !runtimeOnly[k] { + if k, v, ok := strings.Cut(kv, "="); ok && !runtimeOnly[k] && k != fingerprintEnv { words[k] = v } }