Pular para o conteúdo

Uso o Google Analytics pra entender o que é lido, compartilhado e clicado por aqui. Ele só carrega se você aceitar — nada de terceiros roda antes disso. Como o Google usa esses dados

A planta · aberta

Arquitetura — a planta, em aberto

Este site é o argumento. Esta página é a planta — como ele é construído, e como você construiria o seu.

Comecei o ano perdido

Um projeto que não estava indo bem, um monte de obrigações de catch-up nas ferramentas de IA, e a coisa foi degradando até o fim do ano. O Kiro já estava à mão fazia um tempo, e eu comecei o ano disposto a aprender a usar a ferramenta. E tem um detalhe que eu suspeito que muita gente sênior está vivendo e não diz em voz alta: eu tinha a ferramenta de desenvolvimento agêntico na mão — e mesmo assim me sentia de fora do hype.

Porque o problema não era a ferramenta; era onde eu ia usá-la. Naquele começo de ano, todo trabalho com IA de que eu estava perto se dividia em duas metades: a modelagem, que é forte, e o resto — systems integration, legado que não dá pra trocar, as complicações comuns de TI corporativa. É nessa segunda metade que eu passei dezoito anos, e é ela que não tem use case pronto pra você aprender — o caso tem que aparecer sozinho, no trabalho de verdade.

O caso que virou o jogo não foi este site. No início do ano, em janeiro, comecei a construir por fora um mecanismo de autenticação e autorização com regras de negócio densas, custom em Spring Boot e Spring Security, integrando sistemas legados. Eu jamais teria conseguido desenvolver aquilo sem uma agentic development tool — e não era só o prazo: eu dividia as responsabilidades de tech lead naquele projeto ao mesmo tempo. É essa a parte que a ferramenta comprou. Não velocidade de digitação: as duas coisas caberem na mesma semana. E nada me diverte mais que ver uma aplicação funcionando bonito — numa escala que sozinho eu não alcançava. Foi ali que eu vi uma coisa que não via fazia tempo: se o requisito é onde eu fico e o código é trabalhado por AI-DLC, projeto de software engineering pode ser mais audacioso. Não como previsão — como o que eu enxerguei naquele momento, com aquilo rodando na minha frente.

"Computer programming is an art, because it applies accumulated knowledge to the world, because it requires skill and ingenuity, and especially because it produces objects of beauty."

— Donald Knuth, 1974

Letras serifadas brancas em relevo sobre uma parede clara de museu, vista de ângulo, com o nome de Donald Knuth e o ano de 1974 abaixo, à direita.
Cinquenta anos antes de mim, alguém já tinha nomeado a parte de que eu mais gosto — e a parede fica no museu que existe pra registrar isso.

As férias foram em maio, em São Francisco e no Vale, e é dali que sai o resto desta página. Não teve lugar por onde eu passei sem alguma oferta de IA — no trem, na rua, na vitrine, no crachá de quem estava do lado. Voltei com a ideia do que fazer, e desde então toco isso em duas frentes: uma interna, no trabalho, com Kiro, e esta, pública, com Claude Code. Dois harness rodando o mesmo tipo de trabalho é o que me deixa separar o que é do modelo do que é do setup em volta dele.

Numa manhã eu peguei o Caltrain para sul — 8h57, próxima parada Palo Alto. O vagão era laptop aberto de ponta a ponta, loop rodando, gente trocando ideia em voz alta a caminho do trabalho. Não era evento, não era comunidade, não era nada combinado. O que eu concluí dali, e não o que eu vi: um monte de gente fazendo o mesmo tipo de trabalho, no mesmo lugar, na mesma hora — perto o suficiente para ouvir sem pedir e para responder sem marcar. Eu estive dentro disso por uma semana, em maio. No resto do ano, não estou.

Montagem de três fotos da mesma semana: à esquerda, eu e minha companheira numa calçada de pedra ao lado de uma fileira de bicicletas vermelhas, amarelas e verde-água, com árvores e céu limpo atrás; no alto à direita, o painel de bordo de um vagão do Caltrain, com "Southbound · 510 EXPRESS · 8:57a" e, abaixo, "NEXT STOP Palo Alto"; embaixo à direita, uma vitrine de museu com um iPhone de 2007 desmontado atrás de acrílico, suas peças etiquetadas — câmera, sensor de luz, microfone, alto-falante, SIM, vibracall — sob a legenda "iPhone · INTRODUCED IN JUN 2007".
Uma semana, em maio: o visitor center do Google em Mountain View, o Caltrain para sul das 8h57, a vitrine do Computer History Museum. Um trem, uma manhã, nenhuma medição. Não é dado; é o que eu vi.

Fora daquela semana o vagão não existe, e é ele que a frente pública substitui — tem uma razão para ela existir em vez de um caderno. Há opções de configuração demais — qual harness, quais hooks, que persona, que gate, qual modelo — e ninguém tem sessões suficientes para testar todas sozinho. Trocar a experiência de cada um usando IA é o que vai acelerar esse aprendizado, e por isso o que está aqui é o setup inteiro, não só a conclusão a que ele chegou.

O que o requisito exigia, e a arquitetura que ele justificou

O requisito desta frente pública é curto: publicar conteúdo, em dois idiomas, com a construção inteira em aberto. É ele que decide a arquitetura, a conta, e o resto desta página.

E ela não foi construída enxuta. Foi construída inteira e depois cortada: havia uma plataforma com backend — BFF em Lambda, DynamoDB, Cognito, SES —, um Lambda@Edge renderizando imagens OG a cada requisição, um serviço de unfurl de links, GitFlow com staging e produção, e um PWA offline-first. Um banco sem nada para guardar. Auth sem ninguém para autenticar. Um staging para um site cujo revert é um merge. Cada uma era defensável quando foi decidida, e nenhuma sobreviveu à pergunta "para que isso serve, aqui" — e cada reversão está registrada junto com a decisão que a substituiu: 0025, 0026, 0027, 0028, 0029.

O corte não é o assunto desta página; ele é a consequência. O que sobrou são três coisas — um site estático, um plugin de dev-loop e um runtime de agente — e elas não são camadas de um mesmo sistema: cada uma existe sem as outras duas. O site roda sem o plugin. O plugin instala em qualquer repositório. O runtime não é meu. O plugin tadeumendonca-skills está desligado neste repositório, e o método que roda aqui vem da workstation, no nível do usuário. O que fica no meio é a única coisa que nenhuma das três entrega sozinha — e é ali que mora o jeito como eu construo isto, que é o jeito como eu quero ser contratado pra construir: desenvolvimento AI-native com o rigor de SDLC que a maior parte do trabalho com IA dispensa, num loop construído sobre Context & Harness Engineering, com AI-DLC rodando dentro dele.

