Execução não supervisionada (Away run)
O operador sai; uma fila é processada. Cada item é executado em um processo headless novo,
então um limite de uso ou uma falha custa apenas uma iteração, não a noite inteira.
O estado reside em disco na pasta da execução; a saída do processo substitui o /clear.
Fatos marcados para claude -p estão na skill headless-claude.
Configuração do repositório e perfil. <repo>/.claude/project-workflow.json é opcional;
essa skill lê suas chaves projects_dir (padrão my-projects), profile (padrão
<projects_dir>/WORKFLOW.md), backlog_file (padrão <projects_dir>/backlog.md) e
bootstrap (uma lista de argv, ou nulo). Leia a seção § Away run do perfil se o arquivo
existir: comandos de teste, fontes de descoberta, classes de permissão automática.
Onde o perfil e esta skill diferirem, o perfil vence.
Fases — carregar um arquivo ao entrar em sua fase
| Fase | Quem | Ler |
|---|---|---|
| arm | operador presente | § Arm abaixo, depois discover.md para construir a fila |
| iteration | away-orchestrator, um por processo | iteration.md |
| status, disarm | operador | § Status, § Disarm abaixo |
project-workflow e away-run compartilham arquivos (o arquivo de backlog,
<projects_dir>/proposals/open/), não chamadas, exceto uma: uma linha project
invoca /project-workflow através da ferramenta Skill no modo não supervisionado.
Uma onda de projeto abrange várias linhas project, um grupo de etapas da seção
§ Session shape do wave.md cada (1; 2-3; 4-7). Cada linha trabalha dos nomes na etapa
## Resume até o final do seu grupo, faz commit chore(<NNNN>): checkpoint wave N at step <n>,
e anexa a linha seguinte para a próxima etapa, a menos que o limite tenha sido atingido.
Uma linha anexa uma, attempts 0, apenas se completou pelo menos uma etapa; uma linha
que não completou nenhuma permanece claimed e tenta novamente por conta própria (attempts).
Isso termina: cada linha seguinte segue pelo menos uma das sete etapas da onda,
e o limite de tentativas encerra uma etapa que nunca é concluída.
O checkpoint e a ## Resume são a única transferência (iteration.md § 3).
Layout
<repo>-worktrees/away-<data>/ worktree, branch away/<data> a partir de main
<pasta da execução>/ rastreado em away/<data>; arm.ps1 -RunFolder,
queue.md decisions.md log.md padrão <projects_dir>/away/<data>/
morning-report.md escrito pela iteração de encerramento
<repo>-worktrees/away-<data>-run/ rascunho, não rastreado: away.env, watchdog.sh,
entry-prompt.md, watchdog.log, iter-NNN.*, locks
tarefa agendada away-<repo>-<data> a cada 15 min até a parada forçada
Linhas da fila
templates/queue.md contém o esquema. Colunas: id | item | agent | status | claimed_by | lease_until | attempts | evidence. agent é mechanical-worker,
stream-worker, researcher, project ou discover. Toda edição na fila adquire
o lock: mkdir <scratch>/queue.lock (atômico; se falhar, tente novamente a cada 10 s
por 2 minutos; uma pasta de lock com última modificação há mais de 10 minutos é obsoleta,
com ou sem seu arquivo owner: remova-a), edite, rm -rf o lock. O que acontece após
uma tentativa falha de 2 minutos está em iteration.md § 2 e § 4. Uma claim define
claimed_by como a tag de claim da iteração (iter-NNN, exatamente como o prompt de
entrada fornece) e lease_until; uma lease vencida significa uma iteração morta e
a linha pode ser reivindicada novamente, attempts + 1.
Arm (operador presente)
- Fila. Construa-a com
discover.md: apenas linhas de nível 1, cada uma com uma verificação nomeada. O trabalho de nível 2 torna-se propostas. Nomeie o padrão para cada decisão que uma linha pode encontrar; uma linha com uma decisão em aberto e sem padrão não é enfileirada. - Postura. Diga claramente: a execução usa
--permission-mode bypassPermissions, então toda chamada de ferramenta ocorre sem aviso; regras de negação global ainda se aplicam. "Sem portões" (perguntas abertas tornam-se padrões nomeados, falhas são puladas e repetidas) é opt-in por execução, definido comogates: noneno cabeçalho da fila; nunca inferido de uma execução anterior. - Armar. Faça um teste primeiro, depois para valer, a partir do PowerShell:
powershell -NoProfile -File <skill>/arm.ps1 -Repo <caminho> -StopAt "<YYYY-MM-DD HH:MM>" -Queue <queue.md> -WhatIf. Ele cria a worktree emaway/<data>a partir demain, semeia a pasta da execução a partir detemplates/e faz commit com a fila, executa obootstrapargv da configuração ({worktree}substituído pelo caminho da worktree, cwd o checkout principal; ignorado se a chave estiver ausente ou for nula) e espera por ele, copiawatchdog.sheentry-prompt.mdpara o rascunho, escreveaway.enve registra a tarefa (Register-ScheduledTask, nuncaschtasks /Create: PowerShell 5.1 distorce a citação de/TR). Uma saída diferente de zero do bootstrap recusa antes que qualquer tarefa exista; a worktree e o branch permanecem para inspeção. A tarefa não tem principal, então é executada apenas enquanto o operador estiver logado, em uma janela de console que, se fechada, a mata: trave a tela, não faça logoff. - Verificar.
Get-ScheduledTask -TaskName 'away-*'mostra a tarefa; a primeira execução escrevewatchdog upemwatchdog.log. - Edições posteriores da fila. arm.ps1 faz commit da fila uma vez. Faça commit de
qualquer edição na fila feita após armar em
away/<data>você mesmo (sob o lock da fila assim que a tarefa for executada): iterações tratam trabalho não comitado que não fizeram como sendo de outra pessoa e nunca o preparam.
O que o watchdog faz (watchdog.sh)
- Lança
claude -p --agent away-orchestrator --max-turns N, prompt no stdin. Modelo e esforço vêm do frontmatter do agente; sem--effort, sem flag TTL, sem--disable-slash-commands(isso desabilitaria o Skill). - Julga uma iteração por
is_error/api_error_statuse sequeue.mdmudou, nunca pornum_turns. Três iterações sem mudança na fila a encerram. - Limite de uso: dorme até o reset que a mensagem indica. "Você atingiu seu limite do Opus"
continua no Sonnet (
--model sonnet) apenas para linhasmechanical-worker; com nenhuma reivindicável, dorme até o reset. - Estouro de orçamento (
subtypeerror_max_budget_usd, kindbudget): sem sono, já que o limite é por processo. Ele mantém a claim da linha, então a próxima iteração pega a próxima linha e esta retorna quando sua lease expirar; estouros contam paraFAIL_MAXcomo erros. - Reserva de cota: com gasto imputado de
WINDOW_CAP_USDem uma janela móvel de 5 horas, dorme até que a janela libere espaço; os últimosRESERVE_MINminutos vão para o encerramento. - Fila vazia: uma iteração de encerramento escreve o relatório matinal, então sai.
Qualquer outra saída deixa um relatório provisório escrito pelo watchdog. Toda saída
escreve
STOP, então execuções futuras da tarefa são no-ops; delete-o para retomar. - Após cada iteração de item, ele expira as leases mantidas sob a tag de claim daquela iteração, para que uma linha interrompida por um limite ou erro seja repetida, não abandonada até o encerramento. Ele pula isso após o encerramento, que não reivindica nada, e após um estouro de orçamento (acima).
- Registra
claude: <caminho>no início de cada iteração: o binário que está prestes a executar. - Recusa executar em
main, em um checkout principal, ou em um branch que não sejaaway/*. - Execução de teste:
CLAUDE=<script simulado> AWAY_NO_SLEEP=1 bash watchdog.sh <away.env>contra uma worktree de rascunho emaway/*; os sonos são registrados, não executados. UmCLAUDEouPYdefinido no ambiente vence aquele nomeado emaway.env, então o script simulado é executado mesmo com umaway.envescrito pelo arm; confirme pela linha de logclaude: <script simulado>.
Status
Veja o final de <scratch>/watchdog.log; leia queue.md. Antes de confiar que "outro watchdog
está ativo", confirme um processo claude.exe (tasklist) e uma linha iteration N starting recente: um lock órfão estaciona toda execução silenciosamente. Git Bash não tem
pgrep.
Desarmar
powershell -NoProfile -File <skill>/disarm.ps1 -Repo <caminho> -Date <data>: ele escreve
STOP, cancela o registro da tarefa e verifica se Get-ScheduledTask -TaskName 'away-*' não retorna nada. Uma tarefa deixada registrada continua gerando bash a cada 15
minutos. A worktree e o branch permanecem para revisão: leia o relatório matinal, então
faça merge de away/<data> pela rota usual do repositório, ou delete-o.
Por que foi construído assim
- A resiliência vive fora do CLI.
CronCreate durable:trueretornou apenas para a sessão (2026-09-19);/loopreentra na mesma sessão;nohup … &a partir de uma chamada de ferramenta Bash tem como pai aquele shell; Git Bash não temsetsid. - Um limite de uso é dormido até o reset que a mensagem indica, não por um backoff crescente,
e uma iteração nunca é julgada falha por um
num_turnsbaixo: um backoff ultrapassa o reset, e uma iteração pode fechar uma linha em um único turno reportado.