expxdev v0.5.1
/

Método Expx

O método, escrito e executável

Pedir a um agente de IA para construir uma feature funciona — até a segunda hora. O plano era vago o bastante para o agente decidir sozinho no meio da implementação, e ele decide: escolhe um padrão que não é o do projeto, escreve o teste na pasta que o runner não olha, refatora três arquivos que ninguém pediu. O método Expx é o conjunto das restrições que evitam isso, escrito. Este site é a referência completa do expxdev — o CLI que instala e mantém as oito skills — e de cada uma delas.

terminal
npx expxdev init
7
skills no catálogo
7
subcomandos do CLI
441
testes, sem rede
16
verificações do doctor

Apresentação para o time → — deck navegável em HTML, pronto para levar essa introdução a uma reunião de engenharia.

As quatro apostas

O método parte de quatro premissas, e tudo o mais decorre delas.

  1. Todo o esforço vai para o planejamento

    Uma pergunta feita durante a execução é sempre uma falha da fase de planejamento. Se a ambiguidade foi eliminada antes, a execução pode ser autônoma sem virar aposta.

  2. Nada avança sem critério verificável

    Task, fase e sprint têm portão de aceite binário, sem adjetivo. TDD não é sugestão: o teste vem antes, e a task só fecha com a suíte inteira verde.

  3. O escopo é travado no que a investigação provou

    O que não está no plano não é tocado. Melhoria avulsa vira registro de dívida, nunca um brinde no diff.

  4. Quem implementa não aprova

    O QA e a auditoria são papéis distintos, e os agentes que os executam têm acesso somente de leitura — o que transforma “aponta, não corrige” de promessa em impossibilidade técnica.

O método de ponta a ponta

prodx diz se vale fazer, stackx diz como este projeto escreve código, legadox diz o quanto ter medo, sprintx e runx fazem o trabalho, mergex entrega, e o expxdev instala todos e mostra o andamento. Quando o projeto é novo e inteiro, a buildx conduz essa cadeia sozinha, feature a feature.

Build e Run são a mesma disciplina

sprintx e runx não são dois métodos: são o mesmo método com gatilhos diferentes.

sprintx (Build)runx (Run)
Gatilhofeature nova, planejada do zeroocorrência num sistema em produção
Entradauma ideia, um requisitoum chamado, ticket ou relato de cliente
EstágiosF1F6E1E5
Saídaa feature entreguea ocorrência encerrada, com dois relatórios
Raiz em discodocs/sprintx/features/<slug>/docs/manutencao/<OC-ID>-<slug>/

As duas compartilham exatamente os mesmos contratos: base de conhecimento antes de qualquer plano, hierarquia sprint → fase → task, TDD obrigatório com no mínimo dois testes por task, critério de aceite verificável em toda transição e execução autônoma guiada por um arquivo orquestrador. Muda o gatilho e o tamanho. Nunca o rigor.

Começar

Instalação

O init busca as skills que você escolher nos repositórios oficiais, empacota apenas as selecionadas como um plugin local chamado expx e configura o harness.

Requisito: Node ≥ 20.19.0 e o git do sistema no PATH. O CLI usa git clone --depth 1 justamente para aproveitar a credencial já configurada na máquina — repositório privado funciona sem nenhum token.

O caminho declarativo

A seleção é feita por flag, o que faz a mesma linha servir ao seu terminal e ao CI:

terminal
npx expxdev init --skills sprintx,runx,mergex --harness claude,opencode --yes
FlagEfeito
--skills <lista>Skills a instalar, separadas por vírgula. Repetível; nomes duplicados são ignorados
--harness <lista>claude, opencode, ou os dois. Padrão: claude
--yes · --simAplica sem exigir terminal interativo

Todas aceitam também a forma --flag=valor.

Sem terminal interativo e sem --yes, o init imprime o que instalaria e sai sem escrever nada. É o modo de simulação, e é o que protege um CI de escrever por engano.

O caminho interativo

Rodando npx expxdev init sem --skills num terminal completo (stdin e stdout precisam ser TTY), o CLI abre um assistente:

expx init
  ███████ ██   ██ ██████  ██   ██   dev
  o CLI do metodo Expx · v0.5.0

? Quais skills instalar? (espaço marca, enter confirma)
  sprintx   planeja e executa features novas
  runx      ocorrencias de manutencao do dia a dia
 ◯ legadox   camada para projetos legados
 ◯ stackx    descobre o dialeto tecnico do repositorio
  mergex    versionamento, entrega e revisao de pull requests
 ◯ memox     memoria do projeto, indexa os artefatos ja fechados
 ◯ prodx     camada de produto, decide se o pedido vira trabalho

? Qual harness?  claude  ◯ opencode

Resumo
  skills   sprintx, runx, mergex
  harness  claude

? Confirmar? (S/n)

Se já existe um .expx/ no projeto, o assistente pergunta antes se você quer reconfigurar, com o padrão em não — seguir remonta a instalação a partir da nova seleção.

O que fica no seu projeto

A montagem inteira acontece numa pasta temporária ao lado do destino e é trocada por rename ao final. Se falhar no meio, o .expx/ anterior é devolvido ao lugar.

Sobre o registro do plugin. Declarar o marketplace na configuração do projeto não instala o plugin — isso foi verificado em execução, não presumido da documentação. O init chama claude plugin marketplace add e claude plugin install. Como esse registro grava um caminho absoluto na configuração do usuário, ele não viaja no commit: cada pessoa roda expx init na própria máquina. Sem o binário claude no PATH, o .expx/ é montado normalmente e o CLI imprime os dois comandos para você rodar à mão.

Commite o .expx/

A instalação é travada por lock, e o lock é para ser versionado. Quem clona o projeto recebe exatamente as mesmas skills que o time está usando, sem rede e sem rodar nada. O doctor trata como erro um .gitignore que ignore o .expx/.

Próximo passo, dentro do Claude Code: /expx:onboarding. Ele mapeia as camadas instaladas antes do primeiro plano — ver /expx:onboarding.

Começar

O ecossistema

Oito skills que não se conhecem por código: elas se encontram em contratos escritos. É isso que permite instalar três delas e não as outras cinco, ou atualizar uma sem tocar nas demais.

O CLI busca cada skill no seu repositório, empacota só as escolhidas num plugin local e configura os harnesses. Os comandos ficam com namespace no Claude Code e sem namespace no OpenCode. A buildx é a única que exige companhia: sem prodx, sprintx e mergex ela não tem o que orquestrar.

As oito skills

Camadas sozinhas não fazem nada. legadox, stackx, memox e prodx modificam o comportamento de sprintx e runx em vez de agir por conta própria. O CLI avisa se você selecionar uma camada sem base, mas nunca impede.

A buildx é o caso oposto e a única exceção do método: ela não modifica ninguém — invoca. Sem prodx, sprintx e mergex instaladas ela não roda, e diz o que falta. É a única peça com dependência dura, porque rodar sem elas significaria reimplementar quatro skills mal, dentro de uma quinta.

Como as camadas compõem

A prodx é a única que roda antes das outras: ela decide se existe trabalho; as demais tratam de como fazê-lo. Sem ela, o método planeja com rigor uma feature que não deveria existir — o desperdício mais caro de uma software house, porque passa em todos os testes.

Quando a camada existeO que muda na sprintxO que muda na runx
docs/stack/CONVENCOES.md
stackx
a ingestão lê as convenções; a descoberta transforma cada PROPOSTA em pergunta; o plano define caminho do teste, camada e padrão de erro por task; a auditoria roda a verificação de aderência a investigação consulta o cartucho conforme o sintoma; o fix obedece o padrão de teste e o isolamento de banco
docs/legado/PERFIL.md
legadox
cada fase ganha rigor proporcional ao raio: caracterização antes de alterar, orçamento de diff por task, plano de reversão, aprovação humana em raio ALTO
mergex instalada abre a branch no início da F6, commita cada task, e entrega ao fim abre a branch no início do E3, e entrega entre o E4 e o E5
docs/produto/ com veredito assinado
prodx
a F1 recebe o BRIEFING.md como entrada, e o plano referencia o PD-ID de origem o BRIEFING.md vira o 00-OCORRENCIA.md, com o tipo já classificado

A ausência nunca quebra. Sem CONVENCOES.md, sem PERFIL.md, sem a mergex ou sem a prodx, as outras skills se comportam exatamente como se comportariam sem elas. Insumo que não existe vira aviso do que falta — nunca invenção, e nunca um erro que trava o trabalho.

A regra de precedência que evita o pior colateral

stackx descreve o que deve ser seguido daqui pra frente. legadox descreve o que existe hoje, incluindo os dialetos conflitantes. Em projeto novo, só o stackx governa. Em projeto legado, na área tocada manda o padrão local descrito no PERFIL.md; o stackx governa apenas código novo, em arquivo novo.

Sem essa regra, a IA “moderniza” arquivo antigo achando que está obedecendo convenção — o colateral mais perigoso que existe, porque vem com a justificativa de estar seguindo uma regra.

Quadro comparativo

SkillFasesComandosAgentesHooksRaiz dos artefatos
sprintx6 +F3.5836docs/sprintx/
runx5636docs/manutencao/ · docs/relatorios/
legadox11627docs/legado/
stackx5512docs/stack/
mergex10726docs/entregas/
memox5502.expx/memoria/
prodx6600docs/produto/
buildx6400docs/projeto/

A memox é a única que não grava nada em docs/: o índice dela é derivado, descartável e gitignorado. A prodx e a buildx são as únicas sem hooks — e a buildx é a única cujos artefatos descrevem um projeto, não um trabalho.

Começar

As três camadas de garantia

Uma regra escrita na skill é uma instrução — e instrução é coisa que o modelo pode esquecer na task 14 de uma execução longa, justamente quando o trabalho é grande e o risco é maior.

Cada camada cobre o que a anterior não garante.

Todo hook de método nasce em modo aviso

ModoComportamentoQuando promover
avisoregistra no rastro, não bloqueiaestado inicial de todo hook de método
bloqueiobarra a ação e devolve o motivo ao modelosó depois de rodar semanas sem falso positivo
desligadonão roda e não registradesligar explicitamente um hook

A razão é prática: hook que dá falso positivo é desinstalado, e junto com ele vão os que funcionavam. A exceção são os hooks de segurança, que nascem em bloqueio e falham fechados — segredo commitado não tem volta, e o falso positivo ali é raro.

O modo de cada hook vive em .expx/hooks.json:

.expx/hooks.json
{
  "expx_hooks": 1,
  "hooks": {
    "escopo-da-task":   { "modo": "aviso",    "tipo": "metodo" },
    "segredo":          { "modo": "bloqueio", "tipo": "seguranca" }
  }
}

Arquivo ausente, ilegível ou sem a entrada: hook de segurança assume bloqueio, hook de método assume aviso. Só um desligado explícito desliga um de segurança.

Os agentes do ecossistema

AgenteUsado porFerramentasPapel
auditor-planosprintx F5leitura apenasFura o plano antes de ele virar código
revisor-testessprintx, runxleitura apenasResponde: esse teste passaria com a implementação errada?
qarunx E4leitura + rodar suíteValida contra os critérios; não corrige
investigadorrunx E1, sprintx F1leitura + buscaMonta a base e prova a causa raiz
cartografostackx, legadoxleitura + históricoVarre o repositório e extrai convenção ou perfil
avaliador-de-raiolegadox C2leitura + escrita em docs/legado/raio/Coleta os oito sinais e classifica a faixa
revisor-diffmergex E3leitura + suíteClassifica o diff nas três faixas de atenção
analista-de-conflitomergex E9leitura apenasExplica o que cada lado pretendia; nunca resolve

Um agente sem restrição declarada herda todas as ferramentas no Claude Code, o que destruiria exatamente a garantia que justifica o agente existir. No Claude Code a restrição se escreve tools: Read, Glob, Grep; no OpenCode não existe o campo tools — usa-se permission: com edit: deny, write: deny, bash: deny.

