Repository navigation
Description
Parent Epic: #7937
Canonical NemoClaw scope was accepted in #7937 on 2026-08-13. Active dependency selection and merge remain blocked on the released compatibility set from #8885.
Outcome
An explicitly enabled NemoClaw-managed Hermes sandbox loads native NeMo Relay and the nvidia.switchyard plugin once in the normal supervised Hermes process, using one root-owned Relay plugin-activation file and one separate root-owned Switchyard version-1 deployment file. No Relay or Switchyard sidecar is started, and requested-but-inactive routing cannot reach any model provider.
Current upstream gate — 2026-08-25
Switchyard #528 remains open, review-required, and targets Relay 0.8.0-rc.3. Its current README and implementation now use the same manifest-backed dynamic record consumed by Hermes and derive plugin identity from relay-plugin.toml. That source-level configuration mismatch is resolved; a stable release, immutable plugin bundles, and a Hermes-style activation/readiness test are still required before NemoClaw freezes a production selector.
Stable Relay remains 0.7.3, while Hermes Agent 0.20.5 still locks Relay 0.7.2 and requires Relay below 0.8. Draft NemoClaw #9012's published head models the older #270 embedded configuration and is lifecycle reference material only. Its local V5 successor implements the current two-file shape while deliberately selecting or activating no unreleased runtime artifact.
Canonical file boundary
The released path consumes exactly two upstream-owned configuration contracts:
-
Relay plugin activation file
- one plugins.dynamic record;
- immutable installed manifest path;
- plugin config containing only priority and switchyard_config_path;
- explicit activation consent for the manifest whose defaults remain disabled.
-
Switchyard deployment file
- schema version 1;
- llm_clients, targets, and routes;
- the exact route ID requested by Hermes;
- released algorithm fields and target/client references;
- endpoint and raw-key environment names derived from accepted OpenShell provider evidence.
A NemoClaw-internal secret-free binding receipt may attest how those files were derived, but it is not a third Relay/Switchyard configuration language.
Scope
- Generate the manifest-backed Relay dynamic-plugin record accepted by the exact released Hermes/Relay loader.
- Generate the separate Switchyard version-1 deployment accepted by the released switchyard-runner.
- Never emit the old embedded version-2 feat: recommend optimal NIM model based on detected GPU VRAM #270 configuration or plugin_id as a substitute for the manifest path.
- Set HERMES_NEMO_RELAY_PLUGINS_TOML only when routing is explicitly enabled.
- Bind Hermes model selection to the configured Switchyard route ID. Because an unknown route deliberately continues through Relay unchanged, route-ID mismatch must fail preflight/readiness rather than silently bypass Switchyard.
- Bind activation to the supervised Hermes process and persist it across restart/rebuild.
- Include every activation-affecting input in the configuration/state identity: released artifact identities, architecture, manifest/schema/library digests, Relay range/native API, both generated file bytes, route ID, algorithm, provider attestations, policy, and credential-placeholder revisions.
- Validate the plugin manifest, library digest, native API, Relay range, architecture, deployment schema, algorithm, route ID, client, target, and credential references before Hermes readiness.
- Resolve active plugin ownership through Relay structured discovery fields: plugin ID, kind, component ordinal, and local name. Do not construct, persist, or compare Relay versioned effective component names.
- Require the expected Relay runtime and nvidia.switchyard component to be loaded, active, and ready before admitting any Hermes turn or allowing bootstrap, judge, weak, or strong provider execution.
- Override upstream fail-open behavior at the NemoClaw readiness boundary: invalid configuration or missing Relay/plugin support must produce actionable failure, not a healthy unrouted Hermes agent.
- Preserve ordinary Hermes behavior exactly when routing is disabled.
- Prove one supervised Hermes process owns Relay and Switchyard and that Relay/Switchyard sidecar count is zero.
- Retain only the release-independent lifecycle ideas from draft feat(hermes): define native Switchyard routing contract #9012: typed disabled-default profile input, atomic root-owned file promotion, exact-byte replay verification, stale-artifact removal, and rejection of missing, extra, raw, or mixed-revision placeholders.
Acceptance
- Routing-disabled sandboxes behave exactly as before and do not contain active Switchyard configuration.
- The Relay activation file parses through the exact released Hermes loader path; plugin_id and unknown fields are rejected.
- The Switchyard deployment parses through the exact released runner and rejects unknown fields, algorithms, routes, clients, targets, or dangling references.
- Routing-enabled sandboxes report active native Relay and structured nvidia.switchyard ownership before readiness.
- The observed plugin manifest, schema, native library, Relay version, native API, architecture, route ID, and both generated file digests match the expected immutable tuple.
- Hermes requests the configured Switchyard route ID; a mismatched or unknown route cannot fall through to direct provider execution.
- Missing, unreadable, malformed, incompatible, disabled, or rejected activation/deployment state fails preflight/readiness before any provider request.
- The active supervised Hermes PID owns Relay/plugin activation and no Relay CLI, switchyard-server, Relay sidecar, or Switchyard sidecar exists.
- Restart and rebuild restore the same attested activation and deployment state without accepting stale or mixed-generation files.
- Generated configuration, receipts, readiness output, and diagnostics contain no raw provider credential.
- Removal or disablement deletes stale activation/deployment artifacts and restores ordinary unrouted Hermes behavior only after the requested routing state is explicitly disabled.
Activity
cjagwani commentedon Aug 12, 2026
Activation/readiness contract audit — 2026-08-12
Hermes #77915 has the right process topology and canonical
[[plugins.dynamic]]loader, but it is currently fail-open:FAILEDorFOREIGN;/healthresponse can still reportstatus: ok;NemoClaw cannot safely infer activation from the TOML file, process list, or log text. This issue therefore needs an upstream or released Hermes contract that reports whether Relay was requested and active, plus the active non-secret plugin IDs. The preferred surface is an authenticated detailed-health/readiness check. When routing is requested, NemoClaw can require
activeandnvidia.switchyard; missing, malformed, incompatible, foreign, or failed activation must keep the sandbox unready.The configuration generator, environment wiring, restart persistence, and negative tests can be developed independently of #8896 after the released loader and plugin bundle exist. #8896 is only needed when this state is exercised in the final live E2E lane.
cjagwani commentedon Aug 13, 2026
Draft #9012 now defines and hardens the generated native Relay/Switchyard configuration path. It intentionally does not package the plugin or claim readiness: this issue still owns the requirement to verify the reviewed plugin artifact and fail startup unless Hermes reports
nvidia.switchyardloaded and active.cjagwani commentedon Aug 24, 2026
2026-08-24 activation contract update
The final upstream shape differs from the older single generated-TOML design:
The process topology remains correct: Hermes, Relay, and Switchyard run in one supervised Hermes process with zero Relay/Switchyard sidecars.
NemoClaw still owns the fail-closed boundary. Hermes #90199 intentionally makes a missing nemo_relay installation a graceful no-op, so requested routing must not become ready or admit a model request unless the expected plugin and route are proven active. Hermes #81858 should also be consumed by the later restart/lifecycle qualification rather than widening the first activation slice.
cjagwani commentedon Oct 27, 2026
Superseded by #13862 and #13864 under the replanned #7937 implementation. Configuration and route selection are now separated from fail-closed readiness.