Os três pilares, e o que fica na interseçãoTrês círculos do mesmo tamanho, sobrepostos, com uma interseção comum no centro. O primeiro círculo é a solução, o repositório tadeumendonca-io, e dentro dele estão a SPA em React com Vite e TypeScript, o Terraform que provisiona CloudFront e S3, o pipeline com os gates e o deploy, e o conteúdo em markdown no próprio repositório. O segundo é a customização do harness, o repositório tadeumendonca-skills, e dentro dele estão as personas no diretório agents, os hooks registrados em hooks.json, a biblioteca de skills no diretório skills, os sete comandos que uma pessoa digita no diretório commands — autonomy, blueprint, funnel-review, new-issue, sprint-planning, sprint-review e sprint-retrospective — e os ADRs de metodologia. O terceiro é o runtime do harness, o Claude Code, e dentro dele estão o orquestrador e os subagentes, os seis eventos de hook que ele dispara — PreToolUse, UserPromptSubmit, SessionStart, Stop, SubagentStart e SubagentStop —, a política de permissões e as ferramentas com o MCP. No centro, onde os três se sobrepõem, está escrito Context & Harness Engineering. A afirmação do desenho é essa: nenhum dos três círculos sozinho é a disciplina, ela é o que existe onde os três se encontram.A soluçãotadeumendonca-ioSPA React · Vite · TSTerraform: CloudFront, S3Pipeline: gates, deployMarkdown no repositórioA customizaçãotadeumendonca-skillsPersonas em agents/Hooks em hooks.jsonA biblioteca de skillsComandos que você digitaADRs de metodologiaO runtimeClaude CodeOrquestrador, subagentesSeis eventos de hookPolítica de permissõesFerramentas e MCPContext & HarnessEngineering
Os três pilares, e o que fica na interseção

O que fica na interseção é o trabalho de verdade: decidir o que o harness barra, o que ele aconselha e o que ele só documenta — e depois provar que o inventário disso continua verdadeiro.

O lançamento mostrou o resultado. A vitrine mostra a máquina.

Pilar 1 · a solução

Uma SPA totalmente estática — React + Vite + TypeScript — servida a partir de S3 atrás do CloudFront, com uma pequena CloudFront Function reescrevendo URLs limpas. Sem servidor, sem banco, sem auth. O conteúdo é markdown no próprio repositório, e cada rota publicada é prerenderizada no build, nos dois idiomas — um artigo pode ficar retido antes de ser publicado, e um retido é compilado no bundle sem nunca ser prerenderizado.

(→ ADR-0002 totalmente estático / sem backend · ADR-0013 S3 + CloudFront)

De ponta a ponta, com os bastidores junto — e o que interessa nesse desenho é o que não está nele:

As raias e os tiers — o que o leitor encontra, e o que mantém isso de péUma grade que se lê da esquerda para a direita, com quatro colunas — público, dispositivos, frontend e infra cloud — e três raias empilhadas dentro delas. A raia de cima é a audiência, o que o leitor encontra no site: o público chega por um link, o dispositivo pede uma URL, e o que volta é HTML pré-renderizado nos dois idiomas, com a SPA React assumindo depois e nenhum terceiro carregado antes de o leitor autorizar — GA4 só com consentimento, YouTube só no clique. Essa página vem inteira da coluna de infra cloud: Route 53, ACM, CloudFront com a função de reescrita, e um bucket S3 privado que só responde àquela distribuição. Entre o frontend e a infra não existe coluna de backend, e essa ausência é a afirmação do desenho: não há tier de aplicação, porque o requisito nunca pediu um, e nada meu roda a cada requisição. As duas raias de baixo são os bastidores, o que ninguém vê e que mantém a operação de pé. A raia de produção: eu abro a Issue e ratifico o irreversível; o GitHub é o console, de qualquer dispositivo, e uma menção a claude dispara o agente dentro do CI sem nenhuma máquina minha ligada; o repositório e o build carregam os gates de CI que toda merge request roda, e produzem os dois idiomas e o PDF do CV, enquanto as personas vêm do método instalado no nível do usuário e nenhum hook recusa nada aqui; o Terraform aplica a infraestrutura só pelo pipeline, com estado no Terraform Cloud. A raia de operação é a mais fina, e é fina por constatação e não por desenho: o que eu meço é GA4 depois do consentimento, então quem recusa não entra na conta; nada observa o dispositivo do leitor, sem RUM, sem log de acesso e sem monitor de disponibilidade; depois de cada deploy um smoke roda contra o apex vivo e confere que a função publicada é a deste repositório; e sobre a conta inteira há um orçamento que avisa por e-mail, que é o único vigia contínuo que existe.INFRA CLOUDFRONTENDDISPOSITIVOSPÚBLICOabre um linkpede uma URLvem inteira daqui —e entre as duasnão há backend nenhumabre o trabalhodispara o loop deagentespublica na origemAUDIÊNCIAleitores, recrutadoresquem chegou por umlinkBASTIDORES · produçãoeu — abro a Issuee ratifico oirreversívelBASTIDORES · operaçãoo que eu meço:GA4 só depois doconsentimentoquem recusa não émedidonavegador, celulare os scrapers deLinkedIn e Xpedindo a mesma URLGitHub, de qualquerdispositivoIssue, comentário, PRuma menção a clauderoda o agente no CInada observa odispositivosem RUM, sem log deacessosem monitor dedisponibilidadeHTML pré-renderizadonos dois idiomasa SPA React assumedepoisterceiro nenhumantes de o leitorautorizaro repositório e obuildos gates de CI em todamerge requestnenhum hook recusanada aquios dois idiomas e oPDF do CVdepois de cada deploysmoke contra o apexvivoe a função no arconferida contra esterepoRoute 53 · ACMCloudFront com afunção de reescritaS3 privado, só por OACTerraform só pelopipelineplan no PR, apply nomerge, via OIDCestado no TerraformCloudsobre a conta inteiraum orçamento avisa pore-mailo único vigia contínuo
As raias e os tiers — o que o leitor encontra, e o que mantém isso de pé

A ausência é deliberada, não uma lacuna. Um desenho desses, para um sistema assim, costuma ter uma coluna de aplicação, um banco e integrações internas entre o frontend e a infra; aqui não há coluna nenhuma ali, e o que o leitor pede vem inteiro de um bucket. O único terceiro em tempo de execução é a analytics, e ela depende de consentimento. E "sem backend" levanta uma pergunta antes das outras — como um crawler enxerga isto —, cuja resposta é que nada precisa ser renderizado para ele enxergar: o que ele pede vem como HTML completo, com as tags OG dentro, direto de um arquivo estático. Sem SSR, sem renderização na borda — a função de reescrita da borda roda a cada requisição de página e mexe na URL, nada mais.