Skill · base

sprintx

Planeja e executa features novas em seis fases: ingestão → descoberta → plano → orquestrador → auditoria → execução. Todo o esforço vai para o planejamento, e a execução é autônoma porque a ambiguidade já foi eliminada.

base 6 fases + 1 opcional 8 comandos 3 agentes 6 hooks

As fases

FaseNomeO que produz
F1Ingestãobase/00-INDICE.md, base/00-LACUNAS.md, um arquivo por recurso, 00-BLOQUEIOS.md
F2Descoberta00-DECISOES.md — linhas D-NN e PENDENTE-NN
F3Planosprint-NN/sprint.md, fases.md (com o grafo de tasks), tasks.md
F3.5Estimativa opcional00-ESTIMATIVA.md
F4OrquestradorORQUESTRADOR.md — oito seções fixas, na ordem
F5Auditoria00-AUDITORIA.md — tabela de achados e a linha VEREDITO:
F6Execuçãoatualiza tasks.md e fases.md; grava FECHAMENTO.md e apenda o histórico de estimativas

A fase é detectada pelo disco

A skill nunca lê o .expx/estado.json para decidir onde está — ela olha o que existe:

Estado do discoFase
base/ não existeF1
base/ existe, 00-DECISOES.md nãoF2
00-DECISOES.md existe, sprint-01/ nãoF3
sprint-01/ existe, ORQUESTRADOR.md nãoF4
ORQUESTRADOR.md existe, sem auditoria aprovadaF5
00-AUDITORIA.md contém VEREDITO: SIMF6

Comandos

ComandoO que faz
/sprintxDetecta a fase atual e continua de onde parou
/sprintx-baseF1 — ingestão, constrói a base de conhecimento
/sprintx-descobertaF2 — entrevista o usuário e registra as decisões
/sprintx-sprintsF3 — gera o plano de sprints, fases e tasks
/sprintx-estimarF3.5 — estima o esforço em faixa, com premissas e confiança
/sprintx-orquestradorF4 — gera o ORQUESTRADOR.md
/sprintx-auditoriaF5 — audita o plano e dá o veredito de prontidão
/sprintx-executarF6 — executa o plano auditado de forma autônoma

No Claude Code os comandos ganham o namespace do plugin: /expx:sprintx-sprints. No OpenCode ficam sem prefixo: /sprintx-sprints.

Agentes e hooks

HookEventoModoO que barra
segredoPreToolUse escritabloqueiosegredo com forma reconhecível indo para arquivo versionado
git-perigosoPreToolUse Bashbloqueiooperação de versionamento irreversível durante a execução autônoma
escopo-da-taskPreToolUse escritaavisoarquivo editado fora do campo arquivos da task em andamento
task-so-fecha-verdePreToolUse escritaavisostatus: concluida com suíte ≠ verde ou faltando os dois testes
sem-placeholder-no-planoPostToolUseavisomarcador {{…}} de template não substituído
tdd-teste-antesPostToolUseavisoimplementação nasceu antes do teste — inativo sem CONVENCOES.md

Regras invioláveis

São vinte no total. As que mais governam o dia a dia:

  • R2 — “As fases são estritamente sequenciais; nunca pule fase nem execute fora de ordem.”
  • R3 — “TDD é obrigatório: o teste é escrito antes da implementação.”
  • R4 — “Task só é marcada como concluída quando o teste de integração E o teste funcional passam; não existe ‘concluído com ressalva’.”
  • R8 — “Dúvida nova durante a execução: registrar em 00-BLOQUEIOS.md, pular a task e seguir para a próxima paralelizável; nunca parar e esperar.”
  • R9 — “Na F1 nada de invenção: se a fonte não afirma, escreva NÃO DOCUMENTADO; todo número vem com a referência que o afirma.”
  • R14 — “Na F5 a IA é auditora: só aponta, nunca corrige; achado de severidade ALTA manda voltar para a F3.”
  • R15 — “Proibido escrever código de implementação em qualquer fase antes da F6.”
  • R18/R19 — “Estimativa sai sempre como faixa… Número único é proibido.” / “Estimativa é esforço, nunca prazo de calendário.”

Artefatos em disco

árvore
docs/sprintx/features/<slug>/
  00-BLOQUEIOS.md  00-DECISOES.md  00-ESTIMATIVA.md
  ORQUESTRADOR.md  00-AUDITORIA.md  FECHAMENTO.md
  base/00-INDICE.md  base/00-LACUNAS.md  base/<recurso>.md
  sprint-NN/sprint.md  sprint-NN/fases.md  sprint-NN/tasks.md
docs/sprintx/estimativas/HISTORICO.md   # append-only, atravessa features
docs/eventos/<trabalho_id>.jsonl        # rastro, gitignorado

Skill · base

runx

A metade Run: ocorrências de manutenção em produção, em cinco estágios — investigação com causa raiz comprovada, plano, fix sob TDD, QA independente e relatórios de fechamento.

base 5 estágios 6 comandos 3 agentes 6 hooks

Os estágios

EstágioNomeO que produz
E1Investigação00-OCORRENCIA.md, base/00-INDICE.md, base/00-LACUNAS.md, 01-CAUSA-RAIZ.md
E2Planosprint-NN/sprint.md, fases.md, tasks.md, ORQUESTRADOR.md
E3Fixatualiza tasks.md; preenche BLOQUEIOS.md
E4QAQA.md com VEREDITO: APROVADO ou REPROVADO
E5Relatóriodocs/relatorios/<data>-<OC-ID>-<slug>/tecnico.md e uso.md; atualiza o INDICE.md

QA.md reprovado volta para o E3. E há um retorno que o disco não mostra: se no E3 o teste de regressão passar antes do fix, a ocorrência volta ao E1 — porque o que se acreditava ser a causa não era.

Os tipos de ocorrência governam o E1

bug exige causa raiz comprovada; os demais entram em análise de impacto.

bugmelhoria-uimelhoria-ux novo-relatorioregra-de-calculocampo-novooutro

Comandos

ComandoO que faz
/runxDetecta o estágio atual e continua de onde parou
/runx-causaE1 — mapeia a base e comprova a causa raiz (ou mapeia o impacto)
/runx-planoE2 — converte a investigação em sprints, fases e tasks
/runx-fixE3 — implementa o plano sob TDD estrito, de forma autônoma
/runx-qaE4 — valida a entrega contra o plano e o escopo, sem corrigir
/runx-relatarE5 — relatórios técnico e de uso, e fechamento da ocorrência

Hooks

Os hooks da runx rodam por um despachante único: cada python3 custa cerca de 30 ms de partida, e cinco processos estourariam o orçamento de 200 ms por chamada de ferramenta.

HookModoO que garante
segredo-no-commitbloqueiobarra credencial indo para arquivo versionado
causa-antes-do-planoavisoplano sem 01-CAUSA-RAIZ.md, ou com comprovada: false num bug
regressao-antes-do-fixavisocódigo de produção tocado antes de o teste de regressão existir
task-so-fecha-verdeavisostatus: concluida sem suite: verde e sem os dois testes
escopo-da-ocorrenciaavisoescrita fora de arquivos_impactados e do arquivos das tasks
sem-jargao-no-usoavisocaminho de arquivo, nome de função, tabela ou stack trace no relatório do cliente

Regras invioláveis

  • R1 — “Nenhum plano nasce sem base/ preenchida. Mapear antes de planejar.”
  • R2 — “Bug não avança de E1 sem causa raiz comprovada.”
  • R5 — “O teste de regressão é escrito antes do fix e tem que falhar antes.”
  • R8 — “Escopo travado: o que não está em 01-CAUSA-RAIZ.md e em tasks.md não é tocado — nada de refactor de brinde, nada de ‘já que estou aqui’.”
  • R10 — “Quem implementa não aprova: E4 é papel distinto de E3, e E4 não corrige nada.”
  • R13 — “Durante E3 a skill não pergunta nada. Dúvida nova vira registro em BLOQUEIOS.md e a task é pulada.”
  • R15 — “Coincidência de arquivo não é regressão. O campo regressao_de só é preenchido com evidência de vínculo causal.”

Proporcionalidade: uma correção de uma linha gera 1 sprint, 1 fase e 2 tasks. “Proibido inflar o plano para parecer robusto. Proibido enxugar campos para parecer ágil.”

Skill · base

mergex

Versionamento, entrega e revisão: branch, um commit por task, portão de prontidão, descrição de PR, pacote de QA e abertura do pull request. O princípio que a governa: o revisor humano é recurso caro e finito.

base10 etapas 7 comandos2 agentes6 hooks

As etapas

Não é uma máquina de estados sequencial: E0 e E1 acontecem durante a execução do trabalho, E2E8 acontecem no fim, e E9 é manual e avulsa.

EtapaNomeO que produz
E0Aberturaa branch do trabalho. “Branch que já existe é retomada, nunca duplicada”
E1Commit por taskum commit por task fechada, com varredura de segredo antes de cada um
E2Portão de prontidãoPRONTO ou BLOQUEADO. “BLOQUEADO encerra: a mergex não segue e não maquia”
E3Atenção humanaATENCAO.mdé o coração da skill
E4Descrição do PRPR.md — “Cabe em uma tela”
E5Pacote para o QAQA-PACOTE.md — “O QA não deve precisar ler código”
E6Pushsobe a branch. “Nunca forçado, nunca na principal”
E7Abertura do PRabre pela CLI do serviço quando existir; ausente, grava em PR.md
E8Registro da entregaENTREGA.md com kind: entrega
E9Revisão e merge manualconduz um PR por vez. “Nunca resolve conflito”

As três faixas de atenção humana

O E3 classifica cada arquivo do diff em exatamente uma faixa, a partir de evidência já registrada pelas outras skills — nunca de sensação.

FaixaO que o revisor fazCritérios — basta um
OLHO OBRIGATÓRIO Lê linha a linha zona de risco do PERFIL.md; mudança de regra de negócio ou cálculo; migração de banco; autenticação, autorização ou dado pessoal; alteração de contrato público; código sem cobertura antes e depois; efeito irreversível; tudo que veio de raio ALTO; arquivo com histórico de regressão no memox
LEITURA RÁPIDA Confere intenção, não implementação mudança coberta por teste de caracterização que continua passando; alteração em camada isolada com cobertura existente; código novo em arquivo novo, com os dois testes verdes
DISPENSÁVEL A máquina já provou arquivo de teste que só acrescenta caso; alteração mecânica coberta por regressão verde; arquivo gerado automaticamente, quando declarado como tal

Tamanho do diff não é critério. Uma linha que muda um cálculo fiscal é OLHO OBRIGATÓRIO; trezentas linhas de teste novo são DISPENSÁVEL. E a faixa nunca desce por causa do memox — o índice só agrava.

Comandos

ComandoEtapasO que faz
/mergexE2–E8Fluxo automático completo a partir do estado atual
/mergex-abrirE0Abre a branch antes da primeira linha de código
/mergex-checkE2As dez verificações do portão de prontidão
/mergex-atencaoE3Classifica o diff nas três faixas
/mergex-prE4, E6, E7Monta a descrição, sobe a branch e abre o PR
/mergex-qaE5Gera o pacote de teste executável por quem não programa
/mergex-revisarE9só por chamada explícita revisão e integração de PRs

O /mergex-revisar nunca é encadeado a partir de nenhum fluxo nem oferecido ao fim de um trabalho: integrar código é decisão humana.

As dez verificações do portão

tasks concluídassuíte verdedois testes por task teste de regressãoQAauditoria bloqueiosmodo legadoarquivos fora do escopo segredos no diff

