Épicos & Tickets
Épicos agrupam trabalho relacionado. Tickets são as unidades atômicas que agentes implementam. Dependências impõem a ordem de execução — o grafo dirige tudo.
Épicos
Um épico é um agrupamento lógico de tickets. Nada mais, nada menos.
Épicos não têm implementação própria — agentes nunca “implementam um épico.” Eles implementam tickets. O épico existe para organizar tickets em blocos coerentes que humanos podem raciocinar sobre e que o orquestrador pode usar para estruturar execução paralela.
O Que Define um Épico
| Campo | Propósito |
|---|---|
epicNumber | Número sequencial auto-atribuído |
title | Nome do épico |
objective | O que este épico alcança como um todo |
status | todo → in_progress → completed (calculado automaticamente) |
order | Ordem de prioridade de execução |
acceptanceCriteria | Condições para o épico ser considerado completo |
O status do épico é totalmente automático. Quando o primeiro ticket de um épico inicia uma work session, o épico move para in_progress. Quando todo ticket no épico alcança done, o épico move para completed. Você nunca transiciona manualmente um épico.
Como Pensar Sobre Épicos
Agrupe por área funcional, não por camada técnica. “Core Authentication” é um bom épico — contém tudo relacionado a login, registro e gerenciamento de sessão. “Database Migrations” é um épico ruim — espalha trabalho relacionado através de fronteiras funcionais e força dependências cross-epic artificiais.
Uma boa decomposição produz épicos que podem rodar em paralelo com mínimas dependências cross-epic. Se cada ticket no Épico 2 depende de um ticket no Épico 1, eles provavelmente deveriam ser um épico só com ordenação interna.
💡 Na implementação autônoma, o orquestrador usa épicos como unidade de atribuição de equipe. Uma equipe por épico (ou por lote, dependendo da estratégia). Épicos que podem rodar em paralelo = mais agentes trabalhando simultaneamente = conclusão mais rápida.
Tickets
Um ticket é a unidade atômica de implementação. Ele descreve um único trabalho focado que um agente pode completar em uma work session sem precisar de contexto de outros tickets ativos.
Anatomia de um Ticket
Identidade e classificação:
| Campo | Propósito |
|---|---|
ticketNumber | Número sequencial auto-atribuído |
title | Nome conciso descrevendo o entregável |
complexity | small · medium · large · xlarge |
priority | critical · high · medium · low |
Complexidade e prioridade influenciam como o orquestrador atribui trabalho. Tickets critical são pegos primeiro. Tickets large podem receber workers dedicados ao invés de serem agrupados.
Contrato de implementação:
| Campo | Propósito |
|---|---|
steps[] | Passos de implementação ordenados para o agente |
acceptanceCriteria[] | Condições que devem ser atendidas para o ticket passar no review |
dependencies[] | O que deve estar pronto antes deste ticket poder começar |
Steps são as instruções de implementação. Cada passo deve descrever uma ação concreta: “Criar classe JwtService em src/auth/jwt.service.ts” — não “implementar geração de token.” Quanto mais específicos os passos, menos o agente adivinha.
Acceptance criteria são o contrato. Eles definem o que “pronto” significa em termos verificáveis: “Tokens são assinados com algoritmo RS256” e “Tokens inválidos retornam 401 com corpo de erro { error: 'INVALID_TOKEN' }.” O validador verifica estes durante o Implementation Review.
Expectativas de arquivo:
| Campo | Propósito |
|---|---|
filesToCreate[] | Novos arquivos que este ticket produz |
filesToModify[] | Arquivos existentes que este ticket altera |
Expectativas de arquivo servem dois propósitos. Primeiro, o Implementation Review verifica se os arquivos esperados foram realmente entregues. Segundo, o grafo de dependência usa informação de arquivo para prevenir que dois tickets modifiquem o mesmo arquivo simultaneamente — evitando conflitos de merge na execução paralela.
O Que Faz um Bom Ticket
Atômico. Um ticket deve produzir um incremento funcional e testável. “Configurar modelo User e schema de banco de dados” é atômico — você pode rodar migrations e verificar que a tabela existe. “Construir o sistema inteiro de auth” não é — é um épico disfarçado de ticket.
Contexto auto-contido. Quando uma work session começa, o agente recebe os passos do ticket, critérios de aceite e outputs de dependência. Isso deve ser suficiente. Se implementar um ticket requer ler 5 outros tickets para entender o que está acontecendo, o ticket está muito acoplado.
Passos concretos. “Implementar hashing de senha” é vago. “Criar função hashPassword em src/auth/hash.ts usando bcrypt com fator de custo 12, exportar como named export, adicionar teste unitário em tests/auth/hash.test.ts” é implementável.
Dependências
Dependências são o tecido conectivo da especificação. Elas definem a ordem de execução — quais tickets devem completar antes que outros possam começar. O grafo de dependência é um grafo acíclico direcionado (DAG) onde nós são tickets e arestas são relacionamentos de dependência.
Dois Tipos de Dependência
blocks — O ticket dependente não pode começar até que a dependência seja completada.
Este é o tipo mais comum. O Ticket B depende do Ticket A porque B precisa que algo que A cria exista primeiro.
Exemplo: “Construir endpoint de registro” bloqueia em “Configurar modelo User e schema de banco de dados.” O endpoint não pode ser construído até que o modelo User exista — o código literalmente não vai compilar sem a tabela e definições de tipo.
requires — O ticket dependente precisa do resultado da dependência.
Isso é mais sutil. O ticket dependente não apenas precisa que a dependência esteja pronta — precisa consumir seu output.
Exemplo: “Escrever testes E2E para fluxo de auth” requer “Construir endpoint de login” E “Construir endpoint de registro.” Os testes não apenas precisam que esses endpoints existam — precisam chamá-los, verificar seu comportamento e fazer assertions nas suas respostas. O ticket de teste consome o output de ambas dependências como sua entrada.
Quando Usar Qual
Na prática, a maioria das dependências são blocks. Use requires quando o ticket dependente explicitamente consome o output da dependência — tickets de teste que exercitam endpoints implementados, tickets de integração que conectam componentes construídos separadamente, tickets de documentação que descrevem features implementadas.
A distinção importa para o Implementation Review. Dependências requires são escrutinadas mais cuidadosamente — o revisor verifica não apenas que a dependência está pronta, mas que seu output foi realmente usado pelo ticket dependente.
⚠️ O SpecForge previne dependências circulares automaticamente. Se você tentar adicionar uma dependência que criaria um ciclo, a operação é rejeitada com uma descrição do caminho do ciclo.
O Grafo
Quando todos os tickets e dependências estão definidos, a especificação forma um grafo acíclico direcionado. Este grafo é o plano de execução.
Waves
O grafo naturalmente produz waves de trabalho paralelizável:
| Wave | O que contém |
|---|---|
| Wave 1 | Tickets sem dependências — imediatamente ready |
| Wave 2 | Tickets que dependem apenas da Wave 1 — desbloqueiam quando a Wave 1 completa |
| Wave 3 | Tickets que dependem da Wave 1 ou Wave 2 — e assim por diante |
Cada wave é um lote de tickets que pode executar em paralelo com zero risco de colisão. O grafo de dependência garante — nenhum ticket na Wave 2 toca algo que outro ticket da Wave 2 está trabalhando, porque todos dependem de outputs diferentes da Wave 1.
Caminho Crítico
O caminho crítico é a cadeia mais longa de dependências sequenciais no grafo. Ele determina o tempo mínimo para completar a especificação, independente de quantos agentes você use.
get_critical_path calcula esta cadeia e retorna o esforço total estimado. Se seu caminho crítico tem 8 tickets mas você tem 50 tickets no total, isso significa que 42 tickets podem ser paralelizados ao redor do caminho crítico. É aí que escalar agentes compensa.
Por Que o Grafo Importa
Sem o grafo, agentes paralelos colidem. O Agente A modifica um arquivo que o Agente B está prestes a ler. O Agente C implementa uma feature que depende de algo que o Agente D ainda não terminou. O Agente E toma uma decisão arquitetural que contradiz a abordagem do Agente F.
O grafo elimina tudo isso. Não é uma sugestão — é um mecanismo de enforcement. Um agente literalmente não pode começar um ticket até que toda dependência esteja done e validada. O grafo é o controlador de tráfego que torna o paralelo seguro.
Veja Também
- Especificações — O pai que contém épicos
- Gates de Qualidade — Validam antes e depois da implementação
- Sessões de Trabalho — Como agentes executam tickets
- Estados do Ticket — Máquina de estados completa com regras de auto-cálculo
- Ciclos de Vida — Os três ciclos que impulsionam o SpecForge