🇺🇸🇧🇷

Testei as Agent Skills do Matt Pocock — Este Foi o Resultado

Experimentei o harness de skills de engenharia do Matt Pocock em um refactor CRUD Java. Na primeira execução pulou arquitetura; na segunda fez 17 perguntas — e isto é o que saiu.

Testei as agent skills do Matt Pocock em um refactor real. Isto é o que saiu — não uma demo polida, mas uma conversa com um LLM e o código que ele produziu depois.

A versão curta: na primeira tentativa, pedi um CRUD e o agente pulou arquitetura. Na segunda, disse “pergunte tudo de novo” e obtive 17 decisões explícitas antes de mudar uma linha.

Por que o repositório se chama faruk-base2

faruk-base (o primeiro repo) foi eu escolhendo skills uma a uma — instalar isso, testar aquilo, montar meu próprio workflow na mão. Funcionou o suficiente para aprender a mecânica, mas não havia um harness coerente: sem router, sem protocolo de grilling, sem cadeia spec/ticket quando as coisas ficavam grandes.

faruk-base2 é a aposta oposta. Clonei um template construído em torno das engineering skills do Matt Pocock — alguém com mais experiência que eu curando quais skills existem e como elas encadeiam. Instale com npx skills add mattpocock/skills, restaure de skills-lock.json, leia HELP-SKILLS.md.

Renomeei o router de entrada localmente de /ask-matt para /ask-fmz. Mesmo conteúdo de skill, nome de invocação diferente em .agents/skills/, .claude/skills/ e agent/skills/. Quando vir /ask-fmz abaixo, leia mattpocock/skills.

O repositório é um testbed de skills. Esta sessão focou em examples/java-crud — uma API REST de Product em Java 21, Spring Boot 4.1 e PostgreSQL no Docker:

ItemValor
APIhttp://localhost:8090/api/products
StackJava 21, Spring Boot 4.1, PostgreSQL 17
Editor SQL (host)localhost:5433

Cada exemplo tem CONTEXT.md e ADRs em docs/adr/. Regra do workspace: decisões técnicas só após minha confirmação, uma de cada vez.

Tentativa um: “faça um CRUD” — e o agente pulou arquitetura

Antes da sessão documentada aqui, pedi ao agente — usando as skills do Matt — para construir um CRUD. Rodou. Código apareceu. Docker subiu.

O que ele não fez: me guiar pela arquitetura. Sem pergunta de design em camadas. Sem estratégia de schema. Sem momento “onde fica o banco?”. Assumiu defaults e seguiu.

Esse é o modo de falha que me importa. Um LLM com skills ainda é um LLM: se o prompt é vago e a cadeia de skills não força uma entrevista, você ganha um CRUD, não o seu CRUD.

Então abri um novo thread e anexei /ask-fmz com uma instrução mais clara:

Reconstrua o módulo Java e pergunte tudo de novo.

Tentativa dois: o fluxo que realmente usamos

flowchart LR
  A["/ask-fmz"] --> B["/grill-with-docs<br/>17 perguntas, uma por vez"]
  B --> C["Entendimento compartilhado<br/>resumo + minha confirmação"]
  C --> D["/implement<br/>TDD + testes + commit"]

Não usamos /to-spec, /to-tickets, /handoff, /prototype, nem um /code-review formal com sub-agentes paralelos. O escopo já estava fechado após o grilling — mesma sessão, direto para /implement.

O harness completo do Matt suporta um caminho mais longo (/to-spec/to-tickets/implement por ticket). Isso é para builds multi-sessão. Aqui foi revalidação de um exemplo existente, não feature greenfield.

A conversa, turno a turno

Abaixo está o arco da sessão — não cada palavra, mas as decisões como aconteceram.

Turnos 1–4 — Baseline de stack

Eu: /ask-fmz reconstrua o módulo Java e pergunte tudo de novo

Agente: Leu o java-crud atual (Spring Boot 4.1, Java 21, PostgreSQL, H2 nos testes, ddl-auto, Swagger sempre ligado). Iniciou /grill-with-docs.

TurnoPerguntaMinha resposta
1Objetivo do refactorA — mesmo CRUD de Product, revalidar stack e decisões
2Versão JavaA — Java 21
3Spring BootA — 4.x
4Banco em runtime(ver turno 5)

Turno 5 — “Onde vai ficar esse banco?”

A pergunta 4 era escolher o banco de runtime. Antes de escolher, interrompi:

Me diga onde esse banco vai ficar?

Não queria um checkbox “PostgreSQL”. Queria uma imagem do que cai na minha máquina quando rodo docker compose up.

Agente: Em vez de assumir, leu docker-compose.yml e respondeu com um diagrama — depois refez a pergunta 4 com uma tabela mapeando cada opção para portas e containers:

flowchart TB
  subgraph host["Sua máquina"]
    Editor["Editor SQL"]
    Client["Browser / curl"]
  end

  subgraph docker["Docker Compose"]
    App["java-crud"]
    DB[("PostgreSQL<br/>container: db")]
    Vol[("volume<br/>product_pg_data")]
  end

  Editor -->|"localhost:5433"| DB
  Client -->|"localhost:8090/api/products"| App
  App -->|"jdbc:postgresql://db:5432/products"| DB
  DB --- Vol

