Estado fora do modelo: arquivos e git como memória
Num loop longo, o contexto do modelo vai ser compactado, resetado ou trocado por uma sessão nova. O que só existia na conversa some ou volta como resumo, misturando fato e palpite. A saída: sessão descartável, estado em arquivos e no git, e todo ciclo começa relendo. Você monta um ciclo assim e o interrompe de propósito.
1Por que a memória do modelo não aguenta um loop longo
2A lista de itens com passes, o arquivo de progresso e o git log
3Interromper e retomar sem refazer nem pular
4Git como desfazer e como histórico do loop
Objetivo: montar um ciclo descartável que relê o estado em arquivo, faz um item, verifica e commita, e retomar depois de interromper sem refazer nada.
01 · Uma sessão descartável, um estado que fica
Clique em cada passo do ciclo: o que ele lê e o que deixa gravado.
Aula 501 · Uma sessão descartável, um estado que ficaClique em cada passo do ciclo: o que ele lê e o que deixa gravado.
A sessão acaba ou cai; a próxima começa relendo os arquivos e segue do primeiro pendente.
1/6
Sessão nova
Pode ser um /clear, uma compactação, um codex exec novo, o Ralph chamando de novo ou outra pessoa assumindo. O desenho parte do pior caso: a sessão não lembra de nada e pode ser interrompida no meio.
Role a página: cada etapa abaixo acende a sua parte do diagrama.
1/6
Sessão nova
Pode ser um /clear, uma compactação, um codex exec novo, o Ralph chamando de novo ou outra pessoa assumindo. O desenho parte do pior caso: a sessão não lembra de nada e pode ser interrompida no meio.
2/6
Relê o estado
No harness de longa duração da Anthropic (26/11/2025), toda sessão começa assim: onde estou (pwd), o que foi feito (git log e o arquivo de progresso), qual o próximo item, e um teste básico antes de codar. A lista de itens é JSON com o campo passes; o post diz que o modelo sobrescreve JSON menos que Markdown.
3/6
Faz um item
Escolhe o primeiro item pendente e faz só ele. No post da Anthropic, as sessões seguintes só podem mudar o campo passes; não reescrevem nem apagam itens da lista.
4/6
Verifica e marca
O item só vira passes: true se a verificação daquele item passou. A linha no progresso diz quando e o resultado. Se falhou, o item continua pendente e o motivo fica registrado.
5/6
Commit
O commit é o checkpoint: se a próxima sessão cair, nada do que foi verificado se perde; se um item saiu errado, git revert desfaz. O LOOP-R usa o mesmo princípio para versões do processo ("git é o mecanismo de promoção e rollback"; detalhe no curso 5).
6/6
Relê a pasta, não a conversa
A sessão é descartável; o estado não. O que precisa sobreviver a uma compactação, a um reset ou a uma troca de modelo vai para arquivo e commit antes do fim do ciclo.
O kit execucao-longa leva a ideia para sete arquivos (goal, plan, state, progress, failures, decisions, canal): é a aula 1 do curso 2.
02 · Um ciclo descartável em Python
Cada execução é uma "sessão" que não lembra de nada: relê, faz um item, verifica, grava e commita. Sem modelo: a ação é escrever um arquivo.
Terminal · preparar a pasta
mkdir -p ~/ensaio-loop/estado && cd ~/ensaio-loop/estado && git init -q
cat > features.json <<'EOF'
[
{"id":"f1","descricao":"ler o CSV","passes":false},
{"id":"f2","descricao":"contar linhas","passes":false},
{"id":"f3","descricao":"gravar o resumo","passes":false}
]
EOF
git add -A && git commit -qm inicio
ciclo.py
#!/usr/bin/env python3
"""Um ciclo que começa do zero toda vez: relê o estado nos arquivos, faz UM item, grava e commita."""
import json, subprocess, sys, datetime, pathlib
estado = pathlib.Path("features.json")
itens = json.loads(estado.read_text())
pendentes = [i for i in itens if not i["passes"]]
if not pendentes:
print("nada pendente: objetivo cumprido")
sys.exit(0)
item = pendentes[0]
print(f"releu features.json: {len(itens) - len(pendentes)} feitos, {len(pendentes)} pendentes")
print(f"faz: {item['id']} ({item['descricao']})")
pathlib.Path(f"{item['id']}.txt").write_text(item["descricao"] + "\n") # a "ação"
item["passes"] = pathlib.Path(f"{item['id']}.txt").exists() # a "verificação"
estado.write_text(json.dumps(itens, ensure_ascii=False, indent=2) + "\n")
agora = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
with open("progress.md", "a") as f:
f.write(f"| {agora} | {item['id']} | passes={item['passes']} |\n")
subprocess.run(["git", "add", "-A"], check=True)
subprocess.run(["git", "commit", "-qm", f"feito: {item['id']}"], check=True)
print(f"commit: feito: {item['id']}")
Terminal · rodar, "cair" e retomar
python3 ciclo.py
# feche o terminal aqui, abra outro e volte para a pasta
cd ~/ensaio-loop/estado
python3 ciclo.py && python3 ciclo.py && python3 ciclo.py
git log --oneline
Os hashes mudam na sua máquina; a ordem e as mensagens não.
Troque a linha da "ação" por uma chamada ao agente (codex exec ou claude -p) e a da "verificação" por um teste que roda de verdade. O resto (reler, um item, marcar só com prova, commit) fica igual. A verificação desta versão de brinquedo é fraca de propósito: só confere que o arquivo existe (nível 2 na escala da aula 6).
03 · Interrompa no meio e veja a retomada
Cada tarefa é um ciclo. Rode, interrompa e rode de novo: o que já tem commit não é refeito.
pendentes (passes: false)
nesta sessão
passes: true + commit
verificação falhou
Simulação ilustrativa no navegador. A falha é proposital: item sem prova não vira passes: true.
04 · Prática
Na sua máquina. Não gasta cota: não há modelo no ciclo.
E1 · Três sessões, três commits
10 min
Prepare a pasta, cole o ciclo.py e rode uma vez. Feche o terminal, abra outro e rode até aparecer "nada pendente".
Pronto quando: A última rodada imprime nada pendente: objetivo cumprido, e git log --oneline | wc -l → 4.
E2 · A verificação que reprova
15 min
Acrescente o item f4 "arquivo vazio" e mude a verificação para exigir arquivo não vazio (stat().st_size > 0). Faça a ação do f4 gravar um arquivo vazio e rode.
Pronto quando:python3 -c "import json;print([i['passes'] for i in json.load(open('features.json'))])" → [True, True, True, False], e tail -1 progress.md termina com passes=False |.
E3 · A lista de um trabalho seu
15 min
Escolha uma tarefa real de várias horas e quebre em pelo menos 5 itens verificáveis num features.json, todos com passes: false, numa pasta de projeto com git.
Pronto quando:python3 -c "import json;d=json.load(open('features.json'));print(len(d)>=5, any(i['passes'] for i in d))" → True False, e git log --oneline -1 -- features.json mostra o commit da lista.
05 · Teste da aula
Pergunta 1 de 4
Depois de uma compactação, o resumo diz "f3 concluído", mas features.json mostra f3 com passes: false e não há commit de f3. O que vale?competência
Correto
O resumo mistura o confirmado com o palpite. O que tem prova é o que está no arquivo com commit. Marcar sem verificar é exatamente o atalho que a lista existe para impedir.
Não é essa
O resumo mistura o confirmado com o palpite. O que tem prova é o que está no arquivo com commit. Marcar sem verificar é exatamente o atalho que a lista existe para impedir.Rever: Uma sessão descartável, um estado que fica
Pergunta 2 de 4
Por que o post de harness da Anthropic guarda a lista de itens em JSON e não em Markdown?
Correto
É a razão dada no próprio post: com JSON o modelo tende a só trocar o campo passes, em vez de reescrever a lista. As sessões seguintes só podem mudar esse campo.
Não é essa
É a razão dada no próprio post: com JSON o modelo tende a só trocar o campo passes, em vez de reescrever a lista. As sessões seguintes só podem mudar esse campo.Rever: Uma sessão descartável, um estado que fica
Pergunta 3 de 4
Qual a vantagem de um commit por item em vez de um commit no fim?
Correto
Se a sessão cair, o que foi verificado está salvo; se um item saiu errado, git revert desfaz só ele. Um commit no fim perde tudo numa queda e mistura acertos com erros.
Não é essa
Se a sessão cair, o que foi verificado está salvo; se um item saiu errado, git revert desfaz só ele. Um commit no fim perde tudo numa queda e mistura acertos com erros.Rever: Um ciclo descartável em Python
Pergunta 4 de 4
Na simulação, a sessão caiu no meio de um item. O que acontece com ele na retomada?competência
Correto
Sem verificação e sem commit, não há prova de que terminou: volta para pendentes e é refeito. O que já tem commit não é refeito.