teqo-backup/docs/plans/ops110-attach-detach-runs-agent.md

93 lines
7.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# OPS110 — Acompanhar runs longos de agente por attach/detach, sem manter terminal aberto
Status: rascunho
Atualizado em: 2026-09-15
Issue: #1019
Priority: P2
Impeccable: A — N/A (ferramenta/ops; sem UI de produto)
Rascunho UI: N/A — sem UI
Appetite: ~1–2 dias eng
Responsável: —
## Intenção
Hoje cada run de agente exige presença: o opencode roda no terminal do workstation e, se o TUI fechar (ou a sessão SSH cair), o run para. O fsolla quer largar um `/work-issue` ou `/plan-issue` longo no workstation e ir embora — almoço, reunião, fim de expediente — acompanhando do laptop ou do celular, entrando e saindo da sessão quantas vezes quiser enquanto o agente trabalha.
Não é um pedido de "rodar agentes em background" solto: é o mesmo run de hoje, com o ciclo de vida desacoplado do terminal que o observa. O que os agentes fazem não muda; muda como o humano os acompanha. O painel de Issues (OPS109) também quer abrir a sessão do run daquela Issue — para isso este item precisa deixar a sessão **endereçável**, não só persistente.
## Persona e fluxo
- **Persona / contexto:** fsolla no workstation, com worktrees de agente ativos; longe dele, no laptop ou celular, por SSH ou rede confiável. Não quer vigiar em tempo real — quer poder espiar, sair e voltar.
- **Job principal:** iniciar um run longo, desconectar, e (re)entrar na sessão de outro dispositivo quando quiser, sem interromper o agente.
- **Fluxo desejado:**
1. Dispara o run do jeito que já dispara hoje (worktree + skill, ex. `/work-issue`).
2. Fecha o terminal do workstation ou perde o SSH; o agente continua trabalhando.
3. Do laptop ou celular, entra na sessão existente e vê o histórico/estado do agente; acompanha ou digita se quiser.
4. Sai de novo — quantas vezes quiser — sem matar o run.
5. Quando decidir encerrar, encerra de forma explícita, nunca por acidente ao fechar o cliente.
- **Anti-goals de produto:**
- Não vira pool/supervisor de agentes (o pool morreu na OPS65; não ressuscitar).
- Não automatiza produção nem cria caminho que burle gates humanos (PR/CI/approval).
- Não cria um segundo jeito de iniciar sessão que ignore o worktree/claim vigente.
- Não exige terminal aberto no workstation nem processo pendurado em SSH.
- Não abre porta pública na internet.
## Objetivo e aceite
- O run continua trabalhando quando nenhum cliente está olhando (nenhum terminal/SSH aberto no workstation).
- (Re)entrar na sessão de outro dispositivo retoma exatamente onde estava — mesma sessão, mesmo worktree, mesmo histórico.
- Sair do cliente nunca é o mesmo que encerrar o run; encerrar é ato explícito.
- Nada novo escutando além do loopback sem credencial: se alguma superfície passar de `127.0.0.1`, exige autenticação e só em rede confiável (SSH/tailnet) — fail-closed sem credencial.
- O worktree/branch em que o agente roda continua sendo o contrato de ambiente; não há nova forma de claim nem de sessão órfã.
- A sessão de um run é endereçável a partir da Issue/worktree (dá para saber como chegar nela sem adivinhar) — pré-requisito do "abrir a sessão do agente" do painel OPS109.
## Dados (intenção)
- **Vou apresentar dados?** Não.
- **Decisões desbloqueadas:** N/A.
- **Forma:** N/A — `Dados: N/A` — ferramenta/ops de operação de agentes; sem métrica, gráfico ou dado eleitoral/de contato envolvido.
## Dados da decisão (literais)
- Se algo escutar além do loopback, a credencial é a do próprio opencode por ambiente: `OPENCODE_SERVER_PASSWORD` (e `OPENCODE_SERVER_USERNAME`); valores reais vivem fora do repo (workstation), nunca commitados — sem credencial, a superfície responde 401.
- "Loopback" aqui é `127.0.0.1`, o default atual do modo servidor do opencode 1.18.31.
- Os nomes acima são o contrato disponível hoje; porta, host de bind, paths de log/socket e nome de serviço são hipóteses do plano de implementação, não de contrato de produto.
- O painel OPS109 consome este endereçamento (abrir a sessão da Issue); o artefato/mecanismo concreto de descoberta é decisão do plano de implementação — sem mapa paralelo.
## Direção no codebase (hipótese)
- **Áreas prováveis:** `scripts/lib/worktree.mjs` (diretiva `launch`, ~207–233) e `.agents/shell/worktree.sh` (~104–112, executa o launch); documentação em `docs/AGENT-OPS.md` e `AGENTS.md`.
- **Duas direções citáveis, sem escolha aqui:** (a) servidor nativo persistente do opencode (`opencode serve`, dono da sessão) com cliente `opencode attach <url>` de qualquer dispositivo (replay/`--continue`); ou (b) multiplexador de terminal mantendo o TUI vivo entre anexações. A forma é decisão do plano de implementação; o aceite de produto é o mesmo.
- **Precedente a olhar:** OPS106 `scripts/auto-unblock.mjs` (spawn destacado + log + flock) mostra o padrão local de processo que sobrevive ao invocador, embora não seja sessão interativa; OPS40 `scripts/dev.mjs` mostra wrapper de CLI passando flags.
- **Risco de acoplamento:** o launch atual nasce da shell function e depende do `cd`/worktree — qualquer modo destacado precisa preservar worktree/branch e não duplicar a porta de entrada; o painel OPS109 consome o mesmo endereçamento (sem mapa paralelo). Expor bind além do loopback é o risco nº 1: a workstation não tem IP tailnet documentado (só o homeserver) e o repo não tem precedente de acesso remoto a ela.
## Dependências
- Nenhuma dura. Depende de capacidades já presentes no opencode instalado (servidor + attach). O OPS109 (painel) depende deste item para abrir a sessão da Issue — o endereçamento da sessão é aceite daqui.
## Fora de escopo
- Multi-usuário ou servir agentes para terceiros.
- Web UI como produto — se útil na implementação, é meio, não aceite.
- Notificações/push de progresso, painel de frota de runs, métricas de agentes.
- Mudanças no fluxo de claim/worktree ou nos gates de PR/deploy.
## Rabbit holes de produto
- **"Já que tem servidor, vira painel de frota".** Se alguém "só completar": status de todos os runs, iniciar/parar agentes, retomar por lista. **Corte neste item:** uma sessão, um worktree, attach/detach — nada de orquestração.
- **"Expõe na tailnet e pronto".** Se alguém "só completar": bind aberto sem auth "porque a rede é confiável". **Corte neste item:** qualquer superfície além do loopback exige credencial, fail-closed.
- **"Persistência própria de sessão".** Se alguém "só completar": banco/daemon próprio guardando estado do run. **Corte neste item:** usar o que o opencode já persiste; nada de um segundo dono da sessão.
## Questões em aberto (produto)
- **Servidor nativo vs multiplexador?** **Opções:** A servidor persistente + `attach` | B multiplexador de terminal mantendo o TUI | C os dois. **Recomendação:** deixa ao impl plan decidir; produto só exige o mesmo aceite (run sobrevive sem cliente, reattach exato, encerramento explícito, auth fora do loopback). _(assumido — validar com produto)_
- **De onde se acompanha no celular?** **Opções:** A SSH/TUI no terminal do celular | B navegador (web UI) | C só laptop por enquanto. **Recomendação:** A — reaproveita a superfície TUI já validada; B adiciona escopo de UI que o aceite não exige.
## Referências
- GitHub Issue #1019
- `scripts/lib/worktree.mjs` (diretiva `launch`) e `.agents/shell/worktree.sh` (execução do launch) — de onde o run nasce hoje
- `scripts/auto-unblock.mjs` — precedente OPS106 de processo local destacado
- `docs/AGENT-OPS.md` — operação de agentes paralelos; `AGENTS.md` — convenções do repo
- `docs/ops/teqo-1313-deploy.md` — topologia de rede (homeserver × workstation)
- opencode 1.18.31 instalado: `opencode serve`, `opencode attach`, `opencode run --attach` e `opencode web` (help local)