621e8895c9
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
233 lines
12 KiB
Markdown
233 lines
12 KiB
Markdown
---
|
|
id: "0146"
|
|
title: "add-pc one-shot: añade PC al mesh + agente LLM en <2min desde movil"
|
|
status: pending
|
|
priority: high
|
|
created: 2026-05-24
|
|
related_flows: ["0009"]
|
|
related_issues: ["0134", "0144", "0145"]
|
|
dependencies: []
|
|
tags: [mesh, wireguard, ssh, scaffolder, agents, llm, scaling, dx]
|
|
---
|
|
|
|
## Objetivo
|
|
|
|
Reducir de 8 pasos manuales (~15min) a **1 comando (<2min)** el flujo de añadir un PC nuevo al mesh con su propio agente LLM conversacional. Goal final: chatear desde Element movil con cualquier PC del usuario tras un `./fn run add_pc <name>`.
|
|
|
|
## Estado actual (post-0145)
|
|
|
|
Pipeline manual funcional pero verboso:
|
|
1. Instalar wireguard en PC nuevo.
|
|
2. wg_keygen.
|
|
3. wg_peer_add en hub (organic-machine.com).
|
|
4. wg_client_config + wg_client_install.
|
|
5. Build/scp device_agent binario.
|
|
6. Manifest YAML local.
|
|
7. systemd unit.
|
|
8. provision-agent-user.sh + edit launcher main.go + rebuild + restart agents_and_robots.
|
|
|
|
Solo agent-wsl-lucas existe. Bloqueado por friccion de pasos para escalar a aurgi-pc, windows-lucas, raspberry, etc.
|
|
|
|
## Vision
|
|
|
|
```
|
|
operador$ ./fn run add_pc aurgi-pc --via wg
|
|
[1/9] generating WG keypair...
|
|
[2/9] enrolling peer at hub (10.42.0.21)...
|
|
[3/9] cross-compiling device_agent for linux/amd64...
|
|
[4/9] uploading binary + manifest + systemd unit via SSH...
|
|
[5/9] starting WG + device_agent on remote...
|
|
[6/9] provisioning Matrix user @agent-aurgi-pc...
|
|
[7/9] generating agent config + system prompt...
|
|
[8/9] wiring launcher + rebuild...
|
|
[9/9] restarting agents_and_robots.service...
|
|
✓ agent-aurgi-pc live. Send a DM from your Matrix client.
|
|
```
|
|
|
|
Y para hosts sin posibilidad de instalar binary:
|
|
```
|
|
operador$ ./fn run add_pc customer-vps-01 --via ssh --ssh-alias customer-prod
|
|
✓ agent-customer-vps-01 live (ssh-backed). Send a DM.
|
|
```
|
|
|
|
## Arquitectura
|
|
|
|
Dos backends para un mismo UX:
|
|
|
|
### Backend A — WG + device_agent (mesh nativo)
|
|
- PC tiene WG client + binary device_agent corriendo.
|
|
- Comandos viajan VPS → WG → device_agent → exec local → audit chain LOCAL.
|
|
- 14 capabilities completas (fs.*, git.*, docker.*, pkg.*, proc.*, shell.exec, shell.eval).
|
|
- Para tus PCs (laptop, desktop, raspberry, mac, movil rooted).
|
|
|
|
### Backend B — SSH-only (sin binary remoto)
|
|
- PC tiene solo SSH server. VPS tiene SSH key autorizada.
|
|
- Comandos viajan VPS → ssh.Executor → exec remoto → audit en VPS.
|
|
- Tools reducidos: `ssh_exec(argv)`, `ssh_fs_read`, `ssh_fs_list`. Sin docker/git/pkg salvo wrapper.
|
|
- Para customer servers, VPS terceros, throwaway boxes.
|
|
|
|
LLM agent ve diferentes tool sets segun backend. Mismo system prompt template.
|
|
|
|
## Tareas
|
|
|
|
### Fase 1 — Pipeline `add_pc_wg_bash_pipelines`
|
|
|
|
1.1. Cross-compile device_agent matrices:
|
|
- `GOOS=linux GOARCH=amd64` (default)
|
|
- `GOOS=linux GOARCH=arm64` (raspberry pi4+, mac M-series via Linux)
|
|
- `GOOS=windows GOARCH=amd64`
|
|
- `GOOS=darwin GOARCH=arm64`
|
|
- Reusa `nohup` cgo-free build (swap mattn/go-sqlite3 → modernc.org/sqlite si no esta hecho ya).
|
|
- Output: `cpp/build/cross/device_agent.<os>-<arch>`.
|
|
|
|
1.2. Funcion `cross_compile_device_agent_bash_infra(target_os, target_arch)` que devuelve path al binario.
|
|
|
|
1.3. Funcion `add_pc_wg_bash_pipelines(name, ssh_alias, target_os?, target_arch?)`. Compone:
|
|
- wg_keygen_go_infra (hub side: priv hub + psk; client side: priv cliente)
|
|
- wg_peer_add_go_infra (en hub via SSH al VPS)
|
|
- wg_client_config_go_infra (genera client.conf)
|
|
- ensure_remote_wireguard_installed (SSH al target, apt/dnf install wireguard si falta)
|
|
- wg_client_install_bash_infra (en target via SSH push)
|
|
- cross_compile_device_agent_bash_infra (local)
|
|
- rsync_device_agent_bundle (binary + manifest template + systemd unit → target ~/.local/bin/ + ~/.config/device_agent/)
|
|
- start_device_agent_service (systemctl --user enable --now device_agent)
|
|
- provision_agent_user (ssh al VPS, ejecuta dev-scripts/agent/provision-agent-user.sh con --mode user)
|
|
- wire_launcher_import (edita cmd/launcher/main.go en VPS, anade blank import, git commit + rebuild + restart service)
|
|
- assert_dm_received (espera 30s a que el bot mande "hola" via notify-developer.sh)
|
|
|
|
1.4. Manifest template Y matrix per-OS: paths_allowed difieren (`/home/<user>/**` en Linux, `C:\Users\<user>\**` en Windows). Templates en `dev-scripts/agent/templates/manifest.<os>.yaml.tmpl`.
|
|
|
|
1.5. Idempotente: re-run con mismo name → no-op + verificar state. Si peer existe pero device_agent caido, restart.
|
|
|
|
1.6. Rollback: si paso N falla, deshacer 1..N-1. Estado parcial NO debe quedar (peer huerfano, Matrix user sin agent, etc).
|
|
|
|
### Fase 2 — Pipeline `add_pc_ssh_bash_pipelines` (backend B)
|
|
|
|
2.1. Funcion `ssh_exec_capability_go_infra` — wrapper que recibe `{argv, host}` y hace `ssh <host> -- <argv...>`. Whitelist binaries opcional. Audit en VPS (`apps/agents_and_robots/ssh_audit.db` o similar).
|
|
|
|
2.2. Funcion `ssh_fs_read_capability_go_infra`, `ssh_fs_list_capability_go_infra` (read-only, no write para evitar accidentes en customer boxes).
|
|
|
|
2.3. Tool registry adapter: cuando agent config tiene `device_mesh.backend: ssh`, el adapter no apunta a HTTP device_agent — apunta a las funciones `ssh_*` directamente. Mantener interface ToolRegistry pero swap implementation.
|
|
|
|
2.4. `add_pc_ssh_bash_pipelines(name, ssh_alias)` compone:
|
|
- assert_ssh_reachable (BatchMode yes connect test)
|
|
- provision_agent_user --mode user --backend ssh
|
|
- generate agent config con `device_mesh.backend: ssh, ssh_alias: <alias>`
|
|
- wire launcher + restart
|
|
|
|
NO toca el remote — solo VPS.
|
|
|
|
### Fase 3 — Cross-compile device_agent CGO-free
|
|
|
|
3.1. Swap mattn/go-sqlite3 (CGO) → modernc.org/sqlite (pure Go) en device_agent. Tests verde tras swap.
|
|
|
|
3.2. `cross_compile_device_agent_bash_infra` produce 4 binarios en <30s.
|
|
|
|
3.3. Bundle script `make-bundle.sh <os> <arch>` empaqueta zip con binario + manifest.template + systemd-unit/launchd-plist/Task-Scheduler.xml segun OS.
|
|
|
|
### Fase 4 — agents_dashboard "Add device" panel C++
|
|
|
|
4.1. Modal nuevo en panel "Devices" con:
|
|
- Input: nombre del PC.
|
|
- Dropdown backend: WG mesh / SSH-only.
|
|
- Si WG: SSH alias para upload + OS/arch detect via uname remote.
|
|
- Si SSH: solo alias.
|
|
- Boton "Add". Spawn pipeline en background. Stream logs en TextLog.
|
|
|
|
4.2. Grid de status: device_id, IP mesh, last handshake, capabilities count, last command ts, audit chain integrity.
|
|
|
|
4.3. Boton "Revoke" por device → llama wg_peer_revoke + deactivate Matrix user + remove launcher import + restart. Confirmacion doble.
|
|
|
|
### Fase 5 — Health monitor cron + alertas
|
|
|
|
5.1. Cron 5min `monitor_mesh_health_bash_pipelines`:
|
|
- wg_status → cada peer con last_handshake > 600s → mark stale.
|
|
- HTTP GET /health a cada device_agent IP del mesh → si falla → mark unreachable.
|
|
- verify_hash_chain por device → si rota → mark corrupted.
|
|
|
|
5.2. Alertas Matrix a `#operator-alerts` (room a crear) con mensaje formato:
|
|
```
|
|
[ALERT] device_id=aurgi-pc status=stale (handshake 8min ago)
|
|
[ALERT] device_id=home-wsl status=hash_chain_corrupted (id=47 broken)
|
|
```
|
|
|
|
5.3. Dashboard tab "Health" muestra el feed SSE.
|
|
|
|
### Fase 6 — Movil UX validation
|
|
|
|
6.1. Test en Element movil iOS/Android:
|
|
- Lista de rooms con 1 per device.
|
|
- Notifications activas → push cuando agent responde.
|
|
- Smoke tests de capabilities mas comunes via voice-to-text.
|
|
|
|
6.2. Documentar `docs/mobile-control.md` con flujo recomendado:
|
|
- Como agrupar rooms por device en Element favorites.
|
|
- Comandos comunes ("status", "deploy X", "que esta caido").
|
|
- Tiempos esperados (claude-code latency 3-5s + tool exec 0.1-2s).
|
|
|
|
## Aceptacion (DoD triada)
|
|
|
|
### Mecanica
|
|
- `./fn run add_pc <name> --via wg` exit 0 + agent live en <2min en wallclock.
|
|
- `./fn run add_pc <name> --via ssh` exit 0 + agent live en <30s.
|
|
- Tests unit + integration verde en `bash/functions/pipelines/add_pc_*`.
|
|
|
|
### Cobertura
|
|
- Smoke matrix: 4 target OS (linux/amd64, linux/arm64, windows/amd64, darwin/arm64) cada uno con add_pc_wg flujo end-to-end.
|
|
- Rollback: simular falla en paso 5 (binary upload corrupted) → assert estado limpio (no peer huerfano, no Matrix user, no entry en launcher).
|
|
- SSH backend: target solo con SSH + sin sudo → agent funciona con tools ssh_exec read-only.
|
|
- Anti-criterio A3 (heredado de 0009): tras add_pc, smoke real via Matrix → audit DB en device tiene entries reales (no bot hallucination).
|
|
|
|
### Vida util
|
|
- 5 PCs reales añadidos durante 7 dias.
|
|
- 0 revokes manuales por error de provision.
|
|
- Operador usa Element movil >=1 sesion/dia interactuando con >=2 devices distintos.
|
|
- Health monitor detecta peer caido en <10min (test con `wg-quick down` aleatorio).
|
|
|
|
### Anti-criterios
|
|
- Si add_pc deja estado parcial (peer en wg0 + no agent en launcher) → invalida.
|
|
- Si SSH backend ejecuta comandos sin audit en VPS → invalida (no fake "ssh OK" sin log).
|
|
- Si dashboard muestra device "online" pero ultimo handshake >24h → invalida (false positive grave).
|
|
|
|
## Sub-issues planificados
|
|
|
|
| ID | Titulo | Esfuerzo |
|
|
|---|---|---|
|
|
| 0146a | cross_compile_device_agent + CGO-free swap a modernc.org/sqlite | 2h ✅ |
|
|
| 0146b | add_pc_wg_bash_pipelines (Fase 1) | 4h |
|
|
| 0146c | add_pc_ssh_bash_pipelines + ssh_exec_capability (Fase 2) | 3h |
|
|
| 0146d | Bundle script multi-OS + manifest templates (Fase 3) | 2h |
|
|
| 0146e | agents_dashboard panel "Add device" + status grid (Fase 4) | 4h |
|
|
| 0146f | monitor_mesh_health pipeline + alertas Matrix (Fase 5) | 1.5h |
|
|
| 0146g | Movil UX doc + smoke real con 4 devices fisicos (Fase 6) | 1h+observacion 7d |
|
|
|
|
Total: ~17h dev + 7d observacion.
|
|
|
|
## Decisiones de diseño
|
|
|
|
1. **Pipeline en bash compose funciones del registry**, no codigo Go monolitico. Permite que cada paso sea trazable + reusable individualmente.
|
|
|
|
2. **modernc.org/sqlite** vs mattn/go-sqlite3: pure Go elimina CGO + cross-compile trivial. Performance es comparable (modernc benchmarks dentro del 10% para nuestro workload de audit append).
|
|
|
|
3. **Backend SSH NO replica el manifest enforcement remoto** — el manifest vive en VPS y filtra antes de SSH. Trade-off aceptable: SSH backend = "trust the VPS sudo enforcement". Para PCs propios usa WG backend.
|
|
|
|
4. **Cada device = un agent Matrix separado** (NO un agent multi-device). Razon: aislamiento blast radius + room por device = UX claro en Element + capability manifest distinto por device. Coste: mas Matrix users + mas claude-code subprocesses.
|
|
|
|
5. **NO usar Ansible/Terraform** para este flujo. Pipeline bash + funciones del registry es suficiente y evita la dep externa. Si crece a >50 PCs, reconsiderar.
|
|
|
|
## Riesgos
|
|
|
|
- **Cross-compile + CGO-free**: el swap a modernc puede romper audit en runtime si schemas no migran. Mitigar con test golden DB + WAL mode check.
|
|
- **Windows systemd equivalente**: Task Scheduler es feo. Considera nssm.exe para autostart fiable. Documentar bien en bundle.
|
|
- **SSH key trust amplification**: backend B requiere SSH agent del VPS confiable a TODOS los target hosts. Si VPS comprometido → todos los SSH targets caen. Reforzar con SSH key per-host + revocacion centralizada.
|
|
- **Mac iCloud signing**: device_agent.app necesitaria notarization para auto-launch en macOS reciente. Skip para POC, abordar si añadimos Mac al mesh real.
|
|
- **Movil notifications**: Element push depends on FCM (Android) / APNs (iOS). Sin push, el operador puede perderse approvals time-sensitive. Doc sobre alternativas (NTFY, Gotify).
|
|
|
|
## Notas
|
|
|
|
- **2026-05-24 — 0146a done**: swap mattn/go-sqlite3 → modernc.org/sqlite v1.50.1 (pure Go). 4 binarios cross-compile OK (linux-amd64 11MB, linux-arm64 10MB, windows-amd64 11MB, darwin-arm64 10MB), todos stripped + statically linked. Build script idempotente en `apps/device_agent/build_all.sh`. Self-test pass en linux-amd64 nativo. Quedan smoke tests reales en windows/darwin/arm cuando 0146b despliegue a peers fisicos.
|
|
- `./fn run add_pc` deberia llamar via mcp__registry__fn_run para que telemetria de issue 0085 quede registrada.
|
|
- Aprovechar 0144b provision-agent-user.sh que ya esta hecho — solo compone, no reescribe.
|
|
- Sub-issue 0146g (UX movil) cierra el flow 0009 completo al fin: "humano controla N maquinas desde movil".
|
|
- Si esto funciona, abrir issue 0147 para "voice control" — Element soporta voice messages; usar transcripcion (Whisper local en VPS) → inyectar como texto al agent.
|