My App
Agents

Red→Green Iterate Workflow

Ciclo testes vermelhos → user feedback → testes verdes pra resolver bug pipelines. State machine, decision tree pra AskUserQuestion, templates literais, contrato de reversibilidade total. Bootstrap autocontido pra sessão zerada replicar.

TL;DR. Quando o user pede "review feedbacks → arruma bug pipeline → testes red→green → solvable por LLM agent", siga este workflow. Não improvise estilo de commit nem ordem das fases. Resultado real: 27 feedbacks analisados, PR mergeado limpo, foundation de observabilidade no ar — sem retrabalho, sem loop infinito.

Bootstrap pra sessão zerada. Se você é um agente Claude Code começando agora:

  1. Leia esta página até o fim antes de tocar em código
  2. Estabeleça o contrato de reversibilidade (seção 3) antes de qualquer commit — git tag session-start-<topic>-<ts> + branch isolada
  3. Aplique a state machine (seção 5) — não pule fases
  4. Copie templates literais (seção 6) — não improvise estilo de commit
  5. Pause em pontos do decision tree (seção 7) — não decida unilateralmente
  6. Responda o self-check (seção 17) — se algum item falhar, pergunta antes de seguir

Contrato de reversibilidade. Toda sessão autônoma que rode este workflow tem garantia explícita: qualquer trabalho feito pode ser desfeito, em 5 níveis de granularidade (do último commit até a sessão inteira), com 1 comando cada. Sem necessidade de --force-push, sem reset --hard, sem panic. Detalhes formais na seção 3.

1. Quando aplicar este workflow

Pré-condições obrigatórias no prompt do user (4 gatilhos). Se algum falta, provavelmente este não é o workflow certo:

  1. "go deep" — exploração profunda em múltiplas fontes (DB + logs + frontend + backend)
  2. "generate /html report" — saída tangível antes de propor mudança
  3. "red state → green" — testes falhando antes de qualquer fix
  4. "solvable by an llm agent" — pipeline reusável, não fix one-shot

Trigger phrase canônica observada na sessão fundadora:

"Do a review on what its gathered, go deep in logs, [...] generate /html report with findings, common pains, categorize, [...] develop a plan to tackle each. To solve an issue, automated tests, ensuring red state, then fix until green. Solid pipeline solvable by an llm agent."

Se o user não pediu nada parecido, ofereça este workflow só se a tarefa for complexa o suficiente. Senão, faça direto.

2. Sessão fundadora

session 72ccdb3f (arquivada localmente, não pública). Projeto interno: produto SaaS com agente conversacional + feedback tracker próprio.

Tarefa: revisar ~30 feedbacks brutos coletados pelo agente; classificar; gerar plano de correção determinístico; entregar PR mergeavel com observability foundation pra destravar o pipeline issue-tracker → bug fix.

Resultado: 1 PR mergeado limpo (PKG-00), 39 testes verdes, 4 gaps de infra fechados, retrocompatibilidade preservada por 6 baselines protegidos. Foundation destrava 10 PKGs subsequentes (geo guard, anti-sycophancy, NLP filter loss, share-link bugs, etc).

3. Contrato de reversibilidade

Conceito fundador. Sessão autônoma sem contrato de reversibilidade é uma bomba. Sessão com contrato é uma proposta — user revisa, aceita ou descarta.

3.1 Os 5 níveis de reversão

NívelGranularidadeComandoCustoQuando usar
L1Último commitgit checkout HEAD~1 -- <files> + git reset --soft HEAD~1Quase zero — working tree preservadoErro óbvio no último step
L2Uma fase (red, green, etc)git reset --soft <tag-da-fase-anterior>Baixo — múltiplos commits viram unstagedToda fase precisa repensar
L3Um PKG inteirogit revert <hash-do-merge>..HEAD ou git reset --soft <tag-pkg-NN-start>Médio — preserva diff pra estudoPKG inteiro foi pelo caminho errado
L4Sessão inteiragit checkout main && git branch -D red-green/<topic> + git tag -d session-start-<topic>Alto se sessão durou 6h — mas zero risco residualSessão autônoma inteira falhou validação humana
L5Cherry-pick parcialgit checkout -b red-green/<topic>-v2 main && git cherry-pick <good-commits>Médio — escolhe o que salvarSessão majoritariamente boa, partes ruins descartadas

3.2 Pré-condições obrigatórias