O limite viaja junto com a afirmação, porque é a parte que um leitor consegue derrubar: uma URL que não existe responde 200, não 404 — e o que volta é a landing page, com as tags OG da própria landing, sob um endereço que nunca existiu. O CloudFront mapeia 403 e 404 para /index.html, que é o que deixa uma SPA funcionar em rotas profundas e é uma troca real, não um detalhe. Já mordeu aqui uma vez: um desvio de caminho jogou as imagens de OG por artigo nesse mesmo fallback, e cada uma respondeu 200 text/html a todo scraper que a pediu.

A única lógica que roda entre um leitor e um arquivo é essa função: dez linhas executáveis, com testes unitários próprios e uma verificação pós-deploy de que a função no ar continua sendo a deste repositório. E o bucket não é público em nenhum sentido: só responde a s3:GetObject vindo desta distribuição.

(→ ADR-0004 render no build, sem SSR · ADR-0005 toda URL OG-completa · ADR-0033 analytics dependente de consentimento · iac/frontend.tf a distribuição e as policies)

R$ 34,31 por mês

Esse número mede o que este site acrescentou, não aquilo de que ele depende, e mede aquilo em que ele roda, não aquilo com que eu o construo. Dizer "custo quase zero" é a coisa mais fácil desta página, e a mais fácil de ninguém conferir — então segue a conta, com as linhas de hospedagem lidas do custo diário da conta no fim de julho de 2026 e o registro lido da tabela do registrador. Nenhuma estimada. A fatura da AWS é em dólar, e o câmbio usado aqui é R$ 5,222/USD, o fechamento de 14 de agosto de 2026 — fixo no texto, não buscado a cada build, para que o número publicado só mude quando alguém decidir mudá-lo. É com ele que você desfaz qualquer linha abaixo de volta ao valor da fatura:

  • O domínio — R$ 370,76/ano pelo .io, uma cobrança anual que cai num mês só. R$ 30,91/mês amortizado. Escolhi o .io por branding, não por custo: é a razão honesta, e a única linha daqui que você pode recusar.
  • Route 53 — R$ 2,61/mês, fixo. A hosted zone, com ou sem visitante.
  • S3 — cerca de R$ 0,78/mês, e são escritas de deploy, não leituras.
  • CloudFront — na prática R$ 0,00 com esse volume: o tráfego deste site não chega a arranhar o piso do serviço.

Some as linhas e você chega a R$ 34,30, um centavo abaixo do título. Cada linha é arredondada por conta própria, e o total lá em cima é a conversão dos USD 6,57 — que não são uma fatura só: USD 0,65 saem do custo diário da AWS e USD 5,92 são o .io amortizado, da tabela do registrador. Os dois nascem em dólar, e o real desta seção inteira é derivado deles.

Fora da AWS o critério é o mesmo. GitHub Team e Claude Max são pagos e ficam fora do total — a assinatura do GitHub Team é anterior ao site, embora a carga de CI em cima dela seja inteiramente dele; GitHub Actions e SonarCloud são zero porque os repositórios são públicos — propriedade dos repositórios, não do plano — e Terraform Cloud é zero porque a infraestrutura é pequena. E o iCloud+ é a linha que mostra o critério sendo aplicado em vez de anunciado: ele é anterior ao site, mas carrega o e-mail com domínio próprio no apex e o iac/email.tf provisiona os registros MX, DKIM e SPF dele — então não é adjacente a esta infraestrutura, está dentro dela. (→ ADR-0016)

Fora do total ficam também todas as minhas horas: R$ 34,31 por mês é o que custa manter isto no ar, não o que custou construir. Em pessoas, custou uma — fins de semana, em paralelo com consultoria. E a mesma leitura mostrou cerca de R$ 66,84 por mês que o site não estava usando: web ACLs de WAF e IPv4 públicos ociosos, esquecidos quando o backend foi aposentado. Descobri lendo a fatura, o que é tarde — infraestrutura que você para de usar não para de cobrar —, e quem vigia agora é um orçamento em iac/budget.tf deliberadamente não escopado às tags deste projeto: se fosse, só enxergaria gasto que este repo criou, e este era justamente do tipo que ele não criou.

Pilar 2 · a customização

A parte interessante não é a stack — é como ela é construída: agent-led verification, human-residual. O agente prova o "pronto" com gates mecânicos e evidência real (lint, tipos, testes ≥85%, build verde, SonarCloud, E2E funcional, um revisor de contexto fresco); o humano fica com as decisões irreversíveis e arquiteturais. É uma metodologia que você pode adotar, não algo sob medida só pra este site, e ela não mora neste repositório. O plugin tadeumendonca-skills está desligado neste repositório, e o método que roda aqui vem da workstation, no nível do usuário. Os agentes, as skills e os comandos dele são instalados pelo tedeuxx/mhw (mhw install --method), como o README diz; o plugin mora no tadeumendonca-skills. O plugin continua publicado, mas está descontinuado como fonte, e o README dele aponta para o tedeuxx/mhw. Neste repositório nenhum hook recusa nada. O merge é segurado por uma regra escrita. Os comandos irreversíveis são segurados por regras nativas de deny que reconhecem o comando pela grafia, em duas camadas: o piso de deny da workstation, instalado no nível do usuário, e as regras de deny do próprio projeto, versionadas no .claude/settings.json. A entrega é barrada pelo CI e pelo gate de contexto fresco. Onde este pilar desenha hooks, ele desenha o plugin como publicado: o que ele faz onde alguém o instala.

