package catalogue // The node's tool runtime, as the catalogue knows it (novox/hq ADR 0175, to-be 38). // // **One module is the runtime.** Where it is assigned, one process per machine serves every assigned // module's tools and every held seat's verbs, on the host side, from the bundles each module's build // produced — and no module needs a container to reach the bus with its tools. The name is a constant // rather than a manifest field because a rule turns on it: the composer places the runtime's process // where this module is, and registration refuses the old pattern once this module exists. // RuntimeModule is the module that is the node's tool runtime. Mirrored in the broker package, // which composes a principal of its own for it; the agreement test there holds the two to one string. const RuntimeModule = "node-tools" // BundleRoot is where a machine keeps the tools bundles the mesh delivers to it: under the mesh's // own directory, beside the daemons the host unpacks there, and never where a package manager also // writes. One directory per module, one per bundle beneath it, at a path that does not move with // the version — so the runtime's process names each entrypoint once and is restarted, not // recomposed, when a bundle changes. const BundleRoot = "/var/lib/mesh/bundles" // BundleID names the archive resource that delivers one of a module's bundles; prefixed with the // module like every resource of its own. func BundleID(bundle string) string { return "bundle-" + bundle } // BundlePath is where one module's bundle is unpacked on a machine. func BundlePath(module, bundle string) string { return BundleRoot + "/" + module + "/" + bundle } // runtimeHere says whether this node's set includes the runtime module, which is what decides // whether anything about tools changes on the machine (to-be 38 WP2): until the runtime is assigned, // a node is sent exactly what it was sent before, bundles included, because a bundle nothing loads // is bytes nobody reads. func (r Resolution) runtimeHere() bool { for _, m := range r.Modules { if m.Module == RuntimeModule { return true } } return false } // bundleArchives is one archive per tools bundle of a module — a bundle with entrypoints, which a // runtime LOADS — as the host fetches and unpacks any artifact (novox/hq ADR 0175 §3: a module brings // its tools as a bundle, delivered by the host like any artifact, never an image). A bundle without // entrypoints is run rather than loaded: a daemon, a step, the runtime itself — delivered by the // process that runs it, and not again here. // // The source is the kept reference; the per-resource pass that follows routes it through the // artifact store as this network reaches it now, as it does every image and archive the mesh built. func bundleArchives(m Manifest) []map[string]any { var out []map[string]any for _, b := range m.Bundles { if len(b.Entrypoints) == 0 { continue } out = append(out, map[string]any{ "id": BundleID(b.Name), "type": "archive", "source": b.Source, "digest": b.Digest, "path": BundlePath(m.Module, b.Name), }) } return out }