Antes do primeiro commit da sessão, o agente garante:

  1. Branch isolada criada: git checkout -b red-green/<topic>-<YYYYMMDD> — nunca commit em main/master
  2. Tag de início: git tag session-start-<topic>-<ts> aplicada no commit pai (cabeça atual de main no momento de fork). Esta tag é o ponto-de-zero da sessão.
  3. Tag de início pushada (se remote existe): git push origin session-start-<topic>-<ts> — protege contra git tag -d acidental local.
  4. Working tree limpo: git status --porcelain retorna vazio antes do bootstrap. Se sujo, dirty_commit separado (vide seção 12.2 Aider pattern).

Sem esses 4 itens, o contrato está quebrado. Sessão não inicia.

3.3 Pontos de checkpoint

A cada transição de fase do state machine, agente aplica tag adicional:

git tag phase-red-<topic>-<ts>        # ao entrar em red
git tag phase-green-<topic>-<ts>      # ao entrar em green
git tag phase-probe-<topic>-<ts>      # ao entrar em probe_review
git tag pkg-NN-merged                 # ao mergear (terminal — não move)

Cada tag = âncora pra reset L2. Permite "voltar pra antes do green" sem perder o trabalho do red.

3.4 Ponto-de-não-retorno

Uma vez que pkg-NN-merged foi pushada pro remote, não desfaz. Por construção:

  • Tag pushada = terminal (vide Aider em 12.4)
  • Reverter = abrir novo PKG com revert(NN): undo pkg-NN — <reason>, não rewrite

Sem exceção. --force-push em sessão autônoma é violação de contrato.

3.5 Discard de sessão inteira (L4)

Sequência canônica quando user aprova descarte total:

# 1. Sair da branch
git checkout main

# 2. Apagar branch local (todo o trabalho some)
git branch -D red-green/<topic>-<YYYYMMDD>

# 3. Apagar branch remota (se foi pushada)
git push origin --delete red-green/<topic>-<YYYYMMDD>

# 4. Apagar tags de fase + session-start
for tag in $(git tag --list "phase-*-<topic>-*" "session-start-<topic>-*"); do
  git tag -d "$tag"
  git push origin --delete "refs/tags/$tag" 2>/dev/null || true
done

# 5. Sanity: nada da sessão sobreviveu
git log --grep "<topic>" --oneline   # deve retornar vazio

5 comandos. Reversibilidade L4 garantida.

3.6 Cherry-pick parcial (L5)

Quando user gostou de N de M PKGs e quer descartar o resto:

# 1. Nova branch a partir de main
git checkout -b red-green/<topic>-v2 main

# 2. Cherry-pick os PKGs aprovados (in order)
git log red-green/<topic>-<YYYYMMDD> --grep '^pkg(0[12]):' --reverse --format='%H'
# pega hashes → cherry-pick

git cherry-pick <hash-pkg-01-scaffold> <hash-pkg-01-green> <hash-pkg-02-scaffold> ...

# 3. Tag inicial da v2
git tag session-start-<topic>-v2-<ts>

# 4. Branch original pode ser apagada agora (L4)

L5 é a forma de sessão autônoma "falhar parcialmente". O bom do trabalho sobrevive sem o ruim.

3.7 O contrato escrito

O agente escreve este compromisso no body do primeiro commit da sessão:

chore(<topic>): bootstrap autonomous session