Como o trabalho atravessa os tiers de agente — e onde eu entroUm fluxo de cima para baixo em três tiers, com o dono nas duas pontas e uma caixa grande no meio que roda sem ele. No topo estou eu: sou o único que gera demanda, e abro a Issue. O tier 1 é a admissão, e não é uma caixa só: são três raias, e o tipo da issue decide em qual ela entra. Uma issue de produto fecha pelas duas lideranças que discordam por construção, product-lead e tech-lead. Uma de conteúdo fecha por product-lead sozinha, julgando se vale a pena escrever aquilo — não como será escrito. Uma de loop, que é a maquinaria em si, fecha por agents-lead sozinha — nunca em par, e sem exceção nenhuma —, porque a maquinaria é o objeto dela e de mais ninguém. As três raias desembocam no mesmo rótulo ready, que é o artefato que diz que a descrição foi fechada — e numa issue de loop pôr esse rótulo é decisão minha, que a sessão principal executa depois que nos alinhamos. Do ready para baixo começa o trecho AFK, o que roda sem perguntar quando eu mando drenar a fila: tudo ali dentro passa pelo orquestrador, que é a sessão principal e o eixo por onde toda persona é acionada, e que nunca faz merge e nunca decide o irreversível. Nenhuma das duas é mais segurada por hook: o plugin cujo hook recusava o merge à sessão principal está desligado aqui, então o merge é segurado por uma regra; o que ainda recusa um push direto na trunk é uma regra de deny, e ela reconhece o comando pela grafia. Na edição do repositório não há tranca nenhuma: o hook que recusava isso foi apagado, então o que mantém uma edição passando pela persona dona daquilo virou uma regra, e não um mecanismo. Ao lado dessa regra fica o scrum-master, desenhado fora do caminho: um profile que não tem ferramenta nenhuma — não aciona, não edita, não roda comando, não põe label — e que ordena a fila elegível e nomeia num registro quem deveria agir em seguida. São três partes, e a terceira é a que precisa ficar: nada impede a edição, o registro nomeia quem deveria ter agido, e o registro é escrito pela própria parte que ele restringe e não é lido por nada. Isso é detecção, autodeclarada, e não prevenção. Ele aciona o tier 2, o build, também dividido por tipo: developer no produto, content-writer no conteúdo, agents-lead no loop, construindo o que ele mesmo acabou de estressar. No conteúdo o build é um par, e não um perfil só — é por isso que aquela caixa carrega dois nomes: o content-reviewer lê o rascunho contra a mesma régua com que ele foi escrito, no máximo duas rodadas, e ele não barra nada: conserta o rascunho ali mesmo. Quem aciona os dois é o orquestrador, como todo o resto aqui dentro — um não passa trabalho para o outro direto. Sai dali uma merge request por story, que chega ao tier 3 — contexto fresco, sem viés de autoria — onde quality-assurance verifica a Definition of Done e, à parte, se aquilo pode quebrar a produção; é o único que pode fazer merge. A raia de loop chega na mesma caixa em vez de passar por fora, e ali ela responde por mais, e não por menos: numa mudança na própria maquinaria, o quality-assurance confere a mesma Definition of Done e a mesma pergunta sobre produção, e ainda exige que o agents-lead tenha deixado o marcador de veredito dele antes de poder fazer merge — é um revisor a mais que precisa ter passado, não uma revisão que deixa de acontecer. O que é classe segura ele mesmo mergeia, e o merge é o deploy. Classe de fronteira são três coisas — infraestrutura e o que ameaçar a continuidade do site, uma mudança nas regras do próprio loop, publicar um artigo — e o gate não faz merge de nenhum deles antes do meu go: cada um sai do trecho AFK e volta para mim, o meu go é um comentário meu na merge request, o gate lê esse comentário ele mesmo em vez de confiar no relato de alguém, e só então faz o merge. Depois que existe uma merge request, recusa é um canal só: o gate pedindo mudanças e o meu no-go caem na mesma caixa de devolvido, e ela volta pelo orquestrador, nunca direto para quem construiu. Nove caixas de persona, oito nomes, por dois motivos diferentes: product-lead e agents-lead aparecem duas vezes cada, porque o mesmo perfil é acionado em momentos diferentes; e uma caixa carrega dois nomes em vez de um porque a raia de conteúdo é um par. E há um canal tracejado meu com o orquestrador, para quando algo trava — existe o tempo todo e não fica no caminho. A afirmação do desenho é essa: entre o rótulo ready e o merge não há nenhum humano no caminho, e eu apareço só nas duas pontas — o que atravessa aquele trecho sozinho é apenas a classe segura.AFK · do ready ao merge, nada no caminho é humanoTIER 1 · conteúdoTIER 1 · produtoTIER 1 · loopprodutoprodutoconteúdoloopprodutoconteúdoloopacionada peloorquestradorclasse seguraclasse de fronteiragomudançasno-goHITL · EUo único que gerademandaabro a Issueagents-leadsozinha — a maquinariaé o objeto delaproduct-leadtech-leaddiscordam porconstruçãoproduct-leadsozinha — se vale apena escreverO TIER 1 FECHA AQUI ·o rótulo readya descrição fechada —numa issue de loop,decisão minha, postapela sessão principalORQUESTRADOR ·a sessão principalaciona toda personao merge: nenhum hookrecusa, uma regraseguraum push na trunk: umdeny, pela grafiaa edição dorepositório: nada arecusascrum-master · não temferramenta nenhumaordena a fila e nomeiaquem age em seguidaum registro que elemesmo escreve —ninguém lêTIER 2 · BUILDdeveloper — produtoTIER 2 · BUILDcontent-writer comcontent-reviewer —conteúdono máximo duasrodadas, contra amesma réguaTIER 2 · BUILDagents-lead — loopconstrói o queestressouMERGE REQUEST · umapor storyTIER 3 · GATE— contexto fresco, semviés de autoriaquality-assurance · oúnico que pode fazermergetoda raia — aDefinition of Done,e se isso quebra aproduçãoloop — e o marcador deveredito doagents-leaddevolvido — um canalde volta sómerge em main = odeployHITL · EUclasse de fronteira:infraestruturae continuidade, asregras do loop,um artigogo / no-go
Como o trabalho atravessa os tiers de agente — e onde eu entro

Eu apareço nas duas pontas, e são trabalhos diferentes: no começo abrindo a Issue, e no fim, só no que é classe de fronteira, decidindo se aquilo sobe. Entre uma ponta e outra não há humano nenhum no caminho. E o desenho afirma uma coisa mais estrita do que "no plano": eu sou a única origem de demanda — nada entra na fila por conta própria —, e quem fecha a admissão é o rótulo ready, que é o artefato que diz que a descrição foi fechada; do ready para baixo, só a classe segura atravessa sozinha. Nenhuma raia passa por fora do gate, nem a que constrói o próprio loop. Uma mudança na maquinaria é escrita pelo agents-lead e chega na mesma caixa, e ali ela responde por mais, e não por menos: a mesma Definition of Done, a mesma pergunta sobre produção, e em cima das duas uma exigência que nenhuma outra raia tem — que o agents-lead tenha deixado o marcador de veredito dele antes de o gate poder fazer merge. É um revisor a mais que precisa ter passado, não uma revisão que deixa de acontecer. E o custo disso, já que o resto desta página assume os seus: quem decide que uma mudança é segura é o mesmo tipo de coisa que escreveu a mudança. Classifique uma errado e ela pega o caminho vazio. O que torna isso aceitável aqui é raio de impacto, não confiança — é um site estático, e reverter é um merge.

(→ ADR-0003 trunk-based, ambiente único · ADR-0018 os gates de CI)

Do que o harness é feito

