mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 19:01:54 +00:00
Requirement 034 inverts the isolation model of the other agent roles: the boundary is the whole machine rather than a kernel boundary inside it. Adding this role to a device switches the agent from isolated to embodied. The agent then runs privileged with exactly the devices from ROBOT_DEVICE_ALLOWLIST bound into its container, and the kernel-isolating runtime is dropped, because a microVM between the agent and the hardware it is meant to drive defeats the purpose. The allowlist lives in group_vars so the agent templates can read it; a role variable is not visible across roles. The admission checks run inside the agent role before it deploys rather than in this role afterwards. The agent is declared shared, so the service loader brings it up during the constructor stage while svc-ai roles only run at the following step; a check placed here would sit behind the deployment it exists to prevent. The dedicated-device check now compares against something group_names actually carries: any other web-app role on the host. The previous list held Docker node labels, which are a different namespace from Ansible inventory groups, so that intersection could never match and the failure message always blamed a multi-node swarm. Which agent embodies the device follows from the topology: both agent flags take the dynamic in-group_names form, Hermes Agent wins when both are present, and the matrix pins one per round so neither path rots. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
39 lines
1.6 KiB
YAML
39 lines
1.6 KiB
YAML
---
|
|
# Admission checks for embodied mode, included by the agent role BEFORE it
|
|
# deploys. They cannot live in svc-ai-robot's own tasks: the agent is a shared
|
|
# service, so sys-service-loader preloads it in the constructor stage while the
|
|
# svc-ai group only runs at the following step, which would put every check
|
|
# behind the deployment it is meant to prevent.
|
|
#
|
|
# Param: admit_agent_role - role id of the agent being embodied
|
|
- name: "🛑 Refuse a blanket device grant"
|
|
ansible.builtin.assert:
|
|
that:
|
|
- ROBOT_DEVICE_ALLOWLIST | length > 0
|
|
fail_msg: >-
|
|
svc-ai-robot: ROBOT_DEVICE_ALLOWLIST is empty. Privileged mode is opt-in and explicit:
|
|
list every device the agent may drive (e.g. /dev/gpiomem, /dev/i2c-1, /dev/video0).
|
|
An empty list means deny-all, so there is nothing to deploy.
|
|
|
|
- name: "🔍 Collect the applications sharing this device"
|
|
ansible.builtin.set_fact:
|
|
_admit_foreign_apps: >-
|
|
{{
|
|
group_names
|
|
| select('match', '^web-app-')
|
|
| reject('equalto', admit_agent_role)
|
|
| list
|
|
}}
|
|
changed_when: false
|
|
|
|
- name: "🛑 Refuse privileged hardware access on a shared device"
|
|
ansible.builtin.assert:
|
|
that:
|
|
- _admit_foreign_apps | length == 0
|
|
- (groups['svc-swarm-node'] | default([])) | length <= 1
|
|
fail_msg: >-
|
|
svc-ai-robot grants {{ admit_agent_role }} direct hardware access, so it MUST own a
|
|
dedicated, single-tenant, network-segmented device. This host also runs
|
|
{{ _admit_foreign_apps | join(', ') or 'a multi-node swarm' }}. Move the robot to its own
|
|
device instead of widening the blast radius of the cluster.
|