Reversibility contract:
- Branch: red-green/<topic>-<YYYYMMDD>
- Session start tag: session-start-<topic>-<ts>
- L1-L5 rollback supported (see docs/agents/red-green-iterate-workflow#3)
- No force-push, no reset --hard, no rewrite of pushed history
- Terminal markers: pkg-NN-merged tags (push = irreversible)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Este commit é a assinatura do contrato. Auditor (user, code reviewer, outro agente) lê e sabe exatamente o que está protegido.

4. Anatomia: dois cycles aninhados

OUTER cycle (por PKG):
  explore → plan (n×PKG.md) → red → expand_red → green → probe_review → merged

INNER cycle (dentro de cada estado):
  ação → status report ao user → AskUserQuestion se trigger bateu → próximo estado

A página inteira gira em torno da OUTER. INNER é a granularidade de cada turno.

Cada transição da OUTER aplica uma tag (vide 3.3) — a tag é o ponto de reversão L2.

5. State machine

EstadoCritério de entradaCritério de saídaArtefatoTag aplicadaReverte para
session-startBranch isolada + working tree limpoTag session-start-<topic>-<ts> aplicada + contrato commitadoCommit chore(<topic>): bootstrap autonomous sessionsession-start-<topic>-<ts>(nada — é o piso)
pendingPKG-NN.md criado, escopo definidoUser confirmou escopo via AskUsertasks/PKG-NN.md frontmatter status: pendingsession-start
exploringPelo menos 5 TaskCreate paralelos em fontes independentesFindings sintetizados em HTML report/tmp/claude-html/<topic>-<ts>.htmlsession-start
plannedHTML report aberto + plano de N pacotes mapeadoUser aprovou recorteREADME.md, TEMPLATE.md, PROMPT.mdphase-planned-<topic>-<ts>session-start
redTest scaffold escrito, todos falhampytest ≥N failed + ≥1 passed (baseline)commit pkg(NN): scaffold red ...phase-red-<topic>-<ts>planned
expand_redUser pediu mais cobertura ou baseline faltapytest ≥M failed + ≥6 passed (retrocompat)commit pkg(NN): expand red ...red
greenCada gap tem fix mapeadoTodos os testes do PKG passam + zero regressão lateralcommit pkg(NN): make ... greenphase-green-<topic>-<ts>red ou expand_red
probe_reviewMigração aplicada prod + UI wired + smoke okUser reviewou e aprovou mergestatus .md → probe_reviewphase-probe-<topic>-<ts>green
mergedPR squashed em main, tag aplicada e pushada— (terminal)tag pkg-NN-merged, status .md → mergedpkg-NN-merged (push)L3 only — abrir PKG novo de revert

Transições críticas com guard:

  • red → expand_red só se user pediu cobertura extra ou falta baseline. Senão pula pra green.
  • green → probe_review exige zero regressão em suites laterais. Não é só "PKG passa".
  • probe_review → merged é o único ponto onde squash acontece. Antes disso, commits ficam no branch.
  • merged é o único estado que viola reversibilidade fácil. Push da tag = ponto-de-não-retorno.

6. Templates literais

Copy-paste ready. Anonimizados onde precisa.

6.1 Frontmatter de tasks/packages/PKG-NN-<slug>.md

---
status: pending  # → red → red_expanded → green → probe_review → merged
priority: P0  # P0 P1 P2 P3 P4
gaps:
  - G1: <gap description>
  - G2: <gap description>
tests_failing: 0
tests_passing: 0
pr: null
refs:
  - <product>.com/issues
---

6.2 Bootstrap de sessão autônoma (assinatura do contrato)

# Pré-flight
git status --porcelain                                # MUST be empty
TOPIC="<topic>"
TS=$(date -u +%Y%m%dT%H%M%SZ)
BRANCH="red-green/${TOPIC}-$(date -u +%Y%m%d)"

# Cria branch isolada
git checkout -b "$BRANCH"

# Tag de início
git tag "session-start-${TOPIC}-${TS}" HEAD
git push origin "session-start-${TOPIC}-${TS}" || true   # remote pode não existir

# Primeiro commit: contrato
git commit --allow-empty -m "$(cat <<EOF
chore(${TOPIC}): bootstrap autonomous session

Reversibility contract:
- Branch: ${BRANCH}
- Session start tag: session-start-${TOPIC}-${TS}
- L1-L5 rollback supported
- No force-push, no reset --hard, no rewrite of pushed history
- Terminal markers: pkg-NN-merged tags (push = irreversible)
EOF
)"

6.3 Commit seed pipeline (planned state)

docs(packages): seed <project> issues package pipeline + Ralph runbook

Roadmap orientado a pacotes (não semanas). Cada PKG = 1 PR mergeable,
spec auto-contida, test red→green deterministico.

