Control-plane evolution playbook (foundations first)
Objetivo: evoluir de forma segura do control-plane local para delegação e, só depois, para federação multi-control-plane — sem misturar conceitos no mesmo ciclo.
Distribuição operacional: o núcleo deste playbook também viaja como skill versionada em packages/lab-skills/skills/control-plane-ops/SKILL.md para reduzir drift entre documentação local e comportamento dos agentes.
Radar estratégico relacionado: docs/research/linux-agent-primitives-radar-2026.md (limpeza -> pesquisa -> escalabilidade com gates de promoção local-safe).
Princípios
- Playbook-first: consolidar contrato operacional antes de ampliar arquitetura.
- State in parent: estado canônico permanece no control-plane principal (
.project/*). - Workers are disposable: subagentes/swarm são efêmeros (
spawn -> slice -> evidence -> kill). - Federation is a phase, not a flag: coordenação federada entra apenas após estabilidade comprovada das fases anteriores.
Três modos (não misturar)
Modo 1 — Single control-plane (agora)
- Escopo: 1 projeto / 1 board canônico.
- Fluxo: execução direta + micro-delegação controlada.
- Gate mínimo: readiness strict (
subagent_readiness_status(strict=true)) + budget saudável. - Critério de saída: 3+ ciclos estáveis com evidência reprodutível e sem recovery manual frequente.
Modo 2 — Delegação descartável (próximo)
- Escopo: subagentes/swarm por fatia.
- Ciclo de vida padrão:
spawn -> executar -> retornar evidência -> encerrar. - Regras:
- budget cap curto por run;
- sem memória estratégica no worker;
- decisão e priorização sempre no parent control-plane.
- Critério de saída: throughput melhora sem aumento de incidentes de contexto/budget.
Modo 3 — Federação de control-planes (futuro)
- Escopo: múltiplas instâncias (projetos distintos) sob coordenação superior.
- Papel do coordenador: rotear, observar, consolidar sinais e governança global.
- Pré-condições:
- contratos de handoff e evidência padronizados entre instâncias;
- telemetria mínima comum (status/readiness/budget/health);
- runbook de contenção para isolar instância degradada sem parar o ecossistema.
Workload matrix — local vs remoto (GitHub Actions/offload protegido)
Objetivo: usar runners remotos como acelerador, sem substituir governança local-first.
Fica local por default
- triagem de task, decisão de prioridade e fechamento canônico no board;
- microfatias de implementação com blast radius pequeno;
- qualquer alteração de escopo protegido sem autorização explícita.
Elegível para runner remoto (canário bounded)
- testes pesados ou longos que saturam host local;
- validações paralelas de baixa ambiguidade (mesmo gate local, mesma métrica);
- jobs de preparo/reporte com artefato auditável (sem auto-promote).
Não elegível para offload automático
- publish/release final;
- mutações de settings/governança sem decisão do operador;
- ações destrutivas/irreversíveis.
Trilha de evidência para offload (board/handoff)
Cada run remota deve registrar, no mínimo:
task,owner,decision(promote|defer);workflow,runId,result,artifacts;expectedValue,focalValidationGate,rollbackPlan.
Template prático local:
pnpm run offload:evidence:template -- --task TASK-BUD-134 --decision defer
Steer/Intervenção do Operador (cancel/retry/override)
- cancel: parar run quando custo/qualidade/governança saírem do envelope.
- retry: repetir apenas com motivo curto + gate focal explícito.
- override: exceção auditável e temporária, com rollback já definido.
Sem esse trio de controles, a recomendação padrão é defer.
Release lane (v0.8.0) — draft primeiro, publish gateado
Fluxo end-to-end recomendado:
- preparar versão (
changeset version) e validar alinhamento de versões nos pacotes; - rodar
pnpm run release:evidence:refreshpara atualizar canaries locais, readiness, draft preview e final gate; - revisar o artifact
.artifacts/release-cut/vX.Y.Z-final-gate.jsone os prompts protegidos; - criar draft release manual para revisão do operador;
- publicar somente após gates canônicos + decisão explícita.
Automação mínima existente:
publish.ymlmantém publish gateado por tag semver + smoke/test/verify/audits;release-draft.ymlprepara draft release manual com artefato de notas;pnpm run release:readiness -- --target X.Y.Zgera checklist local canônico para qualquer target;pnpm run release:readiness:json -- --target X.Y.Zgera o mesmo contrato em JSON para agentes;pnpm run release:readiness:strict -- --target X.Y.Zaplica o mesmo contrato como gate local não-verde;pnpm run release:readiness:strict:json -- --target X.Y.Zaplica o gate e preserva o artefato estruturado;pnpm run release:readiness:v0.8.0gera checklist local canônico em.artifacts/release-readiness/.pnpm run release:readiness:v0.8.0:jsongera o mesmo estado em JSON para agentes e automação local, incluindooperatorDecisions.pnpm run release:evidence:refresh -- --target X.Y.Zatualiza a cadeia segura local:agent-run:driver-canaries, readiness, draft preview, cut preview auditado, artifact audit e final gate.pnpm run release:evidence:refresh:json -- --target X.Y.Zemite o mesmo packet em JSON legível; o resultado esperado antes de revisão do operador émode=release-evidence-refresh,decision=pass,finalGateDecision=passeprotectedActionsAllowed=false.pnpm run release:evidence:status -- --target X.Y.Zlê a evidência já materializada e retorna um resumorelease-evidence-statussem rodar canários, sem escrever artefatos e sem ações protegidas.pnpm run release:final:gate -- --target X.Y.Zrecompõe em memória cut preview + artifact audit + cut auditado sem tag, push, workflow dispatch ou publish.pnpm run release:artifact:audit -- --target X.Y.Zaudita artifacts já gerados quando for necessário inspecionar a cadeia manualmente.
Interpretação do readiness report:
Release Blockerssepara gate técnico, decisão de operador e estado do board;Operator Decisionslista as decisões do operador restantes antes do release;- no JSON,
mode=release-readiness-reporteschemaVersion=1identificam o contrato estruturado; - no JSON,
markdownacompanha o mesmo relatório legível para operador, então agentes não precisam escolher entre contrato estruturado e contexto legível; - no JSON,
generatedAtedecisionidentificam o snapshot e a decisão (readyounot-ready) sem parsear Markdown; - no JSON,
versions,versionsAligned,targetVersionReady,workflows,gates,worktree,agentRunDrivers,packageSmokeeuserSurfaceexpõem os gates principais sem parsearchecklist[*].evidence; - no JSON,
gates.worktreeCleaneworktree.statusLinesbloqueiam readiness quando há mudanças rastreadas locais; arquivos untracked de evidência local não bloqueiam por si só; - no JSON,
agentRunDrivers.canaryScriptNameemissingCanaryScriptMarkersexpõem se o comando local agregadoagent-run:driver-canariesestá registrado para materializar evidência; - no JSON,
agentRunDrivers.canarySuiteEvidenceaponta.artifacts/agent-run-driver/suite.json; para readiness de release, essa suíte agregada precisa existir, retornardecision=passe, quandoHEADGit estiver disponível, carregargitHeadigual aoheaddo relatório; - no JSON,
agentRunDrivers.lastCanaryEvidencepode apontar.artifacts/agent-run-driver/latest.jsoncomo evidência local advisory; ausência desse arquivo não bloqueia release por si só; - no JSON,
agentRunDrivers.lastMutationCanaryEvidencepode apontar.artifacts/agent-run-driver/latest-mutation.jsoncomo evidência local advisory defile_contract=mutation; - no JSON,
userSurfaceresume a auditoriapi-stack:user-surfacee bloqueia readiness se houver scripts raizlab-onlyoupromotion-candidatesem assimilação explícita; pnpm run agent-run:driver-canaryproduz essa evidência local com um canário bounded denode --version, sem provider real, sem fan-in e sem colônia;- no JSON,
checklist[*].kindclassifica cada gate comotechnical-gate,operator-decisionouboard-state; - no JSON,
releaseBlockersexpõe os mesmos bloqueios do Markdown comid,kindeevidence; - no JSON,
operatorDecisions[*]inclui payload acionável por decisão, comoallowedActions, versões atuais ecandidateTaskIds; - no JSON,
operatorDecisions[*].releaseVersionDecisionPacketaparece quandotarget-version-readyestá falso; ele incluicurrentVersions,recommendedActionerequiredApprovalPromptsem editar manifestos, tags ou publish; - no JSON,
operatorDecisions[*].boardReleaseDispositionPacketaparece quando o board tem candidatos com evidência de release; ele listadispositionRows[*].recommendedAction,dispositionRows[*].approvalPrompterequiredApprovalPromptsem editar.project/tasks.jsonnem autorizar automação; - no JSON,
nextActions[*].boardReleaseDispositionPacketreplica esse packet quando ele for o próximo passo, permitindo consumo direto denextActionssem inferência adicional; - no JSON,
nextActions[*].releaseDraftReviewPacketaparece quando todos os gates estão verdes; ele exigerequiredApprovalPrompte mantémtagAllowed,publishAllowed,workflowDispatchAllowedeprocessStartAllowedfalsos; - no JSON,
operatorDecisions[*].requiresOperatorDecision=trueeautomationAllowed=falsedeixam claro queallowedActionssão opções para operador, não dispatch automático; - no JSON,
nextActionCodeenextActionsindicam o próximo passo seguro sem autorizar publish automático; - no JSON,
automationPermissionsmantémtagAllowed,publishAllowed,workflowDispatchAllowedeprocessStartAllowedfalsos; readiness report é sempre report-only; - no final gate,
requiredApprovalPromptslista as aprovações protegidas (tag create,tag push,prepare-draft-release,publish-release) sem executá-las; - no refresh,
protectedActionsAllowed=falseconfirma que o comando atualiza evidência local e não inicia release real; Board Evidence Candidateslista tarefas ainda abertas que já têm evidência local-safe para decisão;- no JSON,
board.openP0Rows,board.inProgressRowseboard.blockedRowsexpõem o estado do board sem exigir parse de linhas Markdown; - no JSON,
board.evidenceCandidateRowsexpõe os mesmos candidatos em forma estruturada para agentes; releaseDecisionReady: yessignifica que o board está pronto para decisão explícita, não que o release está aprovado.
Checklist de readiness v0.8.0 (board/handoff):
- versões de pacotes alinhadas;
- CI/publish/release-draft prontos e auditáveis;
- candidatos de evidência do board decididos como
park-for-target-releaseourequire-work; - decisão explícita do operador de
draft->publish; - rollback documentado para falha pós-corte.
Inspirado por tuts-agentic-ai-examples
Referência: https://github.com/nilayparikh/tuts-agentic-ai-examples
Mapeamento conceitual (adaptado ao ecossistema pi/refarm):
- Single agent / sequential / parallel / coordinator / agent-as-tool / loop-critique (trilha
agents/) -> matriz de padrões de delegação progressiva. - A2A progressivo e capstone multiagente (trilha
a2a/) -> base para contrato entre instâncias e interoperabilidade de runtime.
Adaptação local obrigatória:
- manter board-first (
.project/*) como fonte canônica; - preservar
no-auto-closepara itens estratégicos; - promoção por verificação (
verification) antes decompleted.
Espelho externo de issues/status
Mapeamento canônico:
.project/tasks[].idé o identificador operacional; issue externa entra como referência em nota/evidência.description/título externo são resumo espelhado, não fonte final de verdade.- labels externas só alteram
priority/milestonequando houver mapping explícito registrado. statuslocal só muda paracompletedcomverificationlocal passada; fechamento externo não auto-fecha task estratégica.
Direção e conflito:
- default: board-first (
.project-> GitHub/Gitea) para mirrors públicos; - import externo só cria proposta/nota quando houver divergência;
- conflito de status/label/evidência vira nota auditável e exige política/operador, sem overwrite silencioso;
- operações remotas mutantes (
gh issue close/edit, labels, milestones) exigem intenção explícita.
Idempotência mínima:
- registrar URL/número externo uma vez por task;
- reaplicar sync não deve duplicar notas ou mudar status sem nova evidência;
- cada sync deve declarar direção, entidade externa, task alvo e campos promovidos/ignorados.
Anti-patterns (evitar)
- transformar subagente em “memória longa” do sistema;
- acoplar decisão estratégica ao worker;
- abrir federação antes de estabilizar operação local;
- compensar arquitetura frágil com compactação frequente.
Checklist GO/NO-GO — transição Modo 1 -> Modo 2
GO (todos obrigatórios)
subagent_readiness_status(strict=true)retornaready=truepor pelo menos 2 checks consecutivos.- Últimas runs controladas não apresentam
BUDGET_EXCEEDEDno recorte operacional. - Board canônico está íntegro (
project-validateclean) e handoff atualizado. - Delegações curtas já demonstraram retorno auditável (evidência + status de task sem auto-close indevido).
NO-GO (qualquer item bloqueia)
- readiness strict oscilando (
ready=falserecorrente) por causas não diagnosticadas. - falha de governança de budget (streak de bloqueio, retries exaustos sem contenção).
- dependência de memória de subagente para decisão estratégica.
- ausência de evidência canônica no parent control-plane.
Envelope mínimo de telemetria — Modo 3 (federação)
Cada control-plane federado deve expor, no mínimo:
instanceId: identidade estável da instância (workspace/projeto).status:running|paused|degraded.readiness: resultado gate strict (ready, checks críticos, timestamp).budget: estado resumido por provider/account (ok|warn|block).lease: owner + heartbeat + expiração.workload: fila pendente e task ativa (se houver).lastHandoffAtIso: timestamp da última atualização canônica.
Contrato de operação do coordenador federado:
- nunca decidir por contexto implícito de worker;
- sempre agir com base em telemetria explícita + evidência do board local;
- isolar instância degradada sem interromper as saudáveis.
Rollout / rollback por modo
Modo 1 (single control-plane)
Rollout:
- validar saúde:
context_watch_status+project-validate; - confirmar gate strict:
subagent_readiness_status(strict=true); - executar slices locais com board/handoff atualizados.
Rollback (voltar para estabilidade local):
- se houver oscilação de readiness/budget, pausar delegação e voltar para execução direta até 2 ciclos limpos.
Operação noturna local-safe (batch 3–5 fatias, hard-intent)
Contrato operacional para rodar sem check-in entre tasks elegíveis:
- iniciar com
autonomy_lane_next_taskeautonomy_lane_auto_advance_snapshot; - executar uma fatia curta por vez (commit + checkpoint);
- permitir auto-advance apenas quando snapshot
decision=eligible; - manter parada imediata quando snapshot
decision=blocked.
Stop conditions mínimos (formato curto):
stop: protected;stop: risk;stop: reload-required;stop: validation-failed-or-unknown;stop: no-eligible-local-safe-successor.
Rollback padrão AFK:
- ação: pausar auto-advance, manter foco explícito e voltar para uma fatia manual bounded;
- evidência: registrar blocker no board +
context_watch_checkpoint; - saída: retomar auto-advance só após blocker limpo e smoke focal verde.
Modo 2 (delegação descartável)
Gate de entrada — simple-delegate rehearsal bounded:
simple_delegate_rehearsal_packet.decision == ready;- foco local-safe já estável (batch 3–5 concluído com checkpoint/commit por fatia);
- sem blockers hard-intent (
protected,risk,reload-required,validation-failed-or-unknown); - escopo protegido continua opt-in do operador (nenhum auto-dispatch).
Canário protegido de capacidade externa (GitHub Actions/offload) — pré-condições:
- declarar valor esperado do canário (throughput/custo/tempo) com métrica observável;
- declarar validação focal obrigatória antes/depois (mesmo gate local para comparação);
- declarar rollback explícito e não-destrutivo (
git revert <commit>+ retorno imediato ao caminho local); - registrar envelope mínimo no board/handoff:
task,maxCost,owner,evidence,decision=promote|defer; - manter
dispatch=noaté decisão explícita do operador de promote.
Rollout canário:
- escolher 1 task curta com critérios claros;
- executar rehearsal report-first (sem dispatch automático) e só então avaliar execução delegada bounded;
- exigir evidência no parent antes de nova delegação;
- encerrar worker após entrega (não manter sessão longa do worker).
Rollback:
- trigger:
FAILEDrecorrente,BUDGET_EXCEEDED, blocked-rate alto no telemetry, ou ausência de evidência canônica; - ação: descer para Modo 1 por 1 janela operacional (sem novas delegações) e corrigir causa raiz.
Runbook curto — rehearsal real (1 task):
- start: usar
simple_delegate_rehearsal_start_packet; só avançar quandodecision=ready-for-operator-decisione houver go explícito do operador; - monitor: manter execução bounded e parar no primeiro
stop: protected|risk|reload-required|validation-failed-or-unknown; - abort: em blocker, encerrar rehearsal no mesmo slice, sem promover próxima task automaticamente;
- rollback: aplicar rollback não-destrutivo declarado, registrar evidência no board e checkpoint curto;
- postflight: registrar decisão
go/no-gopara próxima fatia antes de qualquer novo start.
Modo 3 (federação)
Rollout canário:
- federar só 1 instância filha inicialmente;
- validar envelope mínimo (
status/readiness/budget/lease/workload/handoff); - testar isolamento: simular instância degradada sem afetar as demais.
Rollback:
- trigger: perda de telemetria mínima, lease inconsistente, ou decisões sem evidência local;
- ação: remover instância da federação, manter operação local autônoma, reintroduzir apenas após requalificação.
Sinais esperados por estágio
- Modo 1 saudável:
subagent_readiness_status(strict=true).ready == truecontext_watch_status.level in {ok,warn-controlado}project-validate.status == clean
- Modo 2 saudável:
- presença de
COMPLETEnas runs controladas; - ausência de
BUDGET_EXCEEDEDno recorte operacional; - evidência registrada em
verificationpara cada delegação relevante.
- presença de
- Modo 3 saudável:
- telemetria mínima disponível para todas as instâncias ativas;
- coordenador sem decisões “cegas” (sempre com status/readiness/budget/lease);
- isolamento comprovado de instância degradada sem efeito cascata.