Do que o harness é feitoA afirmação vem primeiro, porque é pra ela que a grade existe. A grade é o plugin como publicado, onde alguém o instala; o plugin está desligado neste repositório, então nenhum desses hooks roda aqui. De tudo que o plugin exporta, exatamente um tipo consegue recusar: só os hooks RECUSAM, e só em dois dos seis eventos em que eles se registram. As personas ACONSELHAM, e as skills e os comandos só DOCUMENTAM. Quatro tipos contra três classes de força dá doze células; cinco têm conteúdo e sete estão vazias, e as sete vazias são o argumento. Agora o inventário de onde a afirmação é lida. As raias são os 16 registros de hook no hooks.json, escritos por 15 scripts porque o preflight está registrado duas vezes; as 8 personas do diretório agents; as 15 skills do diretório skills; e os 7 comandos do diretório commands. Na coluna que nega há uma célula só, e ela tem 4 registros em dois eventos de formatos diferentes: o permission-guard no matcher Bash, o mcp-guard no matcher das ferramentas MCP e o hitl-one-question-guard no AskUserQuestion, os três no PreToolUse, que recusam uma chamada de ferramenta antes dela rodar; e o preflight no UserPromptSubmit, que recusa o próprio prompt, antes do turno começar. Persona, skill e comando não têm célula nenhuma ali. Na coluna do meio também há uma só: as 8 personas — agents-lead, content-reviewer, content-writer, developer, product-lead, quality-assurance, scrum-master e tech-lead — que ACONSELHAM, e isso é uma afirmação sobre o julgamento delas, não sobre a cadeira, porque uma lente que ninguém aciona falha em silêncio. A terceira coluna, a dos componentes que só DOCUMENTAM, tem três células: as 15 skills, que é o que o modelo aciona sozinho; os 7 comandos, que é o que uma pessoa digita; e os outros 12 registros de hook — 5 no SessionStart, 2 no SubagentStart e no SubagentStop, e 5 no Stop. Lidas as duas colunas juntas, o preflight aparece nas duas, porque está registrado duas vezes com uma classe diferente em cada evento, e é isso que significa o desenho ser derivado e não desenhado: ninguém escrevendo à mão desenharia um script em duas colunas da mesma grade.DOCUMENTA12 hooks · nenhumrecusa onde está5 hooks · SessionStartpreflight ·session-wip ·session-plugin-version· cadence-noticeworktree-notice2 hooks ·SubagentStart eSubagentStopdispatch-metrics-start·dispatch-metrics-stop5 hooks · Stopzombie-loop-detect ·orchestrator-tool-censuspremature-pr-link-detect ·owed-pr-link-detectclosure-artifact-guardStop e SubagentStoppoderiam barrar —nenhum dos seis barra— nenhuma persona15 skills · skills/o que o modelo aciona7 comandos · commands/o que você digitaautonomy · blueprint ·funnel-reviewnew-issue ·sprint-planningsprint-review ·sprint-retrospectiveACONSELHA— nenhum hook8 personas · agents/agents-leadcontent-reviewercontent-writerdeveloperproduct-leadquality-assurancescrum-mastertech-lead— nenhuma skill— nenhum comandoNEGA4 hooks · doiseventos, dois formatos3 hooks · PreToolUse —recusam uma chamadamatcher Bash ·permission-guardmatcher mcp__.* ·mcp-guardmatcherAskUserQuestion ·hitl-one-question-guard1 hook ·UserPromptSubmit —recusa o promptpreflight— nenhuma persona— nenhuma skill— nenhum comandotipo · o que o -skills exporta onde instaladohooks · 16hooks.json15 scripts — um estáregistrado duas vezespersonas · 8agents/skills · 15skills/comandos · 7commands/
Do que o harness é feito

Dos componentes do próprio plugin, onde ele está instalado, exatamente um tipo consegue te barrar, e essa é a versão honesta do convite a adotar: quatro dos dezesseis registros no hooks.json devolvem uma negativa antes do ato, e o ato não acontece. E eles fazem isso em dois formatos diferentes, que é a parte que vale ter: o permission-guard no Bash, o mcp-guard nas ferramentas MCP e o hitl-one-question-guard no AskUserQuestion estão no PreToolUse e recusam uma chamada de ferramenta; o preflight está no UserPromptSubmit e recusa o prompt, antes do turno começar. os três hooks de PreToolUse — o permission-guard e o wip-guard no Bash, e o orchestrator-write-guard nas ferramentas que escrevem arquivo — riscado: daquelas quatro afirmações, sobrou uma. Dois desses guards foram apagados no plugin e o mcp-guard nunca tinha aparecido nesta página. E nada aqui pegou isso — que é a perna atrasada descrita dois parágrafos abaixo, chegando como instância e não como ressalva: o desenho concordava com o manifesto, então aquela checagem ficou verde com os dois lados desatualizados juntos, e um apagamento de lá não dispara nada deste lado. E o preflight está desenhado em duas colunas da grade acima, porque está registrado duas vezes com uma classe diferente em cada evento — que é a única coisa aqui que ninguém escrevendo à mão teria desenhado.

Os outros doze registros só reportam, e não pelo mesmo motivo — e essa distinção esta página te deve, não dá pra arredondar. Seis deles estão em eventos que não recusam nada, o SessionStart e o SubagentStart, então esses seis não conseguiriam barrar nem se quisessem; e repare que o motivo é o evento, e não a ausência de uma chamada de ferramenta, porque o UserPromptSubmit também não tem chamada nenhuma na frente e recusa assim mesmo. Os outros seis conseguiriam. O Stop consegue barrar o fim do turno e o SubagentStop consegue barrar a parada de um subagente, e todos esses scripts escolhem não barrar: toda saída deles é de sucesso. O zombie-loop-detect percebe, um turno atrasado e uma vez por sessão pra aquele head, que tem branch parado em cima de um veredito do gate que ninguém tratou; o dispatch-metrics-stop registra os números do acionamento e sai da frente; o orchestrator-tool-census nomeia o que o orquestrador fez com as próprias mãos, as chamadas que escrevem e postam separadas das que só leem, e não decide nada sobre isso. Seis hooks escolhendo não ser mecanismo dizem mais sobre este harness do que um dizia. E as personas aconselham — o julgamento delas não é verificado por nada, e o guia do próprio plugin diz com todas as letras que uma lente que ninguém aciona falha em silêncio. Essa é a garantia que o loop do plugin dá — e ela vale exatamente o que valer o inventário do desenho acima.