Regras invioláveis

  • R1 — “A branch nasce com o trabalho, não no fim.”
  • R3 — “Cada task concluída com suíte verde vira um commit próprio. Nunca amontoar tasks distintas.”
  • R6 — “O portão de prontidão barra e explica. Nunca maquia.”
  • R7 — “Nada na entrega é inventado: todo conteúdo vem de artefato existente.”
  • R9 — “Zona de risco, migração de banco, mudança de contrato público e efeito irreversível são sempre OLHO OBRIGATÓRIO.”
  • R11 — “Nunca push forçado, nunca na branch principal, nunca reescrever histórico já enviado.”
  • R18 — “A mergex não faz merge no fluxo automático, não aprova, não publica e não faz deploy.”
  • R19 — “A mergex entrega; quem fecha a ocorrência é a runx.”

Limitação declarada pela própria skill: a mergex não previne colisão entre desenvolvedores. Ela organiza a entrega de um trabalho; coordenar duas pessoas no mesmo arquivo continua sendo problema de processo humano.

Skill · camada

legadox

Camada que endurece o trabalho em projetos legados. Não acrescenta fase: muda o rigor de cada uma, proporcional ao raio de impacto da mudança. Em código legado o comportamento atual é o contrato, bugs inclusive.

camada11 camadas 6 comandos2 agentes7 hooks

O gatilho é um arquivo. Sem docs/legado/PERFIL.md não existe modo legado. A primeira coisa a fazer é gerá-lo, com /legadox-perfil.

O raio de impacto

Oito sinais coletados por evidência — chamadores, telas e rotas, consumo assíncrono, cobertura, zona de risco, churn e idade, migração, dado histórico. Sinal que não puder ser coletado conta como pior caso, e isso fica escrito.

A faixa é calculada por sinais, nunca escolhida por sensação. BAIXO exige que todas as condições valham juntas; MEDIO e ALTO bastam uma.

O que cada faixa aciona

CamadaBAIXOMEDIOALTO
Raio registrado C2simsimsim
Prova de código vivo C10simsimsim
Proibição de colateral C6simsimsim
Testes de caracterização C3simsim
Ponto de costura C4simsim
Orçamento por task C55 arq / 150 linhas3 arq / 80 linhas2 arq / 40 linhas
Plano de reversão C7simsim
Roteiro de teste manual C8simsim
Plano aprovado antes do códigosimsim
Perguntas da zona C11se tocar zonasim
Comparação com dado real C9sim
Chave de desligamentosim
Aprovação humana registradasim

A camada 9 é obrigatória, independentemente da faixa, em qualquer mudança de cálculo ou de regra de negócio.

Nenhum hook de método roda em raio BAIXO. Todos leem a faixa primeiro e saem imediatamente. A exceção é o zona-de-risco, que bloqueia em qualquer faixa.

Comandos

ComandoCamadaO que faz
/legadoxVerifica o modo legado e mostra o que falta no trabalho atual
/legadox-perfilC1Gera ou atualiza o PERFIL.md, o gatilho do modo legado
/legadox-raioC2Calcula o raio por evidência e declara quais camadas isso aciona
/legadox-caracterizarC3Escreve os testes que congelam o comportamento atual
/legadox-dividaC6Consulta e acrescenta ao inventário de dívida, sem corrigir
/legadox-manualC8Gera o roteiro de teste manual, com a seção de colateral

Regras invioláveis

  1. “Sem docs/legado/PERFIL.md não existe modo legado. A primeira coisa é gerá-lo.”
  2. “Nenhum plano é gerado sem o raio de impacto calculado e escrito.”
  3. “A faixa do raio é calculada por sinais, nunca escolhida por sensação.”
  4. “Em raio MEDIO ou ALTO, nada é alterado antes de existir teste de caracterização passando no código atual.”
  5. “Nenhuma melhoria colateral. O que incomoda vai para docs/legado/DIVIDA.md.”
  6. “O orçamento de mudança por task não é estourado em silêncio.”
  7. “Toda task de raio MEDIO ou ALTO declara como se reverte, inclusive os efeitos que o versionador não desfaz.”
  8. “Zona de risco tocada obriga as perguntas da zona respondidas antes do plano.”
  9. “Raio ALTO obriga aprovação humana explícita e registrada.”
  10. “Código morto identificado não é removido: vira achado.”
  11. “Dado real usado em comparação é anonimizado e nunca é commitado.”
  12. “O legadox não substitui a sprintx nem a runx: ele os endurece.”

Artefatos em disco

árvore
docs/legado/PERFIL.md                    # C1 — gatilho do modo legado
docs/legado/LACUNAS.md
docs/legado/DIVIDA.md                    # C6 — append-only
docs/legado/raio/<trabalho_id>.md        # C2
docs/legado/manual/<trabalho_id>.md      # C8
docs/legado/comparacao/<trabalho_id>.md  # C9

Skill · camada

stackx

Descobre o dialeto técnico do repositório — onde os testes moram, como o banco é isolado, quais comandos funcionam de verdade, quem pode chamar quem — e grava tudo com evidência. Convenção não se propõe, se descobre.

camada5 etapas 5 comandos1 agente2 hooks

As etapas

EtapaNomeO que produz
1Detecçãoinventário FATO / EVIDÊNCIA / FORÇA em memória — roda no agente cartografo
2O CONVENCOES.mddocs/stack/CONVENCOES.md
3Conflito e lacunadocs/stack/LACUNAS.md
4Verificação de aderênciatabela severidade / arquivo / convenção violada / correção sugerida
5Atualizaçãodiff sobre o CONVENCOES.md — nunca sobrescreve em silêncio

A ordem da detecção

Não é arbitrária: vai do que declara a intenção para o que revela a prática.

  1. manifestos e locks
  2. configuração de runner, lint, formatador, type checker e build
  3. os testes que já existem — a fonte mais rica
  4. migrações e schema
  5. scripts dos manifestos
  6. integração contínua
  7. arquivos de ambiente de exemplo
  8. o próprio código

Os três cartuchos

Um cartucho só existe quando o assunto é, ao mesmo tempo, não óbvio, específico de versão ou engine e caro de errar.

migração segura

O que trava tabela e por quanto tempo, índice sem bloqueio, coluna obrigatória em tabela grande, ordem segura de renomear em deploy sem indisponibilidade, e o que fazer quando reverter não é possível.

N+1 no ORM

Consultas que explodem em produção e passam nos testes com massa pequena.

teste instável

Estado global, paralelismo sem isolamento de banco, relógio, ordem, fuso e rede.

Comandos

ComandoO que faz
/stackxSem CONVENCOES.md, conduz à detecção; com ele, mostra o resumo, as lacunas e os pontos marcados PROPOSTA
/stackx-detectarEtapas 1 e 2 — varre em busca de evidência real e gera os dois arquivos
/stackx-checkEtapa 4 — verifica se um diff respeitou as convenções. Aponta, não corrige
/stackx-atualizarEtapa 5 — redetecta e apresenta o diff. Nunca sobrescreve em silêncio
/stackx-migracaoConsulta dirigida ao cartucho de migração segura

Regras invioláveis

  1. “Toda convenção aponta um arquivo real do repositório que a exemplifica, com caminho e linha.”
  2. “Convenção sem evidência no código não é convenção: é PROPOSTA, e é marcada como tal.”
  3. PROPOSTA não governa. Nas outras skills ela vira decisão a levantar, nunca regra a obedecer.”
  4. “Diante de dialetos conflitantes, o stackx não escolhe sozinho: apresenta os dialetos com contagem e histórico, e pergunta.”
  5. “Comando declarado precisa ter sido encontrado em manifesto, script ou integração contínua. Comando nunca é inferido do nome do framework.”
  6. “Em projeto legado, na área tocada manda o PERFIL.md do legadox. O stackx governa apenas código novo em arquivo novo.”
  7. “Atualização de convenção nunca sobrescreve em silêncio: apresenta diff e espera confirmação.”
  8. “A verificação de aderência aponta, não corrige.”
  9. “Cartucho não repete o que o modelo já sabe. Se virou tutorial de sintaxe, foi escrito errado.”
  10. “Nenhum segredo, credencial ou dado real de cliente entra em CONVENCOES.md, exemplo ou template.”

O formato obrigatório da evidência é literal:

docs/stack/CONVENCOES.md
Evidência: src/users/create-user.test.ts:14, src/orders/place-order.test.ts:9

O CONVENCOES.md liga hooks de outras skills. O tdd-teste-antes e o escopo-da-task da sprintx, a convenção de commit e branch da mergex e o comando de teste de todas ficam inativos quando o arquivo não existe.

Skill · camada

memox

Indexa o que as outras skills já gravaram e responde o que se sabe sobre um arquivo antes de alguém mexer nele. Memória que precisa ser consultada não é usada — por isso ela se injeta sozinha no contexto.

camada5 etapas 5 comandos0 agentes2 hooks

Índice invertido, não busca semântica

A pergunta real não é “o que é parecido com isto”, é “quem já mexeu neste arquivo e por quê” — e isso é uma string exata. Resposta de índice aponta artefato e data, então dá para abrir e conferir; recuperação semântica erra em silêncio, devolvendo algo plausível com a mesma confiança do certo.

O que ele indexa

FonteO que extrai
docs/relatorios/*/tecnico.mdtrabalho, data de fechamento, tipo, módulo afetado, arquivos alterados, causa em uma linha, risco residual
docs/relatorios/INDICE.mda linha do tempo, para ordenação e contagem
docs/manutencao/*/01-CAUSA-RAIZ.mdmodo, se é comprovada, arquivos impactados, decisões
00-DECISOES.mdcada decisão com a alternativa descartada e o motivo
docs/legado/DIVIDA.mddívida observada por arquivo, com risco estimado
base/00-LACUNAS.mdo que a documentação não respondia
docs/manutencao/*/QA.mdreprovações — o sinal mais forte de área frágil
docs/entregas/*/ENTREGA.mdbranch, commits e faixa de atenção por arquivo

Regressão exige evidência causal, não coincidência

Um vínculo só é registrado como regressão quando as três condições valem juntas: um arquivo apontado pela causa raiz do trabalho posterior está entre os que o anterior alterou; a ordem cronológica está estabelecida; e a causa do posterior é comprovada, não hipótese. Faltando qualquer uma, o vínculo aparece como coincidencia_arquivo com o motivo escrito — é isso que impede o sinal mais valioso do índice de virar ruído.

Comandos

ComandoO que faz
/memoxEstado do índice: quantos trabalhos, quando foi reconstruído, o que ficou de fora e por quê
/memox-indexarReconstrói o índice do zero a partir dos artefatos
/memox-arquivoO que se sabe sobre um arquivo — quem o tocou, quando, e se já causou regressão
/memox-moduloHistórico de um módulo, com as decisões e suas alternativas descartadas
/memox-buscarBusca textual nos títulos, causas e resumos dos trabalhos fechados

Os dois hooks falham abertos

HookEventoO que faz
memox-injetarUserPromptSubmitdetecta os arquivos que o prompt declara que serão tocados e injeta o que se sabe sobre eles, com proveniência
memox-reindexarStopreconstrói o índice quando detecta artefato novo ou alterado, de forma assíncrona

Contrato dos dois: silencioso quando não há nada relevante; sai com 0 sempre, inclusive em erro; abaixo de 200 ms; sem rede e sem modelo.

É por isso que o doctor trata “hook sem motor” como erro. Falha aberta nunca trava o prompt de quem está trabalhando — o preço é que uma instalação quebrada fica indistinguível de um projeto sem artefatos. O doctor é o único lugar onde a diferença aparece.

Controle de ruído

No máximo 3 entradas recentes por arquivo, mais as que envolveram regressão, reprovação em QA ou zona de risco. Acima de 8 entradas relevantes ele não lista: informa a contagem. Tudo configurável em .expx/memoria/config.json.

terminal
python3 .claude/skills/memox/assets/memox.py indexar

O índice fica em .expx/memoria/indice.json, é local e gitignorado, e se reconstrói do zero a qualquer momento. Um clone recém-feito não tem nenhum — esse é o caso comum, não um erro.

Skill · camada

prodx

Recebe o pedido cru, tria, verifica se o que foi pedido já existe e emite um veredito com evidência para assinatura humana. O cliente pede solução, não problema.

camada6 estágios 6 comandos0 agentes0 hooks