Esse foi o momento em que o grilling fez sentido. O agente não decidiu — eu ainda escolhi PostgreSQL no Docker (opção A). Mas pude ver o porquê: nada instala Postgres nativo no Windows; dados sobrevivem reinícios em volume nomeado; meu editor usa 5433, a API 8090, e o app fala com db:5432 na rede interna.

Turno 6 — Um requisito nascido no chat

Depois de entender o layout, respondi — e acrescentei algo que o checklist nunca perguntou:

A, mas preciso sempre saber como acessar esse banco no meu editor SQL.

Essa frase virou uma seção do README — “Database access (SQL editor)” (Acesso ao banco (editor SQL) no repo; docs ficam pt-BR) com host, porta, user e senha para copiar e colar. Não é código. Ainda faz parte do entregável.

TurnoTópicoMinha resposta
5Banco de testeA — H2 em memória (profile test)
6Ferramenta de schemaCLiquibase (substituindo ddl-auto: update)
7SwaggerB — só no profile dev
8Portas no hostA — API 8090, Postgres 5433

Turnos 11–17 — Arquitetura, testes, idioma

TurnoTópicoMinha resposta
9Regras de validaçãoA — manter atual (nome max 120, price ≥ 0.01, etc.)
10CamadasA — Controller → Service → Repository + DTOs + exception handler
11Build DockerAmvn test depois mvn package no Dockerfile
12Profile default do composeAdev (Swagger ligado no docker compose up)
13Liquibase nos testes H2A — mesmo changelog da produção
14Formato de erro HTTPB{ "error": "..." } em inglês
15Escopo de teste de integraçãoB“sempre testar mais coisas para não ter bugs”
16Ordenação da listagemBcreatedAt DESC
17Idioma docs vs códigoDocs pt-BR; código, testes, mensagens HTTP, labels Swagger, commits inglês

Após o turno 17, o agente mostrou uma tabela consolidada das 17 decisões mais um diagrama antes/depois. Respondi com /implement.

O que mudou no módulo

AntesDepois
ddl-auto: updateLiquibase + ddl-auto: validate
Swagger sempre ligadoSwagger só em dev; desligado em prod
Erros em português (Produto não encontrado)Inglês (Product not found)
Ordem da listagem indefinidafindAllByOrderByCreatedAtDesc()
4 testes de integração9 testes de integração
README sem bloco de acesso SQLSeção dedicada para editor SQL

Depois do /implement

O agente commitou 90526d2refactor(java-crud): revalidate example with Liquibase and expanded tests. O diff bate com a tabela acima: schema tooling, profiles Swagger, erros em inglês, ordenação da listagem, testes e README.

Vale mostrar só um trecho — a precondition Liquibase para volumes Docker legados. O setup antigo usava ddl-auto: update; meu volume ainda tinha tabela products mas sem linha em DATABASECHANGELOG. O primeiro boot após o refactor falhou com relation "products" already exists. Isto resolveu:

# db.changelog-master.yaml
preConditions:
  - onFail: MARK_RAN
  - not:
      tableExists:
        tableName: products

O resto foi estrutural: ProductRepository.findAllByOrderByCreatedAtDesc(), @Profile("dev") no OpenAPI, nove casos em ProductCrudIntegrationTest, e três ADRs novos em docs/adr/.

Como validamos

cd examples/java-crud
docker compose --profile test run --rm test   # 9/9
docker compose up --build -d
curl http://localhost:8090/actuator/health
curl http://localhost:8090/api/products/9999  # {"error":"Product not found"}

Swagger UI retornou 200 no profile dev default. Editor SQL: jdbc:postgresql://localhost:5433/products (user/pass products).

O que eu tiro disso

O prompt é o produto. Mesmas skills, duas sessões, resultados opostos. “Faça um CRUD” deixou o agente pular arquitetura. “Pergunte tudo de novo” forçou /grill-with-docs a rodar como desenhado — 17 perguntas, uma por turno, cada uma com opções e recomendação. Skills roteiam comportamento; não consertam um pedido vago.

Conversa é canal de requisitos. O requisito do editor SQL não estava em nenhum ADR até eu digitar no meio do grill. Virou seção de README com JDBC para copiar e colar. Os melhores specs às vezes chegam como comentário lateral, não como ticket.

Fatos e decisões ficam separados. Quando perguntei onde o banco ficaria, o agente leu docker-compose.yml e explicou containers, volumes e portas. Eu ainda tive que escolher PostgreSQL em vez de H2. Esse é o ritmo que quero: o agente mostra o que é verdade no repo; eu fico com a escolha.

Versionamento expõe dívida real. Migrar de ddl-auto para Liquibase quebrou startup em volume Docker antigo — tabela existia sem linha em DATABASECHANGELOG. Defaults amigáveis para demo escondem isso até você commitar com migrations. A precondition no changelog não foi teórica; desbloqueou o deploy.

Uma sessão bastou aqui. Pulamos /to-spec e /to-tickets porque o grilling fechou o escopo. Para um build de vários dias com dependências bloqueantes entre tickets, eu pegaria o caminho longo. O harness oferece os dois; escolher o caminho curto também é decisão.


Repo: faruk-base2. Skills upstream: mattpocock/skills. Router local: /ask-fmz. Handoff completo da sessão: resumo.md no repo.

Comentários

Comentários via GitHub — faça login para participar da discussão.