621e8895c9
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
18 KiB
18 KiB
name, id, status, created, updated, priority, risk, related_issues, apps, projects, vaults, capability_groups, trigger, schedule, expected_runtime_s, tags
| name | id | status | created | updated | priority | risk | related_issues | apps | projects | vaults | capability_groups | trigger | schedule | expected_runtime_s | tags | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| agentes-dispositivos-mesh | 0009 | pending | 2026-05-23 | 2026-05-23 | high | high |
|
|
|
|
manual | 300 |
|
Goal
Hablar desde Element con dispositivos completos (PCs, moviles, raspberry, IoT) y con contenedores Docker como si fueran agentes Matrix. Cada device/container ejecuta sus capabilities declaradas (shell/fs/camera/docker/sensores) bajo:
- Mesh WireGuard anclado en
organic-machine.com— sin abrir puertos en los devices. - Matrix E2EE como bus de control y chat — un room por device/container.
- Capability manifest firmado ed25519 — el device rechaza lo que no este firmado.
Pre-requisitos
- VPS
organic-machine.comcon root SSH (aliasvpsen~/.ssh/config). agents_and_robotsyagents_dashboarddesplegados (ya OK).passcon clave operador ed25519 (pass insert operator/ed25519— crear si falta).apt-get install wireguard wireguard-toolspermitido en el VPS.- Devices Linux/WSL: sudo sin password para
wg,wg-quick,systemctl. - Devices Android: Termux + WireGuard app +
pkg install golang openssh-client.
Funciones del registry recomendadas
| Rol | Funcion candidata | Estado |
|---|---|---|
| WG install (host) | wg_install_bash_infra |
FALTA: crear |
| WG keygen | wg_keygen_go_infra |
FALTA: crear |
| WG hub setup | wg_hub_setup_bash_infra |
FALTA: crear |
| WG peer add (hub) | wg_peer_add_go_infra |
FALTA: crear |
| WG peer remove (hub) | wg_peer_remove_go_infra |
FALTA: crear |
| WG peer revoke (kill switch) | wg_peer_revoke_go_infra |
FALTA: crear |
| WG client config gen | wg_client_config_go_infra |
FALTA: crear |
| WG client install (device) | wg_client_install_bash_infra |
FALTA: crear |
WG status (parse wg show) |
wg_status_bash_infra |
FALTA: crear |
| Docker list (host) | docker_container_list_go_infra |
FALTA: crear |
| Docker exec capability | docker_container_exec_go_infra |
FALTA: crear |
| Docker logs tail | docker_container_logs_go_infra |
FALTA: crear |
| Docker container enroll | docker_container_enroll_go_infra |
FALTA: crear |
| Capability sign | capability_manifest_sign_go_infra |
FALTA: crear |
| Capability verify | capability_manifest_verify_go_infra |
FALTA: crear |
| Enrollment token gen | enrollment_token_create_go_infra |
FALTA: crear |
| Enrollment token verify | enrollment_token_verify_go_infra |
FALTA: crear |
| Matrix room per device | matrix_room_for_device_py_browser (extender) |
OK base, EXTENDER |
| Provision hub pipeline | provision_wg_hub_bash_pipelines |
FALTA: crear |
| Enroll device pipeline | enroll_device_bash_pipelines |
FALTA: crear |
| Sink audit log | device_audit_append_go_infra |
FALTA: crear |
| Notify approval | matrix_send_message_py_browser (existente) |
OK |
Apps tocadas
agents_dashboard(cockpit ImGui) — panel "Mesh" + "Devices" + "Containers" + approval queue.agents_and_robots(hub Matrix VPS) — listener Matrix por device/container.wg_hub(nuevo service Go en VPS) — enrollment endpoint, peer CRUD, SSE stream.device_agent(nuevo binario per-host) — capability dispatcher con sandbox.container_agent_sidecar(opcional, nuevo) — sidecar para containers que necesitan WG-peer propio.
Projects relacionados
element_agents(parent project — agents Matrix).
Vaults / storage
apps/wg_hub/operations.db— tablawg_peers,wg_enrollment_tokens,device_audit.apps/agents_dashboard/local_files/agents_dashboard.db— cache devices + capabilities.pass operator/ed25519— clave maestra del operador (firma manifests).pass wg/preshared/<device_id>— PSK por peer.
Capability groups consultados
wireguard(nuevo, verdocs/capabilities/wireguard.md).device-agent(nuevo, capability dispatcher + sandbox + audit).docker-agent(nuevo, capabilities sobre containers locales).
Flow
Fase A — registry primero (delegar a fn-constructor en paralelo)
function: wg_install_bash_infra(delegada).function: wg_keygen_go_infra(delegada).function: wg_hub_setup_bash_infra(delegada).function: wg_peer_add_go_infra(delegada).function: wg_peer_remove_go_infra(delegada).function: wg_peer_revoke_go_infra(delegada).function: wg_client_config_go_infra(delegada).function: wg_client_install_bash_infra(delegada).function: wg_status_bash_infra(delegada).cmd: ./fn index— registra las 9 nuevas.cmd: fn doctor unused | grep wg_— confirma que estan listas y no huerfanas (se usan en pasos C).
Fase C — POC manual end-to-end
function: wg_install_bash_infra(sobreorganic-machine.comvia SSH).function: wg_keygen_go_infra→ key par hub.function: wg_hub_setup_bash_infra— wg0, 10.42.0.1/24, ufw 51820/udp, persistencia.function: wg_keygen_go_infra→ key par devicehome-wsl.function: wg_peer_add_go_infra(en hub) → asigna 10.42.0.10.function: wg_client_config_go_infra→ genera client.conf.function: wg_client_install_bash_infra(enhome-wsl).cmd: ping -c3 10.42.0.1desdehome-wsl— verifica handshake.cmd: curl http://10.42.0.1:8080/healthz— agents_and_robots accesible por IP privada.- Repetir 15-19 para
pc-aurgi.
Fase B — spec + capability manifest + bot Matrix
- Issue 0134 spec protocol: envelope JSON
{request_id, capability, args, signature, nonce}, error model, approval flow, audit chain hash. function: capability_manifest_sign_go_infra(operator firma).function: capability_manifest_verify_go_infra(device verifica antes de aceptar request).function: enrollment_token_create_go_infra(token QR firmado, TTL 10min).function: enrollment_token_verify_go_infra(hub valida en/enroll).- Implementar
apps/device_agent/(Go cross-compile) — Matrix client + capability dispatcher + sandbox firejail. - Panel "Devices" en
agents_dashboard— lista + capability matrix + approval queue + boton revoke. - Bot Matrix por device: cuando hablas en el room
#dev-aurgi:organic-machine.com,agents_and_robotsparsea, valida capability, despacha a device_agent, devuelve resultado al room.
Fase D — agentes-contenedores docker
function: docker_container_list_go_infra— corre en host con docker socket access.function: docker_container_exec_go_infra— exec en container con whitelist binarios.function: docker_container_logs_go_infra— tail logs SSE.- Modo "light": container expuesto via host's
device_agentcapabilitydocker.*. Element room:#host-aurgi:organic-machine.comcon comando!docker exec mycontainer ps. - Modo "deep": container = peer WG propio.
container_agent_sidecarcorre WG dentro del container (privileged) o sidecar gluetun-wg. Manifest firmado mapeaagent_X→ container_id. - Sub-bot Matrix por container:
#cont-mycontainer:organic-machine.com(opcional, modo deep).
Acceptance
- 9 funciones
wg_*creadas + indexadas + sin huerfanas. - Hub WG corriendo en
organic-machine.com,wg showmuestra interface wg0. home-wslypc-aurgicon IP estable 10.42.0.10/11,pingOK.agents_and_robotsaccesible solo desde subnet 10.42.0.0/24 (publico = DROP en :8080).agents_dashboardpanel "Mesh" muestra peers vivos via SSE.- Chat en
#dev-aurgiejecuta capability (ej.!ls /home/lucas) y devuelve resultado. - Capability fuera del manifest rechazada con error en room.
- Capability
requires_approval=trueespera confirmacion en#operator-approvalsantes de ejecutar. docker.container.listinvocado desde Element devuelve containers del host.docker.container.execcon binario fuera de whitelist rechazado.- Revoke device desde
agents_dashboard→ device pierde acceso en <5s. - Audit log append-only inviolable (hash chain) sobrevive reinicio.
Definition of Done
Triada obligatoria (ver .claude/rules/dod_quality.md). Sin las 3 capas + 0 anti-criterios el flow NO se mueve a completed/.
Mecanica (pre-requisito)
- Build device_agent:
cd apps/device_agent && CGO_ENABLED=0 GOOS=linux go build -o device_agent .exit 0; cross-compileGOOS=windows+GOOS=android GOARCH=arm64tambien verdes. - Build agents_and_robots + agents_dashboard:
./fn run redeploy_cpp_app_windows agents_dashboard apps/agents_dashboard --build+ Go build deagents_and_robotsexit 0. - Tests unitarios funciones nuevas verdes:
CGO_ENABLED=1 go test -tags fts5 -count=1 ./functions/infra/...cubriendo wg_, capability_, enrollment_, device_audit_. Lista de IDs en## Notas. ./fn indexsin warnings nuevos tras anadir las ~20 funciones../fn doctor unused --json | jq '.[]|select(.id|startswith("wg_"))'vacio (las wg_* tienen consumidores reales)../fn doctor uses-functionsverde paraapps/device_agent/app.md,apps/wg_hub/app.md,apps/agents_dashboard/app.md../fn doctor services-specverde parawg_hub.serviceydevice_agent.servicecon bloque service: completo.
Cobertura de comportamiento
Minimo: golden + 8 edge/error documentados aqui con assert ejecutable. Cada uno deja entry en e2e_runs de la app afectada (apps/device_agent/operations.db, apps/wg_hub/operations.db).
| Escenario | Tipo | Comando / evidencia | Resultado esperado |
|---|---|---|---|
| Golden: comando whitelist OK | e2e | Element !exec ls /home/lucas en #dev-home-wsl |
output ls en <3s, entry en device_audit con hash valido |
| Edge: comando NO whitelist rechazado | e2e | Element !exec rm -rf / |
reply capability rejected: shell.exec.rm not in manifest; entry device_audit status=rejected_capability |
| Edge: capability fuera de manifest | e2e | Element !camera.snapshot en device sin esa capability |
reply capability not in manifest; alerta a #operator-approvals |
| Edge: replay nonce viejo | e2e | reenviar mismo envelope con nonce ya visto (cmd test: device_agent --replay-test <envelope.json>) |
rechazo + log nonce_replay; entry device_audit status=rejected_nonce |
| Edge: ed25519 manifest invalido | e2e | servir manifest firmado por clave que no es operator; device_agent lo recibe en enrollment |
device_agent rechaza + no instala wg_peer; hub log muestra manifest_invalid_signature |
| Edge: token enrollment expirado | e2e | enrollment_token_create con TTL=1s, esperar 5s, POST /enroll |
hub responde 401 token_expired; cmd curl ... exit != 0 |
| Approval flow honrado | e2e | Element !fs.write /tmp/x hello (requires_approval=true); operador hace 👍 en #operator-approvals |
exec ocurre SOLO tras approval; sin approval no escribe; entry device_audit con approval_msg_id |
| Approval flow no se salta | e2e | Forzar via API directa salto del approval queue (test negativo: cmd curl --data ... directo al device) |
device rechaza + log; sin approval_msg_id en envelope = rechazo |
| Mesh-down handled | e2e | wg-quick down wg0 en hub mientras device manda comando |
device entra en degraded, comando encolado o respuesta mesh_unreachable; al volver hub: handshake reanuda, cola se vacia |
| Dos devices simultaneos sin interferencia | e2e | home-wsl y pc-aurgi ejecutan capabilities en paralelo (script python con 2 threads) |
cada audit chain es independiente, sin cross-contamination; device_audit muestra 2 chains separadas, hash chain valido en cada una |
| Audit chain valida tras restart | e2e | matar device_agent mid-flight (kill -9) + relanzar; cmd: device_audit_verify_chain --device home-wsl |
chain integra, hash anterior coincide, sin huecos |
| Revoke device <5s | e2e | desde agents_dashboard panel "Mesh" boton "Revoke home-wsl"; medir tiempo hasta wg show no liste peer |
peer ausente en <5s; siguientes comandos a #dev-home-wsl -> peer_revoked |
Regla: cada fila genera e2e_check en app.md correspondiente (issue 0068). fn-analizador los corre periodicamente.
Vida util validada
| Metrica | Umbral | Donde se observa | Ventana |
|---|---|---|---|
| Peers vivos en mesh | >=2 constantes (home-wsl + pc-aurgi) |
agents_dashboard panel "Mesh" (last_handshake < 3min) |
7 dias |
Crashes device_agent |
0 |
journalctl --user -u device_agent.service en cada device |
7 dias |
Crashes wg_hub |
0 |
ssh vps journalctl -u wg_hub.service |
7 dias |
| Huecos en audit chain | 0 |
cmd: device_audit_verify_chain --all |
continuo |
| Rollback de wg config | 0 ocurrencias |
hub: git -C /etc/wireguard status debe ser clean; sin restore manual |
7 dias |
| Handshake fail rate | <5% |
wg show all dump parseado por agents_dashboard |
7 dias |
| Approval queue stuck | 0 pendientes >24h |
agents_dashboard panel "Approvals" |
continuo |
| Comandos exec latencia p95 | <3s |
call_monitor.function_stats para capability.shell.exec |
7 dias |
| Replay attacks bloqueados | >=1 detectado y bloqueado (pen-test real) |
device_audit status=rejected_nonce count |
30 dias |
User-facing (reforzado)
- User-facing surface: humano abre Element en movil/web (
element.organic-machine.com), entra a#dev-<nombre>y escribe comandos. Output en el mismo room. NO en una BD, NO en un log. - User-facing usage real: el operador (humano) usa Element con
home-wslYpc-aurgi(>=2 maquinas reales), >=1 sesion/dia durante >=7 dias consecutivos, >=20 comandos totales repartidos entre devices. - User-facing variado: cubre capabilities de >=4 tipos: read (
!fs.read,!ls), write (!fs.write), exec (!exec), approval-required (!fs.writeen path sensible), docker (!docker exec). - User-facing onboarding: parrafo en
## Notascon pasos numerados: abrir Element -> entrar a room ->!help-> ejemplo de comando. Sin leer el flow entero. - User-facing latencia: tras enviar mensaje en Element, output visible en <3s (read/exec) o <5s (con approval) — medido y registrado en
## Notas.
Anti-criterios (invalidan DoD aunque checkboxes verdes)
- Solo-en-home-wsl: el flow funciona en mi WSL pero falla en
pc-aurgiu otro device fisico. - device_agent muere cada noche: cualquier crash recurrente del proceso device_agent en los 7 dias de validacion.
- Approval flow se salta: alguna entrada en
device_auditcon capabilityrequires_approval=trueejecutada sinapproval_msg_idvalido. - Audit chain rota:
device_audit_verify_chainreporta huecos o hash mismatch en algun device. - wg config drift: cambios manuales en
/etc/wireguard/wg0.confdel hub sin pasar porwg_peer_add/remove/revoke. Git status muestra cambios sin trackear. - Dashboard fantasma:
agents_dashboarddeclarado pero el operador no lo abre durante la ventana de 7 dias. Telemetria muerta. - Pen-test no ejercitado: replay attack / capability fuera de manifest / token expirado declarados pero sin entry real en
device_auditcon statusrejected_*en los 7 dias. - Silent-fail: peer cae >24h y nadie se entera (sin alerta a
#operator-approvalsni badge rojo en dashboard). - Secrets en repo: cualquier hit de
git grep -E 'PrivateKey|PSK|operator/ed25519' -- ':!*.md'en cualquier rama.
Custom (security-specific, deben tener evidencia en device_audit)
- (custom) Pen-test capability fuera de manifest: entry
device_auditstatus=rejected_capabilityejercitado intencionalmente >=1 vez. - (custom) Pen-test replay: entry
device_auditstatus=rejected_nonceejercitado >=1 vez con cmd reproducible. - (custom) Stale device: forzar
home-wsloffline >24h, verificar badgestaleenagents_dashboard+ mensaje en#operator-approvals. - (custom) Operator key rotation: ejecutar rollover de la clave ed25519 maestra + revoke-all + re-enroll, sin perder audit chain historica. Documentado en
## Notas.
Telemetria esperada
call_monitor.calls: cadawg_*,capability.*,docker.*con duration_ms, success.apps/wg_hub/operations.db: tablawg_peers+device_audit(hash-chained append-only).apps/agents_and_robots/operations.db: tablamatrix_capability_dispatches.apps/agents_dashboard/local_files/agents_dashboard.db: cache devices + approval queue.- Dashboards visibles:
agents_dashboardpanel "Mesh" (peers vivos + last handshake + bytes rx/tx). - Matrix room
#operator-approvalsrecibe cada approval_request. - Element en movil aprueba/rechaza con reacciones (👍/👎) o comando
!approve <id>.
Riesgos / gotchas
- VPS UDP/51820: firewall del proveedor del VPS puede bloquearlo. Verificar con
nc -u -v vps 51820. - NAT carrier-grade (4G/5G): device tras NAT estricto →
PersistentKeepalive = 25obligatorio. - Sleep laptop / android doze: handshake muere. Auto-reconnect via
systemd-networkd-wait-online+ script. - Privilegio sudo:
wg-quickrequiere root. Devices necesitan sudo-NOPASSWD parawg-quick@wg0. - Clock skew: tokens enrollment + nonces dependen de NTP. Forzar
chronyen VPS y devices. - Container privileged: modo "deep" docker requiere
--cap-add NET_ADMIN. Riesgo si container compromised. Mitigacion: solo modo "deep" para containers de tu propio control (ej.agents_and_robotsself-hosted), no third-party. - Operator key compromise: si tu ed25519 leaks → cualquiera firma manifests. Plan B: rotacion + revoke-all + re-enroll.
- Matrix homeserver compromise: chat E2EE protege contenido, pero metadata (quien habla con quien) leak.
Aceptable porque homeserver es tuyo en
organic-machine.com.
Notas
(rellenar tras ejecutar fases A/C/B/D)
Para hablar con un device desde Element (onboarding)
- Abre Element en movil o web (
element.organic-machine.com). - Entra al room
#dev-<nombre>(un room por device). - Escribe
!help→ bot del room (agents_and_robots) responde con capability matrix del device. - Escribe comando, ej.
!exec ls /home/lucaso!fs.read /var/log/syslog. - Si capability requiere approval, te llega notification a
#operator-approvals→ reaccionas 👍 → ejecuta. - Output aparece en el mismo room del device.
Para hablar con un container docker
- Si el host del container ya esta en la mesh: room
#dev-<host>con!docker exec <container> <cmd>. - Modo deep: room dedicado
#cont-<container>(solo containers enrolled).