O indicador de sucesso declarado pela skill é a taxa de pedidos que NÃO viram trabalho. Três dos quatro vereditos encerram o pedido sem gerar uma linha de código.

Os estágios

EstágioNomeSaídaQuando roda
P0Triagemlinha em docs/produto/INDICE.mdnão gera pastatodo pedido
P1Contexto de produtoPRODUTO.md e LACUNAS.mduma vez, atualizado sob demanda
P2Entendimento do pedido01-pedido.mdavaliação completa
P3Verificação de existência02-existencia.mdavaliação completa
P4Avaliação03-avaliacao.mdquando não for ja_existe
P5Veredito e briefingVEREDITO.md e BRIEFING.mdavaliação completa

Os oito gatilhos da triagem

Nenhum gatilho disparado: veredito direto, uma linha no índice, segue para a runx. Um ou mais: avaliação completa, de P2 a P5.

Gatilho
G1O pedido é do tipo novo, ou pede tela, relatório ou fluxo novo
G2O pedido descreve uma solução, não um problema
G3O pedido serve a um cliente só, num produto multi-cliente
G4O pedido cheira a algo que já existe no sistema
G5O pedido chegou rotulado como bug mas descreve regra de negócio
G6O pedido toca zona de risco declarada no PERFIL.md
G7O mesmo pedido já foi recusado antes
G8O esforço aparente é maior que alguns dias

Os quatro vereditos

VereditoSignificado
ja_existeO sistema já faz. Sai um texto para o cliente explicando onde e como, na linguagem dele
nao_fazerCom o motivo registrado. Este arquivo é ativo permanente: quando o pedido voltar, a avaliação já está feita
fazer_outra_coisaO problema real reformulado, que costuma ser menor e diferente do pedido
fazerE aí sai o briefing

O VEREDITO.md traz sempre um campo de assinatura humana, preenchido pela pessoa, nunca pela skill.

Comandos

ComandoO que faz
/prodxMostra os pedidos abertos e a proporção entre triagem e avaliação completa
/prodx-produtoP1 — cria ou atualiza o contexto de produto que sustenta todos os vereditos
/prodx-triarP0 — roda os oito gatilhos. Seco e rápido, sem criar pasta
/prodx-avaliarP2 a P5 — avaliação completa até o veredito pronto para assinatura
/prodx-existeP3 isolada — “isso já existe?”, com evidência
/prodx-briefingGera o BRIEFING.md no formato que a sprintx ou a runx espera

Regras invioláveis

  1. “A skill não decide. Ela recomenda com evidência; humano assina.”
  2. “Nenhum trabalho segue para sprintx ou runx sem veredito assinado.”
  3. “A triagem nunca é pulada, e a avaliação completa nunca roda em pedido sem gatilho disparado.”
  4. “A solução pedida nunca é tratada como o requisito. O requisito é o problema.”
  5. “A verificação de existência é obrigatória e vem com evidência: tela, rota, arquivo ou relatório. ‘Acho que já tem’ não é resposta.”
  6. “Escopo mínimo é campo obrigatório e nunca fica vazio.”
  7. “Pedido rotulado como bug é verificado contra comportamento intencional antes de virar ocorrência.”
  8. “Informação que falta vira pergunta, nunca suposição.”
  9. “Pedido recusado não é apagado: a avaliação é ativo permanente.”
  10. “O briefing não contém decisão técnica.”
  11. “Nada de invenção no PRODUTO.md. O não verificável vira NAO DETERMINADO.”
  12. “O campo de quem assina nunca fica vazio.”

Skill · orquestração

buildx

Recebe a descrição de um projeto inteiro em linguagem natural, faz uma única pergunta, e conduz as outras skills até o sistema estar construído, testado e validado. Uma descrição entra, um sistema sai.

orquestra6 etapas 4 comandos0 agentes0 hooks

Ela não implementa, não planeja e não escreve teste nenhum. Toda a competência mora nas camadas irmãs. A única coisa que a buildx faz e nenhuma outra faz é a decomposição: quebrar um projeto em features. É o vão entre “quero um sistema de gestão de contratos” e “planejar a feature de upload de PDF” — a sprintx planeja uma feature com rigor e não sabe recortar um sistema.

A pergunta única

É a primeira coisa que acontece, antes de qualquer arquivo:

ModoO que significa
autônomo totalNenhuma outra pergunta chega ao usuário até o fim — nem da buildx, nem de nenhuma camada que ela invocar. Cada decisão tomada em nome dele vira uma premissa registrada, com o fato que a invalidaria
briefingUma rodada de perguntas, no máximo dez, só as que mudam a arquitetura. Respondidas, o comportamento é idêntico ao autônomo: silêncio até o fim

Relatar progresso não é perguntar: nos dois modos o usuário vê onde a cadeia está, sem precisar responder nada.

As seis etapas

EtapaNomeO que aconteceQuem trabalha
B1Concepçãomapeia o escopo e varre o que não foi pedido; cada lacuna vira premissaprodx, modo greenfield
B2Fundaçãoescolhe a stack, instala a suíte, monta o esqueleto que sobe e testastackx, invertido
B3Decomposiçãoquebra o projeto em features, com ordem de dependênciasó a buildx
B4Construçãoo laço: por feature, branch → plano → auditoria → execução TDD → PRsprintx, mergex
B5Recursãoclassifica o que ficou pelo caminho e devolve ao laço o que a máquina resolvebuildx
B6Validaçãoconfere o construído contra o mapa, item a item, e relataprodx, como auditor

O ciclo B4B5 repete enquanto houver pendência que a máquina resolve, com teto de três ciclos. O ciclo 2 resolve o que o B3 recortou mal; o 3 resolve o que o 2 criou. Do quarto em diante o que sobra normalmente não é falta de trabalho, é falta de decisão.

O que ela descobre que você não pediu

A varredura do B1 é a razão de a buildx existir em vez de você falar direto com a sprintx. Trinta e um eixos, percorridos sempre — cada um sai como pedido, descoberto ou descartado com o porquê registrado. Nenhum é pulado em silêncio.

GrupoExemplos do que entra sem ninguém pedir
Segurançaautorização por papéis desde a primeira feature, hash de senha, rate limit nas rotas de autenticação, validação de entrada no servidor
Dado e conformidadeLGPD com exclusão que apaga de fato e exportação do titular, trilha de auditoria, backup com restauração testada
Operaçãolog sem dado pessoal, erro que não vaza rastro de pilha, rota de saúde, variável obrigatória que falha no start e não em produção
Interfaceas duas variantes de tema completas, estados de vazio, carregando e erro, responsividade, contraste conferido

Toda decisão fica auditável

Cada escolha feita em nome do usuário vira uma premissa com cinco campos, e o quinto é o que importa:

PREMISSAS.md
PR-07 — Autorização por papéis

Decisão:  papéis admin e usuario desde a primeira feature,
          verificados no servidor.
Por quê:  o sistema tem dado de mais de um usuário; sem papel,
          qualquer conta alcança o dado de qualquer outra.
O que
invalida: se todo usuário tiver exatamente o mesmo acesso aos
          mesmos dados, de forma permanente.

Como revisar vinte e três decisões em cinco minutos: leia só o campo o que invalida. Se aquilo é verdade no seu caso, a premissa merece atenção. Se não é, siga.

A fronteira que ela não atravessa

A buildx decide como o sistema se protege, não o que o sistema faz.

Requisito não-funcional tem padrão defensável por classe de sistema — um sistema sem rate limit tem um defeito conhecido. Regra de negócio não tem padrão: ela é o negócio. Um sistema com a regra de cálculo errada funciona e está errado, que é o pior resultado possível, porque parece pronto e ninguém procura o defeito.

Regra de negócio não declarada nunca é chutada: vira pendência, a buildx segue com a decisão mais reversível possível, e o relatório final abre com ela.

O que ela quebra de propósito

O modo autônomo viola regras que existem por bons motivos nas irmãs. Cada violação é restrita ao modo e registrada no artefato que ela toca.

Regra violadaDe quemComo fica
“a skill não decide, humano assina”prodx R1a buildx assina, com provisorio: true e aprovado_por: buildx (modo autonomo)
“nada vai à sprintx sem veredito assinado”prodx R2a auto-assinatura satisfaz o portão
“a F2 é obrigada a perguntar ao humano”sprintx R10a buildx responde em quatro degraus — PROJETO.md, PREMISSAS.md, CONVENCOES.md, e só então uma premissa nova — tudo em 00-DECISOES.md com respondido_por: buildx
“convenção só se registra com evidência”stackxno B2 a origem é decidido_pelo_buildx; depois da primeira feature entregue, o stackx-detectar converte cada regra para a evidência real

O que ela nunca quebra. O merge continua humano: a buildx nunca invoca mergex-revisar, nunca oferece, nunca sugere. Todas as outras coisas que ela faz sozinha são reversíveis — uma premissa errada se corrige, um plano ruim se replaneja. Merge é onde o trabalho vira o sistema. Um buildx que faz merge sozinho não é mais autônomo: é irreversível, e são coisas diferentes.

Também intactos: o TDD da sprintx, a regra de que task só conclui com os dois testes passando, e a auditoria da F5 — execução autônoma sem auditoria respeitada é dano autônomo.

Os padrões da casa

O que a buildx assume quando o usuário não diz nada. O usuário sempre ganha do padrão.

PadrãoPor quê
P-1três camadas, fronteira explícitaé o desenho que o stackx sabe verificar e a sprintx sabe recortar em tasks
P-2Next.js, TypeScript, App Routercobre as três camadas num único projeto e num único deploy
P-3SQLite localdependência mínima é requisito de execução autônoma: um banco que exige serviço, credencial e rede é um ponto onde o laço trava esperando algo que a máquina não resolve
P-4autenticação própria, JWT, hash fortenão depende de provedor externo nem de credencial que a buildx não tem
P-5usuário de demonstração com dados de exemploum sistema que sobe numa tela de login vazia é indistinguível de um sistema quebrado
P-6o design system do VS Codetokens semânticos e par claro/escuro já resolvidos — e uma regra verificável: nenhuma cor literal em componente
P-7a skill de frontend design da Anthropictrabalha dentro desses tokens; a competência de design mora numa skill feita para isso
P-8o projeto nasce com a suíte Expx instaladao B4 precisa dela, e quem receber o sistema continua usando o método — o memox só vale se estiver lá desde o primeiro commit

Comandos

ComandoO que faz
/buildx <descrição>o comando único: recebe a descrição, faz a pergunta do modo, e conduz tudo até o fim
/buildxroteador: mostra em que etapa o projeto está, e o estado de cada feature
/buildx-mapaB3 isolada — mostra ou regera o MAPA.md
/buildx-retomarretoma um projeto interrompido, a partir do estado em disco
/buildx-statuspainel seco: features, ciclos de recursão, pendências, premissas

Artefatos em disco

árvore
docs/projeto/
  PROJETO.md      o escopo: o pedido, o descoberto, o descartado
  PREMISSAS.md    toda decisão tomada em nome do humano
  MAPA.md         as features, em ordem de dependência
  RECURSAO.md     pendências por ciclo, e o teto
  VALIDACAO.md    a conferência final
  RELATORIO.md    o que o usuário lê no fim

São os únicos artefatos do método que descrevem um projeto e não um trabalho: usam projeto_id no lugar de trabalho_id. A ponte entre os dois níveis são as chaves origem_buildx e feature_id, que a cadeia acrescenta ao artefato de cada feature — é o que permite abrir um plano de sprint qualquer e saber de qual projeto ele veio.

O que o usuário lê no fim

RELATORIO.md
1. O QUE VOCÊ PRECISA DECIDIR       as regras de negócio não declaradas
2. O QUE VOCÊ PRECISA PROVIDENCIAR  credenciais, acessos, contas
3. O QUE FOI DECIDIDO POR VOCÊ      as premissas, com o que invalida cada uma
4. O QUE FICOU PRONTO               features entregues, com os PRs
5. O QUE NÃO FICOU                  pendências, com o porquê
6. COMO RODAR                       instalar, subir, entrar com o usuário demo
7. O QUE FAZER AGORA                revisar os PRs e fazer merge

