The audit read as prose, so a role could sit under a classification nobody had checked against its own declaration, and "blocked" could not be told apart from "nobody looked". The sections are now named after the exact values a role declares, which makes the section titles the vocabulary: one rule holds every role under its own declared classification, a second rejects a classification outside the vocabulary, and a third requires a named blocker per blocked role while forbidding a blocked role from shipping an enabled surface. The report itself is generated from the roles' own metadata and a drift check imports the generator and compares against the committed file, which caught a stale report twice while this work was in progress. It lives under docs/contributing rather than beside the requirements, because a generated file in that directory reads like a finished criterion. The criteria across seven requirement files now carry what they rest on: what closed them, or what blocks them and where that was measured. Two coverage limits stay stated rather than hidden: the report is built only from roles that declare an MCP block, so a role blocked without one is invisible to it, and a ticked criterion here means implemented and tested rather than proven in operation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
8.3 KiB
034 - Embodied Robot Platform for Hermes (svc-ai-robot)
User Story
As a platform administrator of Infinito.Nexus, I want a svc-ai-robot role that turns one dedicated machine into an embodied platform for Hermes, giving the agent scoped-to-full host access so it can explore its own hardware and act in the physical world, so that Hermes can "come to life" on a robot while this power stays confined to a dedicated, segmented device and never leaks onto shared infrastructure.
Background
Every other agent deployment in 032 keeps the agent kernel-isolated. This role is the deliberate inverse defined by 032 Decision #12 (embodied / dedicated-device mode): for a robot, the useful trust boundary is the whole device, because the agent's job is to drive that device's hardware (GPIO, I2C/SPI sensors, cameras, actuators, motors). A microVM around the agent would only get in the way of the very hardware it is meant to control.
The safety of this design comes entirely from confinement of the device, not from confinement of the agent: the machine is dedicated to Hermes, single-tenant, network-segmented, and physically separate from shared infrastructure. svc-ai-robot is the role that provisions that device and deploys Hermes on it in privileged mode. It builds on the web-app-hermes role rather than reimplementing the agent.
Confirmed Decisions
These choices are settled at requirement creation time and bound the implementation. Re-opening any of them MUST be recorded in the implementing PR.
svc-ai-robotdeploys Hermes in embodied mode on a dedicated device. It reuses theweb-app-hermesagent from 032 and configures it for privileged hardware access. The trust boundary is the device (032 Decision #12), so no microVM wraps the agent here.- Dedicated, single-tenant, segmented node only. The role MUST refuse to deploy on a node that carries any shared-workload label or hosts other tenants, and the node MUST be network-segmented from shared infrastructure. This is enforced, not just documented: a placement/preflight guard hard-fails on a shared node.
- Hardware access is declared, not blanket-by-accident. The role exposes a device allowlist (
/dev/*, GPIO, I2C/SPI, video/camera, serial) that the operator sets; "full access" is an explicit, documented opt-in, not the silent default. The README documents the blast radius: the agent can do anything the granted devices allow. - Control is raw device access plus agent code execution; no robotics middleware is mandated. Hermes drives the hardware by executing code directly against the granted devices (GPIO/I2C/SPI/serial/video libraries), consistent with its self-exploration. This is the deliberate choice over a ROS2/middleware abstraction: the embodied device is already the trust boundary (there is no microVM here), so the agent runs code on the device itself. A middleware layer MAY be added later per robot but is not required by this role.
- Self-exploration is a first-class capability. Hermes enumerates and probes the granted hardware to build a capability map (which sensors/actuators exist, what they report/do) before or during control, and that map is retrievable.
- Models via the 031 gateway; higher-level tools via 025 MCP. Embodiment changes the host boundary, not the model or tool planes: inference still goes through the gateway, and non-hardware tools still come via MCP.
arm64robot SBCs are a target. The role runs onarm64single-board computers typical of robotics, not only x86.- Opt-in and off by default. Privileged embodied mode is never a default; enabling it is an explicit operator action with the guardrails above in force.
- Physical safety is the operator's responsibility, and the role MUST say so. This role does NOT mandate an emergency-stop or motion rate-limits as a platform acceptance criterion. Because an agent driving motors/actuators can cause physical harm, the README MUST prominently warn that hardware safety (e-stop, current/motion limits, fail-safe wiring) is the operator's responsibility and is out of the platform's scope. The role MUST NOT claim any safety guarantee it does not enforce.
Architecture
flowchart TB
operator([Operator]) -->|"opt-in enable"| robot
subgraph device["Dedicated robot device = trust boundary (032 Decision #12)"]
robot["svc-ai-robot<br/>= web-app-hermes, PRIVILEGED"]
hw["declared devices:<br/>/dev, GPIO, I2C/SPI,<br/>cameras, motors, sensors"]
robot -->|"explore + control"| hw
end
gw["svc-ai-litellm /v1 (031)"]
mcp["025 MCP tool servers"]
robot -->|models /v1| gw
robot -.->|"non-hardware tools"| mcp
shared["Shared cluster nodes"]:::no
device -. "segmented, guard hard-fails if shared" .-> shared
classDef no fill:#fdd,stroke:#c00,stroke-dasharray:4 3;
Hardware blockers
Three criteria need a dedicated single-tenant device with real sensors and actuators wired to it. No such device is in the deployment, and the platform cannot simulate one honestly: a stubbed GPIO would make the criteria green while proving nothing about the embodied path. They stay unchecked until the device joins.
What is already provable without it: the admission guard refuses a shared host or an empty device allowlist, both agent images publish linux/arm64, and neither agent is pinned away from arm64.
Closing probes once the device exists: deploy with ROBOT_DEVICE_ALLOWLIST naming the wired devices, ask Hermes for its capability map, then read one granted sensor and drive one granted output.
Where each guarantee is enforced
| Guarantee | Enforced by |
|---|---|
| Every embodiable agent runs the admission checks | test_robot_admission_guard.py, deriving the agent set from svc-ai-robot's own service flags |
| No blanket device grant, no shared host | admit.yml, included by each agent before it deploys |
| Inference reaches only the gateway | test_litellm_consumer_contract.py and test_model_backend_via_gateway.py |
| Tools arrive over MCP | web-app-hermes/meta/mcp.yml direction: client, held to the 025 schema by the MCP lint suite |
| The agent images run on arm64 | test_arm64_images.py |
Acceptance Criteria
- A
svc-ai-robotrole deploysweb-app-hermesin privileged embodied mode on a dedicated device and it comes up healthy. Blocked: see Hardware blockers. - The role hard-fails (placement/preflight guard) when targeted at a node carrying a shared-workload label or hosting other tenants.
- Hardware access is limited to an operator-set device allowlist; no device outside the allowlist is exposed to the agent.
- Hermes produces a retrievable capability map of the granted hardware (self-exploration). Blocked: see Hardware blockers.
- The agent can read a granted sensor and actuate a granted output through its embodied access. Blocked: see Hardware blockers.
- Inference still routes through the 031 gateway; non-hardware tools still come via 025 MCP.
- The role runs on
arm64. - Privileged mode is off by default; enabling it is an explicit, documented operator opt-in, and the README states the blast radius.
- The README prominently warns that physical hardware safety (e-stop, motion/current limits, fail-safe wiring) is the operator's responsibility and out of platform scope; the role claims no safety guarantee it does not enforce.
Cross-linking
- Implementing PR: to be linked.
See Also
- Embodied-mode decision and scenario: 032-agent-employees-firecracker.md
- LLM gateway: 031-llm-gateway-model-backends.md
- MCP tool plane: 025-mcp-role-integration.md