E o inventário desse desenho é conferível — é essa a segunda garantia, e ela é de outra natureza. Renomeie uma persona no plugin e o build deste repositório fica vermelho. — riscado: sozinha, uma renomeação de lá não deixa nada vermelho aqui. Ele fica vermelho no próximo pull request daqui que abrir um dos arquivos que essa comparação lê, o que é uma garantia real e mais fraca que a frase que ela substitui; é na segunda perna, abaixo, que essa diferença mora. O diagrama acima é escrito à mão: um teste compara o desenho, nó a nó e contagem a contagem, com um manifesto versionado, nas duas edições; e um job de CI compara esse manifesto com a árvore viva do plugin. A diferença entre desenhar um harness e provar que o desenho ainda é ele é exatamente essa, e ela é mecânica. E ela tem duas pernas, com limites diferentes, ditos aqui e não depois. Do desenho para o manifesto, a comparação inclui a classe de força de cada uma das doze células, nas duas edições: dar denies a uma persona no manifesto deixa isto vermelho, e é essa a afirmação central da grade. Do manifesto para a árvore viva do plugin, a checagem não tem gatilho próprio — e isso não é a mesma coisa que chegar tarde, que era o que esta página dizia até ser medido. O evento que torna o manifesto falso é um merge no outro repositório, e nenhum filtro de path daqui casa com ele, então a comparação só roda quando um pull request daqui por acaso abre uma das entradas dela. A oitava persona entrou no plugin em 2026-08-31; este job ainda estava sendo pulado em 2026-09-03, e rodou pela primeira vez em 2026-09-06 — vermelho, num pull request sem relação nenhuma que tinha mexido no CLAUDE.md por motivo próprio. Seis dias, e sessenta e sete execuções deste workflow passaram sem que essa comparação rodasse uma única vez. E a classe de cada componente sai de uma regra sobre o formato dele — em que evento um hook está registrado —, não de uma leitura do que o script faz: relendo o manifesto, o que se confere é que a classe é um valor legal, não que ela é verdadeira daquele componente.

E é por isso que eu chamo isto de uma coisa, e não de outra. AI-DLC não é meu — é o nome que a AWS deu a um ciclo de entrega cujas etapas são executadas e verificadas por agentes; eu adoto, não inventei, e ele roda dentro disto, não ao lado. Context & Harness Engineering é a afirmação que eu faço, e as duas palavras são duas coisas diferentes de construir. O contexto é o que um agente lê antes de agir: as skills, os registros, os briefs que dizem a ele o que já foi decidido, para que ele não decida de novo e diferente. O harness é o que fica entre ele e o ato: os gates, as personas que leem o que ele produziu, e o que recusa um comando — hooks onde o plugin está instalado, um piso de deny aqui — e a grade acima é o inventário, no plugin, de quais deles conseguem de fato barrá-lo. Nenhuma das metades é a disciplina sozinha — contexto sem nada que o sustente é conselho, e harness sem nada para ler é um muro — e construir, versionar e provar as duas é o trabalho. Adotar uma metodologia não custa nada dizer — e é justamente por isso que dizer não vale nada. Essa aqui é paga, e o pagamento está no parágrafo acima: um build que quebra quando o inventário deixa de ser verdade — na hora, na perna que compara dois arquivos deste repositório, e só no próximo pull request daqui na perna que alcança o plugin. São dois graus do mesmo pagamento, e cobrar cada um pelo que ele é vale mais do que uma ressalva em cima do outro. É a mesma régua de agent-led verification que o resto desta página aplica ao código, virada para a metodologia: quem afirma é quem produz a evidência.

(→ ADR-0043 o inventário ancorado no plugin)

Oito personas, contra quem cada uma argumenta — e o que cada uma carrega ao ser acionada. A última coluna é o preload de cada brief no método instalado aqui: as skills que entram na sessão da persona antes de ela ler a primeira linha da tarefa.

quemo que é delecontra quem argumentaque skills carrega ao ser acionada
product-leado leitor, valor, ordem, tamanho da fatia — e posicionamento, voz, e a verdade de qualquer coisa publicada fora da via de contento tech-lead; e num diff de product ou loop barra um merge diante de uma afirmação publicada que não é verdade — por convenção, não por hook. Em content esse veto acabou em 2026-09-03: lá ele fica com a intake e nada mais, e nenhuma persona tem bloqueio de copy nessa viaagents-configuration · engineering-standards · definition-of-ready · shell
tech-leadarquitetura, medição, sequenciamento — e é ele que escreve os registros de decisão de produto e de sistema; os do próprio loop não são dele, são do agents-leado product-lead, de propósito: produto-e-mercado e sistema são otimizações genuinamente diferentesagents-configuration · engineering-standards · definition-of-ready · documentation-standard · scm · ci · provisioning · shell
developera fatia inteira — aplicação, infraestrutura, pipeline, e os testes escritos juntoninguém. Ele constrói, e é pra ele que o gate está apontadoagents-configuration · engineering-standards · code-review · quality-gates · scm · ci · provisioning · shell
quality-assurancea entrega contra a Definition of Done, e, à parte, se a mudança pode quebrar a produçãoo developer, nos dois eixos numa passada só — e é o único que uma regra deixa fazer merge; nenhum hook segura isso aqui maisagents-configuration · engineering-standards · definition-of-done · quality-gates · scm · ci · provisioning · shell
content-writerredige artigos, texto do site e a linguagem dos posts de rede social na voz do dono — molda, corta, estrutura e traduz uma experiência que ele já tem, nunca origina umao content-reviewer, e é só isso: ele lê o rascunho contra a mesma régua com que ele foi escrito, e desde 2026-09-03 o product-lead não roda a lente de copy nesta trilha — o papel dele em content é a admissão do item, e nada alémagents-configuration · engineering-standards · shell · published-voice · content-publishing
content-reviewerlevantar a régua de um rascunho antes de ele chegar a mim — no máximo duas rodadas contra o published-voice, e ele não barra nada — conserta o rascunho ali mesmo, por dois motivos e só dois: quando consegue citar uma cláusula dessa skill, ou quando a afirmação é falsa contra a fonteo content-writer, e este é o primeiro par de verdade do elenco: tudo que não cai em nenhum dos dois motivos volta rotulado como opinião descartável, e o texto fica como estáagents-configuration · engineering-standards · shell · published-voice · content-publishing
agents-leada maquinaria em si: hooks, permissões, instruções das personas, skills e comandos, o plugin — e é ele que escreve os registros de decisão sobre o loop, a outra metade da divisão acimaeu — e esse é o caso interessante: o contraponto dele não é outra persona, é a única cadeira deste loop que não tinha com quem discutiragents-configuration · engineering-standards · documentation-standard · definition-of-ready · scm · ci · shell
scrum-masterque os ritos aconteçam, na ordem, e que nada seja pulado — ele ordena a fila elegível e nomeia, num registro, qual profile age em seguidaninguém, e ele não tem ferramenta nenhuma: não aciona, não edita, não roda comando e não põe label, então o que ele produz é um registro que a sessão principal executa — e que nada lêagents-configuration · engineering-standards