A ordem é deliberada: o que exige ação vem antes do que foi feito. Um relatório que abre com onze features entregues e esconde na página três que a regra de cálculo foi chutada é desonesto na estrutura, mesmo dizendo tudo.

Regras invioláveis

  1. “Uma única pergunta ao usuário: o modo. No autônomo, nenhuma outra chega a ele, de nenhuma camada.”
  2. “Toda decisão tomada no lugar do humano é registrada em PREMISSAS.md antes de ser usada, com o que a invalidaria.”
  3. “A buildx não implementa, não planeja e não testa. Ela invoca a camada dona e verifica a saída.”
  4. “Bloqueio nunca para o laço: registra, marca a feature, segue para a próxima.”
  5. “O ciclo B4 → B5 tem teto declarado. Atingido, para e reporta.”
  6. “Nenhuma feature entra no mapa sem entrega verificável e dependências explícitas.”
  7. “Feature de fundação vem primeiro; nenhuma feature precede aquilo de que depende.”
  8. “Merge é humano. Nunca invoca mergex-revisar, nem oferece.”
  9. “O que não for derivável do projeto, das premissas ou das convenções vira premissa nova — nunca invenção silenciosa.”
  10. “Todo artefato usa o frontmatter expx-schema v1.”
  11. “Caminhos sempre relativos.”
  12. “O relatório final declara toda pendência.”

Referência do CLI

Subcomandos

Sete subcomandos. O panel e o watch funcionam sem init: nenhum dos dois escreve no projeto.

ComandoO que faz
expx initInstala as skills escolhidas neste projeto
expx panelSobe o painel de operação lendo o docs/ do projeto
expx watchAcompanha um trabalho no terminal, ao vivo
expx add <skill…>Acrescenta skills à seleção e remonta o plugin
expx remove <skill…>Remove skills da seleção e remonta o plugin
expx update [skill…]Atualiza as skills instaladas
expx doctorDiagnostica uma instalação quebrada

O pacote publica três binários: expx e expxdev (o mesmo programa) e expx-painel, que sobe o painel direto.

init

terminal
expx init [--skills a,b] [--harness claude,opencode] [--yes]

Sem --skills e com terminal interativo, abre o assistente. Sem --yes e sem TTY, imprime o que instalaria e sai sem escrever. Uma skill que falha não derruba as outras: o erro dela é reportado nominalmente e o init segue com as demais.

add e remove

terminal
expx add memox prodx
expx remove legadox

Os dois leem o lock, ajustam a seleção e remontam o plugin do zero com o mesmo harness já registrado. Sem instalação válida, o CLI orienta a rodar o init. Remover a última skill é recusado: uma instalação vazia não é estado válido.

update

FlagEfeito
(sem argumento)Atualiza todas as skills instaladas
<skill…>Atualiza apenas as nomeadas
--checkSó mostra o que mudaria, não aplica nada
--to <ref>Fixa uma skill numa tag ou commit — exige nomear exatamente uma skill
--yes · --simAplica sem exigir terminal interativo

doctor

Não aceita flags. Sai com 0 quando não há nenhum achado de severidade erro — ou seja, só avisos ainda sai 0, mas a lista é impressa.

panel e watch

ComandoFlagPadrãoO que faz
panel--porta <n>4000porta do servidor local
--dir <caminho>./docspasta de documentação a observar
--no-opennão abre o navegador
--dias-bloqueio <n>7dias a partir dos quais um bloqueio é antigo
watch<trabalho_id>segue um trabalho específico
--todoslista os trabalhos abertos, sem árvore
--colunas <n>largura do terminallargura fixa

Os dois aceitam --ajuda, --help ou -h, e a forma --flag=valor.

Flags aceitas que ainda não têm efeito. O parser reconhece --painel e --check no init, e --latest no update, mas nenhuma delas altera o comportamento nesta versão. O dry-run efetivo do init é a ausência de --yes fora de um terminal interativo; a resolução do update já é sempre a maior tag. Não existe expx --version: a versão aparece no cabeçalho do init interativo.

Referência do CLI

Anatomia do init

O que roda, em que ordem, e por quê.

Para cada skill selecionada

  1. Resolve a versão alvo

    Busca a maior tag de versão semântica do repositório — comparando número a número, porque ordenar como texto colocaria v1.10.0 antes de v1.2.0. Pré-lançamento (-rc.1) é ignorado: não é versão publicada. Sem nenhuma tag, cai para a branch padrão e registra travado: false no lock.

  2. Busca o conteúdo

    Com git clone --depth 1 --branch <referência>, usando o git do sistema. É de propósito: assim aproveita a credencial já configurada na máquina e não esbarra em limite de requisição de API.

  3. Detecta o layout

    Os repositórios não têm todos a mesma forma. O CLI não assume caminho: procura o SKILL.md mais raso e adota a pasta dele como raiz, depois confere que o name: do frontmatter é mesmo a skill pedida. Um layout novo passa a funcionar sem tocar nesta camada.

  4. Verifica os caminhos

    Recusa qualquer skill que referencie caminho fora da própria pasta. A mensagem traz até três achados, no formato arquivo:linha → referência.

  5. Calcula o hash de cada arquivo

    SHA-256 por arquivo, registrado no lock junto com repositório, referência, commit e a data de resolução.

Por que “caminho fora da própria pasta” é recusado. Ao instalar, o Claude Code copia o plugin para ~/.claude/plugins/cache/…, e só a pasta do plugin vai junto. Qualquer ../ dentro de uma skill sai da árvore copiada e deixa de resolver — silenciosamente. O CLI recusa instalar uma skill assim, tanto no init quanto no doctor.

Só depois é que a escrita acontece

E ela é atômica: a montagem inteira ocorre numa pasta temporária ao lado do destino — não em /tmp, porque rename só é atômico dentro do mesmo sistema de arquivos — e é trocada por rename ao final. Se falhar no meio, o .expx/ anterior é devolvido ao lugar e permanece intacto.

A configuração do harness

A configuração do Claude Code é mesclada, nunca reescrita: backup datado antes de qualquer alteração, todo o resto preservado, e recusa explícita de “consertar” JSON inválido — nesse caso o arquivo não é tocado e o init emite um aviso.

Duas particularidades medidas em execução, não presumidas:

  • A lista de plugins habilitados é lida nos dois formatos — o array documentado e o objeto que o Claude Code realmente escreve — e sempre gravada como objeto.
  • Os hooks só entram na configuração se houver hooks. Um projeto sem skill com hook não ganha uma seção vazia do nada. E a entrada é deduplicada pelo comando, porque o init roda de novo a cada atualização e a duplicata faria o hook rodar duas vezes por prompt.

Hooks no disco

Quando alguma skill traz hook, o CLI copia a skill inteira para .claude/skills/<nome>/ e o script para .claude/hooks/, com chmod 0755 — sem o bit de execução o hook não roda e não avisa. A skill vai junto porque o hook resolve o próprio motor como um caminho relativo a si mesmo.

Claude Code e OpenCode lado a lado

AspectoClaude CodeOpenCode
Skillsno plugin; e em .claude/skills/ quando há hook.claude/skills/ — sempre, todas
Comandosno plugin, com namespace /expx:….opencode/commands/, sem prefixo
Manifestosplugin.json + marketplace.jsonnenhum
Configuraçãomesclada, com backupnão escreve configuração
Registroclaude plugin marketplace add e installnenhum comando externo
Hookscopiados e registradoslacuna declarada

As skills vão somente para .claude/skills/, que o OpenCode lê nativamente. Copiar também para .opencode/skills/ criaria dois name iguais nas pastas que o OpenCode varre, e a duplicata é resolvida por último-a-escrever-vence com apenas um aviso no log — silenciosamente. É exatamente essa colisão que o doctor detecta.

Referência do CLI

/expx:onboarding

A primeira coisa a rodar depois do init. Sem ela, cada camada instalada roda em modo degradado na primeira vez que alguém a usa — e essa lacuna só aparece no meio de um plano, quando já custou tempo.

stackx, designx, legadox, memox e prodx já sabem cada uma mapear a própria camada. O que faltava era quem decidisse, na primeira vez que alguém abre um projeto com várias instaladas, o que já foi mapeado, o que falta, e em que ordem rodar o resto — em vez da pessoa descobrir isso comando por comando.

Claude Code
/expx:onboarding

Comando fixo do plugin, não de uma skill

Nenhuma camada é dona do onboarding — ele só orquestra as que já existem. Por isso ele mora em nucleo/commands/onboarding.md deste repositório, e viaja sempre para commands/ na raiz de todo plugin montado, junto com as skills selecionadas — do mesmo jeito que o resto do nucleo/ viaja por cópia. Está disponível mesmo que você não tenha escolhido nenhuma camada de mapeamento: nesse caso ele avisa, em uma linha, que não há nada para orquestrar.

Ele nunca reimplementa o critério de detecção de nenhuma camada — só lê o artefato que cada uma produz e chama o comando de verdade.

O que ele faz, em ordem

  1. Descobre o que está instalado

    Entre as cinco camadas que produzem mapeamento inicial. runx, sprintx, mergex e buildx nunca entram nesta lista — elas só consomem o que essas cinco geram.

  2. Verifica o que já foi mapeado

    Pela presença do artefato de cada camada. Camada já mapeada nunca é sobrescrita — redetecção é trabalho de cada uma (/stackx-atualizar e equivalentes), não deste comando.

  3. Monta a fila só com o que é pendente

    Na ordem de dependência: prodxstackxdesignxlegadoxmemox. designx só entra com sinal de UI no projeto; stackx só com sinal de código de verdade; legadox pergunta uma vez — legado é decisão de quem conhece o projeto, nenhuma evidência de código prova isso sozinha.

  4. Executa uma camada de cada vez

    Nunca em paralelo: uma pode se apoiar no que a anterior deixou (designx referencia stackx, por exemplo). Camada que falha é registrada e não derruba as outras.

  5. Fecha com uma tabela-resumo

    Instalada, estado antes, ação tomada, artefato gerado — e uma linha final dizendo o que mudou.

O gatilho de cada camada

CamadaGatilhoArtefato
prodxsempre disponível — o roteador /prodx decide se convoca o P1docs/produto/PRODUTO.md
stackxCONVENCOES.md ausente + sinal de código de verdadedocs/stack/CONVENCOES.md
designxDESIGN-SYSTEM.md ausente + sinal de UI (.tsx/.jsx/.css)docs/design-system/DESIGN-SYSTEM.md
legadoxconfirmação humana — pergunta uma vez, nunca por evidência de códigodocs/legado/PERFIL.md
memoxao menos um artefato de trabalho fechado já existente.expx/memoria/indice.json

Por que legadox não é evidência automática. Legado é decisão de quem conhece o projeto — não algo que sinal de código prova sozinho. Por isso é a única camada da fila que faz uma pergunta direta antes de agir, em vez de decidir pela estrutura do repositório.

Referência do CLI

Lock e atualização

A instalação é travada por lock; a atualização é um ato explícito. Quem clona o projeto recebe exatamente as mesmas skills que o time está usando, sem rede e sem rodar nada.

O hash por arquivo é o que permite detectar modificação local sem consultar a rede.

O formato do lock

.expx/expx-lock.json
{
  "lock_version": 1,
  "cli_version": "0.5.0",
  "harness": ["claude"],
  "skills": {
    "sprintx": {
      "repositorio":  "https://github.com/bittencourtthulio/sprintx",
      "referencia":   "main",
      "travado":      false,
      "commit":       "4e3570c9bb19b8e336a5ca9c22ea17e7394dc6e8",
      "resolvido_em": "2026-08-29",
      "arquivos": {
        "SKILL.md": "e3b0c442…b855"
      }
    }
  }
}