N pacotes seed:
- PKG-00: <foundation>
- PKG-01: <feature> (P0, feedback #X)
[...]

Setup files:
- README.md, PROMPT.md, RALPH_RUNBOOK.md, TEMPLATE.md

Refs: <product>.com/issues

6.4 Commit scaffold red (entra em fase red, tag phase-red-...)

pkg(00): scaffold red test for <foundation>

Test suite confirms N infra gaps blocking the <pipeline>:
- G1 <module> <kwarg/field> missing
- G2 <module> <fn> missing
- G3 <model> <columns> missing
- G4 <model>.<field> missing + <fn> doesn't accept <param>

Current state: 10 failed, 1 passed.

Refs: <product>.com/issues

Após commit:

git tag "phase-red-<topic>-$(date -u +%Y%m%dT%H%M%SZ)" HEAD

6.5 Commit expand red

pkg(00): expand red test suite (27 failed, 6 passed)

User feedback: cobrir mais cenários antes do fix — retrocompatibilidade
fica como guard contra regression.

Added coverage:
- G1 e2e: <signal> reaches HTTP payload + persists to DB
- G2 <fn>: edge cases (mapping file + fallback + plain phone)
- G3 endpoint: <verb> <path> (auth, idempotent)
[...]

Retrocompat baselines now protected (6 tests must keep passing):
- <fn> legacy 3-arg call
- POST <path> without <new_kwarg>
[...]

Refs: <product>.com/issues

6.6 Commit make green (entra em fase green, tag phase-green-...)

pkg(00): make all tests green — <foundation>

Fixes for the N infra gaps:

G1 — <module> agora aceita <kwarg>. Backend já persistia.
G2 — <module>/__init__.py expõe <fn> como top-level.
G3 — <model> tem <field1>+<field2>+<field3>. <verb> <path> idempotente.
G4 — <model>.<field> column adicionada. Backfill em migração.

Test status:
  test/packages/test_pkg_00.py — 33 passed in 11.12s
  test/components/ — zero regressions
  test/bases/ — zero regressions

Refs: <product>.com/issues

6.7 Status report ao user (estilo caveman)

10 failed, 1 passed — RED confirmado. Tag phase-red aplicada. Commit + AskUser.
39 passed (was 33; +6 partner). Migração Neon. phase-green tagged. Status .md → green.

Padrão: [N] failed, [M] passed — <signal>. <tag aplicada>. <next>. Sem artigos.

6.8 Comandos de rollback (L1-L5)

# L1 — desfaz último commit, working tree preservado
git checkout HEAD~1 -- $(git diff-tree --no-commit-id --name-only -r HEAD)
git reset --soft HEAD~1

# L2 — volta pra fase anterior (lista tags primeiro)
git tag --list "phase-*-<topic>-*" | sort
git reset --soft "phase-red-<topic>-<ts>"

# L3 — desfaz PKG inteiro (revert preserva história)
git revert --no-commit <hash-first-pkg-commit>..<hash-last-pkg-commit>
git commit -m "revert(NN): undo PKG-NN — <reason>"

# L4 — sessão inteira sumir (vide 3.5)

# L5 — cherry-pick parcial (vide 3.6)

7. Decision tree pra AskUserQuestion

Regras explícitas. Se nenhuma dispara, não pergunta — caveman + ação direta.

CondiçãoPergunta sugerida
Antes do bootstrap da sessão"Confirma branch isolada red-green/<topic> + tag session-start? Aprovação L4 fácil depois."
Prestes a aplicar migração de DB em prod"Preview SQL anexado. Aplicar agora ou gerar dry-run primeiro?"
Mudança altera role/permissão de usuário existente"<role A> = founder; <role B> = partner? Ambos têm dogfood demote?"
RED scaffold pronto, antes de fixar"Expandir cobertura antes do fix ou já parto pra green?"
Próximo PKG vai começar"PKG-NN começa red agora ou termina docs do PKG anterior?"
Antes de push da tag pkg-NN-merged (ponto-de-não-retorno)"Pushar tag terminal pkg-NN-merged? Após isso, só revert via PKG novo."
Dúvida custaria menos de 30s mas pode dar 30min de retrabalho"<question específica>"
Conflito entre dois critérios de classificação"<X> conta como sinal real ou dogfood?"

Pattern: 12 ocorrências na sessão fundadora + 2 novas (bootstrap, push terminal). Não mais.

Anti-regra: depois de receber resposta, execute imediatamente sem confirmar de novo.

8. Caveman mode

Workflow assume caveman mode full ativo. Skill caveman (/caveman full) ou /caveman ultra se contexto for crítico.

Status reports em fragments. Drop articles, drop pleasantries, drop hedging. Code blocks e commits ficam normais.

Não tente "ser mais claro" voltando pra verbose. Clareza vem do número concreto (27 failed vs 6 passed), não do floreio.

9. Paralelização

FasePadrãoNão fazer
exploring5-7 TaskCreate em paralelo + 1-2 Agent subagentsLoop sequencial de greps
red / greenSequencial, determinísticoParalelizar fix de gaps interdependentes
Bash multi-callAté 6 chamadas independentes num único turnoChain com && quando podiam ser paralelas
Subagent (Agent tool)Quando query é independente e respondeu pra atualizar contextoPra trabalho que precisa contexto contínuo

10. Rastreabilidade

4 camadas redundantes — perde 1, ainda recupera contexto:

  1. .md status files (tasks/packages/PKG-NN.md): frontmatter status: <state> evolui com cada commit.
  2. Git tags por fase (phase-red-<topic>-<ts>, phase-green-..., pkg-NN-merged): âncoras de rollback L1-L3.
  3. Git tag de sessão (session-start-<topic>-<ts>): âncora de rollback L4.
  4. Commit metadata (Refs: <product>/issues#N + Co-Authored-By): foreign key + autoria-agente.

Se sessão quebrar no meio, próximo agente roda:

git tag --list "session-start-*" "phase-*" "pkg-*-merged" | sort
grep -l 'status:' tasks/packages/PKG-*.md | xargs grep '^status:'
git log --oneline -20

E reconstrói o estado em menos de 1 min.

11. Git como base de dados do workflow

Insight central: git não é só versionamento, é o storage do state machine + storage da reversibilidade. Cada artefato git tem papel funcional, não cosmético.

Artefato gitPapel no workflowReverte como?Quem lê
CommitTransição entre estados. Subject = estado novo.L1 — git checkout HEAD~1 -- <files> + soft resetPróximo agente, reviewer
Branch (red-green/<topic>)Escopo de 1 sessão autônoma. Vida curta.L4 — git branch -DOwner da sessão
Tag session-start-<topic>-<ts>Piso da sessão. Âncora L4.(não reverte — é o piso)Discovery + auditoria
Tag phase-<state>-<topic>-<ts>Checkpoint por fase. Âncora L2.L2 — git reset --soft <tag>Rollback de fase
Tag pkg-NN-merged (pushed)Terminal. Marca "estado final".L3 only — abrir PKG de revertDiscovery "o que fechou"
PR review (approve)Gate humano. Substitui AskUser quando precisa revisão estruturada.(não reverte — é gate)Reviewer
PR check (CI)Gate automatizado. Critério de saída de green → probe_review.(não reverte — é gate)Pipeline CI
Refs: <product>/issues#NForeign key reversa. git log --grep '#21' traz histórico.(não reverte — é metadado)Auditoria post-mortem
Co-Authored-ByMarca autoria-agente.(não reverte — é metadado)Análise de retrocompat

Consequência prática: querying estado e revertendo trabalho = git calls, não scraping externo nem ferramenta extra.

# Estado atual de cada PKG sem abrir IDE
git tag --list 'pkg-*-merged' | sort                 # quais fecharam
git tag --list 'session-start-*'                     # quais sessões existiram
git tag --list 'phase-*-<topic>-*'                   # checkpoints da sessão atual
git log --grep '^pkg(' --oneline                     # commits per-package
git log --grep 'Refs: <product>.com/issues#21'       # histórico do feedback #21

Padrões de commit como state transitions:

PrefixTransição disparadaReversível?
chore(<topic>): bootstrap autonomous session(nada) → session-startL4 — sumir com tudo
docs(packages): seed ...pendingplannedL1 ou L2
pkg(NN): scaffold red ...plannedredL2 — volta pra phase-planned
pkg(NN): expand red ...redred_expandedL1 ou L2
pkg(NN): make ... greenredgreenL2 — volta pra phase-red
pkg(NN): UI ... + propagategreenprobe_reviewL2 — volta pra phase-green
pkg(NN): finalize .md status=mergedprobe_reviewmerged (antes do push)L1
(tag pkg-NN-merged pushada)terminalL3 only — revert PKG novo

Anti-pattern: commit sem prefix taxonômico, ou prefix que não bate com transição declarada no .md status. Quebra grep, auditoria e recovery.

Pra próxima sessão: se o repo segue este workflow, lê o git primeiro. Antes de qualquer Read ou Plan, roda os 5 greps acima. Estado completo do projeto em menos de 5s sem custar contexto.

12. Aider — git enforcement concreto

Aider (CLI agent open-source da Aider-AI) implementa de forma madura vários patterns desta cartilha. Leituras diretas do source confirmam decisões.

12.1 Auto-commit per edit-batch

Toda edit-batch dispara auto_commit(edited). Não é commit por arquivo nem por turn — é commit por lote coerente (aider/coders/base_coder.py:2375).

def auto_commit(self, edited, context=None):
    if not self.repo or not self.auto_commits or self.dry_run:
        return
    res = self.repo.commit(fnames=edited, context=context, aider_edits=True, coder=self)
    if res:
        self.show_auto_commit_outcome(res)

No red→green: cada transição é "edit-batch coerente". Commit no momento exato da transição.

12.2 Dirty commit guard — separação humano/agente

Antes de aplicar edits AI, Aider chama dirty_commit(). Mudanças pendentes do user são commitadas primeiro, separadas (aider/coders/base_coder.py:2199, 2238, 2291).

No red→green: parte da pré-condição (3.2 item 4). Garante boundary clean — L4 não joga fora trabalho do user.

12.3 Registry aider_commit_hashes — quem pode desfazer o quê

self.aider_commit_hashes = set()  # base_coder.py:349
self.aider_commit_hashes.add(commit_hash)  # show_auto_commit_outcome:2400

cmd_undo (aider/commands.py:553) usa como gate:

if last_commit_hash not in self.coder.aider_commit_hashes:
    self.io.tool_error("The last commit was not made by aider in this chat session.")
    return

No red→green: sessão mantém set similar. Rollback L1 só toca em commits da própria sessão. Commits do user passam intactos.

12.4 Refuse undo if pushed — git remote como ponto-de-não-retorno

if local_head == remote_head:
    self.io.tool_error("The last commit has already been pushed to the origin. Undoing is not possible.")
    return

aider/commands.py:617. Uma vez no remote, terminal. Sem --force-push.

No red→green: o estado merged (com tag pkg-NN-merged pushada) é terminal por construção. Reversão exige novo PKG de revert — L3 only.

12.5 Surgical undo — per-file checkout + soft reset

Aider undo não faz git reset --hard. Faz:

for file_path in changed_files_last_commit:
    self.coder.repo.repo.git.checkout("HEAD~1", file_path)
self.coder.repo.repo.git.reset("--soft", "HEAD~1")

commands.py:626-644. Restaura cada arquivo, depois solta HEAD um passo atrás sem perder working tree.

No red→green: template L1 (em 6.8) é exatamente isso. Sempre per-file checkout + soft reset. Nunca --hard.

12.6 Attribution semantics

3 flags em aider/repo.py:131:

  • --attribute-author: Author = "User Name (aider)"
  • --attribute-committer: Committer = "User Name (aider)"
  • --attribute-co-authored-by: trailer Co-authored-by: aider (<model>) <aider@aider.chat>

Default: Co-Authored-By trailer on, author/committer off. Permite git log --author='aider' mas mantém author do humano.

No red→green: Co-Authored-By: Claude Opus 4.7 em todo commit segue a convenção. git log --grep 'Claude' traz toda autoria-agente.

12.7 Branch como sandbox autônomo

Aider não isola por default, mas é o pattern recomendado: aider/<topic> branch + revisão antes de mergear. Equivalente: skill solve-issue deste agente roda em worktree isolado.

No red→green: parte do contrato (3.2 item 1). Branch isolada é a pré-condição de L4.

13. Visualizador de fases — git como UI

Se cada commit é uma fase e o trabalho é serializado em git, dá pra renderizar a sessão inteira como página HTML estática com controles de rollback embutidos. Auditor humano entende e age sem reabrir o JSONL.

13.1 Esqueleto do visualizador

Bash one-liner que produz índice navegável:

git log --grep='^pkg(\|^chore(' --reverse --format='%H|%s|%ai' "$BRANCH" | \
  while IFS='|' read hash subj date; do
    state=$(git show "$hash:tasks/packages/PKG-$(echo $subj | grep -oE 'pkg\([0-9]+' | tr -d 'pkg(\)')-*.md" 2>/dev/null | grep '^status:' | head -1)
    echo "<li><a href='./fase-$hash.html'>$subj</a> · $date · $state</li>"
  done > index.html

Cada commit vira .html page com:

  • Subject + body (= o que mudou + por quê)
  • git show <hash> rendered como <pre> com syntax highlight
  • Frontmatter do tasks/packages/PKG-NN.md naquele commit (status, tests_failing, tests_passing)
  • Link pro próximo/anterior commit do mesmo PKG
  • Link "abrir worktree neste ponto" → git worktree add /tmp/snapshot-<hash> <hash>

13.2 Controles de rollback no visualizador

Cada página .html de commit oferece 4 botões (linkando comandos copy-paste pro terminal do user):

BotãoComando geradoNível
Reset until heregit reset --soft <hash-anterior>L1/L2
Revert this commitgit revert <hash>L1 inverso
Fork branch from heregit checkout -b red-green/<topic>-v2 <hash>L5 setup
Discard session (só no commit chore: bootstrap)sequência completa de 3.5L4

O visualizador não executa nada — só gera o comando. User copia-cola, decide.

13.3 Onde mora a UI

Opção mais simples: roda script local que gera estático em /tmp/claude-html/red-green-<session>/. Hook do agente no fim da sessão dispara. Browser abre na pasta.

Opção mais densa: gera dentro do repo como docs/sessions/<topic>.mdx, commitado junto. Próximo agente lendo o repo descobre todas as sessões via find content/docs/sessions/.

13.4 Sinal de sessão autônoma bem-sucedida

Visualizador exibe:

  • Sequência red → expand_red? → green → probe_review → merged linear (sem zigzag)
  • Cada commit tem prefix taxonômico (sem fix: xyz solto)
  • tests_failing decresce monotonicamente nos commits de fix
  • tests_passing cresce monotonicamente
  • Nenhum commit fora do padrão entre dois commits do PKG (no contamination)
  • Toda fase tem tag phase-<state>-... aplicada (rollback L2 funciona)
  • session-start-<topic>-<ts> existe e aponta pro fork-point de main

Se zigzag aparece, sessão entrou em recovery — auditar trecho específico, L5 cherry-pick descarta partes ruins.

13.5 Visualizador como gate de aprovação humana assíncrono

Workflow autônomo + visualizador + reversibilidade L4 viabilizam aprovação 100% assíncrona:

  1. Sessão autônoma roda 6h sem human-in-loop
  2. Gera HTML visualizador no fim, abre browser ou notifica
  3. User abre, lê 10min, decide:
    • Aprovado → merge da branch + push das tags pkg-NN-merged
    • Rejeitado total → L4 discard (3 minutos pra zerar tudo)
    • Parcial → L5 cherry-pick (15 minutos pra preservar o bom)
  4. Em todos os casos, nada irreversível foi feito durante as 6h

O HTML + contrato de reversibilidade são o substituto do AskUserQuestion síncrono em sessões longas.

14. Anti-patterns evitados

  • ❌ Sessão autônoma sem branch isolada → L4 impossível, panic se algo der errado
  • git reset --hard em qualquer momento → perde working tree, perde possibilidade de auditar erro
  • --force-push em branch da sessão → quebra ponto-de-não-retorno, viola contrato
  • ❌ Bootstrap sem tag session-start-<topic>-<ts> → L4 vira difícil
  • ❌ Push de tag pkg-NN-merged sem AskUserQuestion → ponto-de-não-retorno cruzado sem gate humano
  • ❌ Loop infinito de test→fix→test sem checkpoint AskUser → cada fase tem commit + status update
  • ❌ Análise paralisia: gerar relatório sem ação → HTML report sempre seguido de plano de N pacotes
  • ❌ Magic fix sem RED test → cada fix validado por failing test que vira passing
  • ❌ Decisão unilateral em ponto sensível (role, prod migration, push terminal) → AskUserQuestion sync
  • ❌ Drift do caveman mode pra "ser claro" → mantém até o merge
  • ❌ Commit genérico "fix tests" → template estruturado por gap
  • ❌ Perda de contexto entre fases → .md status + tags + Refs no commit

15. Proposta de skill futura

Não implementada. Só descrição pra próximo agente saber o que valeria a pena criar.

Nome: red-green-iterate

Trigger phrases: "review feedbacks + arruma bug pipeline", "itera red→green", "resolve issue tracker com testes auto", "solvable by llm agent", "rola sessão autônoma reversível pra X".

Quatro jobs:

  1. Bootstrap + contrato — gera scaffold tasks/packages/PKG-NN-<slug>.md + TEMPLATE.md + PROMPT.md (Ralph recurring) + README.md master index. Cria branch isolada + tag session-start-<topic>-<ts> + commit de contrato. Recusa se working tree dirty.
  2. State transition — wraps git workflow: cada transição valida critério de saída + atualiza .md + commita com template + aplica tag de fase. Recusa transição se critério falha.
  3. Decision tree advisor — quando agente prestes a tomar decisão das 8 categorias do decision tree (incluindo bootstrap e push terminal), skill injeta AskUserQuestion antes de executar.
  4. Session lifecycle — comandos high-level: start <topic>, checkpoint <phase>, end approve|discard|partial. discard executa sequência L4 inteira (5 comandos de 3.5). partial lista commits e ajuda L5 cherry-pick.

Sub-tools necessárias: templates literais inline, validador de transição, grep helper em .md status, gerador HTML do visualizador (seção 13).

Quando criar: depois que o workflow rodou em ≥3 projetos diferentes e os templates estabilizaram. Antes disso é cedo.

16. Como esta página foi criada e como replicar

Meta-bloco pro próximo agente. Tudo que precisa pra editar/redeployar.

  • Path local: ~/src/docs-fonsecagabriel/content/docs/agents/red-green-iterate-workflow.mdx
  • Stack: fumadocs 16 + Next 16 standalone + Docker multistage + Kamal v2 → Contabo VPS
  • Skill associada: ~/.claude-pessoal/skills/my-docs/

Deploy:

~/.claude-pessoal/skills/my-docs/scripts/deploy.sh

Script: commit pending (prompt mensagem) → refresh GHCR token de gh auth tokenkamal deploy (~150s) → probe https://docs.fonsecagabriel.com.br/docs pra 200.

Verificação pós-deploy:

curl -s https://docs.fonsecagabriel.com.br/llms.txt | grep agents
curl -s https://docs.fonsecagabriel.com.br/llms.mdx/agents/red-green-iterate-workflow
open https://docs.fonsecagabriel.com.br/docs/agents/red-green-iterate-workflow

Sessão original arquivada (local, não pública): ~/.claude-pessoal/projects/<project-slug>/72ccdb3f-b891-4395-a6d7-cd652d83a2bc.jsonl (~3MB, 1150 linhas). Path real fica fora do journal.

17. Self-check antes de começar

Responda mentalmente. Se algum item falhar → release control + AskUser pra confirmar escopo.

  • Tenho prompt do user com os 4 gatilhos? (deep / html report / red→green / llm-solvable)
  • Working tree limpo (git status --porcelain vazio)?
  • Vou criar branch red-green/<topic>-<YYYYMMDD> + tag session-start-<topic>-<ts> + commit de contrato antes de qualquer outro commit?
  • Toda transição de fase vai gerar tag phase-<state>-<topic>-<ts>?
  • Vou criar tasks/packages/PKG-NN-<slug>.md com frontmatter status: pending?
  • Sei quais ≤8 sinks de AskUserQuestion devo usar (incluindo bootstrap e push terminal)?
  • Vou commitar atomicamente per gap usando template literal?
  • Vou manter caveman mode até o merge?
  • Vou usar paralelização em exploring, não em red/green?
  • Sei executar L1-L5 rollback (templates em 6.8)?
  • Nunca vou rodar git reset --hard nem git push --force nesta sessão?
  • Sei como recuperar contexto se sessão quebrar (5 greps em seção 10)?

12 checks. Passou em todos → executa. Falhou em qualquer um → pergunta.

On this page

1. Quando aplicar este workflow2. Sessão fundadora3. Contrato de reversibilidade3.1 Os 5 níveis de reversão3.2 Pré-condições obrigatórias3.3 Pontos de checkpoint3.4 Ponto-de-não-retorno3.5 Discard de sessão inteira (L4)3.6 Cherry-pick parcial (L5)3.7 O contrato escrito4. Anatomia: dois cycles aninhados5. State machine6. Templates literais6.1 Frontmatter de tasks/packages/PKG-NN-<slug>.md6.2 Bootstrap de sessão autônoma (assinatura do contrato)6.3 Commit seed pipeline (planned state)6.4 Commit scaffold red (entra em fase red, tag phase-red-...)6.5 Commit expand red6.6 Commit make green (entra em fase green, tag phase-green-...)6.7 Status report ao user (estilo caveman)6.8 Comandos de rollback (L1-L5)7. Decision tree pra AskUserQuestion8. Caveman mode9. Paralelização10. Rastreabilidade11. Git como base de dados do workflow12. Aider — git enforcement concreto12.1 Auto-commit per edit-batch12.2 Dirty commit guard — separação humano/agente12.3 Registry aider_commit_hashes — quem pode desfazer o quê12.4 Refuse undo if pushed — git remote como ponto-de-não-retorno12.5 Surgical undo — per-file checkout + soft reset12.6 Attribution semantics12.7 Branch como sandbox autônomo13. Visualizador de fases — git como UI13.1 Esqueleto do visualizador13.2 Controles de rollback no visualizador13.3 Onde mora a UI13.4 Sinal de sessão autônoma bem-sucedida13.5 Visualizador como gate de aprovação humana assíncrono14. Anti-patterns evitados15. Proposta de skill futura16. Como esta página foi criada e como replicar17. Self-check antes de começar