Duas coisas dessa última coluna valem ser ditas. agents-configuration e engineering-standards estão nas oito — é o preload universal: entender o próprio loop, e os padrões de engenharia contra os quais ele roda, não é assunto de especialidade nenhuma. A shell — a disciplina de arquivo e comando — está em sete das oito, e a que fica de fora é a scrum-master, que não tem nem Write nem Bash, então a regra não teria o que governar ali. E 13 das 14 skills do método são pré-carregadas por alguém: a que ninguém carrega, planning-poker, só chega numa sessão se o modelo a encontrar sozinho, pela descrição dela. Os dois números são lidos onde o método está instalado: grep -l "managed-by: personal-multi-harness" ~/.claude/skills/*/SKILL.md | wc -l conta as skills do método, e só elas, e awk '/^skills:/{f=1;next} /^[^ ]/{f=0} f' ~/.claude/agents/*.md | sort -u lista o que os oito briefs pré-carregam. As três skills próprias deste repositório, backend, cloud-infrastructure e frontend, não fazem parte do método e nenhuma persona as pré-carrega.

E esta tabela é escrita à mão — a coluna nova inclusive. Os nomes de persona do desenho lá em cima são comparados com o manifesto e com a árvore viva do plugin, então aposentar uma persona deixa um build daqui vermelho — no próximo pull request que abrir uma das entradas dessa checagem, conforme o riscado lá em cima, nunca na aposentadoria em si. Aqui, nada compara coisa nenhuma: o check-harness-drift confere nomes e contagem de personas, e não confere quais skills cada uma carrega. E a coluna tem uma fonte diferente da grade: ela é o método instalado aqui, lido das definições de agente no nível do usuário que o mhw install --method escreve, e não dos arquivos de agente do plugin, que ainda listam devops onde o método carrega scm, ci e provisioning. Nenhum job de CI daqui consegue ler essa fonte. Basta alguém mudar o bloco skills: de um brief para esta coluna passar a mentir no dia seguinte, sem nenhum sinal; a única guarda é uma checagem de grafia que falha se uma linha voltar a listar devops. E um papel mudando de mãos também não deixa nada vermelho: o que essa checagem compara de uma persona é o nome dela, e quantas personas existem — nunca o que uma linha afirma que ela faz. A autoria dos registros de decisão se dividiu entre duas destas linhas e build nenhum percebeu; aquelas duas células foram corrigidas à mão, como todo o resto desta tabela.

Uma linha corre por baixo de tudo isso, e ela é sobre consentimento, não sobre ferramenta. Tudo o que está no desenho acima é versionado — hooks, personas, skills, comandos — no repositório do plugin, e isso é deliberado: é o que faz o trabalho ser reproduzível, de modo que quem o instala receba o piso em si, e não uma descrição dele. Este repositório é diferente: o piso irreversível sob o qual ele roda tem duas camadas, o piso de deny da workstation, instalado no nível do usuário e não versionado aqui, e as regras de deny do próprio projeto, versionadas no .claude/settings.json. Um fork herda a segunda camada e não a primeira. O que não é versionado, e não vai ser, é a configuração que faz o operador ser alcançável. Toda sessão que eu rodo tem Remote Control ligado desde o primeiro segundo — remoteControlAtStartup, que abre uma ponte para eu acompanhar a sessão local viva e aprovar as chamadas de ferramenta dela do meu celular. Não é o sandbox na nuvem que o Claude Code também oferece, e os dois não se substituem: dentro de uma sessão na nuvem o Remote Control se declara indisponível, porque ali não existe a sessão local que ele existe para alcançar. Essa chave mora em ~/.claude/settings.json, na minha máquina, no único arquivo que este repositório não consegue publicar.

Essa assimetria parece um buraco no harness, e a ferramenta já tinha resolvido a discussão — eu é que nunca tinha lido. Então eu li: não o nome da chave, que não é especificação, mas o binário publicado. Configuração com escopo de repositório não consegue ligar o Remote Control. Comite "remoteControlAtStartup": true no .claude/settings.json de um projeto e a CLI ignora e diz por quê — "repo-scoped settings cannot enable Remote Control; set it at user scope". A única coisa que um repositório consegue fazer com essa chave é colocá-la em false, e essa direção é respeitada na hora, à frente do que prefira a pessoa que está rodando a sessão. Ligar é decisão de uma pessoa; desligar é decisão de um projeto; e só a segunda viaja através de um clone.

O que é a mão certa para um repositório cuja premissa inteira é ser forkado. Comitar o true teria entregado uma capacidade de sessão a todo mundo que clonasse isto e à CI, sem que nenhum deles escolhesse — e, pelo parágrafo acima, nem sequer teria funcionado: uma linha que não faz nada parecendo que faz é exatamente o defeito que esta página não para de nomear. Então o passo de configuração está no README, com os dois métodos e o que cada um custa. Esta página guarda a linha, não as instruções.

Pilar 3 · o runtime

O orquestrador é a parte do harness que você não consegue instalar. Ele não está em nada do inventário acima — nem na grade de componentes, nem no manifesto, embora o fluxo dos tiers o desenhe bem no meio do trecho AFK — e é a sessão principal: o contexto que lê uma Issue, decide qual persona acionar e pesa o que volta. O ator não é componente do plugin, a política dele em parte é — a do plugin onde ele está instalado, a do método aqui — e o que você põe é o contexto que roda aquilo. É também a parte contra a qual as fronteiras acima foram desenhadas: a coluna do meio não consegue afirmar nada além de que uma persona aconselha, e o motivo de não conseguir é que nada obriga um acionamento — o que nomeia o modo de falha sem nomear quem aciona. Quem aciona é ele, e uma lente que ele esquece é uma lente que ninguém rodou.

E o contexto dele acaba. É isso que um subagente compra: ele lê, roda, erra e refaz dentro da sessão dele, e o que chega ao orquestrador é a conclusão. Uma tarefa custa ao orquestrador o veredito, não a execução, e por isso a única alavanca real deste harness é o tamanho do veredito, girada escrevendo as instruções de cada persona. Medi uma vez, na sessão deste repositório, em 7–8 de agosto de 2026, lendo as transcrições: o que ficou dentro dos subagentes foi mais de uma ordem de grandeza maior do que o que voltou. E a economia tem teto — mesmo assim, os vereditos que voltaram foram uma fatia grande de tudo que o orquestrador consumiu vindo de uma ferramenta. Não é fuga: aquela sessão compactou duas vezes de qualquer jeito. O número não é publicado porque a fonte é uma transcrição de sessão privada, que gate nenhum alcança.

E o chão embaixo dele se mexe. Esta é a parte que o resto desta página não tem: o site eu controlo, o plugin eu controlo, o runtime não. Quem o produz publica mudança o tempo todo, e cada modelo novo muda qual configuração ainda faz sentido — não porque a configuração tenha ficado errada, mas porque ela estava compensando uma fraqueza que sumiu.

Não é dedução minha. Quando o Opus 5 saiu, o time do Claude Code apagou mais de 80% do próprio system prompt — o do produto deles, não a configuração pessoal de alguém — e o modelo ficou melhor sem o andaime. E não como evento único: a cada upgrade grande de modelo é menos andaime necessário, então se apaga regra e se recoloca só onde o modelo ainda erra. Isso é um ciclo, não uma faxina.

A tese que vem junto é a que me interessa, e ela é dura: modelos de fronteira estão sendo limitados por produtos construídos para os modelos fracos de ontem, e a vantagem fica com quem põe esforço de engenharia em verificação, e não em instrução. É a pessoa que construiu a ferramenta dizendo isso — e o nome que eu dou a esse movimento, agent-led verification, é meu, não dele. Não estou citando isso de enfeite: é corroboração independente de uma escolha que eu já tinha feito, vinda de quem tem o dado que eu não tenho.

E é por isso que este loop é feito de hooks e de gates, e não de um prompt gigante explicando ao agente como se comportar. Neste repositório a metade dos hooks passou, desde então, para regras escritas e para o piso de deny da workstation; a metade que verifica — o CI, os testes e a checagem de harness-drift — continua mecânica. O gate de contexto fresco ainda confere o resultado, mas o que o faz rodar é uma regra escrita. Instrução envelhece a cada modelo novo, e envelhece calada. Um gate, não: ele confere o resultado, e o resultado é a mesma coisa antes e depois do upgrade. Se o argumento acima estiver certo, a parte do meu harness que vai sobreviver é a que verifica — e a que manda é a que eu vou apagar.

Boris Cherny, que construiu o Claude Code, no canal do Y Combinator:

O registro de decisões É a documentação

O argumento clássico para ADRs é o humano do futuro: registre por que a decisão foi tomada, para que daqui a dois anos alguém não a desfaça sem saber o que estava em jogo. Aqui o argumento é outro, e é ele que decide o formato.

Num repositório onde quem desenvolve são agentes, o registro é contexto de inferência. O agente não tem memória do que foi discutido — ele tem o repositório, e é dali que infere o que fazer. Se a arquitetura que se formou ao longo do tempo não estiver ancorada em algum lugar do próprio código, cada mudança nova é decidida sem ela, e o resultado não é uma decisão errada isolada: é uma decisão nova que contradiz uma decisão que ninguém lembra de ter tomado. Por isso uma decisão revertida continua aqui e diz que foi revertida. Sem essa marca, o registro de uma arquitetura aposentada lê como instrução — que é a forma mais barata que existe de fazer um agente reconstruir aquilo que foi cortado de propósito. Com uma exceção, e é a única que existe: havia duas web ACLs de WAF e só a regional tem ADR — a da borda do CloudFront foi construída, foi cortada, e o registro dela é esta frase e não um arquivo.

É esse propósito que escolhe o formato, e não o contrário. MADR: contexto, as opções que estavam na mesa, a decidida, e a consequência. Um documento curto por decisão, um arquivo por decisão, tudo no mesmo repositório que o agente já lê — nada de wiki, nada de ferramenta à parte. O que um formato assim entrega para um leitor humano é rastreabilidade; o que ele entrega para um agente é o que ele precisa para não contradizer.

São 52 decisões, e agora este número também é mecânico. O índice é gerado a partir de docs/adr/, commitado como artefato e conferido no CI: acrescentar ou substituir uma decisão sem regenerar o índice deixa o pipeline vermelho, então o artefato e o diretório não têm como se separar. Esta frase dizia que o número em si era a exceção — digitado à mão, sustentado só pelo link abaixo. Era — e deixou de ser verdade no mesmo dia. Foi escrita na manhã de 2026-08-25, com 49 registros no diretório; a ADR-0050 entrou naquela noite, e a página seguiu publicando 49 — a biblioteca já tinha 50, e 51 a partir da ADR-0051, em 2026-09-04 — até esta correção. Prever uma falha em prosa não é um controle, então o número agora é comparado com esse mesmo índice gerado por um teste, e os dois não têm mais como discordar sem o pipeline ficar vermelho antes. As linhas continuam não impressas aqui de propósito — esta página aponta o detalhe canônico em vez de repeti-lo, e uma cópia de 52 linhas seria a própria regra sendo quebrada na única seção que existe para defendê-la.

(→ a biblioteca de decisões · ADR-0001 enxuto por design)

Replique para o seu contexto

Está tudo público — três repos, sem segredos.

tedeuxx/tadeumendonca-ioTypeScriptEste site e o Terraform que o serve — uma SPA estática em S3 + CloudFront, prerenderizada nos dois idiomas, com a biblioteca de decisões que registra as decisões que sustentam peso e o que cada uma custou.→ Ver no GitHub tedeuxx/mhwPythonA configuração de workstation de onde o loop daqui roda. O instalador do método coloca os agentes, as skills e os comandos no nível do usuário: a metade que dá pra adotar sem nenhuma conta em nuvem.→ Ver no GitHub tedeuxx/tadeumendonca-skillsShellO plugin do dev-loop: continua publicado, mas está descontinuado como fonte. O README dele aponta para o tedeuxx/mhw.→ Ver no GitHub

Os passos de "do fork até no ar" estão nos READMEs, não nesta página: o deste repo traz o caminho de nuvem inteiro, do domínio até o primeiro merge. A metade do loop vem do repositório da workstation, que instala o método no nível do usuário com mhw install --method; o plugin continua publicado, mas está descontinuado como fonte, e o README dele aponta para o tedeuxx/mhw. E a régua que um projeto precisa passar pra entrar no portfólio daqui também é pública, em docs/catalog-ready.md — o gate de prova de engenharia.

Uma coisa eu recomendaria copiar sem pensar duas vezes. O deploy entra na AWS por OIDC, então não há segredo guardado: uma chave vazada é acesso até alguém revogar, e um token vazado é acesso até expirar — e só se quem o pegou também satisfizer a condição do trust, que aqui é o subject imutável daquele repositório, por ID numérico e não por nome, porque nome pode ser transferido pra outra pessoa e os IDs não. A troca é que a raiz dessa confiança precisa nascer fora: o Terraform daqui não cria o provedor OIDC, nem a role que roda o próprio Terraform. É um buraco documentado num piso, e nenhum plan vai te avisar que ela saiu do lugar.

(→ ADR-0042 raiz de confiança fora do Terraform · ADR-0015 subject imutável)

O que eu ficaria nervoso de ver alguém copiar sem o resto é o merge direto pra produção. Trunk-based com ambiente único é rápido e implacável na mesma medida; sem os gates na frente, sobra só a segunda metade.

Isto está em aberto porque há mais escolhas de configuração do que sessões que uma pessoa sozinha consegue rodar. Se você rodou alguma dessas escolhas de outro jeito, é você que tem a metade que falta nesta página: me conte o contra-exemplo, ou compartilhe dizendo o que faria diferente.