5.3 KiB
Impl: Ciclo de vida do plan-issue — colaboração fechada antes de claim
Status: aprovado Atualizado em: 2026-08-02 Issue: #292 Intenção: docs/plans/plan-issue-lifecycle-ready.md Appetite restante: ~0,5d (scripts + skills + pins; sem UI; Action dual = OPS18)
Nota de execução: retomado após kill-all do worker anterior (9ff0b84d); cherry-pick em cima de main com resolução de conflito em plan-issue/SKILL.md (main já tinha o ciclo em prosa; esta entrega amarra o enforce em script + agent:ready).
Leitura da intenção
- Outcome: colaborar no
/plan-issuenão cria Issue/PR até confirmação explícita pós-overview; Issue com plano só fica claimável (ready) depois do plano de intenção emmain. - O que NÃO negociar: chores sem
--plannascemready; não inventar segundo tracker; não exigir review humano no PR de planos; não verificar blob do plano a cada tick do pool. - O que reavaliar: hipótese “só skill soft” — insuficiente; contrato tem de viver em
agent:register(default com--plan) + promote explícito. Action no merge = sucessor OPS18 (#296), fora deste item.
Abordagem recomendada
flowchart LR
Gate["Passo 5 overview + OK lote"] --> Reg["agent:register --plan"]
Reg -->|"estado blocked"| Issue["Issue #N"]
Issue --> PlansPR["PR Related #N → main"]
PlansPR --> Ready["agent:ready → ready"]
Ready --> Pool["fila claim/pool"]
Opções consideradas: A) só checklist na skill (soft) · B) --plan ⇒ blocked no register + agent:ready pós-merge (sessão) · C) novo label needs:plan + gate no pool
Recomendação: B — reusa blocked (já exclui claim/pool); enforce no script (não depende do agente lembrar --blocked); promote determinístico na sessão após merge.
Rejeitadas: A (já falhou na prática — race com pool); C (prolifera estados; intenção cortou rabbit hole).
Decisões de engenharia
-
Estado enquanto espera plano em
main:blocked(nãoneeds:plan).- Opções: A
blocked| Bneeds:plan| C sem Issue até merge - Recomendação: A — vocabulário existente; claim/pool já excluem.
- Rejeitadas: B (label nova sem necessidade); C (quebra
Related #N).
- Opções: A
-
Enforce no register vs só skill: default
blockedquando--planpresente.- Opções: A default no script | B skill manda
--blocked| C pool checa arquivo emmain - Recomendação: A — fail-closed no ponto de criação.
- Rejeitadas: B (esquecível); C (IO no tick — rabbit hole da intenção).
- Opções: A default no script | B skill manda
-
Promote v1:
pnpm agent:ready -- --issue N[,N…]na mesma sessão (Passo 6 pós-merge).- Opções: A script de sessão | B Action no merge | C humano sempre
- Recomendação: A neste item; B = OPS18 (#296).
- Rejeitadas: C (opaco); B fora de escopo (comentário na Issue #292).
-
Nome do comando:
agent:ready(não reviveragent:promotedo cutover stage→main).
Componentes / mudanças
scripts/lib/agent-plan-lifecycle.mjs: puro —resolveRegisterStateLabel({ hasPlan, explicitBlocked }),canPromotePlanIssue(issue)(blocked + linkdocs/plans/+ open + sem in-progress/done/in-prod).scripts/agent-register.mjs: usa o helper; com--plannasceblocked(mesmo sem--blocked); sem--planpreservaready/--blocked.scripts/agent-ready.mjs+pnpm agent:ready: flipblocked→readyidempotente; comenta motivo; recusa se não for “aguardando plano”..cursor/skills/plan-issue/SKILL.md: Passo 5 = gate duro (sem Issue/PR até OK explícito ao lote); Passo 6 = register → PRRelated #N→ merge →agent:ready.docs/AGENT-OPS.md+ skillagent-pool(menção curta) + nota emcapture-review-debts: contrato de labels / promote após plano emmain.- Tests:
tests/unit/agentPlanLifecycle.unit.spec.ts(register label + canPromote). - Migration / Access / Consent / UI: N/A (Impeccable A).
Fases verificáveis
- Tracer — helper puro + register + pins unit;
agent:ready+ skill/docs. - Gates —
pnpm gate:fast; entrega compnpm push.
Rabbit holes / Não escopo (engenharia)
- Action dual no merge (OPS18 #296).
- Checagem de blob do plano no tick do pool.
- Label
needs:plan. - Reescrever
capture-review-debtspara auto-promote (só nota + defer para OPS18). - Rename cosmético
canPromotePlanIssue→canMarkPlanIssueReady— defer; API estável para OPS18 Action. - Hoist
HUMAN_GATE_LABELS/issueHasPlanLink/ lista ativa-ou-terminal para módulo neutro — defer até OPS18 (#296) precisar do mesmo predicado fora deagent-pool-eligibility(2 call sites hoje; gatilho = 3º consumidor ou Action dual). - Batch
agent:readyacumular falhas — defer; v1 fail-fast no primeiro reject não-skip é ok.
Riscos e mitigação
- Issue com
--planficablockedpara sempre se Passo 6 pular promote — mitiga OPS18; v1 documentaagent:readyobrigatório no Passo 6. - Confundir
blockedpor dep de produto com “aguardando plano” —canPromotePlanIssueexige linkdocs/plans/no body; promote sem link falha fechado.
Aceite de engenharia
- Aceite de produto da intenção ainda coberto
- Invariantes AGENTS/engineering-standards (N/A runtime app)
- Testes de domínio previstos (unit no lifecycle)
Self-score decision-quality: 5/5