travado: false significa que a skill segue uma branch, e não uma tag publicada — é o estado atual de todas as oito, porque nenhum dos repositórios publica tag ainda. O doctor reporta isso como aviso, nunca como erro.

O que o update faz

  1. Descobre a versão alvo de cada skill instalada
  2. Compara com o lock — skill já em dia é reportada e não é tocada
  3. Detecta modificação local: se os arquivos divergirem do lock, não sobrescreve
  4. Mostra o resumo por skill: versão atual, versão nova, e os títulos dos commits entre as duas
  5. Pede confirmação e aplica
  6. Remonta o plugin do zero, reescreve o lock e valida

A aplicação remonta o plugin do zero com a seleção inteira do lock, em vez de editar a árvore montada. É mais lento e é de propósito: editar no lugar deixa arquivo órfão quando uma skill encolhe entre versões.

O que conta como modificação local

A comparação do disco contra os hashes do lock produz três listas — alterados, removidos e novos. A instalação só é considerada limpa quando as três estão vazias.

Um arquivo novo criado dentro da pasta de uma skill já bloqueia o update, mesmo que nada tenha sido alterado. A mensagem do bloqueio lista os alterados e os removidos, mas não os novos — então uma skill pode aparecer bloqueada com uma lista aparentemente vazia. Se isso acontecer, procure por arquivo acrescentado à mão dentro de .expx/marketplace/plugins/expx/skills/<nome>/.

Rollback

Como o .expx/ é commitado, desfazer uma atualização é revertê-lo pelo versionador. O update imprime isso em toda execução que aplica:

terminal
git checkout -- .expx

Não existe comando de desfazer no CLI, e é uma decisão: guardar a versão anterior dentro do .expx/ duplicaria no repositório aquilo que o versionador já guarda melhor.

Referência do CLI

O que o doctor verifica

Dezesseis verificações, cada uma com severidade e correção sugerida. Achado de severidade aviso não derruba a saída; erro sim.

terminal
npx expxdev doctor
VerificaçãoSeveridadeO que significa
gitignore-ignora-expxerroo .gitignore ignora o .expx/, que precisa ser versionado
sem-expxerroa pasta .expx/ não existe — o diagnóstico para aqui
lock-ilegivelerrolock ausente, JSON inválido ou fora do formato — o diagnóstico para aqui
lock-futuroerroo lock foi criado por uma versão mais nova do CLI
plugin-json-invalidoerroplugin.json ausente ou fora do schema
marketplace-json-invalidoerromarketplace.json ausente ou fora do schema
skill-ausenteerroskill do lock sem pasta em disco
caminho-foraerroskill referencia caminho fora da própria pasta
settings-ausenteerroharness inclui claude e a configuração está ausente ou inválida
plugin-nao-habilitadoerroo plugin não está habilitado na configuração
colisao-de-nomeerroa mesma skill existe em .claude/skills/ e em .opencode/skills/
<skill>-sem-motorerrohook instalado sem a pasta de assets da skill ao lado
modificacao-localavisoo disco divergiu do lock
skill-nao-travadaavisoa skill segue uma branch, não uma versão publicada
rastro-fora-do-contratoavisolinhas do rastro fora do contrato expx-eventos
rastro-chave-nao-declaradaavisochaves não declaradas no rastro

Por que os achados do rastro são aviso. Um doctor que reprova a instalação por causa de linha antiga em disco é um doctor que as pessoas param de rodar. A instalação está correta; o histórico é que tem linhas de um contrato anterior.

expx doctor
[erro] a skill memox tem hook instalado mas nao tem o motor ao lado
  correcao: rode expx init novamente para reinstalar a skill memox

[aviso] a skill sprintx nao esta travada em versao publicada
  correcao: nenhuma acao necessaria; o repositorio ainda nao publica tag

Referência do CLI

O painel

Lê a pasta docs/, descobre os trabalhos gravados pelas skills e mostra no navegador o que foi planejado, o que está em execução, o que travou e o histórico do que já foi entregue.

terminal
npx expxdev panel

Somente leitura, e não só por convenção. Qualquer requisição que não seja GET recebe 405 com a mensagem o painel e somente leitura. O servidor escuta exclusivamente em 127.0.0.1 — o host é constante no código, sem flag, opção ou variável de ambiente que mude isso.

Porta já em uso não derruba o painel. O caso mais comum é o mais banal — um painel anterior ainda no ar na mesma porta. Em vez de um stack trace, o CLI diz qual porta está ocupada, oferece o endereço do painel que já está rodando e sugere uma porta livre.

Como ele lê o projeto

A cada mudança o projeto é relido inteiro, não em pedaços: as regras de conformidade cruzam referências entre arquivos, e uma leitura parcial produziria violação falsa.

O que ele reconhece

O painel não varre todo .md do projeto: procura os nomes de arquivo do contrato. A razão é que muitos .md legítimos não têm frontmatter — 00-LACUNAS.md e 00-AUDITORIA.md, por contrato, não levam — e varrer por extensão encheria a tela de “fora do schema” com ruído.

ORQUESTRADOR.mdsprint.mdfases.md tasks.mdBLOQUEIOS.md00-BLOQUEIOS.md 00-DECISOES.md00-OCORRENCIA.md01-CAUSA-RAIZ.md QA.mdINDICE.mdtecnico.md uso.md00-INDICE.md

Um trabalho é uma pasta com ORQUESTRADOR.md de frontmatter válido — a regra é sobre o conteúdo, não sobre o caminho. Pasta sem orquestrador é ignorada em silêncio. O 00-INDICE.md só conta quando está dentro de uma pasta base/.

Violação e rejeição são coisas diferentes

A distinção importa e tem duas telas separadas:

Violaçãoo método

O painel leu o arquivo, e o conteúdo desobedece uma regra do método. É um achado sobre o trabalho, e ele continua na tela com o defeito à vista.

Rejeiçãoo arquivo

O painel não conseguiu ler. É um achado sobre o arquivo, e ele fica de fora do painel até ser corrigido.

As dez regras de conformidade

ViolaçãoO que significa
teste_ausentetask sem teste de integração ou funcional declarado
concluida_sem_verdetask marcada como concluída sem a suíte verde
paralela_com_dependenciatask declarada paralelizável mas com dependência aberta
regressao_ausenteocorrência do tipo bug sem o teste que reproduz
sem_criterio_saidafase ou sprint sem critério de saída
bloqueio_antigobloqueio parado há mais dias que o limite configurado
dependencia_inexistentetask que depende de um id que não existe neste trabalho
ciclo_dependenciaduas ou mais tasks que se esperam em círculo
estagio_incoerenteestágio declarado que não combina com a ferramenta (runx com f3, por exemplo)
chave_omitidachave obrigatória ausente do arquivo — pela regra R6, é violação, não rejeição

Cada regra tem escopo estreito de propósito, porque violação falsa é pior que violação ausente: regressão não é cobrada de trabalho da sprintx nem de ocorrência que não é bug, e critério de saída não é exigido de fase que não o declara por não existir.

Os seis motivos de rejeição

sem frontmatter validoYAML invalido kind desconhecidoversao de schema futura expx_schema ausente ou nao numericoestrutura incompativel com o kind

A API

RotaDevolve
GET /api/projetoo estado inteiro do projeto
GET /api/conformidadeas violações
GET /api/rejeicoesos arquivos que não puderam ser lidos
GET /api/historicoas entregas já fechadas
GET /api/memoriao índice da memox, ou null — que é estado legítimo, não erro
GET /api/saude{ ok, raiz, lido_em }
GET /relatorio?oc=<id>&tipo=tecnico|usoo relatório como página HTML autocontida
GET /relatorio.md?oc=…o mesmo relatório como download em Markdown
WS /wso estado inteiro a cada mudança

O websocket manda o estado inteiro, não um delta: o estado de um projeto documental é pequeno, e mandar tudo elimina a classe de bug em que servidor e tela discordam depois de uma mensagem perdida. Conexão caída fica visível na barra de status e reconecta sozinha — uma tela congelada mostrando dado velho é pior que um erro à mostra.

As telas

TelaO que mostra
Dashboardseis cartões, quatro distribuições e os trabalhos recentes. A separação entre planejamento e execução vem do estágio, não do status
Trabalhostabela filtrável por ferramenta, tipo e status, ordenável por atualização, progresso ou título
Detalhesprint por sprint, fase por fase, task por task, com dependências, critérios de saída e caminho crítico
Conformidadeas violações agrupadas por tipo, com arquivo e linha
Históricoas entregas, com link para os relatórios técnico e de uso
Memóriaarquivos de risco, regressões, coincidências e artefatos contaminados
Fora do schemaas rejeições, em duas abas: erros de leitura e arquivos anteriores ao contrato

Toda tela exporta CSV. Um filtro de período global — 7d, 30d, 90d, mês, ano ou intervalo — recorta trabalhos, histórico, bloqueios e violações; data ausente nunca é filtrada para fora.

Por que o quadro kanban foi removido

O kanban pressupõe cartões movendo-se entre colunas por decisão de pessoas. Aqui o estágio é a máquina de estados do método: ele avança quando um artefato passa a existir no disco, não quando alguém arrasta um cartão. A tabela conta essa verdade; o quadro contava outra.

A tela de Memória não respeita o filtro de período

Ao contrário das demais, e de propósito: o valor do sinal é justamente o antigo. Um arquivo que regrediu há dois anos continua sendo um arquivo que regride. Os arquivos de risco são ordenados por regressões, depois reprovações de QA, depois número de trabalhos — nunca por movimento, porque um arquivo central é tocado por dezenas de trabalhos sem nunca ter falhado, e ordenar por contagem o colocaria no topo, enterrando embaixo o arquivo que já quebrou duas vezes.

Referência do CLI

O watch

Acompanha um trabalho no terminal, ao vivo, sem sair do lugar onde você está trabalhando. Como o painel, ele nunca escreve nos arquivos do projeto.

expx watch
2 bloqueios abertos
  B-01 · T-02.03 · 3 dias · Falta o contrato do gateway de pagamento
  B-02 · sem task · hoje · Ambiente de homologacao fora do ar

OC-2026-0142 · runx · Arredondamento na faixa de peso
  e3 · 7/11 tasks · agora T-02.04
  raio medio · arquivos 2/3 · linhas 31/80
  fix/OC-2026-0142-arredondamento · pr aberto

[x] sprint-01 · Congelar o comportamento atual
  [x] F-01.1 · Caracterizacao
    [x] T-01.01 Teste de caracterizacao da faixa 0-5kg
    [x] T-01.02 Teste de caracterizacao da faixa 5-30kg
[>] sprint-02 · Corrigir o arredondamento
  [>] F-02.1 · Fix
    [x] T-02.01 Teste de regressao que reproduz o bug
    [x] T-02.02 Corrigir a funcao de arredondamento
    [!] T-02.03 Integrar com o gateway ← T-02.02
    [>] T-02.04 Atualizar o relatorio de fechamento <
    [ ] T-02.05 Revisar a documentacao de uso ||

eventos recentes
  14:32 task_concluida T-02.02 · suite verde, 14 testes
  14:28  suite_executada T-02.02 · 14 passed
  14:11 regra_violada T-02.02 escopo-da-task · arquivo fora do plano

ultimo evento há 3 min · 1 violacao em aviso

Uso

FormaO que faz
expx watchsegue o trabalho atual, lido do .expx/estado.json
expx watch <trabalho_id>segue um trabalho específico
expx watch --todoslista os trabalhos abertos, um por linha, sem árvore
expx watch --colunas 100largura fixa, útil para capturar saída

Sai com Ctrl+C, devolvendo o terminal ao estado anterior — cursor restaurado inclusive em encerramento por exceção.

Como ele escolhe o trabalho

A precedência é deliberada, e cada degrau existe para um caso real:

  1. o id que você pediu na linha de comando
  2. o trabalho do estado.json, se ele existir no disco observado — apontar para uma pasta apagada ou de outro repositório não trava o watch
  3. entre os trabalhos em_andamento, o mais recente por atualizado_em
  4. sem nenhum em andamento: o mais recente entre os abertos
  5. nada aberto: o mais recente entre todos, inclusive concluídos

Três gatilhos, três custos

O watch não relê tudo a cada mudança. Ele separa o que mudou:

MudouO que ele relê
qualquer arquivo em docs/a visão inteira — a única releitura cara
.expx/estado.jsonsó o estado, e recalcula se está degradado
docs/eventos/*.jsonlsó a cauda dos eventos e a contagem de violações

O rastro é lido pela cauda — só os últimos 64 KB, em linhas completas, descartando o fragmento cortado ao meio. O arquivo só rotaciona em 5 MB, e reler tudo a cada evento seria a chamada cara que a especificação proíbe.

Modo degradado. Quando o .expx/estado.json não pode ser lido — ausente, JSON inválido ou de uma versão desconhecida —, o watch continua funcionando a partir do plano. O que some é o que só o estado sabe: raio, orçamento, branch e estado do PR.

O desenho

Bloqueio aberto sobe ao topo, acima até do cabeçalho. A ordem das seções é fixa: bloqueios, cabeçalho, árvore, eventos, rodapé.

A tela é redesenhada de forma incremental: as linhas anteriores são guardadas, comparadas, e só as que mudaram são reescritas. Se nada mudou, nada é escrito — por isso não pisca. O buffer alternativo do terminal foi descartado de propósito: ele apagaria o que estava na tela quando o watch sai.

MarcaTaskSprint e fase
[x]concluidaconcluido
[>]em_andamentoem_andamento
[!]bloqueadabloqueado
[ ]pendentenao_iniciado

São dois vocabulários porque os enums do contrato são mesmo diferentes para task e para grupo — e não são intercambiáveis. Além das marcas, || indica task paralelizável, lista as dependências e < aponta a task em foco.

Contratos

Convenções R1–R14

O documento raiz. Estas regras valem para todo artefato do método: frontmatter YAML, linha do rastro, configuração de hook, frontmatter de agente. Os contratos derivados não as repetem — citam por número.

RegraDetalhe
R1O bloco YAML é a primeira coisa do arquivoEntre --- antes e depois. Nada acima: nem linha em branco, nem comentário, nem título. BOM é tolerado
R2Toda chave em snake_case, minúscula, sem acentomodulo_afetado, nunca móduloAfetado nem modulo-afetado
R3Todo valor de enum minúsculo e sem acentoconcluida, nunca Concluída. Vale para enum: texto livre leva acento normalmente
R4Datas em ISOAAAA-MM-DD; timestamp do rastro AAAA-MM-DDTHH:MM:SSZ, sempre UTC. Obtenha do sistema, nunca de memória
R5Booleanos true/false, sem aspasNunca "true", sim, yes ou 1
R6Chave nunca omitidaLista vazia é []. Valor ausente é null. A chave está sempre lá
R7O frontmatter é a única fonte para a máquinaA prosa abaixo é para humano. Nenhum leitor extrai informação dela
R8Campos de texto são de uma linhaParágrafo vai na prosa; o YAML carrega só o resumo
R9atualizado_em é reescrito a cada gravaçãoMesmo que só um campo tenha mudado
R10Nenhum caminho absoluto em nenhum valorCaminho absoluto vaza o nome de usuário da máquina, quebra ao trocar de máquina e polui o diff
R11Ausente é null, e sóNada de n/a, -, "" ou nenhum. Em prosa, a marca é n/a por extenso
R12IdsVer a tabela abaixo
R13IdiomaProsa em português do Brasil, com acento. Identificador em português sem acento, por R2 e R3
R14Encoding UTF-8, sem BOMNão escreva BOM; leitores devem tolerá-lo na entrada

Por que R6 existe. O painel diferencia “não se aplica” de “esqueceram de escrever”. Omitir a chave apaga essa diferença. E chave omitida é violação do método, não rejeição do arquivo: o arquivo continua sendo lido e aparece no painel com o defeito à vista. Rejeitar faria o trabalho sumir da tela justamente quando ele tem um problema — o oposto do que o painel serve para fazer.

R12 — os formatos de id

ArtefatoFormatoExemplo
TaskT-NN.MMT-01.02
FaseF-NN.MF-01.1
Sprintsprint-NNsprint-01
BloqueioB-NNB-01
DecisãoD-NND-07
OcorrênciaOC-AAAA-NNNNOC-2026-0142

F-01 sozinho é forma antiga e não deve ser gerada.

R4 na prática

Modelo de linguagem não sabe que dia é hoje. Data escrita de memória é o erro mais comum e o mais silencioso do método:

shell
date +%Y-%m-%d                  # data
date -u +%Y-%m-%dT%H:%M:%SZ     # timestamp do rastro

Cite sempre com o prefixo R. Existe numeração histórica sem prefixo, herdada da primeira versão do expx-schema, e ela não coincide com esta. Uma citação a “regra 6”, sem R, é ambígua.

Contratos

expx-schema v1

O frontmatter YAML de todo arquivo de estado. As skills escrevem; o painel lê e nunca escreve. É a fonte da verdade sobre os kind, seus campos e seus enums quando skill e leitor divergirem.

O cabeçalho comum

Todo arquivo carrega estas quatro chaves antes das específicas:

frontmatter
---
expx_schema: 1
expx_tool: sprintx        # sprintx | runx — quem escreveu
kind: tasks
trabalho_id: exportacao-csv-relatorios
---

trabalho_id é o slug da feature (sprintx) ou o ID da ocorrência (runx). É a chave que costura tudo — um trabalho, um nome, do plano até a entrega. O único kind que não o carrega é o relatorios_indice, que é do projeto inteiro e não de um trabalho.

Os treze kinds

kindArquivoCampos além do cabeçalho
orquestradorORQUESTRADOR.mdtitulo, tipo_trabalho, tipo_ocorrencia, estagio, status, criado_em, atualizado_em, concluido_em, sprints[], caminho_critico[]
sprintsprint-NN/sprint.mdsprint_id, titulo, status, criterio_saida, fases[], riscos[], atualizado_em
fasessprint-NN/fases.mdsprint_id, atualizado_em, fases[] de {id, titulo, status, criterio_saida, paralelizavel, paralela_com[], tasks[]}
taskssprint-NN/tasks.mdsprint_id, atualizado_em, tasks[]o arquivo mais importante para o painel
bloqueiosBLOQUEIOS.mdatualizado_em, bloqueios[] de {id, task, aberto_em, resolvido_em, descricao}
decisoes00-DECISOES.mdatualizado_em, decisoes[] de {id, decisao, alternativa_descartada, motivo, status, bloqueante}
ocorrencia00-OCORRENCIA.mdtitulo, tipo_ocorrencia, recebido_em, origem, tem_reproducao, modulo_afetado[]
causa_raiz01-CAUSA-RAIZ.mdmodo, comprovada, evidencia, arquivos_impactados[], decisoes[], atualizado_em
qaQA.mdveredito, executado_em, achados[] de {severidade, arquivo, problema, correcao_sugerida}
base_indicebase/00-INDICE.mdatualizado_em, areas[] de {arquivo, titulo, lacunas}
relatorio_tecnicorelatorios/…/tecnico.mdtitulo, tipo_ocorrencia, fechado_em, modulo_afetado[], arquivos_alterados[], testes_adicionados
relatorio_usorelatorios/…/uso.mdo mesmo, sem arquivos_alterados nem testes_adicionados — é o arquivo do cliente, e não menciona código nem no YAML
relatorios_indicerelatorios/INDICE.mdatualizado_em, entradas[] de {data, oc_id, tipo, modulo, resumo, pasta} — sem trabalho_id

A anatomia de uma task

sprint-01/tasks.md
---
expx_schema: 1
expx_tool: runx
kind: tasks
trabalho_id: OC-2026-0142
sprint_id: sprint-01
atualizado_em: 2026-08-29
tasks:
  - id: T-01.02
    titulo: Corrigir o arredondamento na faixa de peso
    fase: F-01.1
    status: concluida
    objetivo: Fazer o calculo usar duas casas em vez de truncar
    arquivos:
      cria: []
      altera: [src/frete/calculo.ts]
    teste_regressao: test/frete/calculo.regressao.test.ts
    teste_integracao: test/frete/calculo.int.test.ts
    teste_funcional: test/frete/cotacao.func.test.ts
    criterio_aceite: O teste falha antes do fix e passa depois
    depende_de: [T-01.01]
    paralelizavel: false
    concluida_em: 2026-08-29
    suite: verde
---

O campo fase da task é o vínculo autoritativo entre task e fase — não a lista tasks[] da fase. Quando as duas discordam, vale o que a task diz.

arquivos aceita duas formas: o mapa {cria, altera} que as duas skills gravam, e a lista plana que o contrato descrevia. A lista plana é normalizada para o mapa na leitura.

Os enums

CampoValores
expx_toolsprintx · runx
tipo_trabalhofeature · ocorrencia
tipo_ocorrenciabug · melhoria-ui · melhoria-ux · novo-relatorio · regra-de-calculo · campo-novo · outro · null
estagiosprintx: f1f6 · runx: e1e5
status trabalho, sprint, fasenao_iniciado · em_andamento · bloqueado · concluido
status taskpendente · em_andamento · concluida · bloqueada
suiteverde · vermelha · nao_executada
vereditoaprovado · reprovado
severidadealta · media · baixa
modo causa raizcausa_raiz · analise_impacto
evidenciateste_falho · log · codigo · null
status decisãofechada · pendente

Onde o painel procura

CaminhoO quê
docs/<slug>/features da sprintx
docs/manutencao/<OC-ID>-<slug>/ocorrências da runx
docs/relatorios/o histórico do que já foi entregue

Contratos

expx-eventos v1

O rastro append-only, e o comportamento de hooks e agentes. O estado responde “onde está”; o rastro responde “o que aconteceu e quando”.

A linha do rastro

Uma linha JSON por evento, em docs/eventos/<trabalho_id>.jsonl. Escrito por hooks e pelas skills nas transições de fase; ninguém edita à mão.

docs/eventos/OC-2026-0142.jsonl
{"ts":"2026-08-29T14:32:10Z","expx_eventos":1,"trabalho_id":"OC-2026-0142",
 "ferramenta":"runx","origem":"hook","evento":"task_concluida","fase":"e3",
 "task":"T-01.02","agente":"principal","resultado":"ok",
 "detalhe":"suite verde, 14 testes","arquivos":["src/frete/calculo.ts"]}

As doze chaves são obrigatórias, nesta ordem, e nenhuma é omitida — por R6, o que não se aplica vai null, e arquivos vazio vai []:

tsexpx_eventostrabalho_idferramenta origemeventofasetask agenteresultadodetalhearquivos

Duas chaves extras são permitidas depois das doze: hook (o nome do hook que decidiu, quando a origem é hook) e faixa (a faixa de atenção do arquivo tocado).

A validação é por contenção, nunca por igualdade de conjunto. O histórico explica: a verificação de uma skill passou a reprovar toda linha escrita por outras duas, porque elas acrescentavam uma chave extra legítima.

O vocabulário de eventos

EventoQuem grava
fase_iniciada · fase_concluidaa skill
task_iniciada · task_concluida · task_bloqueadaa skill
suite_executadahook PostToolUse
arquivo_alteradohook PostToolUse
regra_violadahook em modo aviso
acao_bloqueadahook em modo bloqueio
agente_iniciado · agente_concluidohook SubagentStop e a skill
veredito_emitidoo agente auditor ou o QA
commit_criado · pr_abertoa mergex

O campo agente nunca é null: quando não há subagente, o valor é principal.

Como os hooks funcionam

Claude CodeOpenCode
Onde vivemconfiguração do projeto, aninhados evento → matcher → handlerplugins JS auto-carregados de .opencode/plugin/
Como bloqueiamexit 2 em PreToolUse; o stderr volta ao modelolançar exceção em tool.execute.before
Modo avisoo hook registra e deixa passarnão existe no before — o contorno é anexar no after, com prefixo dizendo que a ação NÃO foi bloqueada
Canal em PostToolUsesó JSON no stdout: o exit 2 não bloqueia e o stderr não volta ao modelotool.execute.after

As sete regras que todo hook obedece

  1. Rápido — acima de 200 ms o desenvolvedor sente
  2. Silencioso quando passa — hook que fala sempre vira ruído e é ignorado
  3. Falha aberta, exceto os de segurança
  4. Sem rede
  5. Mensagem acionável — dizer o que fazer, não só o que está errado
  6. Sem estado próprio — o disco já é o estado
  7. Sempre grava no rastro, inclusive quando permite

Versionamento e rotação

O rastro é ignorado pelo versionador por padrão. Acima de 5 MB o arquivo vira <trabalho_id>.1.jsonl e um novo começa; os leitores leem os dois.

Uma consequência que não estava prevista: o rastro dá o esforço real por task sem ninguém anotar nada, e é isso que calibra a estimativa da sprintx nas features seguintes.

Contratos

expx-estado v1

Um arquivo minúsculo em .expx/estado.json, lido pela barra de status e pelo expx watch. Derivado e descartável: apagá-lo não pode quebrar nada.

A regra que justifica tudo. A barra roda a cada mensagem do assistente com debounce de 300 ms, e se um gatilho novo dispara enquanto o script ainda executa, o harness mata a execução em vez de enfileirar — script lento simplesmente não aparece. Por isso a barra nunca lê tasks.md, frontmatter, plano ou rastro: só este arquivo.

Os quinze campos

.expx/estado.json
{
  "expx_estado": 1,
  "atualizado_em": "2026-08-29T14:32:10Z",
  "trabalho": "OC-2026-0142",
  "ferramenta": "runx",
  "titulo_curto": "Arredondamento na faixa",
  "fase": "e3",
  "task": "T-02.04",
  "tasks_concluidas": 7,
  "tasks_total": 11,
  "raio": "medio",
  "orcamento_arquivos": "2/3",
  "orcamento_linhas": "31/80",
  "branch": "fix/OC-2026-0142-arredondamento",
  "pr_estado": "aberto",
  "bloqueios": 2
}

Quem escreve o quê

Cada dono atualiza apenas os seus campos: ler, alterar o que é seu, gravar — nunca sobrescrever o arquivo inteiro.

CamposDono
trabalho, ferramenta, titulo_curto, fasesprintx e runx, nas transições
task, tasks_concluidas, tasks_totalsprintx e runx, ao abrir e fechar task
raio, orcamento_arquivos, orcamento_linhaslegadox
branch, pr_estadomergex
bloqueiosquem registrar bloqueio

As sete regras

  1. Somente exibição — derivado e descartável; apagá-lo não pode quebrar nada
  2. Chave nunca omitida — o que não se aplica vai null: raio fora do modo legado, pr_estado antes do push
  3. Escrita atômica — temporário mais rename
  4. Pequeno — abaixo de 1 KB, nada de listas
  5. titulo_curto cabe em 30 caracteres — corte, não quebre linha
  6. Sem trabalho aberto, trabalho, fase e task viram null e o arquivo continua existindo
  7. Enums iguais aos do expx-schemae3, não E3; alto, não ALTO

A barra de status é mecanismo do Claude Code. O OpenCode tem o seu, com formato possivelmente diferente — isso é lacuna a verificar, não paridade garantida.

Interno

Arquitetura

Camadas isoladas, uma pasta por responsabilidade. Nenhuma regra de negócio vive no código de linha de comando.

árvore
src/
  nucleo/     catálogo das skills, resolução de versão, busca, layout, lock, integridade
  plugin/     montagem do plugin e dos manifestos, com escrita atômica
  harness/    Claude Code e OpenCode, merge de configuração, backup
  doctor/     os verificadores e o efeito de cada achado
  update/     comparação com o lock, modificação local, compatibilidade de schema
  parser/     leitura do expx-schema e do índice da memox, com falha aberta
  servidor/   o painel: HTTP, websocket e o observador de arquivos
  watch/      o watch: fontes, visão, desenho puro e terminal
  cli/        roteamento de subcomando, flags e seleção interativa
ui/           a interface do painel (React + Vite)
docs/contrato/  os contratos compartilhados pelas oito skills

Padrões que atravessam o código

Escrita atômica em toda parte

O .expx/ é montado numa pasta temporária ao lado do destino e trocado por rename. O .expx/estado.json segue a mesma regra. Nunca há um estado intermediário visível no disco.

Falha aberta onde a ausência é normal

A leitura do índice da memox devolve null em quatro casos, e nenhum deles é erro: arquivo ausente (o índice é gitignorado — é o caso comum num clone novo), JSON inválido (o motor reescreve o arquivo inteiro, e ler no instante da gravação devolve truncado), raiz que não é objeto, e versão desconhecida. Degradar mostrando, nunca quebrar.

Dois observadores de arquivo, deliberadamente diferentes

PainelWatch
Debounce300 ms150 ms
.expx/ignoradoobservado, com profundidade zero
Gatilhosum só, cegotrês: plano, estado e rastro

O painel ignora o .expx/ porque é lá que a memox grava o índice: sem ignorá-lo, reindexar dispararia o observador, que recarregaria o estado, que releria o índice — realimentação sem dado novo nenhum. O watch, ao contrário, precisa do estado.json; e observa a pasta, não o arquivo, porque a escrita atômica substitui o inode e um observador preso ao arquivo antigo pararia de ver mudança depois da primeira.

O debounce não é conforto, é correção

As skills gravam tasks.md a cada transição de task. Ler no instante da gravação produz YAML truncado — uma rejeição transitória que apareceria e sumiria da tela “fora do schema”, assustando sem motivo.

Frontmatter lido com posição de linha

O leitor de YAML foi escolhido por dar a linha de cada campo — é o que permite ao painel dizer onde está o problema. A biblioteca mais comum para frontmatter foi descartada por dois motivos medidos: não dá posição, e mantém um cache global indexado pelo conteúdo, de modo que a segunda leitura da mesma string com YAML inválido devolvia dados vazios em silêncio.

Cor ANSI escrita à mão

Os pacotes de cor presentes em node_modules são dependências transitivas de ferramentas de desenvolvimento, e somem na instalação de produção. Seis papéis semânticos — sucesso, atenção, erro, destaque, apagado e neutro — cobrem tudo o que o watch precisa.

Largura contada em code points, com normalização

Nome de arquivo vindo do macOS chega decomposto, e contar caracteres como o JavaScript conta por padrão erraria o corte em 80 colunas. A limitação conhecida: caractere de largura dupla conta como uma coluna — aceitável porque a especificação proíbe emoji e a prosa é em português.

Interno

Decisões de arquitetura

Este projeto foi planejado e executado com o próprio método. Estas são algumas das decisões registradas, com a alternativa que foi descartada e o motivo — o formato do kind: decisoes.

DecisãoAlternativa descartadaMotivo
O plugin fica dentro da árvore do marketplacemarketplace e plugin como irmãos, como a especificação descreviasource relativo que sobe de diretório é rejeitado com source: Invalid input
O init chama claude plugin marketplace add e installapenas declarar o marketplace na configuração do projetocinco sintaxes testadas em execução e nenhuma carregou o plugin
Ler a lista de plugins habilitados como array ou objeto, e escrever objetoseguir o array da documentação oficialo arquivo real que o Claude Code escreve usa objeto
Busca por git clone raso, com o git do sistemaAPI REST do GitHub com tokenaproveita a credencial já configurada e não esbarra em limite de requisição
Com OpenCode, as skills vão para .claude/skills/copiar para os dois diretóriosdois name iguais são resolvidos por último-a-escrever-vence, em silêncio
Modificação local por hash SHA-256 de cada arquivohash único da árvore, ou comparação por data de modificaçãohash por arquivo diz qual arquivo mudou; data de modificação muda sozinha
Rollback pelo versionadorguardar a versão anterior dentro do .expx/duplicaria no repositório o que o versionador já guarda melhor
Normalizador que localiza o SKILL.md e toma a pasta dele como raizassumir caminho fixo por repositórioos repositórios reais divergem, e um layout novo passa a funcionar sem mexer no CLI
Comandos do OpenCode sempre em commands/, no pluralespelhar a pasta de origem, que varia entre singular e plurala forma documentada é o plural; a normalização acontece na escrita
Framework de linha de comando escrito à mãoadotar uma biblioteca de argumentosnenhuma dependência nova para o que já estava resolvido no projeto
Escrita atômica por pasta temporária e renameescrever direto no destino finalfalha no meio deixaria a instalação anterior destruída
O painel difunde o estado inteiro a cada mudançaenviar um deltaelimina a classe de bug em que servidor e tela discordam depois de uma mensagem perdida
Releitura total do disco a cada mudançareleitura incremental do arquivo que mudouas regras cruzam referências entre arquivos; leitura parcial produziria violação falsa
Ordenar arquivos de risco por regressõesordenar por número de trabalhosarquivo central é tocado por dezenas de trabalhos sem nunca ter falhado
A tela de Memória ignora o filtro de períodoaplicar o filtro global como nas demaiso valor do sinal é justamente o antigo
Varredura por nome exato, não por extensãovarrer todo .md00-LACUNAS.md e 00-AUDITORIA.md não levam frontmatter por contrato
Um trabalho é definido pelo conteúdo, não pelo caminhoexigir uma pasta em local fixoa regra vale para qualquer estrutura de pastas que o time adote
Chave omitida é violação, não rejeiçãorejeitar o arquivo inteirorejeitar faria o trabalho sumir da tela justamente quando ele tem um problema
Skill sem tag não vira aviso na instalaçãoavisar sempre que a skill não estiver travadanenhum repositório publica tag hoje, e o aviso disparava sempre
O doctor verifica o efeito da instalação, não só a sintaxevalidar apenas o JSON dos manifestosarquivo sintaticamente válido e instalação quebrada são coisas diferentes

O plano completo, a base de conhecimento e as decisões deste projeto vivem em docs/expx-cli/, e a integração da memória em docs/memox-painel/.

Interno

Desenvolvimento

terminal
npm install
npm test          # 441 testes em 92 arquivos, sem acesso à rede
npm run typecheck
npm run build
441
testes, sem rede
92
arquivos de teste
3
projetos no runner
0
testes que dependem de rede

TypeScript estrito e ESM, Node ≥ 20.19, com o runner dividido em três projetos — servidor, ui e cli. A suíte roda contra repositórios git locais criados em tempo de teste: nenhum teste depende de rede nem do estado do GitHub.

Segurança e limites

  • Nunca pede nem armazena credencial. Repositório privado usa a credencial de git já configurada na máquina
  • Nunca escreve fora da raiz do projeto
  • Nunca escreve uma skill. O CLI busca e empacota; jamais edita conteúdo de skill
  • Escrita atômica. Se falhar no meio, o .expx/ anterior permanece intacto
  • O painel e o watch são somente leitura, e o painel escuta apenas em 127.0.0.1
  • Toda escrita destrutiva pede confirmação, com flag para pular em ambiente não interativo

Divergências conhecidas entre código e contrato

Registradas aqui porque quem for implementar um leitor precisa saber:

PontoSituação
O kind: decisoesexiste no código e nas skills, mas não está descrito no contrato expx-schema v1
Os kind da prodxa skill grava produto, pedido, veredito e briefing, mas o contrato não os descreve — o parser rejeita kind desconhecido, então os artefatos dela ainda não aparecem no painel
A regra R8 (texto de uma linha)tem validador escrito, mas ele não está aplicado a nenhum campo
A violação chave_omitidanão tem rótulo em português na tela de Conformidade, e aparece pelo identificador
O CONTRATO-expx-estado.mdnumera as regras de 1 a 7, sem o prefixo R que as convenções exigem
A verificação de compatibilidade de schemaestá implementada, mas não está ligada ao fluxo do init nem do update

Licença

MIT.